性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

  • 回復(fù)
  • 收藏
  • 點贊
  • 分享
  • 發(fā)新帖

數(shù)控電源學(xué)習(xí)-軟件代碼分解學(xué)習(xí)

今天   準備著手將樂工的開源項目數(shù)控電源的代碼重新梳理一遍   將有疑問的地方貼出來   希望大家能一起學(xué)習(xí)  高手們希望能及時指導(dǎo)我們這些菜鳥    準備火力全開   同時晚上抽空把電源管理芯片494以及輸出濾波電感的計算也講解講解   吼吼
全部回復(fù)(48)
正序查看
倒序查看
2015-04-09 20:47

    首先從AD采樣端口講起,目前樂工的數(shù)控電源,AD采樣端口采用的是P1.1和P1.2.這兩個端口一個用于輸出電壓采樣,一個用于輸出電流采樣.

硬件原理圖很簡單,真正的重點是ADC端口的配置以及端口數(shù)據(jù)采集轉(zhuǎn)換的流程.

    正式開始,樂工的數(shù)控電源采用的單片機型號為STC15W4K16S4,該型號的單片機目前是STC公司最強的單片機.查找STC技術(shù)手冊,在ADC一章,可以看到ADC采樣端口內(nèi)部的拓撲結(jié)構(gòu),最上面為ADC各功能寄存器,最左邊為具有ADC采樣功能的單片機端口,中間為比較器以及DAC轉(zhuǎn)換模塊,再往右為逐次比較寄存器,是該ADC端口采樣的方式,最右邊為ADC采樣結(jié)果保存寄存器.

 

0
回復(fù)
2015-04-09 21:12
@hello-no1
  首先從AD采樣端口講起,目前樂工的數(shù)控電源,AD采樣端口采用的是P1.1和P1.2.這兩個端口一個用于輸出電壓采樣,一個用于輸出電流采樣.[圖片]硬件原理圖很簡單,真正的重點是ADC端口的配置以及端口數(shù)據(jù)采集轉(zhuǎn)換的流程.  正式開始,樂工的數(shù)控電源采用的單片機型號為STC15W4K16S4,該型號的單片機目前是STC公司最強的單片機.查找STC技術(shù)手冊,在ADC一章,可以看到ADC采樣端口內(nèi)部的拓撲結(jié)構(gòu),最上面為ADC各功能寄存器,最左邊為具有ADC采樣功能的單片機端口,中間為比較器以及DAC轉(zhuǎn)換模塊,再往右為逐次比較寄存器,是該ADC端口采樣的方式,最右邊為ADC采樣結(jié)果保存寄存器.[圖片] 

  由ADC端口采樣拓撲結(jié)構(gòu),我們可以獲得很多的信息.第一,該ADC端口采樣位數(shù)為10位,這一指標直接影響ADC采樣的精度,專業(yè)術(shù)語為ADC采樣分辨率,由該技術(shù)指標,我們可以計算出數(shù)控電源能采樣的最小輸入電壓.因為單片機為5V供電,則ADC采樣口最大輸入電壓為5V,根據(jù)Vadc(min)=5*(1/2^10)=4.88mV,則該單片機能分辨的最小輸入電壓為4.88mV.  

    根據(jù)上圖我們能獲得的第二個信息是,該型號的單片機具有ADC采樣功能的端口為P1.0口,所以當電路中需要進行ADC采樣時,需要使用P1.0口.

    獲得的第三個信息是,能控制ADC采樣口的特殊功能寄存器包括ADC_POWER(ADC電源控制寄存器),SPEED1,SPEED0(ADC采樣速度寄存器),ADC_FLAG(ADC轉(zhuǎn)換結(jié)束標志位),ADC_START(ADC轉(zhuǎn)換啟動控制位),CHS2,CHS1,CHS0(模擬通道選擇控制位)等.

    獲得的第四個信息是ADC采樣數(shù)據(jù)保存寄存器包括ADC_RES,ADC_RESL.由該寄存器的使用,我們就知道所謂10位ADC采樣的來源,其實就是兩個8位的寄存器組合起來.不過有一個寄存器只使用2位,另一個寄存器使用8位,具體哪個寄存器使用2位,哪個寄存器使用8位是由另一個寄存器CLK_DIV中的ADRJ位控制的.

  至此該單片機的ADC采樣端口控制寄存器已經(jīng)講述完畢,大家可以參考STC的技術(shù)手冊,上述有詳細的講解.

0
回復(fù)
2015-04-09 21:17
@hello-no1
 由ADC端口采樣拓撲結(jié)構(gòu),我們可以獲得很多的信息.第一,該ADC端口采樣位數(shù)為10位,這一指標直接影響ADC采樣的精度,專業(yè)術(shù)語為ADC采樣分辨率,由該技術(shù)指標,我們可以計算出數(shù)控電源能采樣的最小輸入電壓.因為單片機為5V供電,則ADC采樣口最大輸入電壓為5V,根據(jù)Vadc(min)=5*(1/2^10)=4.88mV,則該單片機能分辨的最小輸入電壓為4.88mV.   根據(jù)上圖我們能獲得的第二個信息是,該型號的單片機具有ADC采樣功能的端口為P1.0口,所以當電路中需要進行ADC采樣時,需要使用P1.0口.   獲得的第三個信息是,能控制ADC采樣口的特殊功能寄存器包括ADC_POWER(ADC電源控制寄存器),SPEED1,SPEED0(ADC采樣速度寄存器),ADC_FLAG(ADC轉(zhuǎn)換結(jié)束標志位),ADC_START(ADC轉(zhuǎn)換啟動控制位),CHS2,CHS1,CHS0(模擬通道選擇控制位)等.  獲得的第四個信息是ADC采樣數(shù)據(jù)保存寄存器包括ADC_RES,ADC_RESL.由該寄存器的使用,我們就知道所謂10位ADC采樣的來源,其實就是兩個8位的寄存器組合起來.不過有一個寄存器只使用2位,另一個寄存器使用8位,具體哪個寄存器使用2位,哪個寄存器使用8位是由另一個寄存器CLK_DIV中的ADRJ位控制的. 至此該單片機的ADC采樣端口控制寄存器已經(jīng)講述完畢,大家可以參考STC的技術(shù)手冊,上述有詳細的講解.

