1.1 整體框架介紹
本次提供以下模塊的Demo程序:

圖1-1
整個(gè)工程包含3個(gè)文件夾,如下所示:

Source包含.c文件,如下所示:

每個(gè)模塊包含兩個(gè).c文件,一個(gè)命名為xxx..c,一個(gè)命名為xxx_Test.c;第一個(gè)c文件包含了模塊相關(guān)的配置程序,第二個(gè)c文件包含了模塊相關(guān)的測(cè)試程序;
Include中存放各個(gè)模塊的頭文件及系統(tǒng)頭文件。
1.2使用實(shí)例說明
在Keil中選擇包含相應(yīng)模塊程序的工程序進(jìn)行編譯加載,對(duì)于有些模塊,因?yàn)榫哂卸鄠(gè)工作方式,為了測(cè)試不同工作方式下的功能,可在相應(yīng)模塊的.h文件中打開相應(yīng)的宏定義,再進(jìn)行編譯加載;例如,需要測(cè)試Timer2工作在方式0捕捉模式的功能,可按如下步驟進(jìn)行測(cè)試:
- 在工程下拉菜單中選擇Timer2工程(如圖1-2所示);

圖1-2
選擇之后,包含Timer2模塊程序的工程被打開,如下圖所示:

圖1-3
.c文件中帶“”,表示該文件包含在當(dāng)前工程中,否則不包含在當(dāng)前工程中。
- 在相應(yīng)的Timer.h頭文件中打開宏定義“#define MODE0”(如圖1-4所示);

圖1-4
2.1.1工作方式配置介紹
系統(tǒng)時(shí)鐘可配置為低頻、高頻,PLL高頻3種模式,sysclk_define.h文件包含以下幾個(gè)宏定義,分別用于初始化時(shí)鐘在相應(yīng)的模式:
#define LOW_FREQUENCE:執(zhí)行函數(shù)void SetClk()可將系統(tǒng)時(shí)鐘配置為低頻模式; #define HIGH_FREQUENCE:執(zhí)行函數(shù)void SetClk()可將系統(tǒng)時(shí)鐘配置為高頻模式; #define PLL_HIGH_FREQUENCE:執(zhí)行函數(shù)void SetClk()可將系統(tǒng)時(shí)鐘配置為高頻
PLL模式;
將相應(yīng)功能的宏定義打開,屏蔽其他宏定義,編譯、加載運(yùn)行可進(jìn)行測(cè)試。
2.1.2測(cè)試程序介紹
選擇“Sysclk”工程,打開宏定義“#define LOW_FREQUENCE”,其它宏定義都屏蔽,設(shè)置系統(tǒng)時(shí)鐘為低頻時(shí)鐘,Option中選擇內(nèi)建128KHz RC振蕩時(shí)鐘作為OSC1CLK;編譯、加載運(yùn)行,測(cè)試P0.0口可得到以下9.1KHz波形:

圖2-1
由于c程序中IO翻轉(zhuǎn)一次需要7個(gè)時(shí)鐘周期,所以IO翻轉(zhuǎn)產(chǎn)生的方波頻率應(yīng)為:
f=128KHz/(7*2)=9.1KHz
注:如果不能觀察到上述結(jié)果,則檢查option是否配置正確;
2.1.3寄存器簡(jiǎn)要介紹
CLKCON
| | |
| 32K_SPDUP | 32.768KHz振蕩器加速模式控制位 0:32.768kHz振蕩器常規(guī)模式, 由軟件清除 1:32.768kHz加速模式,由軟件或者硬件置起 詳細(xì)說明見Spec |
| | 系統(tǒng)時(shí)鐘預(yù)分頻器 00:fSYS = fOSC 01:fSYS = fOSC / 2 10:fSYS = fOSC / 4 11:fSYS = fOSC / 12 如果選擇OSC1CLK為SYSCLK時(shí)鐘源,則fSYS = fOSC1,與CLKS[1:0]內(nèi)容無關(guān)。 |
| | OSC2CLK開關(guān)控制寄存器 0:關(guān)閉OSC2CLK 1:打開OSC2CLK |
| | 頻率選擇位 0:選擇OSC1CLK為SYSCLK 1:選擇OSCSCLK為SYSCLK |
PLLCON
| | |
| | PLL狀態(tài)位 0:鎖相環(huán)沒有鎖住相位 1:鎖相環(huán)鎖住相位 鎖相環(huán)鎖住相位后可以輸出穩(wěn)定的時(shí)鐘 |
| | PLL開關(guān)控制位 0:PLL關(guān)閉 1:PLL開啟 PLL開啟必須OSC2ON=1時(shí)才有效 |
| | PLL系統(tǒng)時(shí)鐘源控制位 0:PLL不作為OSCSCLK 1:PLL的二分頻作為OSCSCLK PLL的輸入時(shí)鐘必須大于5M |
相關(guān)內(nèi)部RC校正寄存器CLKLO、CLKRC0、CLKRC1的詳細(xì)說明見Spec。
SH88F6161提供61個(gè)位可編程雙向I/O端口,端口數(shù)據(jù)在寄存器Px中,端口控制寄存器PxCRy控制端口是作為輸入或者輸出。當(dāng)端口作為輸入時(shí),每個(gè)I/O端口帶有由PxPCRy控制的內(nèi)部上拉電阻。
demo程序中函數(shù)void Sysclk_Test(),以IO翻轉(zhuǎn)為例給出了IO的配置使用方法;
SH88F6161有定時(shí)器2和定時(shí)器3兩個(gè)定時(shí)器,定時(shí)器2可配置為16位捕獲、16位自動(dòng)重載、可編程時(shí)鐘輸出三種方式;定時(shí)器3只可配置為16位自動(dòng)重載方式。
demo程序以Timer2為例給出了不同工作模式的配置方法。
2.3.1工作方式配置介紹
timer_define.h文件中包含以下幾個(gè)宏:
#define MODE0:設(shè)置Timer2工作在16位捕獲方式(下降沿捕獲)
#define MODE1:設(shè)置Timer2工作在16位重載方式
#define MODE2:設(shè)置Timer2工作在可編程時(shí)鐘輸出方式
將相應(yīng)功能的宏定義打開,屏蔽其他宏定義,編譯、加載運(yùn)行可進(jìn)行測(cè)試。
2.3.2測(cè)試程序介紹
選擇“Timer2”工程,依次在timer_define.h文件中打開相應(yīng)宏,然后進(jìn)行編譯加載全速運(yùn)行,觀察現(xiàn)象
- 當(dāng)打開宏“#define MODE0”,全速運(yùn)行后,T2EX引腳輸入下降沿會(huì)產(chǎn)生一次捕獲,并產(chǎn)生外部事件捕獲中斷;
- 當(dāng)打開宏“#define MODE1”,全速運(yùn)行后,定時(shí)器工作在16位自動(dòng)重載方式,定時(shí)產(chǎn)生溢出中斷;
- 當(dāng)打開宏“#define MODE2”,全速運(yùn)行后,定時(shí)器工作在可編程時(shí)鐘輸出方式,產(chǎn)生如下31.9KHz波形(系統(tǒng)時(shí)鐘為128KHz);

