STM8S-匯編Word版_第1頁
STM8S-匯編Word版_第2頁
STM8S-匯編Word版_第3頁
STM8S-匯編Word版_第4頁
STM8S-匯編Word版_第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、STM8與匯編語言(1)不知是心血來潮,還是其它因素,突然又想起玩匯編語言了。這幾年也沒少跟單片機打交道,包括51系列,430系列,ARM系列,但都是用C語言來開發(fā)。不過由于使用C語言,實際上對這些CPU的了解還是不夠深刻,當(dāng)然除了51之外,因為那是我多年前曾經(jīng)用匯編開發(fā)過的芯片。盡管當(dāng)今C語言已經(jīng)在嵌入式產(chǎn)品的開發(fā)過程中成為主流,但我個人依然認(rèn)為,要想真正了解CPU的特點,還得用匯編語言。不知道這種觀點是對還是錯,也許是因為自己從硬件做起,寫過機器碼,用匯編語言做過優(yōu)化,因此對匯編語音有一種特殊的偏愛。51系列的芯片用多了,感覺有時寫起程序來不太方便,因此總想尋找一些其它的8位單片機玩玩,正

2、好手頭有一個ST的三合一開發(fā)板,那是09年參加ST研討會上買的,一直躺在那里,與其躺在那里,不如拿出來玩玩。這幾年,ST在國內(nèi)推廣STM32,力度不小,不過我一直沒有用過,只是初步地看看資料。原因在于在32位單片機方面,我一直在用Luminary公司的LM3S1138,感覺不錯,一直都很順利。09年ST舉辦的研討會上,ST除了介紹STM32外,也介紹了STM8,當(dāng)時聽了以后,覺得還行。尤其是會上的低功耗演示給我留下了很深刻的印象?;谶@些,我決定好好地玩一下STM8芯片,并將玩的結(jié)果拿出來與大家共享。STM8與匯編語言(2)第一次打開STM8的手冊時發(fā)現(xiàn),CPU中的寄存器只有6個,即A、X、Y

3、、SP、PC和CC。這幾個寄存器,看上去特象早年蘋果機使用的微處理器6502。在眼下都是多寄存器的RISC潮流下,不知ST推出的這種CPU架構(gòu)有什么意圖?這樣的芯片能否與Microchip或者Atmel的RISC結(jié)構(gòu)的MCU競爭呢?在此我無意做評論,我只想了解這顆芯片。通過仔細研究,我發(fā)現(xiàn)由于STM8采用了32位寬度的程序存儲器結(jié)構(gòu),使得大部分的指令都能在一個周期內(nèi)取出,并且采用了哈佛結(jié)構(gòu)和流水線,相當(dāng)多的指令也都是單周期完成的。這樣的話,雖然CPU是CISC架構(gòu)的,但也基本上達到了單周期指令的效果,就像手冊上說的,CPU的性能達到了20MISP24MHZ。就這一點來說,我個人感覺STM8還真

4、不錯。舉個例子來說,如果我們要完成內(nèi)存中的2個8位無符號數(shù)相加,結(jié)果還保存到內(nèi)存中,用C語言描述成:unsigned char a,b,c;c = a + b;這一段程序,用STM8匯編可以寫成如下代碼:LD A, $1000 ADD A, $1001 LD $1002, A這里假設(shè)a,b,c這3個變量分別存儲在內(nèi)存中,地址為1000,1001和1002。從STM8的手冊上可以查到,這3條指令都是單周期的,完成一個加法,只需要3個時鐘周期,可見STM8的CPU執(zhí)行速度還是相當(dāng)快的。在這種傳統(tǒng)的所謂CISC架構(gòu)中,我特別關(guān)心累加器A與內(nèi)存的訪問速度,因為如果累加器與內(nèi)存的訪問速度是單周期的話,實