接著上樂工的程序,按照樂工的源代碼,首先是ADC端口的宏定義,這個沒有什么疑問.

#define ADC_POWER   0X80//ADC電源控制位

#define ADC_FLAG    0X10//ADC轉(zhuǎn)換結(jié)束標志

#define ADC_START   0X08//ADC轉(zhuǎn)換啟動控制位

#define ADC_SPEEDLL 0X00//ADC轉(zhuǎn)換速度540個時鐘周期

#define ADC_SPEEDL  0x20//ADC轉(zhuǎn)換速度360個時鐘周期

#define ADC_SPEEDH  0x40//ADC轉(zhuǎn)換速度180個時鐘周期

#define ADC_SPEEDHH 0x60//ADC轉(zhuǎn)換速度90個時鐘周期

#define ADC_CH7     0X07//ADC轉(zhuǎn)換位數(shù)

接著是功能函數(shù)的申明

void InitAdc();//ADC端口初始化

uint GetAdc10BitResult(uchar channel);//ADC采樣數(shù)據(jù)讀取

再其次是各功能函數(shù)

ADC端口初始化

void InitAdc()

{

P1ASF=0XFF;

//設(shè)置P1口為AD口ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零

ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零

ADC_CONTR=ADC_POWER|ADC_SPEEDLL;

//打開AD電源,確定AD轉(zhuǎn)換速率delay_1ms(1);

}

0
回復(fù)
2015-04-09 21:28
@hello-no1
接著上樂工的程序,按照樂工的源代碼,首先是ADC端口的宏定義,這個沒有什么疑問.#defineADC_POWER 0X80//ADC電源控制位#defineADC_FLAG  0X10//ADC轉(zhuǎn)換結(jié)束標志#defineADC_START 0X08//ADC轉(zhuǎn)換啟動控制位#defineADC_SPEEDLL0X00//ADC轉(zhuǎn)換速度540個時鐘周期#defineADC_SPEEDL 0x20//ADC轉(zhuǎn)換速度360個時鐘周期#defineADC_SPEEDH 0x40//ADC轉(zhuǎn)換速度180個時鐘周期#defineADC_SPEEDHH0x60//ADC轉(zhuǎn)換速度90個時鐘周期#defineADC_CH7  0X07//ADC轉(zhuǎn)換位數(shù)接著是功能函數(shù)的申明voidInitAdc();//ADC端口初始化uintGetAdc10BitResult(ucharchannel);//ADC采樣數(shù)據(jù)讀取再其次是各功能函數(shù)ADC端口初始化voidInitAdc(){P1ASF=0XFF;//設(shè)置P1口為AD口ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零ADC_CONTR=ADC_POWER|ADC_SPEEDLL;//打開AD電源,確定AD轉(zhuǎn)換速率delay_1ms(1);}

上述程序都沒有問題,但是下面的ADC采樣數(shù)據(jù)讀取,我就有疑問了,希望樂工以及群里的高手能解答一下,謝謝.

//讀取ADC采樣結(jié)果
uint GetAdc10BitResult(uchar AdcNum)
{
	uint AdcResult;
	uchar i;
	if(AdcNum>ADC_CH7)//ADC采樣位數(shù)判斷
		return 1024;
	ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零
	ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零

	ADC_CONTR=(ADC_CONTR&0XE0)|ADC_START|AdcNum;
	_nop_();
	_nop_();
	_nop_();
	_nop_();

	for(i=0;i<250;i++)
	{
		if(ADC_CONTR&ADC_FLAG)
		{
			ADC_CONTR=ADC_CONTR&(~ADC_FLAG);
			if(PCON2&(0X01<<5))
			{
				AdcResult=(uint)(ADC_RES&0X03);
				AdcResult=(AdcResult<<8)|ADC_RESL;
			}
			else
			{
				AdcResult=(uint)(ADC_RES);
				AdcResult=(AdcResult<<2)|(ADC_RESL&0X03);
			}
			return AdcResult;
		}
	}
	return 1024;
}

0
回復(fù)
2015-04-09 21:40
@hello-no1
上述程序都沒有問題,但是下面的ADC采樣數(shù)據(jù)讀取,我就有疑問了,希望樂工以及群里的高手能解答一下,謝謝.//讀取ADC采樣結(jié)果uintGetAdc10BitResult(ucharAdcNum){uintAdcResult;uchari;if(AdcNum>ADC_CH7)//ADC采樣位數(shù)判斷return1024;ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零ADC_CONTR=(ADC_CONTR&0XE0)|ADC_START|AdcNum;_nop_();_nop_();_nop_();_nop_();for(i=0;i
在上述的程序中,第一個疑問是

這里的疑問是ADC_CH7等于7,也就是當ADC_NUM大于7是,就不執(zhí)行下面的代碼,該功能函數(shù)直接返回1024,我有兩個疑問,第一為什么采樣的位數(shù)大于7就不執(zhí)行,為什么不是大于10.第二個疑問是返回值為什么是1024,不是0.

第二個疑問是下面這段代碼

為什么i需要小于250,這段代碼因為沒有搞懂它的作用,所以后面的代碼看的云里霧里,不知道是是什么作用,希望大家能解答,謝謝.今天我就講到這里,我把我懂得東西貼出來,把我不懂的東西也貼出來,希望大家能指點指點我.