圖2-2
輸出時(shí)鐘頻率計(jì)算公式:
、
2.3.3相關(guān)寄存器介紹
RCAP2L,RCAP2H,TL2,TH2
位編號(hào) | 位符號(hào) | 說明 |
7-0 | RCAP2L [7:0] | 定時(shí)器2重載/捕獲數(shù)據(jù) |
RCAP2H [7:0] |
7-0 | TL2 [7:0] | 定時(shí)器2高位低位計(jì)數(shù)器 |
TH2 [7:0] |
T2CON
位編號(hào) | 位符號(hào) | 說明 |
7 | TF2 | 定時(shí)器2溢出標(biāo)志位 0:無溢出(必須由軟件清0) 1:溢出(由硬件設(shè)1) |
6 | EXF2 | T2EX引腳外部事件輸入(下降沿)被檢測(cè)到的標(biāo)志位 0:無外部事件輸入(必須由軟件清0) 1:檢測(cè)到外部輸入(如果EXEN2 = 1,由硬件設(shè)1) |
3 | EXEN2 | T2EX引腳上的外部事件輸入(下降沿)用作重載/捕獲觸發(fā)器允許/禁止控制位 0:忽略T2EX引腳上的事件 1:檢測(cè)到T2EX 引腳上一個(gè)下降沿,產(chǎn)生一個(gè)捕獲或重載 |
2 | TR2 | 定時(shí)器2開始/停止控制位 0:停止定時(shí)器2 1:開始定時(shí)器2 |
1 | C/ | 定時(shí)器2定時(shí)器/計(jì)數(shù)器方式選定位 0:定時(shí)器方式,T2引腳用作I/O端口 1:計(jì)數(shù)器方式,內(nèi)部上拉電阻被打開 |
0 | CP/ | 捕獲/重載方式選定位 0:16位帶重載功能的定時(shí)器/計(jì)數(shù)器 1:16位帶捕獲功能的定時(shí)器/計(jì)數(shù)器 |
T2MOD
位編號(hào) | 位符號(hào) | 說明 |
7 | TCLKP2 | 分頻選擇控制位 0:選擇系統(tǒng)時(shí)鐘的1/12作為定時(shí)器2的時(shí)鐘源 1:系統(tǒng)時(shí)鐘作為定時(shí)器2的時(shí)鐘源 |
1 | T2OE | 定時(shí)器2輸出允許位 0:設(shè)置P2.4/T2作為時(shí)鐘輸入或I/O端口 1:設(shè)置P2.4/T2作為時(shí)鐘輸出 |
0 | DCEN | 遞減計(jì)數(shù)允許位 0:禁止定時(shí)器2作為遞增/遞減計(jì)數(shù)器,定時(shí)器2僅作為遞增計(jì)數(shù)器 1:允許定時(shí)器2作為遞增/遞減計(jì)數(shù)器 |
SH88F6161具有四個(gè)可編程計(jì)數(shù)器,分別為PCA0、PCA1、PCA2、PCA3;
demo程序以PCA0為例,給出了其比較/捕捉模塊分別工作于Mode0~Mode3時(shí)的參考程序。
2.4.1工作方式配置介紹
pca_define.h文件中包含以下幾個(gè)宏:
#define MODE0:配置比較/捕捉模塊0工作在邊沿觸發(fā)模式
#define MODE1:配置比較/捕捉模塊0工作在軟件定時(shí)方式
#define MODE2: 配置比較/捕捉模塊0工作在頻率輸出方式
#define MODE3_PWM8:配置比較/捕捉模塊0工作在8位脈寬調(diào)制
#define MODE3_PWM16:配置比較/捕捉模塊0工作在16位脈寬調(diào)制
#define MODE3_XPWM16:配置比較/捕捉模塊0工作在16位相位修正脈寬調(diào)制
#define MODE3_XPPWM16:配置比較/捕捉模塊0工作在16位相頻修正脈寬調(diào)制
將相應(yīng)功能的宏定義打開,屏蔽其他宏定義,編譯、加載運(yùn)行可進(jìn)行測(cè)試。
2.4.2測(cè)試程序介紹
選擇“PCA”工程,依次在pca_define.h文件中打開相應(yīng)宏,然后進(jìn)行編譯加載全速運(yùn)行,觀察現(xiàn)象;
1. 打開宏“#define MODE0”,屏蔽其他宏定義,編譯加載后,全速運(yùn)行,P0CEX0引腳上升沿/下降沿會(huì)觸發(fā)一次捕捉,并產(chǎn)生相應(yīng)中斷;
2. 打開宏“#define MODE1”,屏蔽其他宏定義,編譯加載后,全速運(yùn)行,可以實(shí)現(xiàn)連續(xù)軟件定時(shí),當(dāng)PCA0計(jì)數(shù)值與P0CPH0和P0CPL0中的值匹配時(shí)產(chǎn)生一次中斷,同時(shí)P0CEX0口翻轉(zhuǎn)一次;(PxTOP,PxCPn可變)
3. 打開宏“#define MODE2”,屏蔽其他宏定義,編譯加載后,全速運(yùn)行,P0CEX0引腳可輸出如下波形(3.965KHz):