5、際上我們就可以將內(nèi)存當(dāng)寄存器來看,這樣寫程序時就相當(dāng)于擁有了一個大的寄存器陣列,或者說我們也就沒必要再去考慮變量在內(nèi)存中還是在寄存器中。也正是因為這一點,我對STM8越來越感興趣了。STM8與匯編語言(3)STM8的開發(fā)環(huán)境用起來還是不錯的,可以到ST的網(wǎng)站上下載安裝程序ST_Toolset.exe。利用該環(huán)境可以開發(fā)用匯編語言寫的程序,而且與ST的三合一開發(fā)板配合起來,確實非常方便。不過如果要想用C語言來開發(fā),稍微有點麻煩,得去別的公司下載C的編譯器(CXSTM8_16K.exe),而且下載完以后,還得去注冊,等待許可文件。實際上,我也按照ST介紹的方法做了,但始終都沒有收到許可文件,也許本

6、人實在愚笨。但不管怎么說,我覺得ST這一點做得相當(dāng)不好,實在有點摳門。既然是免費的,為什么不一起打包提供給客戶,這么麻煩,多耽誤客戶使用,得少賣多少STM8的芯片。言歸正傳,還回到正題。用匯編語言開發(fā)程序,最簡單的就是利用ST開發(fā)環(huán)境中提供的匯編程序框架自動生成功能。打開開發(fā)環(huán)境后,在File菜單中選擇New Workspace,點擊Create workspace and project圖標(biāo),然后就可以建立項目,在工具鏈中選ST Assembler Linker,最后選擇MCU的型號,點擊OK,就完成了一個項目的建立。這個環(huán)境與微軟的VC6開發(fā)環(huán)境很象,點開項目文件中的Source File

7、s,能看到系統(tǒng)自動生成好了一個匯編語言的框架,我們編寫程序只要在這框架基礎(chǔ)上就可以了。其實不用編寫任何一條指令,這個框架程序是能夠編譯通過,并下載運行的。自動生成的項目中包含3個重要的文件:mapping.inc,mapping.asm和main.asm。mapping.inc文件中定義的是一些常量,mapping.asm文件中定義的是一些內(nèi)存的分配,主要的匯編代碼都在main.asm。下面是main.asm中的匯編代碼及注釋。stm8/#include "mapping.inc"segment 'rom' 下面是定義一個標(biāo)號,ST匯編的寫法,有點不習(xí)慣;

8、這里的main標(biāo)號是復(fù)位后的第一條指令,與后面的中斷向量表中; 的名字是對應(yīng)的main.l ; initialize SPldw X,#stack_endldw SP,X ; 設(shè)置堆棧指針 #ifdef RAM0; 如果定義了RAM0,則要匯編以下代碼 ; clear RAM0ram0_start.b EQU $ram0_segment_startram0_end.b EQU $ram0_segment_endldw X,#ram0_start ;寄存器X指向要清除的內(nèi)存起始地址 clear_ram0.l ;這是一個標(biāo)號定義,用于后面的跳轉(zhuǎn)指令clr (X) ;對應(yīng)的內(nèi)存單元清0 incw X

9、 ;寄存器X+1,指向下一個單元 cpw X,#ram0_end ;比較寄存器X是否等于內(nèi)存的最后一個地址 jrule clear_ram0 ;若不等于,則循環(huán) #endif#ifdef RAM1; 如果定義了RAM1,則要匯編以下代碼,代碼含義與上面完全一樣 ; clear RAM1ram1_start.w EQU $ram1_segment_startram1_end.w EQU $ram1_segment_endldw X,#ram1_startclear_ram1.lclr (X)incw Xcpw X,#ram1_endjrule clear_ram1#endif; clear st

10、ack; 將堆棧區(qū)的內(nèi)存單元清0,代碼含義與上面完全一樣 stack_start.w EQU $stack_segment_startstack_end.w EQU $stack_segment_endldw X,#stack_startclear_stack.lclr (X)incw Xcpw X,#stack_endjrule clear_stackinfinite_loop.l ; 定義一個標(biāo)號;由于是一個框架,初始化內(nèi)存后,進入一個死循環(huán)jra infinite_loop ;下面代碼寫的是一段中斷服務(wù)程序,不過也是空的interrupt NonHandledInterruptNonHa

11、ndledInterrupt.l; 當(dāng)進入中斷服務(wù)程序后,無其它動作,直接返回 iret ; 下面這張表很重要,定義了STM8所有的硬件中斷對應(yīng)的中斷; 服務(wù)程序的入口地址 segment 'vectit'dc.l $82000000+main; resetdc.l $82000000+NonHandledInterrupt; trapdc.l $82000000+NonHandledInterrupt; irq0dc.l $82000000+NonHandledInterrupt; irq1dc.l $82000000+NonHandledInterrupt; irq2dc.