0
回復(fù)
2015-04-10 09:41
@hello-no1
在上述的程序中,第一個疑問是[圖片]這里的疑問是ADC_CH7等于7,也就是當ADC_NUM大于7是,就不執(zhí)行下面的代碼,該功能函數(shù)直接返回1024,我有兩個疑問,第一為什么采樣的位數(shù)大于7就不執(zhí)行,為什么不是大于10.第二個疑問是返回值為什么是1024,不是0.第二個疑問是下面這段代碼[圖片]為什么i需要小于250,這段代碼因為沒有搞懂它的作用,所以后面的代碼看的云里霧里,不知道是是什么作用,希望大家能解答,謝謝.今天我就講到這里,我把我懂得東西貼出來,把我不懂的東西也貼出來,希望大家能指點指點我.
上進好童鞋 加油!~
0
回復(fù)
2015-04-10 11:05
@hello-no1
在上述的程序中,第一個疑問是[圖片]這里的疑問是ADC_CH7等于7,也就是當ADC_NUM大于7是,就不執(zhí)行下面的代碼,該功能函數(shù)直接返回1024,我有兩個疑問,第一為什么采樣的位數(shù)大于7就不執(zhí)行,為什么不是大于10.第二個疑問是返回值為什么是1024,不是0.第二個疑問是下面這段代碼[圖片]為什么i需要小于250,這段代碼因為沒有搞懂它的作用,所以后面的代碼看的云里霧里,不知道是是什么作用,希望大家能解答,謝謝.今天我就講到這里,我把我懂得東西貼出來,把我不懂的東西也貼出來,希望大家能指點指點我.
帖子不錯哦,推薦到帖子底部經(jīng)典圖庫。更多請點擊:http://www.e-ticket.cn/bbs/classic/
0
回復(fù)
2015-04-10 11:57
@hello-no1
在上述的程序中,第一個疑問是[圖片]這里的疑問是ADC_CH7等于7,也就是當ADC_NUM大于7是,就不執(zhí)行下面的代碼,該功能函數(shù)直接返回1024,我有兩個疑問,第一為什么采樣的位數(shù)大于7就不執(zhí)行,為什么不是大于10.第二個疑問是返回值為什么是1024,不是0.第二個疑問是下面這段代碼[圖片]為什么i需要小于250,這段代碼因為沒有搞懂它的作用,所以后面的代碼看的云里霧里,不知道是是什么作用,希望大家能解答,謝謝.今天我就講到這里,我把我懂得東西貼出來,把我不懂的東西也貼出來,希望大家能指點指點我.
ADC_CH7等于7:AD通道只有8個即0-7軟件濾出錯誤,1024其實是自定義的一個數(shù)值,10位AD的有效數(shù)據(jù)為0-1023   只要是1023以上的任意數(shù)據(jù)都可以,只要不是0-1023軟件直接排除錯誤返回了。
0
回復(fù)
2015-04-10 12:04
@yueyunno1
ADC_CH7等于7:AD通道只有8個即0-7軟件濾出錯誤,1024其實是自定義的一個數(shù)值,10位AD的有效數(shù)據(jù)為0-1023 只要是1023以上的任意數(shù)據(jù)都可以,只要不是0-1023軟件直接排除錯誤返回了。
i=250這個for循環(huán)可要可不要
0
回復(fù)
2015-04-10 12:27
@電源網(wǎng)-fqd
帖子不錯哦,推薦到帖子底部經(jīng)典圖庫。更多請點擊:http://www.e-ticket.cn/bbs/classic/
今晚著手整理EEPROM代碼,我到時把我理解的以及我不懂的都貼出來,希望高手錳能及時指點,謝謝諸位
0
回復(fù)
2015-04-10 20:10
@yueyunno1
i=250這個for循環(huán)可要可不要

將重新整理注釋的ADC采樣代碼上傳,供大家參考,其實還是樂工的功勞,我自己只是把它貼出來用于消化而已

#include "Ad.h"
#include "Delay.h"

//ADC端口初始化
void InitAdc()
{
	P1ASF=0XFF;//設(shè)置P1口為AD口
	ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零
	ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零
	ADC_CONTR=ADC_POWER|ADC_SPEEDLL;//打開AD電源,確定AD轉(zhuǎn)換速率
	delay_1ms(1);
}

//讀取ADC采樣結(jié)果
uint GetAdc10BitResult(uchar AdcNum)
{
	uint AdcResult;
	uchar i;
	if(AdcNum>ADC_CH7)//ADC采樣位數(shù)判斷
		return 1024;
	ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零
	ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零

	ADC_CONTR=(ADC_CONTR&0XE0)|ADC_START|AdcNum;//ADC寄存器配置
	_nop_();
	_nop_();
	_nop_();
	_nop_();

	for(i=0;i<250;i++)//
	{
		if(ADC_CONTR&ADC_FLAG)//數(shù)模轉(zhuǎn)換結(jié)束
		{
			ADC_CONTR=ADC_CONTR&(~ADC_FLAG);//ADC采樣寄存器置零
			if(PCON2&(0X01<<5))//ADRJ為1
			{
				AdcResult=(uint)(ADC_RES&0X03);//采樣數(shù)據(jù)高兩位保存于ADC_RES
				AdcResult=(AdcResult<<8)|ADC_RESL;//采樣數(shù)據(jù)低八位保存于ADC_RESL
			}
			else
			{
				AdcResult=(uint)(ADC_RES);//采樣數(shù)據(jù)低八位保存于ADC_RES
				AdcResult=(AdcResult<<2)|(ADC_RESL&0X03);//采樣數(shù)據(jù)高兩位保存于ADC_RESL
			}
			return AdcResult;
		}
	}
	return 1024;
}

0
回復(fù)
2015-04-10 20:33
@hello-no1
將重新整理注釋的ADC采樣代碼上傳,供大家參考,其實還是樂工的功勞,我自己只是把它貼出來用于消化而已#include"Ad.h"#include"Delay.h"http://ADC端口初始化voidInitAdc(){P1ASF=0XFF;//設(shè)置P1口為AD口ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零ADC_CONTR=ADC_POWER|ADC_SPEEDLL;//打開AD電源,確定AD轉(zhuǎn)換速率delay_1ms(1);}//讀取ADC采樣結(jié)果uintGetAdc10BitResult(ucharAdcNum){uintAdcResult;uchari;if(AdcNum>ADC_CH7)//ADC采樣位數(shù)判斷return1024;ADC_RES=0X00;//AD轉(zhuǎn)化寄存器清零ADC_RESL=0X00;//AD轉(zhuǎn)化寄存器清零ADC_CONTR=(ADC_CONTR&0XE0)|ADC_START|AdcNum;//ADC寄存器配置_nop_();_nop_();_nop_();_nop_();for(i=0;i
    今天主要是分解樂工的EEPROM代碼,還是老套路,先熟悉STC15W4K16S4芯片EEPROM的特殊功能寄存器.

第一個寄存器為IAP_DATA,作用為保存讀寫數(shù)據(jù).

第二個寄存器為IAP_ADDRH,IAP_ADDRL,作用為ISP_IAP操作時的地址寄存器高八位和低八位

第三個寄存器是ISP_IAP命令寄存器IAP_CMD,作用是對EEPROM中的數(shù)據(jù)存儲區(qū)進行讀,編程,擦除操作