圖2-3
FPxCEXn= FPCAx /(2 × PxCPHn)
如果應(yīng)用中需要改變波形占空比和頻率,則可通過適時(shí)地改變PxCPHn來獲得相應(yīng)的波形;PxTOPL固定為0xFF,用戶可以配置PxTOPH來改變計(jì)數(shù)最大值;
4. 打開宏“#define MODE3_PWM8”,屏蔽其他宏定義,編譯加載后,全速運(yùn)行,P0CEX0輸出占空比為0.8的正向波形,P0CEX1輸出占空比為0.8的反向波形,如下圖所示:

圖2-4
Duty=(256-(PxCPHn+1))/256
如果應(yīng)用中需要Duty可變的PWM波形,則可通過適時(shí)的改變PxCPHn來獲取希望波形;
PxTOPL不可改變;
5. 打開宏“#define MODE3_PWM16”,屏蔽其他宏定義,編譯加載后,全速運(yùn)行,P0CEX0輸出占空比為0.8的正向波形,P0CEX1輸出占空比為0.8的反向波形,如下圖所示:

圖2-5
Duty=(65536-(PxCPn+1))/65536
如果應(yīng)用中需要Duty可變的PWM波形,則可通過適時(shí)的改變PxCPn(PxCPHn,PxCPLn)和PxTOP來獲取希望波形;
6. 打開宏“#define MODE3_XPWM16”,屏蔽其他宏定義,編譯加載后,全速運(yùn)行,P0CEX0輸出頻率為250Hz的正向波形,P0CEX1輸出頻率為250Hz的反向波形,如下圖所示:

圖2-6
如果應(yīng)用中需要頻率和占空比可變的波形,則可通過適時(shí)的改變PxTOP和PxCPn(PxCPHn,PxCPLn)來獲取相應(yīng)波形;在一個(gè)定時(shí)器時(shí)鐘周期里PCAx值等于PxTOP值,然后在下一次計(jì)數(shù)到來時(shí)PxTOP和PxCPn將得到更新。
7. 打開宏“#define MODE3_XPPWM16”,屏蔽其他宏定義,編譯加載后,全速運(yùn)行,P0CEX0輸出頻率為250Hz的正向波形,P0CEX1輸出頻率為250Hz的反向波形,如下圖所示:

圖2-7
如果應(yīng)用中需要頻率和占空比可變的波形,則可通過適時(shí)的改變PxTOP和PxCPn(PxCPHn,PxCPLn)來獲取相應(yīng)波形;PxCPn和PxTOP在0x0000點(diǎn)更新。
注:對(duì)于XPWM和XPPWM工作方式,一定要配置相應(yīng)的PCAx工作在雙沿模式,否則相應(yīng)口將不能正常輸出波形;
Demo程序給出了LCD的使用實(shí)例,以4COM,2SEG為例,用戶可根據(jù)實(shí)際需要選擇合適COM數(shù)和SEG數(shù)做相應(yīng)的IO配置;配置參考void init_lcd()。
選擇“Lcd”工程,編譯加載運(yùn)行,觀察SEG1、SEG2、COM1~COM4口波形;
Demo程序給出了LED的使用實(shí)例,以2COM,8SEG為例,用戶可根據(jù)實(shí)際需要選擇合適COM數(shù)和SEG數(shù)做相應(yīng)的IO配置;配置參考void init_led()。
選擇“Led”工程,編譯加載運(yùn)行,觀察COM1、COM2、SEG1~ SEG8口波形;
2.5.1寄存器簡(jiǎn)要介紹
DISPCON
位編號(hào) | 位符號(hào) | 說明 |
7 | DISPSEL | LCD,LED選擇控制位 0:選擇LCD驅(qū)動(dòng)器,LED驅(qū)動(dòng)器無效 1:選擇LED驅(qū)動(dòng)器,LCD驅(qū)動(dòng)器無效 |
6 | DISPON | LCD使能控制位 0:禁止LCD驅(qū)動(dòng)器 1:允許LCD驅(qū)動(dòng)器 |
5-4 | DUTY[1:0] | LCD占空比選擇位 00:1/4占空比,1/3偏置 01:1/5占空比,1/3偏置 1X:1/6占空比,1/3偏置 |
3-0 | VOL[3:0] | LCD對(duì)比度控制位 0000:VLCD = 0.531VDD 0001:VLCD = 0.563VDD 0010:VLCD = 0.594VDD 0011:VLCD = 0.625VDD 0100:VLCD = 0.656VDD 0101:VLCD = 0.688VDD 0110:VLCD = 0.719VDD 0111:VLCD = 0.750VDD 1000:VLCD = 0.781VDD 1001:VLCD = 0.813VDD 1010:VLCD = 0.844VDD 1011:VLCD = 0.875VDD 1100:VLCD = 0.906VDD 1101:VLCD = 0.938VDD 1110:VLCD = 0.969VDD 1111:VLCD = 1.000VDD |
DISPCON1
位編號(hào) | 位符號(hào) | 說明 |
4 | RLCD | LCD偏置電阻選擇控制位 0:LCD偏置電阻為225k 1:LCD偏置電阻總和為900k |
3-2 | FCCTL[1:0] | 充電時(shí)間控制位 00:1/8 LCD com周期 01:1/16 LCD com周期 10:1/32 LCD com周期 11:1/64 LCD com周期 充電時(shí)間控制位僅在快速充電模式下有效 |
1-0 | MOD[1:0] | 驅(qū)動(dòng)模式選擇位 00:傳統(tǒng)電阻型模式,偏置電阻總和為225k/900k 01:傳統(tǒng)電阻型模式,偏置電阻總和為60k 1X:快速充電模式,偏置電阻總和自動(dòng)在60k和225k/900k之間切換 |
其它相關(guān)寄存器詳見Spec。
TWI串行總線采用兩根線(SDA和SCL)在總線和裝置之間傳遞信息。SH88F6161完全符合TWI總線規(guī)范,自動(dòng)對(duì)字節(jié)進(jìn)行傳輸進(jìn)行處理,并對(duì)串行通訊進(jìn)行跟蹤。
2.6.1工作方式配置介紹
twi_define.h文件中定義了以下幾個(gè)模式:
#define MT_MODE:打開該宏,配置6161工作在主機(jī)傳送模式;
#define MR_MODE:打開該宏,配置6161工作在主機(jī)接收模式;
#defineSLAVE_MODE:打開該宏,配置6161工作在從機(jī)模式;
將相應(yīng)功能的宏定義打開,屏蔽其他宏定義,編譯、加載運(yùn)行可進(jìn)行測(cè)試。
2.6.2測(cè)試程序介紹
Twi_Test.c分別以作為主機(jī)和從機(jī)傳送和接收10個(gè)byte數(shù)據(jù)為例給出了該模塊的應(yīng)用;
1. 選擇“Twi”工程后,打開宏定義“MT_MODE”,編譯、加載運(yùn)行可測(cè)試6161作為主機(jī)向從機(jī)傳送數(shù)據(jù),分別為“0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A……..”
2. 選擇“Twi”工程后,打開宏定義“MR_MODE”,編譯、加載運(yùn)行可測(cè)試6161作為主機(jī)從從機(jī)接收10個(gè)byte數(shù)據(jù);
3. 選擇“Twi”工程后,打開宏定義“SLAVE_MODE”,編譯、加載運(yùn)行可測(cè)試6161作為從機(jī):
- 向主機(jī)發(fā)送10個(gè)byte數(shù)據(jù),分別為“0x40, 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49”
- 從主機(jī)接收10個(gè)byte數(shù)據(jù),分別為“0x40, 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49”
本模塊測(cè)試需要兩個(gè)6161板子,一個(gè)作為主機(jī),一個(gè)作為從機(jī)進(jìn)行配合。
注:如果不能得到正確結(jié)果,請(qǐng)檢查SCL和SDA是否接上拉電阻,通常選擇10k
串行外部設(shè)備接口(SPI)是一種高速串行通信接口,允許MCU與外圍設(shè)備(包括其它MCU)進(jìn)行全雙工,同步串行通訊。
2.7.1工作方式配置介紹
spi_define.h文件中定義了以下兩個(gè)模式:
#define SLAVE_MODE:打開該宏,配置6161作為從機(jī);
#define MASTER_MODE:打開該宏,配置6161作為主機(jī);
2.7.2測(cè)試程序介紹
以6161作為主機(jī)向另一塊作為從機(jī)的6161傳送數(shù)據(jù)為例,具體過程如下:
主機(jī)6161向從機(jī)6161傳送“0x40, 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A”;從機(jī)收到主機(jī)發(fā)送的數(shù)據(jù)后,將相應(yīng)數(shù)據(jù)返回給主機(jī),主機(jī)接收到從機(jī)返回的數(shù)據(jù)后,將其保存到rcv_data[]數(shù)組中。
選在“Spi”工程后,打開宏定義“#define MASTER_MODE”編譯,下載運(yùn)行使其作為主機(jī);
選在“Spi”工程后,打開宏定義“#define SLAVE_MODE”編譯,下載運(yùn)行使其作為從機(jī);
本模塊程序運(yùn)行測(cè)試需要兩塊6161板子配合。
注:如果從機(jī)向主機(jī)返回的數(shù)據(jù)內(nèi)容與期望值有差別,可嘗試提高從機(jī)的的系統(tǒng)時(shí)鐘頻率,或降低主機(jī)的系統(tǒng)時(shí)鐘頻率;
本次實(shí)例中,以一個(gè)主設(shè)備一個(gè)從設(shè)備的通訊網(wǎng)絡(luò)為例,因此無需控制SS引腳,即只需接SCK,MOSI,MISO三根信號(hào)線;
2.7.3寄存器簡(jiǎn)要介紹
SPCON
| | |
| | 傳送方向選擇位 0:MSB優(yōu)先發(fā)送 1:LSB優(yōu)先發(fā)送 |
| | SP設(shè)備選擇位 0:配置SPI作為從屬設(shè)備 1:配置SPI作為主設(shè)備 |
| | 時(shí)鐘相位控制位 0:SCK周期的第一沿采集數(shù)據(jù) 1:SCK周期的第二沿采集數(shù)據(jù) |
| | 時(shí)鐘極性控制位 0:在Idle狀態(tài)下SCK處于低電平 1:在Idle狀態(tài)下SCK處于高電平 |
| | 引腳控制位 0:在主和從屬模式下,打開引腳 1:在主和從屬模式下,關(guān)閉引腳 如果SSDIS置1,不產(chǎn)生MODF中斷請(qǐng)求。 在從屬模式下,如果CPHA = 0,該位不起作用。 |
| | 串行外部設(shè)備時(shí)鐘速率選擇位 000: fSYS /2 001: fSYS /4 010: fSYS /8 011: fSYS /16 100: fSYS /32 101: fSYS /64 110: fSYS /128 111: fSYS /256 |
SPSTA
| | |
| | SPI控制位 0:關(guān)閉SPI 1:打開SPI接口. |
| | 串行外部設(shè)備數(shù)據(jù)傳送標(biāo)志位 0:由軟件清0 1:表明已完成數(shù)據(jù)傳輸,由硬件置1 |
| | 模式故障位 0:由軟件清0 1:表明引腳電平與SPI模式不一致,由硬件置1 |
| | 寫入沖突標(biāo)志位 0:有軟件清0,表明已處理寫入沖突 1:由硬件置1,表明檢測(cè)到一個(gè)沖突 |
| | 接收超限位 0:表明已處理接收超限,由軟件清0 1:表明已檢測(cè)到接收超限,由硬件置1 |
SPDAT
| | |
| | 寫入SPDAT的數(shù)據(jù)被放置到發(fā)送移位寄存器中。讀取SPDAT時(shí)將獲得接收移位換寄存器的數(shù)據(jù)。 |
Uart工作方式列表:
SM0 | | | 類型 | 波特率 | 幀長(zhǎng)度 | 起始位 | 停止位 | 第9位 |
0 | | | 同步 | fSYS/(4或12) | 8位 | 無 | 無 | 無 |
0 | | | 異步 | 自帶波特率發(fā)生器的溢出率/16 | 10位 | 1 | 1 | 無 |
1 | | | 異步 | fSYS/(32或64) | 11位 | 1 | 1 | 0,1 |
1 | | | 異步 | 自帶波特率發(fā)生器的溢出率/16 | 11位 | 1 | 1 | 0,1 |
通過配置相應(yīng)寄存器可使Uart工作在不同的工作方式,本次Demo程序以Uart0的方式1為例,給出了6161傳送數(shù)據(jù)和接收數(shù)據(jù)的實(shí)例。
注:Uart0和Uart1完全相同;
2.8.1工作方式配置介紹
uart_define.h文件中,定義了以下兩個(gè)宏:
#define Enable_uart_TX_test:測(cè)試6161工作在方式1傳送數(shù)據(jù);
#define Enable_uart_RX_test:測(cè)試6161工作在方式1接收數(shù)據(jù);
2.8.2測(cè)試程序介紹
本項(xiàng)測(cè)試需結(jié)合串口助手調(diào)試,選擇“Uart”工程后,打開宏定義“#define Enable_uart_TX_test”,編譯、加載運(yùn)行后,通過串口助手可看到6161連續(xù)傳送0x96;
注:測(cè)試時(shí),系統(tǒng)時(shí)鐘選擇外掛晶振8M,波特率為9600;
2.8.3寄存器介紹
PCON
位編號(hào) | 位符號(hào) | 說明 |
7 | SMOD | UART0/1波特率加倍器 0:在方式2中,波特率為系統(tǒng)時(shí)鐘的1/64 1:在方式2中,波特率為系統(tǒng)時(shí)鐘的1/32 |
6 | SSTAT | SCON[7:5]功能選擇 0:SCON[7:5]工作方式作為SM0,SM1,SM2 1:SCON[7:5]工作方式作為FE,RXOV,TXCOL |
3-2 | GF[1:0] | 用于軟件的通用標(biāo)志位 |
1 | PD | 掉電模式控制位 |
0 | IDL | 空閑模式控制位 |
SCON
位編號(hào) | 位符號(hào) | 說明 |
7-6 | SM[0:1] | EUART0串行方式控制位,SSTAT = 0 00:方式0,同步方式,固定波特率 01:方式1,8位異步方式,可變波特率 10:方式2,9位異步方式,固定波特率 11:方式3,9位異步方式,可變波特率 |
7 | FE | EUART0幀出錯(cuò)標(biāo)志位,當(dāng)FE位被讀時(shí),SSTAT位必須被置位 0:無幀出錯(cuò),由軟件清零 1:幀出錯(cuò),由硬件置位 |
6 | RXOV | EUART0接收溢出標(biāo)志位,當(dāng)RXOV位被讀時(shí),SSTAT 位必須被置位 0:無接收溢出,由軟件清零 1:接收溢出,由硬件置位 |
5 | SM2 | EUART0多處理機(jī)通訊允許位(第9位“1”校驗(yàn)器),SSTAT = 0 0:在方式0下,波特率是系統(tǒng)時(shí)鐘的1/12 在方式1下,禁止停止位確認(rèn)檢驗(yàn),任何停止位都會(huì)置位RI 在方式2和3下,任何字節(jié)都會(huì)置位RI 1:在方式0下,波特率是系統(tǒng)時(shí)鐘的1/4 在方式1下,允許停止位確認(rèn)檢驗(yàn),只有有效的停止位(1)才能置位RI 在方式2和3下,只有地址字節(jié)(第9位 = 1)才能置位RI |
5 | TXCOL | EUART0發(fā)送沖突標(biāo)志位,當(dāng)TXCOL位被讀時(shí),SSTAT位必須被置位 0:無發(fā)送沖突,由軟件清零 1:發(fā)送沖突,由硬件置位 |
4 | REN | EUART0接收器允許位 0:接收禁止 1:接收允許 |
3 | TB8 | 在EUART0的方式2和3下發(fā)送的第9位,由軟件置位或清零 |
2 | RB8 | 在EUART0的方式1,2和3下接收的第9位 在方式0下,不使用RB8 在方式1下,如果接收中斷發(fā)生,停止位移入RB8 在方式2和3下,接收第9位 |
1 | TI | EUART0的傳送中斷標(biāo)志位 0:由軟件清零 1:由硬件置位 |
0 | RI | EUART0的接收中斷標(biāo)志位 0:由軟件清零 1:由硬件置位 |
SBUF
位編號(hào) | 位符號(hào) | 說明 |
7-0 | SBUF[7:0] | 這個(gè)寄存器尋址兩個(gè)寄存器:一個(gè)移位寄存器和一個(gè)接收鎖存寄存器 SBUF的寫入將發(fā)送字節(jié)到移位寄存器中,然后開始傳輸 SBUF的讀取返回接收鎖存器中的內(nèi)容 |
SADDR、SADEN(多機(jī)通訊時(shí)需設(shè)置)
位編號(hào) | 位符號(hào) | 說明 |
7-0 | SADDR[7:0] | 寄存器SADDR定義了EUART0的從機(jī)地址 |
7-0 | SADEN[7:0] | 寄存器SADEN是一個(gè)位屏蔽寄存器,決定SADDR的哪些位被檢驗(yàn) 0:SADDR中的相應(yīng)位被忽略 1:SADDR中的相應(yīng)位對(duì)照接收到的地址被檢驗(yàn) |
SBRTH、SBRTL
位編號(hào) | 位符號(hào) | 說明 |
7 | SBRTEN | EUART0波特率發(fā)生器使能控制位 0:關(guān)閉(默認(rèn)) 1:打開 |
6-0, 7-0 | SBRT[14:0] | EUART0波特率發(fā)生器計(jì)數(shù)器高7位和低8位寄存器 |
SFINE
位編號(hào) | 位符號(hào) | 說明 |
3-0 | SFINE[3:0] | EUART0波特率發(fā)生器微調(diào)數(shù)據(jù)寄存器 |
USB主機(jī)和從機(jī)之間的通信是建立在既定的USB協(xié)議基礎(chǔ)上,需要主機(jī)驅(qū)動(dòng)程序和從機(jī)驅(qū)動(dòng)程序配合實(shí)現(xiàn);根據(jù)不同的應(yīng)用場(chǎng)合,用戶可以編寫相應(yīng)的USB驅(qū)動(dòng)程序?qū)崿F(xiàn)與PC主機(jī)的通訊。
USB協(xié)議規(guī)定了USB設(shè)備和PC主機(jī)進(jìn)行通訊的過程,主機(jī)和從機(jī)進(jìn)行通訊的第一個(gè)階段是枚舉過程,通過枚舉,從機(jī)設(shè)備會(huì)將其描述符信息發(fā)送給主機(jī),主機(jī)會(huì)在枚舉完之后根據(jù)設(shè)備的描述符信息發(fā)起后續(xù)的通信,后續(xù)通信的過程根據(jù)枚舉時(shí)得到的設(shè)備配置信息的不同而不同。
2.9.1總體流程圖
使用USB模塊之前,首先需調(diào)用模塊初始化函數(shù)void usb_init (),之后USB從機(jī)將等待主機(jī)發(fā)送命令,并產(chǎn)生相應(yīng)中斷;