12、l $82000000+NonHandledInterrupt; irq3dc.l $82000000+NonHandledInterrupt; irq4dc.l $82000000+NonHandledInterrupt; irq5dc.l $82000000+NonHandledInterrupt; irq6dc.l $82000000+NonHandledInterrupt; irq7dc.l $82000000+NonHandledInterrupt; irq8dc.l $82000000+NonHandledInterrupt; irq9dc.l $82000000+NonHandl

13、edInterrupt; irq10dc.l $82000000+NonHandledInterrupt; irq11dc.l $82000000+NonHandledInterrupt; irq12dc.l $82000000+NonHandledInterrupt; irq13dc.l $82000000+NonHandledInterrupt; irq14dc.l $82000000+NonHandledInterrupt; irq15dc.l $82000000+NonHandledInterrupt; irq16dc.l $82000000+NonHandledInterrupt;

14、irq17dc.l $82000000+NonHandledInterrupt; irq18dc.l $82000000+NonHandledInterrupt; irq19dc.l $82000000+NonHandledInterrupt; irq20dc.l $82000000+NonHandledInterrupt; irq21dc.l $82000000+NonHandledInterrupt; irq22dc.l $82000000+NonHandledInterrupt; irq23dc.l $82000000+NonHandledInterrupt; irq24dc.l $82

15、000000+NonHandledInterrupt; irq25dc.l $82000000+NonHandledInterrupt; irq26dc.l $82000000+NonHandledInterrupt; irq27dc.l $82000000+NonHandledInterrupt; irq28dc.l $82000000+NonHandledInterrupt; irq29end把這個項目Build后,點擊Debug中的Start Debugging就可以將程序下載到ST的三合一板上了,然后點擊Run,程序就運行起來了,不過由于框架程序是一個空程序,初始化內(nèi)存后就進入死循環(huán)了

16、,因此什么效果也看不見。因此我們必須在框架程序的基礎(chǔ)上,編寫自己的程序。后面的程序例子都是在這個框架程序的基礎(chǔ)上編寫的。 STM8與匯編語言(4)今天要做的實驗是在ST的三合一開發(fā)板上,用匯編語言寫一個程序,驅(qū)動板上的LED指示燈閃爍。開發(fā)板上的LED1接在STM8的PD3上,因此要將PD3設(shè)置成輸出模式,為了提高高電平時的輸出電流,要將其設(shè)置成推挽輸出方式。這主要通過設(shè)置對應(yīng)的DDR/CR1/CR2寄存器實現(xiàn)。還是利用ST的開發(fā)工具,先生成一個匯編程序的框架,然后修改其中的main.asm,修改后的代碼如下。編譯通過后,下載到開發(fā)板,運行程序,可以看到LED1在閃爍,且閃爍的頻率為5HZ。s

17、tm8/ #include "mapping.inc" 下面定義端口D的寄存器地址PD_ODR EQU $500f PD_IDR EQU $5010PD_DDR EQU $5011 PD_CR1 EQU $5012PD_CR2 EQU $5013; 定義堆棧空間的起始位置和結(jié)束位置stack_start.w EQU $stack_segment_startstack_end.w EQU $stack_segment_end; 下面開始定義一個段,該段位于ROM中 segment 'rom' ; 定義復(fù)位后的第一條指令的標(biāo)號(即入口地址)main.l ; 首先

18、要初始化堆棧指針LDW X,#stack_end LDW SP,X LD A,#08LD PD_DDR,A ; 將PD3設(shè)置成輸出 LD A,#08 LD PD_CR1,A ; 將PD3設(shè)置成推挽輸出 LD A,#00 LD PD_CR2,A ;MAIN_LOOP.L LD A,#08 ; LD PD_ODR,A ; 將PD3的輸出設(shè)置成1 LD A,#100 CALL DELAY_MS ; 延時100MS LD A,#00 ; LD PD_ODR,A ; 將PD3的輸出設(shè)置成1 LD A,#100 CALL DELAY_MS ; 延時100MS JRA MAIN_LOOP ; ; 函數(shù)功能:

19、延時; 輸入?yún)?shù):寄存器A 要延時的毫秒數(shù),這里假設(shè)CPU的主頻為2MHZ; 輸出參數(shù):無; 返 回 值:無; 備 注:無DELAY_MS.L PUSH A ; 將入口參數(shù)保存到堆棧中 LD A,#250 ; 寄存器A<-250,作為下面的循環(huán)數(shù) DELAY_MS_1.L NOP ; 用空操作指令進行延時4T NOP NOP NOP NOP DEC A ; 寄存器A<-A-1,本條指令執(zhí)行之間為1T JRNE DELAY_MS_1 ; 若不等于0,則循環(huán), ; 本條指令執(zhí)行時間為2T(跳時)或1T(不跳時) POP A ; 從堆棧中恢復(fù)入口參數(shù) DEC A ; 將要延時的MS數(shù)1

20、JRNE DELAY_MS ; 若不等于0,則循環(huán)RET ; 函數(shù)返回 interrupt NonHandledInterruptNonHandledInterrupt.l iret; 下面定義中斷向量表 segment 'vectit' dc.l $82000000+main ; reset dc.l $82000000+NonHandledInterrupt ; trap dc.l $82000000+NonHandledInterrupt ; irq0 dc.l $82000000+NonHandledInterrupt ; irq1 dc.l $82000000+Non

21、HandledInterrupt ; irq2 dc.l $82000000+NonHandledInterrupt ; irq3 dc.l $82000000+NonHandledInterrupt ; irq4 dc.l $82000000+NonHandledInterrupt ; irq5 dc.l $82000000+NonHandledInterrupt ; irq6 dc.l $82000000+NonHandledInterrupt ; irq7 dc.l $82000000+NonHandledInterrupt ; irq8 dc.l $82000000+NonHandle

22、dInterrupt ; irq9 dc.l $82000000+NonHandledInterrupt ; irq10 dc.l $82000000+NonHandledInterrupt ; irq11 dc.l $82000000+NonHandledInterrupt ; irq12 dc.l $82000000+NonHandledInterrupt ; irq13 dc.l $82000000+NonHandledInterrupt ; irq14 dc.l $82000000+NonHandledInterrupt ; irq15 dc.l $82000000+NonHandle

23、dInterrupt ; irq16 dc.l $82000000+NonHandledInterrupt ; irq17 dc.l $82000000+NonHandledInterrupt ; irq18 dc.l $82000000+NonHandledInterrupt ; irq19 dc.l $82000000+NonHandledInterrupt ; irq20 dc.l $82000000+NonHandledInterrupt ; irq21 dc.l $82000000+NonHandledInterrupt ; irq22 dc.l $82000000+NonHandl

24、edInterrupt ; irq23 dc.l $82000000+NonHandledInterrupt ; irq24 dc.l $82000000+NonHandledInterrupt ; irq25 dc.l $82000000+NonHandledInterrupt ; irq26 dc.l $82000000+NonHandledInterrupt ; irq27 dc.l $82000000+NonHandledInterrupt ; irq28 dc.l $82000000+NonHandledInterrupt ; irq29endSTM8與匯編語言(5)上一次的實驗程序

25、,完成了LED指示燈的驅(qū)動,用到了GPIO的輸出方式,這一次要用GPIO的輸入方式,進行按鍵的輸入。下面的代碼是讀入按鍵值,如果按鍵按下,則點亮LED,否則熄滅LED。利用ST的開發(fā)工具,生成一個匯編程序的框架,然后修改其中的main.asm,修改后的代碼如下。編譯通過后,下載到開發(fā)板,運行程序,可以看到當(dāng)按下按鍵時,LED1點亮,當(dāng)抬起按鍵時,LED1熄滅。stm8/#include "mapping.inc" 涉及到的硬件資源; LED1定義在PD3; KEY1定義在PD7; 下面定義端口D的寄存器地址PD_ODR EQU $500f PD_IDR EQU $5010P