第四個寄存器為IAP_TRIG,當需要進行IAP操作時,都需要先將IAP_FLAG寫入5A再寫入A5,才能接著進行IAP操作,該操作看手冊我沒有看的明白,需要結(jié)合實際的代碼來分析

第五個寄存器為IAP_CONTR,為IAP控制寄存器,用于控制IAP的使能,復(fù)位起始地址,讀,擦除,編程時間等,該寄存器是EEPROM中比較關(guān)鍵的寄存器之一

第六個寄存器為電源控制寄存器PCON,當檢測到電源電壓過低時,不進行EEPROM_IAP操作

0
回復(fù)
2015-04-10 20:42
@hello-no1
  今天主要是分解樂工的EEPROM代碼,還是老套路,先熟悉STC15W4K16S4芯片EEPROM的特殊功能寄存器.[圖片]第一個寄存器為IAP_DATA,作用為保存讀寫數(shù)據(jù).第二個寄存器為IAP_ADDRH,IAP_ADDRL,作用為ISP_IAP操作時的地址寄存器高八位和低八位第三個寄存器是ISP_IAP命令寄存器IAP_CMD,作用是對EEPROM中的數(shù)據(jù)存儲區(qū)進行讀,編程,擦除操作第四個寄存器為IAP_TRIG,當需要進行IAP操作時,都需要先將IAP_FLAG寫入5A再寫入A5,才能接著進行IAP操作,該操作看手冊我沒有看的明白,需要結(jié)合實際的代碼來分析第五個寄存器為IAP_CONTR,為IAP控制寄存器,用于控制IAP的使能,復(fù)位起始地址,讀,擦除,編程時間等,該寄存器是EEPROM中比較關(guān)鍵的寄存器之一第六個寄存器為電源控制寄存器PCON,當檢測到電源電壓過低時,不進行EEPROM_IAP操作

首先依舊是老套路,寄存器的宏定義

sfr IAP_DATA  = 0xC2;
sfr IAP_ADDRH = 0xC3;
sfr IAP_ADDRL = 0xC4;
sfr IAP_CMD   = 0xC5;
sfr IAP_TRIG  = 0xC6;
sfr IAP_CONTR = 0xC7;

sfr ISP_DATA  = 0xC2;
sfr ISP_ADDRH = 0xC3;
sfr ISP_ADDRL = 0xC4;
sfr ISP_CMD   = 0xC5;
sfr ISP_TRIG  = 0xC6;
sfr ISP_CONTR = 0xC7;

#define CMD_IDLE     0X00//空閑模式
#define CMD_READ     0X01//Iap字節(jié)讀命令
#define CMD_PROGRAM  0X02//Iap字節(jié)編程命令
#define CMD_ERASE    0X03//Iap扇區(qū)擦除命令
#define ENABLE_IAP   0X80//Iap使能設(shè)置
//#define ENABLE_IAP 0x80//if SYSCLK<30MHz
//#define ENABLE_IAP 0x81//if SYSCLK<24MHz
//#define ENABLE_IAP 0x82//if SYSCLK<20MHz
//#define ENABLE_IAP 0x83//if SYSCLK<12MHz
//#define ENABLE_IAP 0x84//if SYSCLK<6MHz
//#define ENABLE_IAP 0x85//if SYSCLK<3MHz
//#define ENABLE_IAP 0x86//if SYSCLK<2MHz
//#define ENABLE_IAP 0x87//if SYSCLK<1MHz
#define SetVoltageAddress 0X0005//
#define SetCurrentAddress 0X0205//

0
回復(fù)
2015-04-10 20:44
@hello-no1
首先依舊是老套路,寄存器的宏定義sfrIAP_DATA=0xC2;sfrIAP_ADDRH=0xC3;sfrIAP_ADDRL=0xC4;sfrIAP_CMD=0xC5;sfrIAP_TRIG=0xC6;sfrIAP_CONTR=0xC7;sfrISP_DATA=0xC2;sfrISP_ADDRH=0xC3;sfrISP_ADDRL=0xC4;sfrISP_CMD=0xC5;sfrISP_TRIG=0xC6;sfrISP_CONTR=0xC7;#defineCMD_IDLE0X00//空閑模式#defineCMD_READ0X01//Iap字節(jié)讀命令#defineCMD_PROGRAM0X02//Iap字節(jié)編程命令#defineCMD_ERASE0X03//Iap扇區(qū)擦除命令#defineENABLE_IAP0X80//Iap使能設(shè)置//#defineENABLE_IAP0x80//ifSYSCLK

接著是各功能函數(shù)的申明

void IapIdle();//關(guān)閉Iap功能
void IapEraseSector(uint addr);//扇區(qū)擦除
uchar IapReadByte(uint addr);//從Isp/Iap/EEPROM中讀取一字節(jié)
IapReadByte16BitData(uint adr);//從Isp/Iap/EEPROM中讀取兩字節(jié)
void IapProgramByte(uint addr,uchar dat);//向Isp/Iap/EEPROM中寫一字節(jié)
void IapProgram16BitData(uint adr, uint dat);////向Isp/Iap/EEPROM中寫兩字節(jié)

0
回復(fù)
2015-04-10 20:51
@hello-no1
接著是各功能函數(shù)的申明voidIapIdle();//關(guān)閉Iap功能voidIapEraseSector(uintaddr);//扇區(qū)擦除ucharIapReadByte(uintaddr);//從Isp/Iap/EEPROM中讀取一字節(jié)IapReadByte16BitData(uintadr);//從Isp/Iap/EEPROM中讀取兩字節(jié)voidIapProgramByte(uintaddr,uchardat);//向Isp/Iap/EEPROM中寫一字節(jié)voidIapProgram16BitData(uintadr,uintdat);////向Isp/Iap/EEPROM中寫兩字節(jié)
        函數(shù)申明這里我有疑問了,IapReadByte16BitData(uint adr)該函數(shù)的申明,樂工并沒有指明函數(shù)的返回值類型,根據(jù)C語言的規(guī)定,如果沒有指定函數(shù)返回值類型,則返回int型數(shù)據(jù).但是該函數(shù)是通過調(diào)用uchar IapReadByte(uint addr)函數(shù)來實現(xiàn)讀取兩字節(jié)數(shù)據(jù)的.我的疑問是IapReadByte(uint addr)的返回值為uchar型,但是IapReadByte16BitData(uint adr)函數(shù)的返回值是int型,是否有錯誤?
