




免費(fèi)預(yù)覽已結(jié)束,剩余26頁(yè)可下載查看
下載本文檔
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
STM8S的C語(yǔ)言編程(1)- 基本程序與啟動(dòng)代碼現(xiàn)在幾乎所有的單片機(jī)都能用C語(yǔ)言編程了,采用C語(yǔ)言編程確實(shí)能帶來(lái)很多好處,至少可讀性比匯編語(yǔ)言強(qiáng)多了。在STM8的開(kāi)發(fā)環(huán)境中,可以通過(guò)新建一個(gè)工程,自動(dòng)地建立起一個(gè)C語(yǔ)言的框架,生成后開(kāi)發(fā)環(huán)境會(huì)自動(dòng)生成2個(gè)C語(yǔ)言的程序,一個(gè)是main.c,另一個(gè)是stm8_interrupt_vector.c。main.c中就是一個(gè)空的main()函數(shù),如下所示:/* MAIN.C file* * Copyright (c) 2002-2005 STMicroelectronics*/main() while (1);而在stm8_interrupt_vector.c中,就是聲明了對(duì)應(yīng)該芯片的中斷向量,如下所示:/* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices* Copyright (c) 2007 STMicroelectronics*/typedef void far (*interrupt_handler_t)(void);struct interrupt_vector unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler;far interrupt void NonHandledInterrupt (void) /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction */ return;extern void _stext(); /* startup routine */struct interrupt_vector const _vectab = 0x82, (interrupt_handler_t)_stext, /* reset */ 0x82, NonHandledInterrupt, /* trap */ 0x82, NonHandledInterrupt, /* irq0 */ 0x82, NonHandledInterrupt, /* irq1 */ 0x82, NonHandledInterrupt, /* irq2 */ 0x82, NonHandledInterrupt, /* irq3 */ 0x82, NonHandledInterrupt, /* irq4 */ 0x82, NonHandledInterrupt, /* irq5 */ 0x82, NonHandledInterrupt, /* irq6 */ 0x82, NonHandledInterrupt, /* irq7 */ 0x82, NonHandledInterrupt, /* irq8 */ 0x82, NonHandledInterrupt, /* irq9 */ 0x82, NonHandledInterrupt, /* irq10 */ 0x82, NonHandledInterrupt, /* irq11 */ 0x82, NonHandledInterrupt, /* irq12 */ 0x82, NonHandledInterrupt, /* irq13 */ 0x82, NonHandledInterrupt, /* irq14 */ 0x82, NonHandledInterrupt, /* irq15 */ 0x82, NonHandledInterrupt, /* irq16 */ 0x82, NonHandledInterrupt, /* irq17 */ 0x82, NonHandledInterrupt, /* irq18 */ 0x82, NonHandledInterrupt, /* irq19 */ 0x82, NonHandledInterrupt, /* irq20 */ 0x82, NonHandledInterrupt, /* irq21 */ 0x82, NonHandledInterrupt, /* irq22 */ 0x82, NonHandledInterrupt, /* irq23 */ 0x82, NonHandledInterrupt, /* irq24 */ 0x82, NonHandledInterrupt, /* irq25 */ 0x82, NonHandledInterrupt, /* irq26 */ 0x82, NonHandledInterrupt, /* irq27 */ 0x82, NonHandledInterrupt, /* irq28 */ 0x82, NonHandledInterrupt, /* irq29 */;在stm8_interrupt_vector.c中,除了定義了中斷向量表外,還定義了空的中斷服務(wù)程序,用于那些不用的中斷。當(dāng)然在自動(dòng)建立時(shí),所有的中斷服務(wù)都是空的,因此,除了第1個(gè)復(fù)位的向量外,其它都指向那個(gè)空的中斷服務(wù)函數(shù)。生成框架后,就可以用Build菜單下的Rebuild All對(duì)項(xiàng)目進(jìn)行編譯和連接,生成所需的目標(biāo)文件,然后就可以加載到STM8的芯片中,這里由于main()函數(shù)是一個(gè)空函數(shù),因此沒(méi)有任何實(shí)際的功能。不過(guò)我們可以把這個(gè)框架對(duì)應(yīng)的匯編代碼反出來(lái),看看C語(yǔ)言生成的代碼,這樣可以更深入地了解C語(yǔ)言編程的特點(diǎn)。生成的代碼包括4個(gè)部分,如圖1、圖2、圖3、圖4所示。 圖1 圖2 圖3 圖4 圖1顯示的是從內(nèi)存地址8000H開(kāi)始的中斷向量表,中斷向量表中的第1行82008083H為復(fù)位后單片機(jī)運(yùn)行的第1跳指令的地址。從表中可以看出,單片機(jī)復(fù)位后,將從8083H開(kāi)始運(yùn)行。其它行的中斷向量都指向同一個(gè)位置的中斷服務(wù)程序80D0H。 圖2顯示的是3個(gè)字節(jié),前2個(gè)字節(jié)8083H為復(fù)位后的第1條指令的地址,第3個(gè)字節(jié)是一個(gè)常量0,后面的啟動(dòng)代碼要用到。 圖3顯示的是啟動(dòng)代碼,啟動(dòng)代碼中除了初始化堆棧指針外,就是初始化RAM單元。由于目前是一個(gè)空的框架,因此在初始化完堆棧指針(設(shè)置成0FFFH)后,由于8082H單元的內(nèi)容為0,因此程序就跳到了80B1H,此處是一個(gè)循環(huán),將RAM單元從0到5初始化成0。然后由于寄存器X設(shè)置成0100H,就直接通過(guò)CALL main進(jìn)入C的main()函數(shù)。 圖4顯示的是main()函數(shù)和中斷服務(wù)函數(shù),main()函數(shù)對(duì)應(yīng)的代碼就是一個(gè)無(wú)限的循環(huán),而中斷服務(wù)函數(shù)就一條指令,即中斷返回指令。 通過(guò)分析,可以看出用C語(yǔ)言編程時(shí),比匯編語(yǔ)言編程時(shí),就是多出了一段啟動(dòng)代碼。 2010-7-30STM8的C語(yǔ)言編程(2) 變量空間的分配 STM8的C語(yǔ)言編程(2) 變量空間的分配采用C這樣的高級(jí)語(yǔ)言,其實(shí)可以不用關(guān)心變量在存儲(chǔ)器空間中是如何具體分配的。但如果了解如何分配,對(duì)編程還是有好處的,尤其是在調(diào)試時(shí)。例如下面的程序定義了全局變量數(shù)組buffer和一個(gè)局部變量i,在RAM中如何分配的呢?/* MAIN.C file* * Copyright (c) 2002-2005 STMicroelectronics*/unsigned char buffer10; / 定義全局變量main() unsigned char i; / 定義局部變量 for(i=0;i10;i+) bufferi = 0x55; 我們可以通過(guò)DEBUG中的反匯編窗口,看到如下的對(duì)應(yīng)代碼:從這段代碼中可以看到,全局變量buffer被分配到空間從地址0000H到0009H。而局部變量i則在堆??臻g中分配,通過(guò)PUSH A指令,將堆棧指針減1,騰出一個(gè)字節(jié)的空間,而SP+1指向的空間就是分配給局部變量使用的空間。由此可以得出初步的結(jié)論,對(duì)于全局變量,內(nèi)存分配是從低地址0000H開(kāi)始向上分配的。而局部變量則是在堆棧空間中分配。另外從上一篇文章中,可以知道堆棧指針初始化時(shí)為0FFFH。而根據(jù)PUSH指令的定義,當(dāng)壓棧后堆棧指針減1。因此堆棧是從上往下使用的。因此根據(jù)內(nèi)存分配和堆棧使用規(guī)則,我們?cè)诔绦蛟O(shè)計(jì)時(shí),不能定義過(guò)多的變量,免得沒(méi)有空間給堆棧使用。換句話(huà)說(shuō),當(dāng)定義變量時(shí),一定要考慮到堆??臻g,尤其是那些復(fù)雜的系統(tǒng),程序調(diào)用層數(shù)多,這樣就會(huì)占用大量的堆??臻g??傊?,在單片機(jī)的程序設(shè)計(jì)時(shí),由于RAM空間非常有限,要充分考慮到全局變量、局部變量、程序調(diào)用層數(shù)和中斷服務(wù)調(diào)用對(duì)空間的占用。STM8的C語(yǔ)言編程(3) GPIO輸出 STM8的C語(yǔ)言編程(3) GPIO輸出與前些日子寫(xiě)的用匯編語(yǔ)言進(jìn)行的實(shí)驗(yàn)一樣,從今天開(kāi)始,要在ST的三合一開(kāi)發(fā)板上,用C語(yǔ)言編寫(xiě)程序,進(jìn)行一系列的實(shí)驗(yàn)。首先當(dāng)然從最簡(jiǎn)單的LED指示燈閃爍的實(shí)驗(yàn)開(kāi)始。開(kāi)發(fā)板上的LED1接在STM8的PD3上,因此要將PD3設(shè)置成輸出模式,為了提高高電平時(shí)的輸出電流,要將其設(shè)置成推挽輸出方式。這主要通過(guò)設(shè)置對(duì)應(yīng)的DDR/CR1/CR2寄存器實(shí)現(xiàn)。利用ST的開(kāi)發(fā)工具,先生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過(guò)后,下載到開(kāi)發(fā)板,運(yùn)行程序,可以看到LED1在閃爍,且閃爍的頻率為5HZ。/* MAIN.C file* * Copyright (c) 2002-2005 STMicroelectronics*/#include STM8S207C_S.h/ 函數(shù)功能:延時(shí)函數(shù)/ 輸入?yún)?shù):ms - 要延時(shí)的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)/ 備 注:無(wú)void DelayMS(unsigned int ms) unsigned char i; while(ms != 0) for(i=0;i250;i+) for(i=0;i75;i+) ms-; / 函數(shù)功能:主函數(shù)/ 初始化GPIO端口PD3,驅(qū)動(dòng)PD3為高電平和低電平/ 輸入?yún)?shù):ms - 要延時(shí)的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)/ 備 注:無(wú)main() PD_DDR = 0x08; PD_CR1 = 0x08; / 將PD3設(shè)置成推挽輸出 PD_CR2 = 0x00; while(1) PD_ODR = PD_ODR | 0x08; / 將PD3的輸出設(shè)置成1 DelayMS(100); / 延時(shí)100MS PD_ODR = PD_ODR & 0xF7; / 將PD3的輸出設(shè)置成0 DelayMS(100); / 延時(shí)100MS 需要注意的是,當(dāng)生成完框架后,為了能方便使用STM8的寄存器名字,必須包括STM8S207C_S.h,最好將該文件拷貝到C:Program FilesSTMicroelectronicsst_toolsetinclude目錄下,拷貝到工程目錄下?;蛘邔⒃撀窂教顚?xiě)到該工程的Settings中的C Compiler選項(xiàng)Preprocessor的Additional include中,這樣編譯時(shí)才會(huì)找到該文件。STM8的C語(yǔ)言編程(4) GPIO輸出和輸入 STM8的C語(yǔ)言編程(3) GPIO輸出和輸入今天要進(jìn)行的實(shí)驗(yàn),是利用GPIO進(jìn)行輸入和輸出。在ST的三合一開(kāi)發(fā)板上,按鍵接在GPIO的PD7上,LED接在GPIO的PD3上,因此我們要將GPIO的PD7初始化成輸入,PD3初始化成輸出。關(guān)于GPIO的引腳設(shè)置,主要是要初始化方向寄存器DDR,控制寄存器1(CR1)和控制寄存器2(CR2),寄存器的每一位對(duì)應(yīng)GPIO的每一個(gè)引腳。具體的設(shè)置功能定義如下:DDR CR1 CR2 引腳設(shè)置0 0 0 懸浮輸入0 0 1 上拉輸入0 1 0 中斷懸浮輸入0 1 1 中斷上拉輸入1 0 0 開(kāi)漏輸出1 1 0 推挽輸出1 X 1 輸出(最快速度為10MHZ)另外,輸出引腳對(duì)應(yīng)的寄存器為ODR,輸入引腳對(duì)應(yīng)的寄存器為IDR。下面的程序是檢測(cè)按鍵的狀態(tài),當(dāng)按鍵按下時(shí),點(diǎn)亮LED,當(dāng)按鍵抬起時(shí),熄滅LED。同樣也是利用ST的開(kāi)發(fā)工具,先生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過(guò)后,下載到開(kāi)發(fā)板,運(yùn)行程序,按下按鍵,LED就點(diǎn)亮,抬起按鍵,LED就熄滅了。另外,要注意,將STM8S207C_S.h拷貝到當(dāng)前項(xiàng)目的目錄下。/ 程序描述:檢測(cè)開(kāi)發(fā)板上的按鍵,若按下,則點(diǎn)亮LED,若抬起,則熄滅LED/ 按鍵接在MCU的GPIO的PD7上/ LED接在MCU的GPIO的PD3上#include STM8S207C_S.hmain() PD_DDR = 0x08; PD_CR1 = 0x08; / 將PD3設(shè)置成推挽輸出 PD_CR2 = 0x00; while(1) / 進(jìn)入無(wú)限循環(huán) if(PD_IDR & 0x80) = 0x80) / 讀入PD7的引腳信號(hào) PD_ODR = PD_ODR & 0xF7; / 如果PD7為1,則將PD3的輸出設(shè)置成0,熄滅LED else PD_ODR = PD_ODR | 0x08; / 否則,將PD3的輸出設(shè)置成1,點(diǎn)亮LED STM8的C語(yǔ)言編程(5)8位定時(shí)器應(yīng)用之一 STM8的C語(yǔ)言編程(5)8位定時(shí)器應(yīng)用之一在STM8單片機(jī)中,有多種定時(shí)器資源,既有8位的定時(shí)器,也有普通的16位定時(shí)器,還有高級(jí)的定時(shí)器。今天的實(shí)驗(yàn)是用最簡(jiǎn)單的8位定時(shí)器TIM4來(lái)進(jìn)行延時(shí),然后驅(qū)動(dòng)LED閃爍。為了簡(jiǎn)單起見(jiàn),這里是通過(guò)程序查詢(xún)定時(shí)器是否產(chǎn)生更新事件,來(lái)判斷定時(shí)器的延時(shí)是否結(jié)束。同樣還是利用ST的開(kāi)發(fā)工具,生成一個(gè)C程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過(guò)后,下載到開(kāi)發(fā)板,運(yùn)行程序,可以看到LED在閃爍,或者用示波器可以在LED引腳上看到方波。在這里要特別提醒的是,從ST給的手冊(cè)上看,這個(gè)定時(shí)器中的計(jì)數(shù)器是一個(gè)加1計(jì)數(shù)器,但本人在實(shí)驗(yàn)過(guò)程中感覺(jué)不太對(duì),經(jīng)過(guò)反復(fù)的實(shí)驗(yàn),我認(rèn)為應(yīng)該是一個(gè)減1計(jì)數(shù)器(也許是我拿的手冊(cè)不對(duì),或許是理解上有誤)。例如,當(dāng)給定時(shí)器中的自動(dòng)裝載寄存器裝入255時(shí),產(chǎn)生的方波頻率最小,就象下面代碼中計(jì)算的那樣,產(chǎn)生的方波頻率為30HZ左右。若初始化時(shí)給自動(dòng)裝載寄存器裝入1,則產(chǎn)生的方波頻率最大,大約為3.9K左右。也就是說(shuō)實(shí)際的分頻數(shù)為ARR寄存器的值+1。/ 程序描述:通過(guò)初始化定時(shí)器4,進(jìn)行延時(shí),驅(qū)動(dòng)LED閃爍/ LED接在MCU的GPIO的PD3上#include STM8S207C_S.hmain() / 首先初始化GPIO PD_DDR = 0x08; PD_CR1 = 0x08; / 將PD3設(shè)置成推挽輸出 PD_CR2 = 0x00; / 然后初始化定時(shí)器4 TIM4_IER = 0x00; / 禁止中斷 TIM4_EGR = 0x01; / 允許產(chǎn)生更新事件 TIM4_PSCR = 0x07; / 計(jì)數(shù)器時(shí)鐘=主時(shí)鐘/128=2MHZ/128 / 相當(dāng)于計(jì)數(shù)器周期為64uS TIM4_ARR = 255; / 設(shè)定重裝載時(shí)的寄存器值,255是最大值 TIM4_CNTR = 255; / 設(shè)定計(jì)數(shù)器的初值 / 定時(shí)周期=(ARR+1)*64=16320uS TIM4_CR1 = 0x01; / b0 = 1,允許計(jì)數(shù)器工作 / b1 = 0,允許更新 / 設(shè)置控制器,啟動(dòng)定時(shí)器 while(1) / 進(jìn)入無(wú)限循環(huán) while(TIM4_SR1 & 0x81) = 0x00); / 等待更新標(biāo)志 TIM4_SR1 = 0x00; / 清除更新標(biāo)志 PD_ODR = PD_ODR 0x08; / LED驅(qū)動(dòng)信號(hào)取反 / LED閃爍頻率=2MHZ/128/255/2=30.63 STM8與匯編語(yǔ)言(9)EEPROM應(yīng)用EEPROM是單片機(jī)應(yīng)用系統(tǒng)中經(jīng)常會(huì)用到的存儲(chǔ)器,它主要用來(lái)保存一些掉電后需要保持不變的數(shù)據(jù)。在以前的單片機(jī)系統(tǒng)中,通常都是在單片機(jī)外面再擴(kuò)充一個(gè)EEPROM芯片,這種方法除了增加成本外,也降低了可靠性。現(xiàn)在,很多單片機(jī)的公司都推出了集成有小容量EEPROM的單片機(jī),這樣就方便了使用,降低了成本,提高了可靠性。STM8單片機(jī)芯片內(nèi)部也集成有EEPROM,容量從640字節(jié)到2K字節(jié)。最為特色的是,在STM8單片機(jī)中,對(duì)EEPROM的訪(fǎng)問(wèn)就象常規(guī)的RAM一樣,非常方便。EEPROM的地址空間與內(nèi)存是統(tǒng)一編址的,地址從004000H開(kāi)始,大小根據(jù)不同的芯片型號(hào)而定。下面的實(shí)驗(yàn)程序,就是先給EEPROM中的第一個(gè)單元004000H寫(xiě)入55H,然后再讀到全局變量ch中。同樣還是利用ST的開(kāi)發(fā)工具,生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。/ 程序描述:對(duì)芯片內(nèi)部的EEPROM存儲(chǔ)單元進(jìn)行實(shí)驗(yàn)#include STM8S207C_S.hunsigned char ch; main() unsigned char *p; p = (unsigned char *)0x4000; / 指針p指向芯片內(nèi)部的EEPROM第一個(gè)單元 / 對(duì)數(shù)據(jù)EEPROM進(jìn)行解鎖 do FLASH_DUKR = 0xae; / 寫(xiě)入第一個(gè)密鑰 FLASH_DUKR = 0x56; / 寫(xiě)入第二個(gè)密鑰 while(FLASH_IAPSR & 0x08) = 0); / 若解鎖未成功,則重新再來(lái) *p = 0xaa; / 寫(xiě)入第一個(gè)字節(jié) while(FLASH_IAPSR & 0x04) = 0); / 等待寫(xiě)操作成功 ch = *p; / 將寫(xiě)入的內(nèi)容讀到變量ch中 while(1) ; 這里要注意的是,2個(gè)密鑰的順序,與STM8的用戶(hù)手冊(cè)上是相反的,如果按照手冊(cè)上的順序,就會(huì)停留在dowhile循環(huán)中。具體原因,也不是很清楚,也可能是我拿到的手冊(cè)(中文和英文的都一樣)太舊了,或者是理解有誤。 另外,上面的實(shí)驗(yàn)程序中,ch不能為局部變量,否則的話(huà),在調(diào)試環(huán)境中跟蹤ch變量時(shí),顯示的結(jié)果就不對(duì),通過(guò)反匯編,我覺(jué)得是編譯有問(wèn)題,當(dāng)定義成局部變量時(shí),ch = *p的匯編代碼如下:main.c:23 ch = *p; / 將寫(xiě)入的內(nèi)容讀到變量ch中 0x80f0 0x7B01 LD A,(0x01,SP) LD A,(0x01,SP) 0x80f2 0x97 LD XL,A LD XL,A 0x80f3 0x1E02 LDW X,(0x02,SP) LDW X,(0x02,SP) 0x80f5 0xF6 LD A,(X) LD A,(X) 0x80f6 0x97 LD XL,A LD XL,A如果將ch定義成全局變量,則匯編代碼為:main.c:22 ch = *p; / 將寫(xiě)入的內(nèi)容讀到變量ch中 0x80ef 0x1E01 LDW X,(0x01,SP) LDW X,(0x01,SP) 0x80f1 0xF6 LD A,(X) LD A,(X) 0x80f2 0xB700 LD 0x00,A LD 0x00,A 這一段代碼的分析僅供參考,本人使用的開(kāi)發(fā)環(huán)境為STVD4.1.0,編譯器版本號(hào)為:COSMIC的CxSTM84.2.4。STM8的C語(yǔ)言編程(10) 修改CPU的時(shí)鐘在有些單片機(jī)的應(yīng)用系統(tǒng)中,并不需要CPU運(yùn)行在多高的頻率。在低頻率下運(yùn)行,芯片的功耗會(huì)大大下降。STM8單片機(jī)在運(yùn)行過(guò)程中,可以隨時(shí)修改CPU運(yùn)行時(shí)鐘頻率,非常方便。實(shí)現(xiàn)這一功能,主要涉及到時(shí)鐘分頻寄存器(CLK_CKDIVR)。時(shí)鐘分頻寄存器是一個(gè)8位的寄存器,高3位保留,位4和位3用于定義高速內(nèi)部時(shí)鐘的預(yù)分頻,而位2到位0則用于CPU時(shí)鐘的分頻。這5位的詳細(xì)定義如下:位4 位3 高速內(nèi)部時(shí)鐘的分頻系數(shù)0 0 10 1 21 0 41 1 8位2 位1 位0 CPU時(shí)鐘的分頻系數(shù)0 0 0 10 0 1 20 1 0 40 1 1 81 0 0 161 0 1 321 1 0 641 1 1 128假設(shè)我們使用內(nèi)部的高速RC振蕩器,其頻率為16MHZ,當(dāng)位4為0,位3為1時(shí),則內(nèi)部高速時(shí)鐘的分頻系數(shù)為2,因此輸出的主時(shí)鐘為8MHZ。當(dāng)位2為0,位1為1,位0為0時(shí),CPU時(shí)鐘的分頻系數(shù)為4,即CPU時(shí)鐘=主時(shí)鐘/4=2MHZ。下面的實(shí)驗(yàn)程序首先將CPU的運(yùn)行時(shí)鐘設(shè)置在8MHZ,然后快速閃爍LED指示燈。接著,通過(guò)修改主時(shí)鐘的分頻系數(shù)和CPU時(shí)鐘的分頻系數(shù),將CPU時(shí)鐘頻率設(shè)置在500KHZ,然后再慢速閃爍LED指示燈。通過(guò)觀察LED指示燈的閃爍頻率,可以看到,同樣的循環(huán)代碼,由于CPU時(shí)鐘頻率的改變,閃爍頻率和時(shí)間長(zhǎng)短都發(fā)生了變化。同樣還是利用ST的開(kāi)發(fā)工具,生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。修改后的代碼編譯連接后,就可以下載到開(kāi)發(fā)板上,運(yùn)行后會(huì)看到LED的閃爍頻率有明顯的變化。/ 程序描述:通過(guò)修改CPU時(shí)鐘的分頻系數(shù),來(lái)改變CPU的運(yùn)行速度#include STM8S207C_S.h/ 函數(shù)功能:延時(shí)函數(shù)/ 輸入?yún)?shù):ms - 要延時(shí)的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)/ 備 注:無(wú)void DelayMS(unsigned int ms) unsigned char i; while(ms != 0) for(i=0;i250;i+) for(i=0;i75;i+) ms-; main()int i; PD_DDR = 0x08; PD_CR1 = 0x08; / 將PD3設(shè)置成推挽輸出 PD_CR2 = 0x00; CLK_SWR = 0xE1; / 選擇芯片內(nèi)部的16MHZ的RC振蕩器為主時(shí)鐘 for(;) / 進(jìn)入無(wú)限循環(huán) / 下面設(shè)置CPU時(shí)鐘分頻器,使得CPU時(shí)鐘=主時(shí)鐘 / 通過(guò)發(fā)光二極管,可以看出,程序運(yùn)行的速度確實(shí)明顯提高了 CLK_CKDIVR = 0x08; / 主時(shí)鐘 = 16MHZ / 2 / CPU時(shí)鐘 = 主時(shí)鐘 = 8MHZ for(i=0;i10;i+) PD_ODR = 0x08; DelayMS(100); PD_ODR = 0x00; DelayMS(100); / 下面設(shè)置CPU時(shí)鐘分頻器,使得CPU時(shí)鐘=主時(shí)鐘/4 / 通過(guò)發(fā)光二極管,可以看出,程序運(yùn)行的速度確實(shí)明顯下降了 CLK_CKDIVR = 0x1A; / 主時(shí)鐘 = 16MHZ / 8 / CPU時(shí)鐘 = 主時(shí)鐘 / 4 = 500KHZ for(i=0;i10;i+) PD_ODR = 0x08; DelayMS(100); PD_ODR = 0x00; DelayMS(100); STM8的C語(yǔ)言編程(10) 修改CPU的時(shí)鐘在有些單片機(jī)的應(yīng)用系統(tǒng)中,并不需要CPU運(yùn)行在多高的頻率。在低頻率下運(yùn)行,芯片的功耗會(huì)大大下降。STM8單片機(jī)在運(yùn)行過(guò)程中,可以隨時(shí)修改CPU運(yùn)行時(shí)鐘頻率,非常方便。實(shí)現(xiàn)這一功能,主要涉及到時(shí)鐘分頻寄存器(CLK_CKDIVR)。時(shí)鐘分頻寄存器是一個(gè)8位的寄存器,高3位保留,位4和位3用于定義高速內(nèi)部時(shí)鐘的預(yù)分頻,而位2到位0則用于CPU時(shí)鐘的分頻。這5位的詳細(xì)定義如下:位4 位3 高速內(nèi)部時(shí)鐘的分頻系數(shù)0 0 10 1 21 0 41 1 8位2 位1 位0 CPU時(shí)鐘的分頻系數(shù)0 0 0 10 0 1 20 1 0 40 1 1 81 0 0 161 0 1 321 1 0 641 1 1 128假設(shè)我們使用內(nèi)部的高速RC振蕩器,其頻率為16MHZ,當(dāng)位4為0,位3為1時(shí),則內(nèi)部高速時(shí)鐘的分頻系數(shù)為2,因此輸出的主時(shí)鐘為8MHZ。當(dāng)位2為0,位1為1,位0為0時(shí),CPU時(shí)鐘的分頻系數(shù)為4,即CPU時(shí)鐘=主時(shí)鐘/4=2MHZ。下面的實(shí)驗(yàn)程序首先將CPU的運(yùn)行時(shí)鐘設(shè)置在8MHZ,然后快速閃爍LED指示燈。接著,通過(guò)修改主時(shí)鐘的分頻系數(shù)和CPU時(shí)鐘的分頻系數(shù),將CPU時(shí)鐘頻率設(shè)置在500KHZ,然后再慢速閃爍LED指示燈。通過(guò)觀察LED指示燈的閃爍頻率,可以看到,同樣的循環(huán)代碼,由于CPU時(shí)鐘頻率的改變,閃爍頻率和時(shí)間長(zhǎng)短都發(fā)生了變化。同樣還是利用ST的開(kāi)發(fā)工具,生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。修改后的代碼編譯連接后,就可以下載到開(kāi)發(fā)板上,運(yùn)行后會(huì)看到LED的閃爍頻率有明顯的變化。/ 程序描述:通過(guò)修改CPU時(shí)鐘的分頻系數(shù),來(lái)改變CPU的運(yùn)行速度#include STM8S207C_S.h/ 函數(shù)功能:延時(shí)函數(shù)/ 輸入?yún)?shù):ms - 要延時(shí)的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)/ 備 注:無(wú)void DelayMS(unsigned int ms) unsigned char i; while(ms != 0) for(i=0;i250;i+) for(i=0;i75;i+) ms-; main()int i; PD_DDR = 0x08; PD_CR1 = 0x08; / 將PD3設(shè)置成推挽輸出 PD_CR2 = 0x00; CLK_SWR = 0xE1; / 選擇芯片內(nèi)部的16MHZ的RC振蕩器為主時(shí)鐘 for(;) / 進(jìn)入無(wú)限循環(huán) / 下面設(shè)置CPU時(shí)鐘分頻器,使得CPU時(shí)鐘=主時(shí)鐘 / 通過(guò)發(fā)光二極管,可以看出,程序運(yùn)行的速度確實(shí)明顯提高了 CLK_CKDIVR = 0x08; / 主時(shí)鐘 = 16MHZ / 2 / CPU時(shí)鐘 = 主時(shí)鐘 = 8MHZ for(i=0;i10;i+) PD_ODR = 0x08; DelayMS(100); PD_ODR = 0x00; DelayMS(100); / 下面設(shè)置CPU時(shí)鐘分頻器,使得CPU時(shí)鐘=主時(shí)鐘/4 / 通過(guò)發(fā)光二極管,可以看出,程序運(yùn)行的速度確實(shí)明顯下降了 CLK_CKDIVR = 0x1A; / 主時(shí)鐘 = 16MHZ / 8 / CPU時(shí)鐘 = 主時(shí)鐘 / 4 = 500KHZ for(i=0;i10;i+) PD_ODR = 0x08; DelayMS(100); PD_ODR = 0x00; DelayMS(100); STM8的C語(yǔ)言編程(11) 切換時(shí)鐘源STM8單片機(jī)的時(shí)鐘源非常豐富,芯片內(nèi)部既有16MHZ的高速RC振蕩器,也有128KHZ的低速RC振蕩器,外部還可以接一個(gè)高速的晶體振蕩器。在系統(tǒng)運(yùn)行過(guò)程中,可以根據(jù)需要,自由地切換。單片機(jī)復(fù)位后,首先采用的是內(nèi)部的高速RC振蕩器,且分頻系數(shù)為8,因此CPU的上電運(yùn)行的時(shí)鐘頻率為2MHZ。切換時(shí)鐘源,主要涉及到的寄存器有:主時(shí)鐘切換寄存器CLK_SWR和切換控制寄存器CLK_SWCR。主時(shí)鐘切換寄存器的復(fù)位值為0xe1,表示切換到內(nèi)部的高速RC振蕩器上。當(dāng)往該寄存器寫(xiě)入0xb4時(shí),表示切換到外部的高速晶體振蕩器上。在實(shí)際切換過(guò)程中,應(yīng)該先將切換控制寄存器中的SWEN(第1位)設(shè)置成1,然后設(shè)置CLK_SWCR的值,最后要判斷切換控制寄存器中的SWIF標(biāo)志是否切換成功。下面的實(shí)驗(yàn)程序首先將主時(shí)鐘源切換到外部的晶體振蕩器上,振蕩頻率為8MHZ,然后,然后快速閃爍LED指示燈。接著,將主時(shí)鐘源又切換到內(nèi)部的振蕩器上,振蕩頻率為2MHZ,然后再慢速閃爍LED指示燈。通過(guò)觀察LED指示燈的閃爍頻率,可以看到,同樣的循環(huán)代碼,由于主時(shí)鐘源的改變的改變,閃爍頻率和時(shí)間長(zhǎng)短都發(fā)生了變化。同樣還是利用ST的開(kāi)發(fā)工具,生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。/ 程序描述:通過(guò)切換CPU的主時(shí)鐘源,來(lái)改變CPU的運(yùn)行速度#include STM8S207C_S.h/ 函數(shù)功能:延時(shí)函數(shù)/ 輸入?yún)?shù):ms - 要延時(shí)的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)/ 備 注:無(wú)void DelayMS(unsigned int ms) unsigned char i; while(ms != 0) for(i=0;i250;i+) for(i=0;i75;i+) ms-; main() int i; / 將PD3設(shè)置成推挽輸出,以便推動(dòng)LED PD_DDR = 0x08; PD_CR1 = 0x08; PD_CR2 = 0x00; / 啟動(dòng)外部高速晶體振蕩器 CLK_ECKR = 0x01; / 允許外部高速振蕩器工作 while(CLK_ECKR & 0x02) = 0x00); / 等待外部高速振蕩器準(zhǔn)備好 / 注意,復(fù)位后CPU的時(shí)鐘源來(lái)自?xún)?nèi)部的RC振蕩器 for(;) / 進(jìn)入無(wú)限循環(huán) / 下面將CPU的時(shí)鐘源切換到外部的高速晶體振蕩器上,在開(kāi)發(fā)板上的頻率為8MHZ / 通過(guò)發(fā)光二極管,可以看出,程序運(yùn)行的速度確實(shí)明顯提高了 CLK_SWCR = CLK_SWCR | 0x02; / SWEN - 1 CLK_SWR = 0xB4; / 選擇芯片外部的高速振蕩器為主時(shí)鐘 while(CLK_SWCR & 0x08) = 0); / 等待切換成功 CLK_SWCR = CLK_SWCR & 0xFD; / 清除切換標(biāo)志 for(i=0;i10;i+) / LED高速閃爍10次 PD_ODR = 0x08; DelayMS(100); PD_ODR = 0x00; DelayMS(100); / 下面將CPU的時(shí)鐘源切換到內(nèi)部的RC振蕩器上,由于CLK_CKDIVR的復(fù)位值為0x18 / 所以16MHZ的RC振蕩器要經(jīng)過(guò)8分頻后才作為主時(shí)鐘,因此頻率為2MHZ / 通過(guò)發(fā)光二極管,可以看出,程序運(yùn)行的速度確實(shí)明顯下降了 CLK_SWCR = CLK_SWCR | 0x02; / SWEN - 1 CLK_SWR = 0xE1; / 選擇HSI為主時(shí)鐘源 while(CLK_SWCR & 0x08) = 0); / 等待切換成功 CLK_SWCR = CLK_SWCR & 0xFD; / 清除切換標(biāo)志 for(i=0;i10;i+) / LED低速閃爍10次 PD_ODR = 0x08; DelayMS(100); PD_ODR = 0x00; DelayMS(100); STM8的C語(yǔ)言編程(12) AD轉(zhuǎn)換在許多的單片機(jī)應(yīng)用系統(tǒng)中,都需要A/D轉(zhuǎn)換器,將模擬量轉(zhuǎn)換成數(shù)字量。在STM8單片機(jī)中,提供的是10位的A/D,通道數(shù)隨芯片不同而不同,少的有4個(gè)通道,多的則有16個(gè)通道。下面的實(shí)驗(yàn)程序首先對(duì)A/D輸入進(jìn)行采樣,然后將采樣結(jié)果的高8位(丟棄最低的2位),作為延時(shí)參數(shù)去調(diào)用延時(shí)子程序,然后再去驅(qū)動(dòng)LED控制信號(hào)。因此不同的采樣值,決定了LED的閃爍頻率。當(dāng)旋轉(zhuǎn)ST三合一開(kāi)發(fā)板上的電位器時(shí),可以看到LED的閃爍頻率發(fā)生變化。同樣還是利用ST的開(kāi)發(fā)工具,生成一個(gè)C語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。/ 程序描述:通過(guò)AD模塊,采樣電位器的電壓,改變LED的閃爍頻率#include STM8S207C_S.h/ 函數(shù)功能:延時(shí)函數(shù)/ 輸入?yún)?shù):ms -
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 海外房地產(chǎn)投資顧問(wèn)及風(fēng)險(xiǎn)評(píng)估合同
- 知乎付費(fèi)專(zhuān)欄原創(chuàng)文章創(chuàng)作與推廣合同
- 河道生態(tài)治理責(zé)任書(shū)及水環(huán)境質(zhì)量監(jiān)管與改善合同
- 講普通話(huà)用規(guī)范字主題班會(huì)
- 重癥監(jiān)護(hù)的護(hù)理技巧試題及答案
- 課程學(xué)習(xí)中級(jí)審計(jì)師試題及答案參考
- 復(fù)合型人才培訓(xùn)體系構(gòu)建與實(shí)踐
- 高級(jí)會(huì)計(jì)新思維與新方法探討試題及答案
- 廣西示范性高中2024-2025學(xué)年高二下學(xué)期4月期中考試 語(yǔ)文 含答案
- 建筑施工合同履行與監(jiān)控課件
- 初中數(shù)學(xué)《軸對(duì)稱(chēng)及其性質(zhì)》教學(xué)課件 2024-2025學(xué)年北師大版數(shù)學(xué)七年級(jí)下冊(cè)
- 食用農(nóng)產(chǎn)品集中交易市場(chǎng)基本情況信息表
- 廣西南寧建寧水務(wù)投資集團(tuán)有限責(zé)任公司招聘筆試題庫(kù)2025
- 乳腺癌防治知識(shí)手冊(cè)運(yùn)動(dòng)與健康生活方式建議
- 2024年上海第二工業(yè)大學(xué)單招職業(yè)技能測(cè)試題庫(kù)附答案
- 2025年中國(guó)空調(diào)清洗市場(chǎng)競(jìng)爭(zhēng)格局及行業(yè)投資前景預(yù)測(cè)報(bào)告
- 蓄水池水池清洗方案
- 空冷器、換熱器設(shè)備試壓方案
- 燃?xì)夤艿兰霸O(shè)施保護(hù)方案
- 企業(yè)綠色發(fā)展中的創(chuàng)新實(shí)踐研究
- 2025中衛(wèi)輔警考試題庫(kù)
評(píng)論
0/150
提交評(píng)論