26、D_DDR EQU $5011 PD_CR1 EQU $5012PD_CR2 EQU $5013; 定義堆棧空間的起始位置和結(jié)束位置stack_start.w EQU $stack_segment_startstack_end.w EQU $stack_segment_end segment 'rom' ; 下面開始定義一個段,該段位于ROM中main.l ; 定義復(fù)位后的第一條指令的標(biāo)號(即入口地址); 首先要初始化堆棧指針 LDW X,#stack_end LDW SP,X; 下面初始化IO端口; PD3設(shè)置成推挽輸出; PD7設(shè)置成懸浮輸入LD A,#08LD PD_DD

27、R,A ; 將PD3設(shè)置成輸出,PD7設(shè)置成輸入LD A,#08LD PD_CR1,A ; 將PD3設(shè)置成推挽輸出LD A,#00LD PD_CR2,A ;MAIN_LOOP.L LD A,PD_IDR ; 讀入端口D的引腳輸入寄存器AND A,#$80 ; 測試最高位是否為1JRNE MAIN_LOOP_1 ; 若最高位為1,則跳轉(zhuǎn) LD A,#$08 ; 否則說明按鍵按下,PD3<-1,點亮LED1LD PD_ODR,A ; JRA MAIN_LOOPMAIN_LOOP_1.LLD A,#$00 ; 若按鍵沒按下,PD3<-0,熄滅LED1 LD PD_ODR,A ; JRA

28、MAIN_LOOP ; interrupt NonHandledInterruptNonHandledInterrupt.liret; 下面定義中斷向量表segment 'vectit'dc.l $82000000+main; resetdc.l $82000000+NonHandledInterrupt; trapdc.l $82000000+NonHandledInterrupt; irq0 dc.l $82000000+NonHandledInterrupt; irq1 dc.l $82000000+NonHandledInterrupt; irq2 dc.l $8200

29、0000+NonHandledInterrupt; irq3 dc.l $82000000+NonHandledInterrupt; irq4dc.l $82000000+NonHandledInterrupt; irq5 dc.l $82000000+NonHandledInterrupt; irq6 dc.l $82000000+NonHandledInterrupt; irq7 dc.l $82000000+NonHandledInterrupt; irq8 dc.l $82000000+NonHandledInterrupt; irq9 dc.l $82000000+NonHandle

30、dInterrupt; irq10 dc.l $82000000+NonHandledInterrupt; irq11 dc.l $82000000+NonHandledInterrupt; irq12 dc.l $82000000+NonHandledInterrupt; irq13 dc.l $82000000+NonHandledInterrupt; irq14 dc.l $82000000+NonHandledInterrupt; irq15 dc.l $82000000+NonHandledInterrupt; irq16 dc.l $82000000+NonHandledInter

31、rupt; irq17 dc.l $82000000+NonHandledInterrupt; irq18 dc.l $82000000+NonHandledInterrupt; irq19 dc.l $82000000+NonHandledInterrupt; irq20 dc.l $82000000+NonHandledInterrupt; irq21 dc.l $82000000+NonHandledInterrupt; irq22 dc.l $82000000+NonHandledInterrupt; irq23 dc.l $82000000+NonHandledInterrupt;

32、irq24 dc.l $82000000+NonHandledInterrupt; irq25 dc.l $82000000+NonHandledInterrupt; irq26 dc.l $82000000+NonHandledInterrupt; irq27 dc.l $82000000+NonHandledInterrupt; irq28dc.l $82000000+NonHandledInterrupt; irq29endSTM8與匯編語言(6)8位定時器應(yīng)用之一STM8單片機中的外設(shè)資源是比較豐富的,定時器有8位的也有16位的,下面的實驗程序,就是利用8位定時器4來進行延時,然后驅(qū)動

33、LED閃爍。同樣還是利用ST的開發(fā)工具,生成一個匯編程序的框架,然后修改其中的main.asm,修改后的代碼如下。編譯通過后,下載到開發(fā)板,運行程序,可以看到LED在閃爍,或者用示波器可以在LED引腳上看到方波。在這里要特別提醒的是,從ST給的手冊上看,這個定時器中的計數(shù)器是一個加1計數(shù)器,但本人在實驗過程中感覺不太對,經(jīng)過反復(fù)的實驗,我認(rèn)為應(yīng)該是一個減1計數(shù)器(也許是我拿的手冊不對,或許是理解上有誤)。例如,當(dāng)給定時器中的自動裝載寄存器裝入255時,產(chǎn)生的方波頻率最小,就象下面代碼中計算的那樣,產(chǎn)生的方波頻率為30HZ左右。若初始化時給自動裝載寄存器裝入1,則產(chǎn)生的方波頻率最大,大約為3.9