0
回復(fù)
2015-04-10 21:04
@hello-no1
        函數(shù)申明這里我有疑問了,IapReadByte16BitData(uintadr)該函數(shù)的申明,樂工并沒有指明函數(shù)的返回值類型,根據(jù)C語言的規(guī)定,如果沒有指定函數(shù)返回值類型,則返回int型數(shù)據(jù).但是該函數(shù)是通過調(diào)用ucharIapReadByte(uintaddr)函數(shù)來實現(xiàn)讀取兩字節(jié)數(shù)據(jù)的.我的疑問是IapReadByte(uintaddr)的返回值為uchar型,但是IapReadByte16BitData(uintadr)函數(shù)的返回值是int型,是否有錯誤?

接下來是各功能函數(shù)的具體實現(xiàn),樂工參考了STC單片機的例程,我把樂工的代碼貼出來同時把我的疑問也寫出來,希望大家指點,謝謝先.

首先是

void IapIdle()//關(guān)閉Iap功能
{
	IAP_CONTR=0X00;//關(guān)閉IAP功能
	IAP_CMD=0X00;//清除命令寄存器
	IAP_TRIG=0X00;//清除觸發(fā)寄存器
	IAP_ADDRH=0X80;//將地址設(shè)置到非IAP區(qū)域
	IAP_ADDRL=0X00;
}
在該函數(shù)中IAP_ADDRH=0X80;//將地址設(shè)置到非IAP區(qū)域
                	IAP_ADDRL=0X00;
這里沒有看懂,不知道將地址設(shè)置到非IAP區(qū)域是什么意思,查閱STC技術(shù)手冊,看到
	

是否與IAP字節(jié)讀時EEPROM結(jié)束扇區(qū)末尾地址有關(guān),望樂工解答,先謝謝樂工.

0
回復(fù)
2015-04-10 21:05
@hello-no1
接下來是各功能函數(shù)的具體實現(xiàn),樂工參考了STC單片機的例程,我把樂工的代碼貼出來同時把我的疑問也寫出來,希望大家指點,謝謝先.首先是voidIapIdle()//關(guān)閉Iap功能{IAP_CONTR=0X00;//關(guān)閉IAP功能IAP_CMD=0X00;//清除命令寄存器IAP_TRIG=0X00;//清除觸發(fā)寄存器IAP_ADDRH=0X80;//將地址設(shè)置到非IAP區(qū)域IAP_ADDRL=0X00;}在該函數(shù)中IAP_ADDRH=0X80;//將地址設(shè)置到非IAP區(qū)域               IAP_ADDRL=0X00;這里沒有看懂,不知道將地址設(shè)置到非IAP區(qū)域是什么意思,查閱STC技術(shù)手冊,看到[圖片]是否與IAP字節(jié)讀時EEPROM結(jié)束扇區(qū)末尾地址有關(guān),望樂工解答,先謝謝樂工.

接著是扇區(qū)擦除操作代碼

void IapEraseSector(uint IapAddress0)//扇區(qū)擦除
{
	IAP_CONTR=ENABLE_IAP;//使能IAP
    IAP_CMD=CMD_ERASE;//設(shè)置IAP命令
    IAP_ADDRL=IapAddress0;//設(shè)置IAP低地址
    IAP_ADDRH=IapAddress0>>8;//設(shè)置IAP高地址
    IAP_TRIG=0x5a;//寫觸發(fā)命令(0x5a)
    IAP_TRIG=0xa5;//寫觸發(fā)命令(0xa5)
    _nop_();//等待ISP/IAP/EEPROM操作完成
    IapIdle();
}

0
回復(fù)
2015-04-10 21:08
@hello-no1
接著是扇區(qū)擦除操作代碼voidIapEraseSector(uintIapAddress0)//扇區(qū)擦除{IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_ERASE;//設(shè)置IAP命令I(lǐng)AP_ADDRL=IapAddress0;//設(shè)置IAP低地址IAP_ADDRH=IapAddress0>>8;//設(shè)置IAP高地址IAP_TRIG=0x5a;//寫觸發(fā)命令(0x5a)IAP_TRIG=0xa5;//寫觸發(fā)命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}

接著是讀一字節(jié)數(shù)據(jù)

//從Isp/Iap/EEPROM中讀取一字節(jié)
uchar IapReadByte(uint IapAddress1)
{
	uchar BufferData0;//緩沖數(shù)據(jù)

    IAP_CONTR=ENABLE_IAP;//使能IAP
    IAP_CMD=CMD_READ;//設(shè)置IAP命令
    IAP_ADDRL=IapAddress1;//設(shè)置IAP低地址
    IAP_ADDRH=IapAddress1>>8;//設(shè)置IAP高地址
    IAP_TRIG=0x5a;//寫觸發(fā)命令(0x5a)
    IAP_TRIG=0xa5;//寫觸發(fā)命令(0xa5)
    _nop_();//等待ISP/IAP/EEPROM操作完成
    BufferData0=IAP_DATA;//讀ISP/IAP/EEPROM數(shù)據(jù)
    IapIdle();//關(guān)閉IAP功能

    return BufferData0;                     //返回
}

0
回復(fù)
2015-04-10 21:14
@hello-no1
接著是讀一字節(jié)數(shù)據(jù)//從Isp/Iap/EEPROM中讀取一字節(jié)ucharIapReadByte(uintIapAddress1){ucharBufferData0;//緩沖數(shù)據(jù)IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_READ;//設(shè)置IAP命令I(lǐng)AP_ADDRL=IapAddress1;//設(shè)置IAP低地址IAP_ADDRH=IapAddress1>>8;//設(shè)置IAP高地址IAP_TRIG=0x5a;//寫觸發(fā)命令(0x5a)IAP_TRIG=0xa5;//寫觸發(fā)命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成BufferData0=IAP_DATA;//讀ISP/IAP/EEPROM數(shù)據(jù)IapIdle();//關(guān)閉IAP功能returnBufferData0;//返回}
//從Isp/Iap/EEPROM中讀取兩字節(jié)
IapReadByte16BitData(uint IapAddress2)
{
	uint BufferData16Bit;//緩沖數(shù)據(jù)
	BufferData16Bit=IapReadByte(IapAddress2);
	BufferData16Bit<<=8;
	IapAddress2++;
	BufferData16Bit=BufferData16Bit|IapReadByte(IapAddress2);
	return BufferData16Bit;

}

