




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、 STM8的C語言編程(1)基本程序與啟動代碼分析現(xiàn)在幾乎所有的單片機都能用C語言編程了,采用C語言編程確實能帶來很多好處,至少可讀性比匯編語言強多了。在STM8的開發(fā)環(huán)境中,可以通過新建一個工程,自動地建立起一個C語言的框架,生成后開發(fā)環(huán)境會自動生成2個C語言的程序,一個是main.c,另一個是stm8_interrupt_vector.c。main.c中就是一個空的main()函數(shù),如下所示:/* MAIN.C file* * Copyright (c) 2002-2005 STMicroelectronics*/main() while (1);而在stm8_interrupt_vect
2、or.c中,就是聲明了對應(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)然在自動建立時,所有的中斷服務(wù)都是空的,因此,除了第1個復(fù)位的向量外,其它都指向那個空的中斷服務(wù)函數(shù)。生成框架后,就可以用Build菜單下的Rebuild All對項目進行編譯和連接,生成所需的目標(biāo)文件,然后就可以加載到STM8的芯片中,這里由于main()函數(shù)是一個空函數(shù),因此沒有任何實際的功能。不過我們可以把這個框架對應(yīng)的匯編代碼反出來,看看C語言生成的代碼,這樣可以更深入地了解C語言編程的特點。生成的代碼包括4個部分,如圖1、圖2、圖3、圖4所示。 圖1 圖2 圖3 圖4 圖1顯示的是從內(nèi)存地址8000H開始的中斷向量表
9、,中斷向量表中的第1行H為復(fù)位后單片機運行的第1跳指令的地址。從表中可以看出,單片機復(fù)位后,將從8083H開始運行。其它行的中斷向量都指向同一個位置的中斷服務(wù)程序80D0H。 圖2顯示的是3個字節(jié),前2個字節(jié)8083H為復(fù)位后的第1條指令的地址,第3個字節(jié)是一個常量0,后面的啟動代碼要用到。 圖3顯示的是啟動代碼,啟動代碼中除了初始化堆棧指針外,就是初始化RAM單元。由于目前是一個空的框架,因此在初始化完堆棧指針(設(shè)置成0FFFH)后,由于8082H單元的內(nèi)容為0,因此程序就跳到了80B1H,此處是一個循環(huán),將RAM單元從0到5初始化成0。然后由于寄存器X設(shè)置成0100H,就直接通過CALL
10、main進入C的main()函數(shù)。 圖4顯示的是main()函數(shù)和中斷服務(wù)函數(shù),main()函數(shù)對應(yīng)的代碼就是一個無限的循環(huán),而中斷服務(wù)函數(shù)就一條指令,即中斷返回指令。 通過分析,可以看出用C語言編程時,比匯編語言編程時,就是多出了一段啟動代碼。 STM8的C語言編程(2) 變量空間的分配采用C這樣的高級語言,其實可以不用關(guān)心變量在存儲器空間中是如何具體分配的。但如果了解如何分配,對編程還是有好處的,尤其是在調(diào)試時。例如下面的程序定義了全局變量數(shù)組buffer和一個局部變量i,在RAM中如何分配的呢?/* MAIN.C file* * Copyright (c) 2002-2005 STMic
11、roelectronics*/unsigned char buffer10; / 定義全局變量main() unsigned char i; / 定義局部變量 for(i=0;i10;i+) bufferi = 0x55; 我們可以通過DEBUG中的反匯編窗口,看到如下的對應(yīng)代碼:從這段代碼中可以看到,全局變量buffer被分配到空間從地址0000H到0009H。而局部變量i則在堆棧空間中分配,通過PUSH A指令,將堆棧指針減1,騰出一個字節(jié)的空間,而SP+1指向的空間就是分配給局部變量使用的空間。由此可以得出初步的結(jié)論,對于全局變量,內(nèi)存分配是從低地址0000H開始向上分配的。而局部變量則
12、是在堆??臻g中分配。另外從上一篇文章中,可以知道堆棧指針初始化時為0FFFH。而根據(jù)PUSH指令的定義,當(dāng)壓棧后堆棧指針減1。因此堆棧是從上往下使用的。因此根據(jù)內(nèi)存分配和堆棧使用規(guī)則,我們在程序設(shè)計時,不能定義過多的變量,免得沒有空間給堆棧使用。換句話說,當(dāng)定義變量時,一定要考慮到堆??臻g,尤其是那些復(fù)雜的系統(tǒng),程序調(diào)用層數(shù)多,這樣就會占用大量的堆??臻g。總之,在單片機的程序設(shè)計時,由于RAM空間非常有限,要充分考慮到全局變量、局部變量、程序調(diào)用層數(shù)和中斷服務(wù)調(diào)用對空間的占用。 STM8的C語言編程(3) GPIO輸出與前些日子寫的用匯編語言進行的實驗一樣,從今天開始,要在ST的三合一開發(fā)板上
13、,用C語言編寫程序,進行一系列的實驗。首先當(dāng)然從最簡單的LED指示燈閃爍的實驗開始。開發(fā)板上的LED1接在STM8的PD3上,因此要將PD3設(shè)置成輸出模式,為了提高高電平時的輸出電流,要將其設(shè)置成推挽輸出方式。這主要通過設(shè)置對應(yīng)的DDR/CR1/CR2寄存器實現(xiàn)。利用ST的開發(fā)工具,先生成一個C語言程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過后,下載到開發(fā)板,運行程序,可以看到LED1在閃爍,且閃爍的頻率為5HZ。/* MAIN.C file* * Copyright (c) 2002-2005 STMicroelectronics*/#include STM8S207C
14、_S.h/ 函數(shù)功能:延時函數(shù)/ 輸入?yún)?shù):ms - 要延時的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ/ 輸出參數(shù):無/ 返 回 值:無/ 備 注:無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ū)動PD3為高電平和低電平/ 輸入?yún)?shù):ms - 要延時的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ/ 輸出參數(shù):無/ 返 回 值:無/ 備 注:無main() PD_DDR = 0x08; PD_CR1
15、= 0x08; / 將PD3設(shè)置成推挽輸出 PD_CR2 = 0x00; while(1) PD_ODR = PD_ODR | 0x08; / 將PD3的輸出設(shè)置成1 DelayMS(100); / 延時100MS PD_ODR = PD_ODR & 0xF7; / 將PD3的輸出設(shè)置成0 DelayMS(100); / 延時100MS 需要注意的是,當(dāng)生成完框架后,為了能方便使用STM8的寄存器名字,必須包括STM8S207C_S.h,最好將該文件拷貝到C:Program FilesSTMicroelectronicsst_toolsetinclude目錄下,拷貝到工程目錄下?;蛘邔⒃撀窂教?/p>
16、寫到該工程的Settings中的C Compiler選項Preprocessor的Additional include中,這樣編譯時才會找到該文件。 STM8的C語言編程(4) GPIO輸出和輸入今天要進行的實驗,是利用GPIO進行輸入和輸出。在ST的三合一開發(fā)板上,按鍵接在GPIO的PD7上,LED接在GPIO的PD3上,因此我們要將GPIO的PD7初始化成輸入,PD3初始化成輸出。關(guān)于GPIO的引腳設(shè)置,主要是要初始化方向寄存器DDR,控制寄存器1(CR1)和控制寄存器2(CR2),寄存器的每一位對應(yīng)GPIO的每一個引腳。具體的設(shè)置功能定義如下:DDR CR1 CR2 引腳設(shè)置0 0 0
17、懸浮輸入0 0 1 上拉輸入0 1 0 中斷懸浮輸入0 1 1 中斷上拉輸入1 0 0 開漏輸出1 1 0 推挽輸出1 X 1 輸出(最快速度為10MHZ)另外,輸出引腳對應(yīng)的寄存器為ODR,輸入引腳對應(yīng)的寄存器為IDR。下面的程序是檢測按鍵的狀態(tài),當(dāng)按鍵按下時,點亮LED,當(dāng)按鍵抬起時,熄滅LED。同樣也是利用ST的開發(fā)工具,先生成一個C語言程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過后,下載到開發(fā)板,運行程序,按下按鍵,LED就點亮,抬起按鍵,LED就熄滅了。另外,要注意,將STM8S207C_S.h拷貝到當(dāng)前項目的目錄下。/ 程序描述:檢測開發(fā)板上的按鍵,若按下,則
18、點亮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) / 進入無限循環(huán) if(PD_IDR & 0x80) = 0x80) / 讀入PD7的引腳信號 PD_ODR = PD_ODR & 0xF7; / 如果PD7為1,則將PD3的輸出設(shè)置成0,熄滅LED else PD_ODR = PD_ODR | 0x08; / 否則,將PD3的輸出設(shè)置成1,點
19、亮LED STM8的C語言編程(5)8位定時器應(yīng)用之一在STM8單片機中,有多種定時器資源,既有8位的定時器,也有普通的16位定時器,還有高級的定時器。今天的實驗是用最簡單的8位定時器TIM4來進行延時,然后驅(qū)動LED閃爍。為了簡單起見,這里是通過程序查詢定時器是否產(chǎn)生更新事件,來判斷定時器的延時是否結(jié)束。同樣還是利用ST的開發(fā)工具,生成一個C程序的框架,然后修改其中的main.c,修改后的代碼如下。編譯通過后,下載到開發(fā)板,運行程序,可以看到LED在閃爍,或者用示波器可以在LED引腳上看到方波。在這里要特別提醒的是,從ST給的手冊上看,這個定時器中的計數(shù)器是一個加1計數(shù)器,但本人在實驗過程中
20、感覺不太對,經(jīng)過反復(fù)的實驗,我認為應(yīng)該是一個減1計數(shù)器(也許是我拿的手冊不對,或許是理解上有誤)。例如,當(dāng)給定時器中的自動裝載寄存器裝入255時,產(chǎn)生的方波頻率最小,就象下面代碼中計算的那樣,產(chǎn)生的方波頻率為30HZ左右。若初始化時給自動裝載寄存器裝入1,則產(chǎn)生的方波頻率最大,大約為3.9K左右。也就是說實際的分頻數(shù)為ARR寄存器的值+1。/ 程序描述:通過初始化定時器4,進行延時,驅(qū)動LED閃爍/ LED接在MCU的GPIO的PD3上#include STM8S207C_S.hmain() / 首先初始化GPIO PD_DDR = 0x08; PD_CR1 = 0x08; / 將PD3設(shè)置成
21、推挽輸出 PD_CR2 = 0x00; / 然后初始化定時器4 TIM4_IER = 0x00; / 禁止中斷 TIM4_EGR = 0x01; / 允許產(chǎn)生更新事件 TIM4_PSCR = 0x07; / 計數(shù)器時鐘=主時鐘/128=2MHZ/128 / 相當(dāng)于計數(shù)器周期為64uS TIM4_ARR = 255; / 設(shè)定重裝載時的寄存器值,255是最大值 TIM4_CNTR = 255; / 設(shè)定計數(shù)器的初值 / 定時周期=(ARR+1)*64=16320uS TIM4_CR1 = 0x01; / b0 = 1,允許計數(shù)器工作 / b1 = 0,允許更新 / 設(shè)置控制器,啟動定時器 whi
22、le(1) / 進入無限循環(huán) while(TIM4_SR1 & 0x81) = 0x00); / 等待更新標(biāo)志 TIM4_SR1 = 0x00; / 清除更新標(biāo)志 PD_ODR = PD_ODR 0x08; / LED驅(qū)動信號取反 / LED閃爍頻率=2MHZ/128/255/2=30.63 STM8的C語言編程(6)8位定時器應(yīng)用之二今天進行的實驗依然是用定時器4,只不過改成了用中斷方式來實現(xiàn),由定時器4的中斷服務(wù)程序來驅(qū)動LED的閃爍。實現(xiàn)中斷方式的關(guān)鍵點有幾個,第一個關(guān)鍵點就是要打開定時器4的中斷允許位,在定時器4的IER寄存器中有定義。第二個關(guān)鍵點,就是打開CPU的全局中斷允許位,在匯
23、編語言中,就是執(zhí)行RIM指令,在C語言中,用下列語句實現(xiàn):_asm(rim);第3個關(guān)鍵點就是中斷服務(wù)程序的框架或?qū)懛?,中斷服?wù)程序的寫法如下:far interrupt void TIM4_UPD_OVF_IRQHandler (void) / 下面是中斷服務(wù)程序的實體 第4個關(guān)鍵點就是要設(shè)置中斷向量,即將中斷服務(wù)程序的入口填寫到中斷向量表中,如下所示,將IRQ23對應(yīng)的中斷服務(wù)程序的入口填寫成TIM4_UPD_OVF_IRQHandlerstruct interrupt_vector const _vectab = 0x82, (interrupt_handler_t)_stext, /*
24、 reset */ 0x82, NonHandledInterrupt, /* trap */ 0x82, NonHandledInterrupt, /* irq0 */ 0x82, NonHandledInterrupt, /* irq1 */ 0x82, NonHandledInterrupt, /* irq2 */ 0x82, NonHandledInterrupt, /* irq3 */ 0x82, NonHandledInterrupt, /* irq4 */ 0x82, NonHandledInterrupt, /* irq5 */ 0x82, NonHandledInterrup
25、t, /* irq6 */ 0x82, NonHandledInterrupt, /* irq7 */ 0x82, NonHandledInterrupt, /* irq8 */ 0x82, NonHandledInterrupt, /* irq9 */ 0x82, NonHandledInterrupt, /* irq10 */ 0x82, NonHandledInterrupt, /* irq11 */ 0x82, NonHandledInterrupt, /* irq12 */ 0x82, NonHandledInterrupt, /* irq13 */ 0x82, NonHandled
26、Interrupt, /* irq14 */ 0x82, NonHandledInterrupt, /* irq15 */ 0x82, NonHandledInterrupt, /* irq16 */ 0x82, NonHandledInterrupt, /* irq17 */ 0x82, NonHandledInterrupt, /* irq18 */ 0x82, NonHandledInterrupt, /* irq19 */ 0x82, NonHandledInterrupt, /* irq20 */ 0x82, NonHandledInterrupt, /* irq21 */ 0x82
27、, NonHandledInterrupt, /* irq22 */ 0x82, TIM4_UPD_OVF_IRQHandler,/* irq23 */ 0x82, NonHandledInterrupt, /* irq24 */ 0x82, NonHandledInterrupt, /* irq25 */ 0x82, NonHandledInterrupt, /* irq26 */ 0x82, NonHandledInterrupt, /* irq27 */ 0x82, NonHandledInterrupt, /* irq28 */ 0x82, NonHandledInterrupt, /
28、* irq29 */;解決了以上4個關(guān)鍵點,我們就能很輕松地用C語言實現(xiàn)中斷服務(wù)了。同樣還是利用ST的開發(fā)工具,生成一個C程序的框架,然后修改其中的main.c,修改后的代碼如下。另外還要修改stm8_interrupt_vector.c。編譯通過后,下載到開發(fā)板,運行程序,可以看到LED在閃爍,或者用示波器可以在LED引腳上看到方波。 修改后的main.c如下:/ 程序描述:通過初始化定時器4,以中斷方式驅(qū)動LED閃爍/ LED接在MCU的GPIO的PD3上#include STM8S207C_S.hmain() / 首先初始化GPIO PD_DDR = 0x08; PD_CR1 = 0x0
29、8; / 將PD3設(shè)置成推挽輸出 PD_CR2 = 0x00; / 然后初始化定時器4 TIM4_IER = 0x00; / 禁止中斷 TIM4_EGR = 0x01; / 允許產(chǎn)生更新事件 TIM4_PSCR = 0x07; / 計數(shù)器時鐘=主時鐘/128=2MHZ/128 / 相當(dāng)于計數(shù)器周期為64uS TIM4_ARR = 255; / 設(shè)定重裝載時的寄存器值,255是最大值 TIM4_CNTR = 255; / 設(shè)定計數(shù)器的初值 / 定時周期=(ARR+1)*64=16320uS TIM4_CR1 = 0x01; / b0 = 1,允許計數(shù)器工作 / b1 = 0,允許更新 / 設(shè)置控
30、制器,啟動定時器 TIM4_IER = 0x01; / 允許更新中斷 _asm(rim); / 允許CPU全局中斷 while(1) / 進入無限循環(huán) / 函數(shù)功能:定時器4的更新中斷服務(wù)程序/ 輸入?yún)?shù):無/ 輸出參數(shù):無/ 返 回 值:無far interrupt void TIM4_UPD_OVF_IRQHandler (void) TIM4_SR1 = 0x00; / 清除更新標(biāo)志 PD_ODR = PD_ODR 0x08; / LED驅(qū)動信號取反 /LED閃爍頻率=2MHZ/128/255/2=30.63 修改后的stm8_interrupt_vector.c如下:/* BASIC
31、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 unexpec
32、ted 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 */ 0x82,
33、 NonHandledInterrupt, /* trap */ 0x82, NonHandledInterrupt, /* irq0 */ 0x82, NonHandledInterrupt, /* irq1 */ 0x82, NonHandledInterrupt, /* irq2 */ 0x82, NonHandledInterrupt, /* irq3 */ 0x82, NonHandledInterrupt, /* irq4 */ 0x82, NonHandledInterrupt, /* irq5 */ 0x82, NonHandledInterrupt, /* irq6 */ 0
34、x82, NonHandledInterrupt, /* irq7 */ 0x82, NonHandledInterrupt, /* irq8 */ 0x82, NonHandledInterrupt, /* irq9 */ 0x82, NonHandledInterrupt, /* irq10 */ 0x82, NonHandledInterrupt, /* irq11 */ 0x82, NonHandledInterrupt, /* irq12 */ 0x82, NonHandledInterrupt, /* irq13 */ 0x82, NonHandledInterrupt, /* i
35、rq14 */ 0x82, NonHandledInterrupt, /* irq15 */ 0x82, NonHandledInterrupt, /* irq16 */ 0x82, NonHandledInterrupt, /* irq17 */ 0x82, NonHandledInterrupt, /* irq18 */ 0x82, NonHandledInterrupt, /* irq19 */ 0x82, NonHandledInterrupt, /* irq20 */ 0x82, NonHandledInterrupt, /* irq21 */ 0x82, NonHandledInt
36、errupt, /* 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 */; STM
37、8的C語言編程(7)16位定時器的中斷應(yīng)用在STM8中,除了有8位的定時器外,還有16位的定時器。今天進行的實驗就是針對16位定時器2來進行的。除了計數(shù)單元為16位的,其它設(shè)置與前面8位的定時器基本一樣。下面的程序也是采樣中斷方式,由定時器2的中斷服務(wù)程序來驅(qū)動LED的閃爍。具體的程序代碼如下,其它注意點見上一篇,另外要注意別忘了修改相應(yīng)的中斷向量。/ 程序描述:通過初始化定時器2,以中斷方式驅(qū)動LED閃爍/ LED接在MCU的GPIO的PD3上#include STM8S207C_S.hmain() / 首先初始化GPIO PD_DDR = 0x08; PD_CR1 = 0x08; / 將P
38、D3設(shè)置成推挽輸出 PD_CR2 = 0x00; / 然后初始化定時器4 TIM2_IER = 0x00; / 禁止中斷 TIM2_EGR = 0x01; / 允許產(chǎn)生更新事件 TIM2_PSCR = 0x01; / 計數(shù)器時鐘=主時鐘/128=2MHZ/2 / 相當(dāng)于計數(shù)器周期為1uS / 設(shè)定重裝載時的寄存器值 / 注意必須保證先寫入高8位,再寫入低8位 TIM2_ARRH = 0xEA; / 設(shè)定重裝載時的寄存器的高8位 TIM2_ARRL = 0x60; TIM2_CNTRH = 0xEA; / 設(shè)定計數(shù)器的初值 TIM2_CNTRL = 0x60; / 定時周期=1*60000=60
39、000uS=60ms TIM2_CR1 = 0x01; / b0 = 1,允許計數(shù)器工作 / b1 = 0,允許更新 / 設(shè)置控制器,啟動定時器 TIM2_IER = 0x01; / 允許更新中斷 _asm(rim); / 允許CPU全局中斷 while(1) / 進入無限循環(huán) / 函數(shù)功能:定時器4的更新中斷服務(wù)程序/ 輸入?yún)?shù):無/ 輸出參數(shù):無/ 返 回 值:無far interrupt void TIM2_UPD_IRQHandler (void) TIM2_SR1 = 0x00; / 清除更新標(biāo)志 PD_ODR = PD_ODR 0x08; / LED驅(qū)動信號取反 /LED閃爍頻率=
40、2MHZ/2/60000/2=8.3 STM8的C語言編程(8) UART應(yīng)用串口通訊也是單片機應(yīng)用中經(jīng)常要用到,今天的實驗就是利用STM8的UART資源,來進行串口通訊的實驗。實驗程序的功能是以中斷方式接收串口數(shù)據(jù),然后將接收到的數(shù)據(jù)以查詢方式發(fā)送到串口。程序代碼如下,首先要對STM8的UART進行初始化,初始化時要注意的是波特率寄存器的設(shè)置,當(dāng)求出一個波特率的分頻系數(shù)(一個16位的數(shù))后,要將高4位和低4位寫到BRR2中,而將中間的8位寫到BRR1中,并且必須是先寫B(tài)RR2,再寫B(tài)RR1。同樣也是利用ST的開發(fā)工具,生成一個C語言的框架,然后修改其中的main.c,同時由于需要用到中斷服務(wù)
41、,因此還要修改stm8_interrupt_vector.c。修改后,編譯連接,然后下載到開發(fā)板上,再做一根與PC機相連的線,把開發(fā)板的串口與PC機的串口連接起來,注意,2、3腳要交叉。在PC機上運行超級終端,設(shè)置波特率為9600,然后每按下一個按鍵,屏幕上就顯示對應(yīng)的字符。修改后的main.c和stm8_interrupt_vector.c如下:/ 程序描述:初始化UART,以中斷方式接收字符,以查詢方式發(fā)送/ UART通訊參數(shù):9600bps,8位數(shù)據(jù),1位停止位,無校驗#include STM8S207C_S.h/ 函數(shù)功能:初始化UART/ 輸入?yún)?shù):無/ 輸出參數(shù):無/ 返 回 值:
42、無/ 備 注:無void UART3_Init(void) LINUART_CR2 = 0; / 禁止UART發(fā)送和接收 LINUART_CR1 = 0; / b5 = 0,允許UART / b2 = 0,禁止校驗 LINUART_CR3 = 0; / b5,b4 = 00,1個停止位 / 設(shè)置波特率,必須注意以下幾點:/ (1) 必須先寫B(tài)RR2/ (2) BRR1存放的是分頻系數(shù)的第11位到第4位,/ (3) BRR2存放的是分頻系數(shù)的第15位到第12位,和第3位到第0位/ 例如對于波特率位9600時,分頻系數(shù)=/9600=208/ 對應(yīng)的十六進制數(shù)為00D0,BBR1=0D,BBR2=0
43、0 LINUART_BRR2 = 0; LINUART_BRR1 = 0x0d; / 實際的波特率分頻系數(shù)為00D0(208) / 對應(yīng)的波特率為/208=9600 LINUART_CR2 = 0x2C; / b3 = 1,允許發(fā)送 / b2 = 1,允許接收 / b5 = 1,允許產(chǎn)生接收中斷 / 函數(shù)功能:從UART3發(fā)送一個字符/ 輸入?yún)?shù):ch - 要發(fā)送的字符/ 輸出參數(shù):無/ 返 回 值:無/ 備 注:無void UART3_SendChar(unsigned char ch) while(LINUART_SR & 0x80) = 0x00); / 若發(fā)送寄存器不空,則等待 LINUART_DR = ch
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年湖南省長沙市中考招生考試數(shù)學(xué)真題試卷(真題+答案)
- 預(yù)防肺炎主題班會課件
- 預(yù)防疾病安全課件
- 靜脈治療護士教育培訓(xùn)體系
- 《電子產(chǎn)品裝配與測試》課件-任務(wù)2 儀器的使用
- 預(yù)防兒童近視課件
- 預(yù)防傳染保健康課件
- 學(xué)校輔導(dǎo)員(班導(dǎo)師)管理及考評辦法
- 城市污水管網(wǎng)建設(shè)項目節(jié)能評估報告(參考模板)
- 2025年年云服務(wù)項目合作計劃書
- DB12T 1443-2025 社會單位消防安全管理導(dǎo)則
- 2025安全生產(chǎn)月活動總結(jié)模板十(19P)
- 內(nèi)蒙古呼和浩特實驗教育集團2025屆八下英語期末考試試題含答案
- 《電子工業(yè)全光網(wǎng)絡(luò)工程技術(shù)規(guī)范》
- 山東女子學(xué)院《大學(xué)英語學(xué)前教育學(xué)院》2023-2024學(xué)年第二學(xué)期期末試卷
- 2025至2030中國電子皮膚行業(yè)項目調(diào)研及市場前景預(yù)測評估報告
- 2025年內(nèi)蒙古煤炭建設(shè)工程(集團)總公司招聘筆試參考題庫含答案解析
- 2025至2030年中國鐵氧體軟磁材料行業(yè)發(fā)展現(xiàn)狀分析及投資規(guī)模預(yù)測報告
- 有理數(shù)加減混合運算練習(xí)題300道-可打印
- 2025吉林長春市軌道交通集團有限公司校園招聘693人筆試參考題庫附帶答案詳解析
- 戰(zhàn)士留疆考試題及答案大全
評論
0/150
提交評論