34、K左右。也就是說實際的分頻數(shù)為ARR寄存器的值+1。stm8/#include "mapping.inc"#include "STM8S207S8.INC" 涉及到的硬件資源; 下面定義端口D的寄存器地址PD_ODR EQU $500f PD_IDR EQU $5010PD_DDR EQU $5011 PD_CR1 EQU $5012PD_CR2 EQU $5013; 定時器4的寄存器定義TIM4_CR1 EQU $5340TIM4_IER EQU $5341TIM4_SR EQU $5342TIM4_EGR EQU $5343TIM4_CNTR EQU

35、 $5344TIM4_PSCR EQU $5345TIM4_ARR EQU $5346; 定義堆??臻g的起始位置和結(jié)束位置stack_start.w EQU $stack_segment_startstack_end.w EQU $stack_segment_end segment 'rom' ; 下面開始定義一個段,該段位于ROM中main.l ; 定義復(fù)位后的第一條指令的標(biāo)號(即入口地址); 首先要初始化堆棧指針 LDW X,#stack_end LDW SP,X; 下面初始化IO端口; PD3設(shè)置成推挽輸出; PD7設(shè)置成懸浮輸入LD A,#08LD PD_DDR,A ;

36、 將PD3設(shè)置成輸出,PD7設(shè)置成輸入LD A,#08LD PD_CR1,A ; 將PD3設(shè)置成推挽輸出LD A,#00LD PD_CR2,A ; 下面初始化定時器4LD A,#$00LD TIM4_IER,A ; 禁止中斷LD A,#$01 LD TIM4_EGR,A ; 允許產(chǎn)生更新事件LD A,#$07LD TIM4_PSCR,A ; 計數(shù)器時鐘=主時鐘/128=2MHZ/128 ; 相當(dāng)于計數(shù)器周期為64uSLD A,#255LD TIM4_ARR,A ; 設(shè)定重裝載時的寄存器值,255是最大值LD A,#255LD TIM4_CNTR,A ; 設(shè)定計數(shù)器的初值 ; 定時周期=(ARR

37、+1)*64=16384uS ; 產(chǎn)生方波頻率=30.5HZLD A,#$01 ; b0 = 1,允許計數(shù)器工作; b1 = 0,允許更新LD TIM4_CR1,A ; 設(shè)置控制器,啟動定時器MAIN_LOOP.LLD A,TIM4_SR ; 讀入定時器4的狀態(tài)AND A,#01 ; 判斷是否產(chǎn)生更新標(biāo)志 JREQ MAIN_LOOP ; 若沒有,則等待 LD A,#0 ; 清除更新標(biāo)志 LD TIM4_SR,A LD A,PD_ODR ; 將LED驅(qū)動信號取反XOR A,#$08LD PD_ODR,A ; LED閃爍頻率=2MHZ/128/255/2=30.63JRA MAIN_LOOP ;

38、 無限循環(huán) interrupt NonHandledInterruptNonHandledInterrupt.liret; 下面定義中斷向量表 segment 'vectit' dc.l $82000000+main; reset dc.l $82000000+NonHandledInterrupt; trap dc.l $82000000+NonHandledInterrupt; irq0 dc.l $82000000+NonHandledInterrupt; irq1 dc.l $82000000+NonHandledInterrupt; irq2 dc.l $820000

39、00+NonHandledInterrupt; irq3 dc.l $82000000+NonHandledInterrupt; irq4dc.l $82000000+NonHandledInterrupt; irq5 dc.l $82000000+NonHandledInterrupt; irq6 dc.l $82000000+NonHandledInterrupt; irq7 dc.l $82000000+NonHandledInterrupt; irq8 dc.l $82000000+NonHandledInterrupt; irq9 dc.l $82000000+NonHandledI