圖2-8
2.9.2基本通信過程說明
如果從機(jī)可以接收主機(jī)向控制端點(diǎn)0發(fā)送的數(shù)據(jù),收到SETUP命令后,需進(jìn)行如下操作:
- 置位OEP0RDY;
- 待產(chǎn)生OEP0中斷后,通過OEP0CNT寄存器可獲取接收到的數(shù)據(jù)個(gè)數(shù),從EP0 OUT Buf可獲取所收到的數(shù)據(jù)內(nèi)容;
- 如果OEP0CNT的值小于8,則IEP0CNT清0,置位IEP0RDY,此時(shí)主機(jī)會(huì)向從機(jī)發(fā)送In包,從機(jī)將向主機(jī)傳送0長(zhǎng)度數(shù)據(jù)包,本次控制傳輸結(jié)束。要想開始下一筆控制傳輸,主機(jī)需重新發(fā)送SETUP包;
- 如果OEP0CNT的值等于8,則重復(fù)步驟1)~3);
如果從機(jī)有數(shù)據(jù)通過端點(diǎn)0向主機(jī)發(fā)送,收到SETUP命令后,需執(zhí)行如下操作:
- 設(shè)置相應(yīng)的IEP0DTG;
- 向EP0 IN BUF填寫數(shù)據(jù)內(nèi)容,向IEP0CNT填寫數(shù)據(jù)個(gè)數(shù);
- 置位IEP0RDY;
- 待產(chǎn)生IEP0中斷后,如果IEP0CNT值小于8,表示從機(jī)沒有剩余數(shù)據(jù)向主機(jī)發(fā)送,此時(shí)應(yīng)置位OEP0RDY,等待主機(jī)向從機(jī)傳送0長(zhǎng)度數(shù)據(jù)包產(chǎn)生OEP0中斷,本次控制傳輸結(jié)束;
- 如果IEP0CNT值等于8,表示從機(jī)還有數(shù)據(jù)向主機(jī)發(fā)送,此時(shí)應(yīng)重復(fù)1)~4);
如果從機(jī)可以接收主機(jī)向端點(diǎn)1傳送的數(shù)據(jù),則需執(zhí)行如下操作:
- 設(shè)置OEP1BUFSEL占用相應(yīng)buf,
- 置位OEP1RDY;
- 待產(chǎn)生OEP1中斷后,通過OEP1CNT寄存器可獲取接收到的數(shù)據(jù)個(gè)數(shù),釋放當(dāng)前被占用的buf,從中可獲取接收到的數(shù)據(jù)內(nèi)容,如果當(dāng)前接收到的數(shù)據(jù)個(gè)數(shù)等于16,則重復(fù)1)~3);如果當(dāng)前接收到的數(shù)據(jù)個(gè)數(shù)小于16,本次傳輸結(jié)束;
如果從機(jī)有數(shù)據(jù)通過端點(diǎn)1向主機(jī)發(fā)送,則需執(zhí)行如下操作:
- 設(shè)置IEP1DTG;
- 填寫IEP1CNT,填寫相應(yīng)的BUF,并設(shè)置IEP1BUFSEL占用BUF;
- 置位IEP1RDY,向主機(jī)發(fā)送數(shù)據(jù);
- 產(chǎn)生IEP1中斷后,如果從機(jī)沒有數(shù)據(jù)傳送(即IEP1CNT小于16),則本次數(shù)據(jù)傳輸結(jié)束,否則重復(fù)步驟1)~4);
如果從機(jī)可以接收主機(jī)向端點(diǎn)2傳送的數(shù)據(jù),則需執(zhí)行如下操作:
- 設(shè)置OEP2BUFSEL占用相應(yīng)buf,
- 置位OEP2RDY;
- 待產(chǎn)生OEP2中斷后,通過OEP2CNT寄存器可獲取接收到的數(shù)據(jù)個(gè)數(shù),釋放當(dāng)前被占用的buf,從中可獲取接收到的數(shù)據(jù)內(nèi)容,如果當(dāng)前接收到的數(shù)據(jù)個(gè)數(shù)等于64,則重復(fù)1)~3);如果當(dāng)前接收到的數(shù)據(jù)個(gè)數(shù)小于64,本次傳輸結(jié)束;
如果從機(jī)有數(shù)據(jù)通過端點(diǎn)2向主機(jī)發(fā)送,則需執(zhí)行如下操作:
- 設(shè)置IEP2DTG;
- 填寫IEP2CNT,填寫相應(yīng)的BUF,并設(shè)置IEP2BUFSEL占用BUF;
- 置位IEP2RDY,向主機(jī)發(fā)送數(shù)據(jù);
- 產(chǎn)生IEP2中斷后,如果從機(jī)沒有數(shù)據(jù)傳送(即IEP2CNT小于64),則本次數(shù)據(jù)傳輸結(jié)束,否則重復(fù)步驟1)~4);
2.9.3應(yīng)用實(shí)例
本次Demo程序以HID類設(shè)備為例,給出了枚舉過程。