該代碼中IapAddress2++作用是否是將該數(shù)值加一后用于存儲下一段數(shù)據(jù)

0
回復(fù)
2015-04-10 21:15
@hello-no1
//從Isp/Iap/EEPROM中讀取兩字節(jié)IapReadByte16BitData(uintIapAddress2){uintBufferData16Bit;//緩沖數(shù)據(jù)BufferData16Bit=IapReadByte(IapAddress2);BufferData16Bit
//向Isp/Iap/EEPROM中寫一字節(jié)
void IapProgramByte(uint IapAddress3,uchar BufferData1)
{
	IAP_CONTR=ENABLE_IAP;//使能IAP
    IAP_CMD=CMD_PROGRAM;//設(shè)置IAP命令
    IAP_ADDRL=IapAddress3;//設(shè)置IAP低地址
    IAP_ADDRH=IapAddress3>>8;//設(shè)置IAP高地址
    IAP_DATA=BufferData1;//寫ISP/IAP/EEPROM數(shù)據(jù)
    IAP_TRIG=0x5a;//寫觸發(fā)命令(0x5a)
    IAP_TRIG=0xa5;//寫觸發(fā)命令(0xa5)
    _nop_();//等待ISP/IAP/EEPROM操作完成
    IapIdle();
}

//向Isp/Iap/EEPROM中寫兩字節(jié)
void IapProgram16BitData(uint IapAddress4, uint BufferData16Bit)
{
	uchar DataTemp1,DataTemp2;

	DataTemp1=BufferData16Bit/256;
	DataTemp2=BufferData16Bit%256;

	IapProgramByte(IapAddress4, DataTemp1);
	IapAddress4++;
	IapProgramByte(IapAddress4, DataTemp2);
}
0
回復(fù)
2015-04-10 21:16
@hello-no1
//向Isp/Iap/EEPROM中寫一字節(jié)voidIapProgramByte(uintIapAddress3,ucharBufferData1){IAP_CONTR=ENABLE_IAP;//使能IAPIAP_CMD=CMD_PROGRAM;//設(shè)置IAP命令I(lǐng)AP_ADDRL=IapAddress3;//設(shè)置IAP低地址IAP_ADDRH=IapAddress3>>8;//設(shè)置IAP高地址IAP_DATA=BufferData1;//寫ISP/IAP/EEPROM數(shù)據(jù)IAP_TRIG=0x5a;//寫觸發(fā)命令(0x5a)IAP_TRIG=0xa5;//寫觸發(fā)命令(0xa5)_nop_();//等待ISP/IAP/EEPROM操作完成IapIdle();}//向Isp/Iap/EEPROM中寫兩字節(jié)voidIapProgram16BitData(uintIapAddress4,uintBufferData16Bit){ucharDataTemp1,DataTemp2;DataTemp1=BufferData16Bit/256;DataTemp2=BufferData16Bit%256;IapProgramByte(IapAddress4,DataTemp1);IapAddress4++;IapProgramByte(IapAddress4,DataTemp2);}

這幾段代碼的整理以及消化花的時間不多,相對于昨天ADC采樣來說,簡單了一點.

這里我很感謝也很感激樂工,每次我有問題,他都能及時給我解答給我?guī)椭?我很感謝樂工.謝謝

0
回復(fù)
2015-04-11 00:01
@hello-no1
這幾段代碼的整理以及消化花的時間不多,相對于昨天ADC采樣來說,簡單了一點.這里我很感謝也很感激樂工,每次我有問題,他都能及時給我解答給我?guī)椭?我很感謝樂工.謝謝
不錯~
0
回復(fù)
2015-04-12 09:24
@wangchuangwccc
不錯~
今天整理PWM函數(shù),等會上傳,把不能理解的地方以及理解的東西都貼出來,吼吼
0
回復(fù)
2015-04-12 10:05
@hello-no1
今天整理PWM函數(shù),等會上傳,把不能理解的地方以及理解的東西都貼出來,吼吼

    STC15系列自帶六路PWM輸出,功能還是比較強大的.首先我們還是先要認識一下PWM輸出功能寄存器的配置.

    第一個寄存器為P_SW2,端口配置寄存器.左右為用于擴展SFR訪問控制使能,說的直白一點就是,如果單片機想訪問外部特殊功能寄存器SFR或者外部RAM,必須先將設(shè)置該寄存器.需要補充一點,外部功能寄存器不一定在單片機外部.因為現(xiàn)在單片機的功能比較強大,內(nèi)部集成了很多的模塊,所謂外部設(shè)備只是相對于內(nèi)部的RAM和SFR.其實說穿了就是單片機訪問的地址不同而已.

    第二個寄存器為PWMCFG,PWM配置寄存器,該寄存器還是比較重要的.主要作用有兩個.第一個當PWM計數(shù)器歸零時是否觸發(fā)ADC轉(zhuǎn)換功能.第二個作用是設(shè)置PWM輸出口的初始電平.

    第三個寄存器為PWMCR,PWM控制寄存器.該寄存器的作用也比較重要,主要作用為設(shè)置單片機IO口的狀態(tài),如果為0則為普通的單片機IO口(GPIO),如果為1則為PWM輸出口.該寄存器說穿了就是用于控制單片機IO的PWM功能的開啟與關(guān)閉.

    第四個寄存器為PWMIF,PWM中斷標志寄存器,主要作用是當PWM發(fā)生翻轉(zhuǎn)時,通過該寄存器的設(shè)置,程序會進入相應(yīng)的中斷程序執(zhí)行相應(yīng)的程序.

    第五個寄存器為PWMFDCR,PWM外部異常控制寄存器,該寄存器的作用是當PWM輸出口外部發(fā)生異常時(比如短路,過載,過壓等特殊情況),通過該寄存器的配置可以使PWM輸出口變?yōu)楦咦钁B(tài)輸入口.

    第六個寄存器為PWM計數(shù)器,分為PWMCH和PWMCL,通過PWMCH和PWMCL來設(shè)置PWM輸出的周期.

    第七個寄存器為PWMCKS,PWM時鐘選擇寄存器.作用很簡單,用于時鐘源的選擇以及預(yù)分頻作用.

    第八個寄存器為PWM2翻轉(zhuǎn)計數(shù)器,主要用于設(shè)置PWM波形翻轉(zhuǎn)的時刻.

    上述寄存器為STC15W4K系列的PWM輸出寄存器,上述寄存器的配置主要作用是控制IO口輸出PWM波形以及輸出的周期等