40、nterrupt; irq10 dc.l $82000000+NonHandledInterrupt; irq11 dc.l $82000000+NonHandledInterrupt; irq12 dc.l $82000000+NonHandledInterrupt; irq13 dc.l $82000000+NonHandledInterrupt; irq14 dc.l $82000000+NonHandledInterrupt; irq15 dc.l $82000000+NonHandledInterrupt; irq16 dc.l $82000000+NonHandledInterru

41、pt; irq17 dc.l $82000000+NonHandledInterrupt; irq18 dc.l $82000000+NonHandledInterrupt; irq19 dc.l $82000000+NonHandledInterrupt; irq20 dc.l $82000000+NonHandledInterrupt; irq21 dc.l $82000000+NonHandledInterrupt; irq22 dc.l $82000000+NonHandledInterrupt; irq23 dc.l $82000000+NonHandledInterrupt; ir

42、q24 dc.l $82000000+NonHandledInterrupt; irq25 dc.l $82000000+NonHandledInterrupt; irq26 dc.l $82000000+NonHandledInterrupt; irq27 dc.l $82000000+NonHandledInterrupt; irq28dc.l $82000000+NonHandledInterrupt; irq29endSTM8與匯編語言(7)8位定時器應(yīng)用之二上次寫的是用STM8單片機中的8位定時器作為軟件延時,采用的是查詢方式。在實際系統(tǒng)中,定時器的應(yīng)用,更多的是采用中斷方式,下面的

43、代碼就給出8位定時器在中斷方式下的應(yīng)用。實驗程序首先初始化驅(qū)動LED的端口,然后初始化8位的定時器4,最后啟動中斷允許,要記住,一定要將中斷服務(wù)程序的入口地址填寫到中斷向量表中,并且要根據(jù)中斷向量號在正確的位置上填寫。同樣還是利用ST的開發(fā)工具,生成一個匯編程序的框架,然后修改其中的main.asm,修改后的代碼如下。編譯通過后,下載到開發(fā)板,運行程序,可以看到LED在閃爍,或者用示波器可以在LED引腳上看到方波。stm8/#include "mapping.inc"#include "STM8S207S8.INC" 涉及到的硬件資源; LED1定義在P

44、D3; 下面定義端口D的寄存器地址PD_ODR EQU $500f PD_IDR EQU $5010PD_DDR EQU $5011 PD_CR1 EQU $5012PD_CR2 EQU $5013; 定時器4的寄存器定義TIM4_CR1 EQU $5340TIM4_IER EQU $5341TIM4_SR EQU $5342TIM4_EGR EQU $5343TIM4_CNTR EQU $5344TIM4_PSCR EQU $5345TIM4_ARR EQU $5346; 定義堆??臻g的起始位置和結(jié)束位置stack_start.w EQU $stack_segment_startstack_

45、end.w EQU $stack_segment_endsegment 'rom' ; 下面開始定義一個段,該段位于ROM中main.l ; 定義復(fù)位后的第一條指令的標(biāo)號(即入口地址); 首先要初始化堆棧指針 LDW X,#stack_end LDW SP,X; 下面初始化IO端口; PD3設(shè)置成推挽輸出; PD7設(shè)置成懸浮輸入 LD A,#08          LD PD_DDR,A ; 將PD3設(shè)置成輸出,PD7設(shè)置成輸入 LD A,#08LD PD_CR1,A ; 將PD3設(shè)置成推挽輸出 LD A,#00LD PD_CR2,A ; 下面初始化定時器4LD A,#$01 LD TIM4_EGR,A ; 允許產(chǎn)生更新事件LD A,#$07LD TIM4_PSCR,A ; 計數(shù)器時鐘=主時鐘/128=2MHZ/128 ; 相當(dāng)于計數(shù)器周期為64uSLD A,#255LD TIM4_ARR,A ; 設(shè)定重裝載時的寄存器值,255是最大值LD A,#255LD TIM4_CNTR,A ; 設(shè)定計數(shù)器的初值 ; 定時周期=(255+1)*64=16384uSLD   A,#$01 ; b0 = 1,允許計數(shù)器工作 ; b1 = 0,允許更新LD TI

溫馨提示

  • 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)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論