




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、 stm8的c語(yǔ)言編程(1)基本程序與啟動(dòng)代碼分析現(xiàn)在幾乎所有的單片機(jī)都能用c語(yǔ)言編程了,采用c語(yǔ)言編程確實(shí)能帶來(lái)很多好處,至少可讀性比匯編語(yǔ)言強(qiáng)多了。在stm8的開發(fā)環(huán)境中,可以通過(guò)新建一個(gè)工程,自動(dòng)地建立起一個(gè)c語(yǔ)言的框架,生成后開發(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_vect
2、or.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
3、(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,
4、 /* trap */ 0x82, nonhandledinterrupt, /* irq0 */ 0x82, nonhandledinterrupt, /* irq1 */ 0x82, nonhandledinterrupt, /* irq2 */ 0x82, nonhandledinterrupt, /* irq3 */ 0x82, nonhandledinterrupt, /* irq4 */ 0x82, nonhandledinterrupt, /* irq5 */ 0x82, nonhandledinterrupt, /* irq6 */ 0x82, nonhandledinterr
5、upt, /* irq7 */ 0x82, nonhandledinterrupt, /* irq8 */ 0x82, nonhandledinterrupt, /* irq9 */ 0x82, nonhandledinterrupt, /* irq10 */ 0x82, nonhandledinterrupt, /* irq11 */ 0x82, nonhandledinterrupt, /* irq12 */ 0x82, nonhandledinterrupt, /* irq13 */ 0x82, nonhandledinterrupt, /* irq14 */ 0x82, nonhand
6、ledinterrupt, /* irq15 */ 0x82, nonhandledinterrupt, /* irq16 */ 0x82, nonhandledinterrupt, /* irq17 */ 0x82, nonhandledinterrupt, /* irq18 */ 0x82, nonhandledinterrupt, /* irq19 */ 0x82, nonhandledinterrupt, /* irq20 */ 0x82, nonhandledinterrupt, /* irq21 */ 0x82, nonhandledinterrupt, /* irq22 */ 0
7、x82, nonhandledinterrupt, /* irq23 */ 0x82, nonhandledinterrupt, /* irq24 */ 0x82, nonhandledinterrupt, /* irq25 */ 0x82, nonhandledinterrupt, /* irq26 */ 0x82, nonhandledinterrupt, /* irq27 */ 0x82, nonhandledinterrupt, /* irq28 */ 0x82, nonhandledinterrupt, /* irq29 */;在stm8_interrupt_vector.c中,除了
8、定義了中斷向量表外,還定義了空的中斷服務(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ù),因此沒有任何實(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開始的中斷向量表
9、,中斷向量表中的第1行82008083h為復(fù)位后單片機(jī)運(yùn)行的第1跳指令的地址。從表中可以看出,單片機(jī)復(fù)位后,將從8083h開始運(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,就直
10、接通過(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)代碼。 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-20
11、05 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開始向上分配
12、的。而局部變量則是在堆??臻g中分配。另外從上一篇文章中,可以知道堆棧指針初始化時(shí)為0fffh。而根據(jù)push指令的定義,當(dāng)壓棧后堆棧指針減1。因此堆棧是從上往下使用的。因此根據(jù)內(nèi)存分配和堆棧使用規(guī)則,我們?cè)诔绦蛟O(shè)計(jì)時(shí),不能定義過(guò)多的變量,免得沒有空間給堆棧使用。換句話說(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輸出與前些日子寫的用匯編語(yǔ)言進(jìn)行的實(shí)驗(yàn)一樣,從今天開始,要在st
13、的三合一開發(fā)板上,用c語(yǔ)言編寫程序,進(jìn)行一系列的實(shí)驗(yàn)。首先當(dāng)然從最簡(jiǎn)單的led指示燈閃爍的實(shí)驗(yàn)開始。開發(fā)板上的led1接在stm8的pd3上,因此要將pd3設(shè)置成輸出模式,為了提高高電平時(shí)的輸出電流,要將其設(shè)置成推挽輸出方式。這主要通過(guò)設(shè)置對(duì)應(yīng)的ddr/cr1/cr2寄存器實(shí)現(xiàn)。利用st的開發(fā)工具,先生成一個(gè)c語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過(guò)后,下載到開發(fā)板,運(yùn)行程序,可以看到led1在閃爍,且閃爍的頻率為5hz。/* main.c file* * copyright (c) 2002-2005 stmicroelectronics*/#include s
14、tm8s207c_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;
15、 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目錄下,拷貝到工程目錄下
16、?;蛘邔⒃撀窂教顚懙皆摴こ痰膕ettings中的c compiler選項(xiàng)preprocessor的additional include中,這樣編譯時(shí)才會(huì)找到該文件。 stm8的c語(yǔ)言編程(4) gpio輸出和輸入今天要進(jìn)行的實(shí)驗(yàn),是利用gpio進(jìn)行輸入和輸出。在st的三合一開發(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 引腳
17、設(shè)置0 0 0 懸浮輸入0 0 1 上拉輸入0 1 0 中斷懸浮輸入0 1 1 中斷上拉輸入1 0 0 開漏輸出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的開發(fā)工具,先生成一個(gè)c語(yǔ)言程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過(guò)后,下載到開發(fā)板,運(yùn)行程序,按下按鍵,led就點(diǎn)亮,抬起按鍵,led就熄滅了。另外,要注意,將stm8s207c_s.h拷貝到當(dāng)前項(xiàng)目的目錄下。/ 程序描述:檢測(cè)開發(fā)板上的
18、按鍵,若按下,則點(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的
19、輸出設(shè)置成1,點(diǎn)亮led 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)單起見,這里是通過(guò)程序查詢定時(shí)器是否產(chǎn)生更新事件,來(lái)判斷定時(shí)器的延時(shí)是否結(jié)束。同樣還是利用st的開發(fā)工具,生成一個(gè)c程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過(guò)后,下載到開發(fā)板,運(yùn)行程序,可以看到led在閃爍,或者用示波器可以在led引腳上看到方波。在這里要特別提醒的是,從st給的手冊(cè)上看,這個(gè)定時(shí)器中的計(jì)數(shù)器是一個(gè)加1計(jì)數(shù)器,但
20、本人在實(shí)驗(yàn)過(guò)程中感覺不太對(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; /
21、 將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è)置控制器,啟
22、動(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的c語(yǔ)言編程(6)8位定時(shí)器應(yīng)用之二今天進(jìn)行的實(shí)驗(yàn)依然是用定時(shí)器4,只不過(guò)改成了用中斷方式來(lái)實(shí)現(xiàn),由定時(shí)器4的中斷服務(wù)程序來(lái)驅(qū)動(dòng)led的閃爍。實(shí)現(xiàn)中斷方式的關(guān)鍵點(diǎn)有幾個(gè),第一個(gè)關(guān)鍵點(diǎn)就是要打開定時(shí)器4的中斷允許位,在定時(shí)器4的ier寄存器中有定義。第二個(gè)關(guān)鍵點(diǎn),就是打開cpu的全局
23、中斷允許位,在匯編語(yǔ)言中,就是執(zhí)行rim指令,在c語(yǔ)言中,用下列語(yǔ)句實(shí)現(xiàn):_asm(rim);第3個(gè)關(guān)鍵點(diǎn)就是中斷服務(wù)程序的框架或?qū)懛?,中斷服?wù)程序的寫法如下:far interrupt void tim4_upd_ovf_irqhandler (void) / 下面是中斷服務(wù)程序的實(shí)體 第4個(gè)關(guān)鍵點(diǎn)就是要設(shè)置中斷向量,即將中斷服務(wù)程序的入口填寫到中斷向量表中,如下所示,將irq23對(duì)應(yīng)的中斷服務(wù)程序的入口填寫成tim4_upd_ovf_irqhandlerstruct interrupt_vector const _vectab = 0x82, (interrupt_handler_t)_s
24、text, /* reset */ 0x82, nonhandledinterrupt, /* trap */ 0x82, nonhandledinterrupt, /* irq0 */ 0x82, nonhandledinterrupt, /* irq1 */ 0x82, nonhandledinterrupt, /* irq2 */ 0x82, nonhandledinterrupt, /* irq3 */ 0x82, nonhandledinterrupt, /* irq4 */ 0x82, nonhandledinterrupt, /* irq5 */ 0x82, nonhandled
25、interrupt, /* irq6 */ 0x82, nonhandledinterrupt, /* irq7 */ 0x82, nonhandledinterrupt, /* irq8 */ 0x82, nonhandledinterrupt, /* irq9 */ 0x82, nonhandledinterrupt, /* irq10 */ 0x82, nonhandledinterrupt, /* irq11 */ 0x82, nonhandledinterrupt, /* irq12 */ 0x82, nonhandledinterrupt, /* irq13 */ 0x82, no
26、nhandledinterrupt, /* irq14 */ 0x82, nonhandledinterrupt, /* irq15 */ 0x82, nonhandledinterrupt, /* irq16 */ 0x82, nonhandledinterrupt, /* irq17 */ 0x82, nonhandledinterrupt, /* irq18 */ 0x82, nonhandledinterrupt, /* irq19 */ 0x82, nonhandledinterrupt, /* irq20 */ 0x82, nonhandledinterrupt, /* irq21
27、 */ 0x82, nonhandledinterrupt, /* irq22 */ 0x82, tim4_upd_ovf_irqhandler,/* irq23 */ 0x82, nonhandledinterrupt, /* irq24 */ 0x82, nonhandledinterrupt, /* irq25 */ 0x82, nonhandledinterrupt, /* irq26 */ 0x82, nonhandledinterrupt, /* irq27 */ 0x82, nonhandledinterrupt, /* irq28 */ 0x82, nonhandledinte
28、rrupt, /* irq29 */;解決了以上4個(gè)關(guān)鍵點(diǎn),我們就能很輕松地用c語(yǔ)言實(shí)現(xiàn)中斷服務(wù)了。同樣還是利用st的開發(fā)工具,生成一個(gè)c程序的框架,然后修改其中的main.c,修改后的代碼如下。另外還要修改stm8_interrupt_vector.c。編譯通過(guò)后,下載到開發(fā)板,運(yùn)行程序,可以看到led在閃爍,或者用示波器可以在led引腳上看到方波。 修改后的main.c如下:/ 程序描述:通過(guò)初始化定時(shí)器4,以中斷方式驅(qū)動(dòng)led閃爍/ led接在mcu的gpio的pd3上#include stm8s207c_s.hmain() / 首先初始化gpio pd_ddr = 0x08; pd_c
29、r1 = 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,允許
30、更新 / 設(shè)置控制器,啟動(dòng)定時(shí)器 tim4_ier = 0x01; / 允許更新中斷 _asm(rim); / 允許cpu全局中斷 while(1) / 進(jìn)入無(wú)限循環(huán) / 函數(shù)功能:定時(shí)器4的更新中斷服務(wù)程序/ 輸入?yún)?shù):無(wú)/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)far interrupt void tim4_upd_ovf_irqhandler (void) tim4_sr1 = 0x00; / 清除更新標(biāo)志 pd_odr = pd_odr 0x08; / led驅(qū)動(dòng)信號(hào)取反 /led閃爍頻率=2mhz/128/255/2=30.63 修改后的stm8_interrupt_vector.c如下:/
31、* 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
32、 unexpected events during development, it is recommended to set a breakpoint on the following instruction */ return;extern void _stext(); /* startup routine */extern far interrupt void tim4_upd_ovf_irqhandler (void);struct interrupt_vector const _vectab = 0x82, (interrupt_handler_t)_stext, /* reset
33、*/ 0x82, nonhandledinterrupt, /* trap */ 0x82, nonhandledinterrupt, /* irq0 */ 0x82, nonhandledinterrupt, /* irq1 */ 0x82, nonhandledinterrupt, /* irq2 */ 0x82, nonhandledinterrupt, /* irq3 */ 0x82, nonhandledinterrupt, /* irq4 */ 0x82, nonhandledinterrupt, /* irq5 */ 0x82, nonhandledinterrupt, /* i
34、rq6 */ 0x82, nonhandledinterrupt, /* irq7 */ 0x82, nonhandledinterrupt, /* irq8 */ 0x82, nonhandledinterrupt, /* irq9 */ 0x82, nonhandledinterrupt, /* irq10 */ 0x82, nonhandledinterrupt, /* irq11 */ 0x82, nonhandledinterrupt, /* irq12 */ 0x82, nonhandledinterrupt, /* irq13 */ 0x82, nonhandledinterru
35、pt, /* irq14 */ 0x82, nonhandledinterrupt, /* irq15 */ 0x82, nonhandledinterrupt, /* irq16 */ 0x82, nonhandledinterrupt, /* irq17 */ 0x82, nonhandledinterrupt, /* irq18 */ 0x82, nonhandledinterrupt, /* irq19 */ 0x82, nonhandledinterrupt, /* irq20 */ 0x82, nonhandledinterrupt, /* irq21 */ 0x82, nonha
36、ndledinterrupt, /* irq22 */ 0x82, tim4_upd_ovf_irqhandler,/* irq23 */ 0x82, nonhandledinterrupt, /* irq24 */ 0x82, nonhandledinterrupt, /* irq25 */ 0x82, nonhandledinterrupt, /* irq26 */ 0x82, nonhandledinterrupt, /* irq27 */ 0x82, nonhandledinterrupt, /* irq28 */ 0x82, nonhandledinterrupt, /* irq29
37、 */; stm8的c語(yǔ)言編程(7)16位定時(shí)器的中斷應(yīng)用在stm8中,除了有8位的定時(shí)器外,還有16位的定時(shí)器。今天進(jìn)行的實(shí)驗(yàn)就是針對(duì)16位定時(shí)器2來(lái)進(jìn)行的。除了計(jì)數(shù)單元為16位的,其它設(shè)置與前面8位的定時(shí)器基本一樣。下面的程序也是采樣中斷方式,由定時(shí)器2的中斷服務(wù)程序來(lái)驅(qū)動(dòng)led的閃爍。具體的程序代碼如下,其它注意點(diǎn)見上一篇,另外要注意別忘了修改相應(yīng)的中斷向量。/ 程序描述:通過(guò)初始化定時(shí)器2,以中斷方式驅(qū)動(dòng)led閃爍/ led接在mcu的gpio的pd3上#include stm8s207c_s.hmain() / 首先初始化gpio pd_ddr = 0x08; pd_cr1 = 0x
38、08; / 將pd3設(shè)置成推挽輸出 pd_cr2 = 0x00; / 然后初始化定時(shí)器4 tim2_ier = 0x00; / 禁止中斷 tim2_egr = 0x01; / 允許產(chǎn)生更新事件 tim2_pscr = 0x01; / 計(jì)數(shù)器時(shí)鐘=主時(shí)鐘/128=2mhz/2 / 相當(dāng)于計(jì)數(shù)器周期為1us / 設(shè)定重裝載時(shí)的寄存器值 / 注意必須保證先寫入高8位,再寫入低8位 tim2_arrh = 0xea; / 設(shè)定重裝載時(shí)的寄存器的高8位 tim2_arrl = 0x60; tim2_cntrh = 0xea; / 設(shè)定計(jì)數(shù)器的初值 tim2_cntrl = 0x60; / 定時(shí)周期=1*
39、60000=60000us=60ms tim2_cr1 = 0x01; / b0 = 1,允許計(jì)數(shù)器工作 / b1 = 0,允許更新 / 設(shè)置控制器,啟動(dòng)定時(shí)器 tim2_ier = 0x01; / 允許更新中斷 _asm(rim); / 允許cpu全局中斷 while(1) / 進(jìn)入無(wú)限循環(huán) / 函數(shù)功能:定時(shí)器4的更新中斷服務(wù)程序/ 輸入?yún)?shù):無(wú)/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)far interrupt void tim2_upd_irqhandler (void) tim2_sr1 = 0x00; / 清除更新標(biāo)志 pd_odr = pd_odr 0x08; / led驅(qū)動(dòng)信號(hào)取反 /
40、led閃爍頻率=2mhz/2/60000/2=8.3 stm8的c語(yǔ)言編程(8) uart應(yīng)用串口通訊也是單片機(jī)應(yīng)用中經(jīng)常要用到,今天的實(shí)驗(yàn)就是利用stm8的uart資源,來(lái)進(jìn)行串口通訊的實(shí)驗(yàn)。實(shí)驗(yàn)程序的功能是以中斷方式接收串口數(shù)據(jù),然后將接收到的數(shù)據(jù)以查詢方式發(fā)送到串口。程序代碼如下,首先要對(duì)stm8的uart進(jìn)行初始化,初始化時(shí)要注意的是波特率寄存器的設(shè)置,當(dāng)求出一個(gè)波特率的分頻系數(shù)(一個(gè)16位的數(shù))后,要將高4位和低4位寫到brr2中,而將中間的8位寫到brr1中,并且必須是先寫brr2,再寫brr1。同樣也是利用st的開發(fā)工具,生成一個(gè)c語(yǔ)言的框架,然后修改其中的main.c,同時(shí)由于
41、需要用到中斷服務(wù),因此還要修改stm8_interrupt_vector.c。修改后,編譯連接,然后下載到開發(fā)板上,再做一根與pc機(jī)相連的線,把開發(fā)板的串口與pc機(jī)的串口連接起來(lái),注意,2、3腳要交叉。在pc機(jī)上運(yùn)行超級(jí)終端,設(shè)置波特率為9600,然后每按下一個(gè)按鍵,屏幕上就顯示對(duì)應(yīng)的字符。修改后的main.c和stm8_interrupt_vector.c如下:/ 程序描述:初始化uart,以中斷方式接收字符,以查詢方式發(fā)送/ uart通訊參數(shù):9600bps,8位數(shù)據(jù),1位停止位,無(wú)校驗(yàn)#include stm8s207c_s.h/ 函數(shù)功能:初始化uart/ 輸入?yún)?shù):無(wú)/ 輸出參數(shù):無(wú)
42、/ 返 回 值:無(wú)/ 備 注:無(wú)void uart3_init(void) linuart_cr2 = 0; / 禁止uart發(fā)送和接收 linuart_cr1 = 0; / b5 = 0,允許uart / b2 = 0,禁止校驗(yàn) linuart_cr3 = 0; / b5,b4 = 00,1個(gè)停止位 / 設(shè)置波特率,必須注意以下幾點(diǎn):/ (1) 必須先寫brr2/ (2) brr1存放的是分頻系數(shù)的第11位到第4位,/ (3) brr2存放的是分頻系數(shù)的第15位到第12位,和第3位到第0位/ 例如對(duì)于波特率位9600時(shí),分頻系數(shù)=2000000/9600=208/ 對(duì)應(yīng)的十六進(jìn)制數(shù)為00d0
43、,bbr1=0d,bbr2=00 linuart_brr2 = 0; linuart_brr1 = 0x0d; / 實(shí)際的波特率分頻系數(shù)為00d0(208) / 對(duì)應(yīng)的波特率為2000000/208=9600 linuart_cr2 = 0x2c; / b3 = 1,允許發(fā)送 / b2 = 1,允許接收 / b5 = 1,允許產(chǎn)生接收中斷 / 函數(shù)功能:從uart3發(fā)送一個(gè)字符/ 輸入?yún)?shù):ch - 要發(fā)送的字符/ 輸出參數(shù):無(wú)/ 返 回 值:無(wú)/ 備 注:無(wú)void uart3_sendchar(unsigned char ch) while(linuart_sr & 0x80) = 0x00); / 若發(fā)送寄存器不空,則等待
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 3.1溫度說(shuō)課稿 2025年初中 人教版物理八年級(jí)上冊(cè)
- 《跨境電商》課件-3.其他平臺(tái)注冊(cè)
- 《Linux操作系統(tǒng)》課件-10.Linux進(jìn)程管理
- 高質(zhì)量三農(nóng)田水利設(shè)施建設(shè)指南
- 農(nóng)民創(chuàng)業(yè)創(chuàng)新培訓(xùn)作業(yè)指導(dǎo)書
- 沉淀池施工安全措施
- 蛋糕店項(xiàng)目可行性研究報(bào)告
- 機(jī)場(chǎng)工程車輛租賃合同范本
- 二零二五年度北京市網(wǎng)吧裝修工程網(wǎng)絡(luò)設(shè)備采購(gòu)合同
- 加油站安全管理預(yù)案
- 統(tǒng)計(jì)法律知識(shí)培訓(xùn)課件
- 活動(dòng)三《垃圾“流浪”記》(教學(xué)設(shè)計(jì))-2023-2024學(xué)年三年級(jí)下冊(cè)綜合實(shí)踐活動(dòng)滬科黔科版
- 2025年2月廣東省深圳市羅湖區(qū)聯(lián)考初三年級(jí)質(zhì)量檢測(cè)英語(yǔ)試卷(含答案)
- 政治-廣西壯族自治區(qū)考閱評(píng)·2025屆(年)2月高三畢業(yè)班聯(lián)合調(diào)研測(cè)試試題和答案
- 2025年合伙協(xié)議模板
- 2025年南京鐵道職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)適應(yīng)性測(cè)試題庫(kù)及答案一套
- 對(duì)外漢語(yǔ)綜合課教案集成
- 北京市朝陽(yáng)區(qū)2024-2025學(xué)年高一上學(xué)期期末質(zhì)量檢測(cè)數(shù)學(xué)試題【含答案解析】
- 2025年南京科技職業(yè)學(xué)院高職單招職業(yè)技能測(cè)試近5年常考版參考題庫(kù)含答案解析
- 信息系統(tǒng)監(jiān)理師教程筆記版
- 龍門吊拆除合同
評(píng)論
0/150
提交評(píng)論