0
回復(fù)
2015-04-12 10:12
@hello-no1
  STC15系列自帶六路PWM輸出,功能還是比較強大的.首先我們還是先要認識一下PWM輸出功能寄存器的配置.    第一個寄存器為P_SW2,端口配置寄存器.左右為用于擴展SFR訪問控制使能,說的直白一點就是,如果單片機想訪問外部特殊功能寄存器SFR或者外部RAM,必須先將設(shè)置該寄存器.需要補充一點,外部功能寄存器不一定在單片機外部.因為現(xiàn)在單片機的功能比較強大,內(nèi)部集成了很多的模塊,所謂外部設(shè)備只是相對于內(nèi)部的RAM和SFR.其實說穿了就是單片機訪問的地址不同而已.  第二個寄存器為PWMCFG,PWM配置寄存器,該寄存器還是比較重要的.主要作用有兩個.第一個當PWM計數(shù)器歸零時是否觸發(fā)ADC轉(zhuǎn)換功能.第二個作用是設(shè)置PWM輸出口的初始電平.  第三個寄存器為PWMCR,PWM控制寄存器.該寄存器的作用也比較重要,主要作用為設(shè)置單片機IO口的狀態(tài),如果為0則為普通的單片機IO口(GPIO),如果為1則為PWM輸出口.該寄存器說穿了就是用于控制單片機IO的PWM功能的開啟與關(guān)閉.    第四個寄存器為PWMIF,PWM中斷標志寄存器,主要作用是當PWM發(fā)生翻轉(zhuǎn)時,通過該寄存器的設(shè)置,程序會進入相應(yīng)的中斷程序執(zhí)行相應(yīng)的程序.  第五個寄存器為PWMFDCR,PWM外部異??刂萍拇嫫?該寄存器的作用是當PWM輸出口外部發(fā)生異常時(比如短路,過載,過壓等特殊情況),通過該寄存器的配置可以使PWM輸出口變?yōu)楦咦钁B(tài)輸入口.  第六個寄存器為PWM計數(shù)器,分為PWMCH和PWMCL,通過PWMCH和PWMCL來設(shè)置PWM輸出的周期.  第七個寄存器為PWMCKS,PWM時鐘選擇寄存器.作用很簡單,用于時鐘源的選擇以及預(yù)分頻作用.  第八個寄存器為PWM2翻轉(zhuǎn)計數(shù)器,主要用于設(shè)置PWM波形翻轉(zhuǎn)的時刻.  上述寄存器為STC15W4K系列的PWM輸出寄存器,上述寄存器的配置主要作用是控制IO口輸出PWM波形以及輸出的周期等

    針對上述PWM輸出的寄存器配置,我想說說自己的理解.

    其實上述寄存器配置貌似很多,細細想想,一點都不復(fù)雜.大家如果覺得不好理解,可以結(jié)合普通的PWM波形理解.對于普通的PWM波形,需要考慮的因素包括PWM的周期,導(dǎo)通和關(guān)閉的時間等.結(jié)合到單片機的PWM輸出,其實大同小異.首先是周期,那需要涉及的東西就是時鐘源,分頻器.考慮到高低電平的時間,那就需要通過計數(shù)器來實現(xiàn).再加上單片機IO的輸出狀態(tài)功能,那就需要涉及到IO口的功能配置等.最后當單片機PWM輸出發(fā)生翻轉(zhuǎn)時,是否需要執(zhí)行其他的動作,那就需要涉及到中斷,這是我的理解,大致上單片機IO的PWM輸出配置就是這些功能.

0
回復(fù)
2015-04-12 10:14
@hello-no1
    針對上述PWM輸出的寄存器配置,我想說說自己的理解.    其實上述寄存器配置貌似很多,細細想想,一點都不復(fù)雜.大家如果覺得不好理解,可以結(jié)合普通的PWM波形理解.對于普通的PWM波形,需要考慮的因素包括PWM的周期,導(dǎo)通和關(guān)閉的時間等.結(jié)合到單片機的PWM輸出,其實大同小異.首先是周期,那需要涉及的東西就是時鐘源,分頻器.考慮到高低電平的時間,那就需要通過計數(shù)器來實現(xiàn).再加上單片機IO的輸出狀態(tài)功能,那就需要涉及到IO口的功能配置等.最后當單片機PWM輸出發(fā)生翻轉(zhuǎn)時,是否需要執(zhí)行其他的動作,那就需要涉及到中斷,這是我的理解,大致上單片機IO的PWM輸出配置就是這些功能.

接下來我們上樂工的代碼,通過樂工的代碼來看看具體的寄存器的配置

#include"PWM10Bit.H"

//PWM配置函數(shù)
// 參數(shù): none
// 返回: none
void PWM10BitConfig(void)
{
	u8	xdata	*px;

	EAXSFR();//訪問XFR	 P_SW2 |=  0x80

	PWMCR|=0x02;//PWM通道3為PWM輸出口,受PWM波形發(fā)生器控制
	PWMCFG|=0x02;//PWM3輸出口初始電平1
	P21=0;//端口P2^1
	P2n_push_pull(0x01<<1);//P2^1口為強推挽輸出,P2M1&=~(bitn),P2M0|=(bitn)為01

	PWMCR|=0x04;//PWM通道4為PWM輸出口,受PWM波形發(fā)生器控制
	PWMCFG|=0x04;//PWM4輸出口初始電平1
	P22=1;//端口P2^1
	P2n_push_pull(0x01<<2);//P2^2口為強推挽輸出,P2M1&=~(bitn),P2M0|=(bitn)為01

	px=PWMCH;//PWM計數(shù)器的高字節(jié)
	*px=1023/256;
//	*px=4095/256;
	px++;
	*px=1023%256;//PWM計數(shù)器的低字節(jié)
//	*px=4095%256;//PWM計數(shù)器的低字節(jié)

	px++;//PWMCKS,PWM時鐘選擇
	*px=PwmClk_1T;//時鐘源: PwmClk_1T,PwmClk_2T, ... PwmClk_16T, PwmClk_Timer2

	EAXRAM();//恢復(fù)訪問XRAM	 P_SW2 &= ~0x80	

	PWMCR|=ENPWM;//使能PWM波形發(fā)生器,PWM計數(shù)器開始計數(shù)	 PWMCR |= ENPWM;
	PWMCR|=ECBI;// 允許PWM計數(shù)器歸零中斷
}