當(dāng)6161下載該程序運(yùn)行后,插入PC,PC端會(huì)識(shí)別到一個(gè)HID類設(shè)備插入,如下所示:

如果用戶需要實(shí)現(xiàn)其他應(yīng)用,則應(yīng)根據(jù)USB協(xié)議規(guī)定修改相應(yīng)的描述符信息,并增加相應(yīng)的類請(qǐng)求響應(yīng)程序以及后續(xù)通信相關(guān)程序。
ADC負(fù)責(zé)模擬信號(hào)到相應(yīng)12位的數(shù)字信號(hào)的轉(zhuǎn)換,支持VDD,內(nèi)建1.5V,內(nèi)建2.5V,外接VREF四種基準(zhǔn)電壓,可通過軟件啟動(dòng)AD轉(zhuǎn)換,也可通過觸發(fā)源觸發(fā)AD轉(zhuǎn)換,另外通過啟動(dòng)比較功能,可實(shí)現(xiàn)連續(xù)轉(zhuǎn)換。
2.10.1工作方式配置介紹
adc_define.h文件中定義了以下幾個(gè)宏:
#define STARTUP_BY_SOFTWARE:打開該宏,測(cè)試軟件觸發(fā)一次ADC0轉(zhuǎn)換
#define STARTUP_BY_HARDWARE:打開該宏,測(cè)試外部中斷2上升沿觸發(fā)ADC0轉(zhuǎn)換
#define DIGITAL_COMPARE_FUNCTION:打開該宏,測(cè)試連續(xù)ADC0轉(zhuǎn)換
2.10.2測(cè)試程序介紹
選擇“Adc”工程,打開宏“#define STARTUP_BY_SOFTWARE”,編譯、加載,
- ADC0通道(P0.0)外接電壓源;
- 在ADC中斷服務(wù)程序中設(shè)置斷點(diǎn),全速運(yùn)行至斷點(diǎn)處,通過寄存器ADCL和ADCH可觀測(cè)外部電壓轉(zhuǎn)換值;
注:本項(xiàng)測(cè)試只完成一次AD轉(zhuǎn)換,要想再進(jìn)行一次AD轉(zhuǎn)換,軟件需再次啟動(dòng)AD轉(zhuǎn)換。
選擇“Adc”工程,打開宏“#define STARTUP_BY_HARDWARE”,編譯、加載,
- ADC0通道(P0.0)外接電壓源;
- 在ADC中斷服務(wù)程序中設(shè)置斷點(diǎn),全速運(yùn)行;
- 給P6.1口上升沿信號(hào),可看到程序運(yùn)行至斷點(diǎn)處,此時(shí)通過寄存器ADCL和ADCH可觀測(cè)外部電壓轉(zhuǎn)換值;
注:本項(xiàng)測(cè)試中,一次外部中斷只能觸發(fā)一次AD轉(zhuǎn)換,要想再進(jìn)行一次AD轉(zhuǎn)換,需再次觸發(fā)外部中斷。
選擇“Adc”工程,打開宏“#define DIGITAL_COMPARE_FUNCTION”,編譯、加載,
- ADC0通道(P0.0)外接電壓源;
- 在ADC中斷服務(wù)程序中設(shè)置斷點(diǎn),全速運(yùn)行至斷點(diǎn)處,通過寄存器ADCL和ADCH可觀測(cè)外部電壓轉(zhuǎn)換值;
- 調(diào)節(jié)電壓后再全速運(yùn)行,可看到程序再次運(yùn)行至斷點(diǎn)處,通過寄存器ADCL和ADCH可觀測(cè)外部電壓轉(zhuǎn)換值;
- 重復(fù)步驟5),實(shí)現(xiàn)連續(xù)AD轉(zhuǎn)換。
2.10.3寄存器簡(jiǎn)要介紹
| | |
| | 設(shè)置ADC時(shí)鐘與采樣時(shí)間、ADC精度模式選擇 |
| | AD模塊使能、啟動(dòng)、比較使能、及轉(zhuǎn)換完成中斷標(biāo)志、觸發(fā)源使能、事件觸發(fā)設(shè)置 |
| 中斷使能、基準(zhǔn)源控制、上/下限比較設(shè)置 |
| | |
| |
| | |
| |
| | |
| |
| | 參考電壓設(shè)置、通道設(shè)置、結(jié)果寄存器格式配置 |
| |
| |
寄存器的每一位詳細(xì)介紹見Spec。
DAC支持自校準(zhǔn)功能,在精度要求較高的情況下,需先進(jìn)行自校準(zhǔn),然后再正常使用DAC。
2.11.1測(cè)試程序介紹
選擇工程“Dac”,編譯、加載運(yùn)行,測(cè)量DAC輸出口(P1.6)電壓約為2.5V;
注:本次測(cè)試程序選擇DACL執(zhí)行寫操作觸發(fā)DAC輸出更新,選擇內(nèi)建2.5V作為參考電壓,且輸入數(shù)字量為0xFFF,故轉(zhuǎn)換輸出電壓應(yīng)該為2.5V。
實(shí)際應(yīng)用中,可根據(jù)需要在初始化DAC時(shí)選擇其他觸發(fā)方式或決定是否開啟DAC補(bǔ)償。
2.11.2寄存器介紹
DACCON0
| | |
| | DAC轉(zhuǎn)換控制位 0: DAC 禁止 1: DAC使能 |
| | DAC輸出驅(qū)動(dòng)選擇: 00:DAC輸出不帶緩沖器. 01:DAC輸出帶緩沖器(1倍) 1x:DAC輸出帶緩沖器(3倍) |
| | 鎖存器觸發(fā)源選擇 00: DACL執(zhí)行寫操作觸發(fā)DAC輸出更新 01: 定時(shí)器2溢出觸發(fā)DAC輸出更新 10: 定時(shí)器3溢出觸發(fā)DAC輸出更新 11: PCA0定時(shí)器溢出觸發(fā)DAC輸出更新 |
| | DAC的數(shù)據(jù)格式 0: 二進(jìn)制 1: 二進(jìn)制補(bǔ)碼 |
| | DAC端口配置寄存器 0:P1.6作為為IO口 1:P1.6作為DAC輸出口 |
| | DAC中斷標(biāo)志位 0:DAC轉(zhuǎn)換未完成. 1:DAC轉(zhuǎn)換完成,由硬件置1,軟件清0 |
DACCON1
| | |
| | DAC自校準(zhǔn)操作控制(當(dāng)DACOSEL[1:0] = 01或1x時(shí),自校準(zhǔn)功能有效) 0: 自校準(zhǔn)關(guān)閉(自校準(zhǔn)完成,硬件清零) 1: 自校準(zhǔn)開啟(軟件開啟) |
| | DAC補(bǔ)償開關(guān) 0: 開啟DAC補(bǔ)償 1: 關(guān)閉DAC補(bǔ)償 |
| | 外部參考電壓輸入口選擇 0:P1.4作為I/O口 1:P1.4作為VREF輸入引腳 |
| | 內(nèi)建電壓選擇: 0:內(nèi)建2.5V 1:內(nèi)建1.5V (內(nèi)建電壓切換需要1ms的穩(wěn)定時(shí)間) |
| | 內(nèi)建1.5V/2.5V開關(guān): 0:內(nèi)建1.5V/2.5V關(guān)(P1.5作為I/O口) 1:內(nèi)建1.5V/2.5V開(P1.5作為內(nèi)部參考電壓輸出引腳) (內(nèi)建電壓開啟需要1ms的穩(wěn)定時(shí)間) |
| | DAC的參考源選擇: 00: 選擇VDD為基準(zhǔn)電壓 01: 選擇外部VREF端口輸入為基準(zhǔn)電壓 1x: 選擇內(nèi)建電壓1.5V/2.5V為基準(zhǔn)電壓 (DACSREF選擇內(nèi)建電壓1.5V/2.5V時(shí),確保REFON = 1,REFSEL選擇需要的內(nèi)建電壓) |
DACCAL
| | |
| | DAC自校準(zhǔn)補(bǔ)償電壓數(shù)據(jù)符號(hào)位: 0:正(轉(zhuǎn)換值比實(shí)際的值大) 1:負(fù)(轉(zhuǎn)換值比實(shí)際的值小) |
| | DAC自校準(zhǔn)補(bǔ)償電壓數(shù)據(jù) (DAC自校準(zhǔn)完成,根據(jù)校準(zhǔn)結(jié)果更新此寄存器。 當(dāng)OFFSETSW = 0時(shí),實(shí)際DAC的輸出是DACH:DACL與OFFSETDATA經(jīng)過運(yùn)算后的輸出值,以便DAC輸出精度更高 當(dāng)OFFSETSW = 1時(shí),DAC的輸出為DACH:DACL對(duì)應(yīng)的模擬電壓) |
注:該寄存器,在執(zhí)行DAC自校準(zhǔn)功能時(shí),硬件會(huì)自動(dòng)更新;另外,軟件也可修改該寄存器,如,通常為了提高精度,軟件會(huì)對(duì)多次自校準(zhǔn)后得到的DACCAL值求平均,然后再將其寫入DACCAL。
DACH、DACL
| | |
| | DAC數(shù)據(jù) 位3~0是12位DAC數(shù)據(jù)字的高4位。 位7~0是12位DAC數(shù)據(jù)字的低8位。 |
本次Demo程序給出了讀寫EEPROM的接口函數(shù),如下:
1)UINT8 EEPromByteRead(UINT8 nAddrH,UINT8 nAddrL)
從EEPROM指定地址處讀取1個(gè)byte;
2)void EEPromByteProgram(UINT8 nAddrH,UINT8 nAddrL, UINT8 nData)
向EEPROM指定地址處寫一個(gè)byte;
3)void EEPromSectorErase(UINT8 nAddrH)
擦除EEPROM指定扇區(qū)中內(nèi)容;
注:在對(duì)EEPROM進(jìn)行擦除和寫操作之前,一定要關(guān)閉中斷,待操作結(jié)束后,才可打開中斷;另外,對(duì)Flash的讀、寫、擦除操作過程類似于類EEPROM操作,唯一區(qū)別是,在擦除或?qū)、讀之前應(yīng)將FAC位清0。