0
回復(fù)
2015-04-12 10:57
@hello-no1
接下來我們上樂工的代碼,通過樂工的代碼來看看具體的寄存器的配置#include"PWM10Bit.H"http://PWM配置函數(shù)//參數(shù):none//返回:nonevoidPWM10BitConfig(void){u8xdata*px;EAXSFR();//訪問XFRP_SW2|=0x80PWMCR|=0x02;//PWM通道3為PWM輸出口,受PWM波形發(fā)生器控制PWMCFG|=0x02;//PWM3輸出口初始電平1P21=0;//端口P2^1P2n_push_pull(0x01

    上述代碼中,樂工申明了一個指針型變量*PX,  該變量的類型為整型,存儲區(qū)域為xdata.解釋一下xdata,所謂xdata只是用于指明該變量的保存區(qū)域為外部數(shù)據(jù)存儲區(qū).這里大家有疑問的地方可能第一個就是xdata這里.其實單片機一般的數(shù)據(jù)默認存儲區(qū)是通過編譯器來配置的(以keil為例).C51有三種存儲模式,分別為小模式,緊湊型模式和大模式.小模式對應(yīng)存儲類型為data型,緊湊型模式對應(yīng)存儲類型為pdata,大模式對應(yīng)存儲類型為xdata(該資料我引用與單片機原理及應(yīng)用(黃勤主編)).

    接下來EAXSFR()這段代碼的作用為配置單片機的操作對象為擴展SFR區(qū)域,大家可以參考STC技術(shù)手冊.

    在上述的代碼段中主要是用于PWM口的配置,沒有什么難點.

0
回復(fù)
2015-04-12 11:01
@hello-no1
    上述代碼中,樂工申明了一個指針型變量*PX, 該變量的類型為整型,存儲區(qū)域為xdata.解釋一下xdata,所謂xdata只是用于指明該變量的保存區(qū)域為外部數(shù)據(jù)存儲區(qū).這里大家有疑問的地方可能第一個就是xdata這里.其實單片機一般的數(shù)據(jù)默認存儲區(qū)是通過編譯器來配置的(以keil為例).C51有三種存儲模式,分別為小模式,緊湊型模式和大模式.小模式對應(yīng)存儲類型為data型,緊湊型模式對應(yīng)存儲類型為pdata,大模式對應(yīng)存儲類型為xdata(該資料我引用與單片機原理及應(yīng)用(黃勤主編)).  接下來EAXSFR()這段代碼的作用為配置單片機的操作對象為擴展SFR區(qū)域,大家可以參考STC技術(shù)手冊.  在上述的代碼段中主要是用于PWM口的配置,沒有什么難點.

最后這段關(guān)于PWM中斷函數(shù)我覺得還是比較重要的,也是樂工整個項目真正的難點以及核心所在

//PWM中斷函數(shù)
void PWM_int(void) interrupt PWM_VECTOR
{
	u8	xdata	*px;
	u8	SW2_tmp;

	if(PWMIF&CBIF)//PWM計數(shù)器歸零中斷標志
	{
		PWMIF&=~CBIF;//清除中斷標志
		SW2_tmp=P_SW2;//保存SW2設(shè)置

		EAXSFR();//訪問XFR,P_SW2|=0x80,訪問擴展RAM中的寄存器必須EAXSFR=1 
		px=PWM3T2H;
		*px=OUT_Current_PWM/256;
		px++;
		*px=OUT_Current_PWM%256;

		px=PWM4T2H;
		*px=OUT_Voltage_PWM/256;//OUT_Current_PWM
		px++;
		*px=OUT_Voltage_PWM%256;

		P_SW2 = SW2_tmp;//恢復(fù)SW2設(shè)置

	}
}

0
回復(fù)
2015-04-12 11:06
@hello-no1
最后這段關(guān)于PWM中斷函數(shù)我覺得還是比較重要的,也是樂工整個項目真正的難點以及核心所在//PWM中斷函數(shù)voidPWM_int(void)interruptPWM_VECTOR{u8xdata*px;u8SW2_tmp;if(PWMIF&CBIF)//PWM計數(shù)器歸零中斷標志{PWMIF&=~CBIF;//清除中斷標志SW2_tmp=P_SW2;//保存SW2設(shè)置EAXSFR();//訪問XFR,P_SW2|=0x80,訪問擴展RAM中的寄存器必須EAXSFR=1px=PWM3T2H;*px=OUT_Current_PWM/256;px++;*px=OUT_Current_PWM%256;px=PWM4T2H;*px=OUT_Voltage_PWM/256;//OUT_Current_PWMpx++;*px=OUT_Voltage_PWM%256;P_SW2=SW2_tmp;//恢復(fù)SW2設(shè)置}}
    該段代碼主要用于輸出兩路互補型SPWM波形,這段代碼大家可以參考STC15系列的技術(shù)手冊中<用STC15W4K系列輸出兩路互補SWPM>一章,書中有具體的講解,大家可以看看.針對PWM配置以及輸出這一段,我自己本身的疑問并不多.如果說有難點,那就是PWM本身寄存器的配置這里會有一些疑問.
0
回復(fù)
2015-04-12 15:02
@hello-no1
    該段代碼主要用于輸出兩路互補型SPWM波形,這段代碼大家可以參考STC15系列的技術(shù)手冊中一章,書中有具體的講解,大家可以看看.針對PWM配置以及輸出這一段,我自己本身的疑問并不多.如果說有難點,那就是PWM本身寄存器的配置這里會有一些疑問.
分析得很透徹,說明你把數(shù)字電路的核心理解到了,其實這些程序的實現(xiàn)就是在模擬數(shù)字電路,只要把這個思維模式搞懂其他的代碼都不是問題了。
0
回復(fù)
發(fā)