導航:首頁 > 編程語言 > arm匯編延時子程序

arm匯編延時子程序

發布時間:2023-03-03 11:17:27

1. 使用ARM匯編指令編寫R0的內容(1)與R1的內容(10)相加送回R0的程序。(要求用子程序調用實現)

b subadd
...
...
...
subadd
add r2, r1, r0

b lr

2. 用匯編語言編寫一個時鍾程序,在微機屏幕上顯示當前時間的時、分、秒。

;*********************************************************
; 帶有時間設置和秒顯示的數字鬧鍾
; Date : 2007.10.26 12MHZ晶振
; Create by :星星 緣木求魚
; P3.2設置鍵 P3.3小時調整鍵 P3.5分鍾調整鍵 P3.7定時輸出指示
;**************************************************************
;*********************************************************
; 變數地址分配
;*********************************************************
SwDelay equ 2; 設置按鍵時去抖動時間
DisplayBuffer equ 30h; 設置顯示緩沖區的地址為30h-35h共6個位元組
BeepVal equ 38h; 蜂鳴時間長短存儲器地址
OneSecondCounter equ 39h; 設置1秒計數器的地址,1秒計數器是用來計數1秒內計時器的中斷次數
Hour equ 3ah; 設置小時計數器的地址
Minute equ 3bh; 設置分鍾計數器的地址
Second equ 3ch; 設置秒計數器的地址
Year equ 3dh; 設置月日年計數器的地址
Month equ 3eh;
Day equ 3fh;
P1Val equ 40h; 設置數碼管位驅動值的地址
ClockMode equ 20h.0; 模式(正常走時/鬧時)設置寄存器地址,值為0時正常走時,為1時鬧時設定
AlarmOnOff equ 20h.1; 鬧鍾開啟/關閉標志,為0關閉,為1開啟
AlarmTimeOn equ 20h.2; 此位為1時表示鬧時時間到
DataMode equ 20h.3
DispHour equ 21h; 設置小時顯示寄存器的地址
DispMinute equ 22h; 設置分鍾顯示寄存器的地址
DispSecond equ 23h; 設置秒顯示寄存器的地址
Dnum equ 24h
AlarmHour equ 2eh; 設置鬧時小時計數器的地址
AlarmMinute equ 2fh; 設置鬧時分鍾計數器的地址
AlarmSetKey bit P3.2; 鬧鍾設置鍵
MinuteKey bit P3.3; 定義分設置鍵
HourKey bit P3.4; 定義小時設置鍵
DataSetKey bit p3.5;
RelayOut equ P3.7; 定義輸出引腳
;**********************************************************************
; 程序開始
;**********************************************************************
org 00h
ajmp Reset ;程序開始
org 0bh ;Timer0中斷向量地址
ajmp TimeInt ;跳到中斷處理程序
org 0020h
Reset: ;以下為初始化程序,為各個變數賦初值
mov sp,#70h;
setb RelayOut
mov OneSecondCounter,#125
;
mov Hour,#23
mov Minute,#59
mov Second,#30 ;設置上電時時鍾顯示的初值
;
mov Year,#07
mov Month,#12
mov Day,#27
;
mov AlarmHour,#00
mov AlarmMinute,#00 ;設置上電時鬧時時間的初值
;
clr AlarmOnOff ;上點復位後鬧時功能處於關閉狀態
clr ClockMode ;正常走時模式
clr AlarmTimeOn
setb RelayOut ;清鬧時輸出
clr DataMode
;
mov 36h,#10
mov 37h,#11
;
;************************************
; Use Timer 0 Mode 1
; 400us interrupt
;************************************
mov tmod,#00000001b
mov th0,#0E3h
mov tl0,#5Dh
mov ie, #82h ;開全局中斷
SETB EA
SETB ET0
setb tr0 ;開定時中斷

;*****************************************
; 以下為主程序
;*****************************************
MainLoop:
jb AlarmSetKey,CheckMinuteKey ;鬧時設置鍵按下了嗎?沒有則轉去檢測秒設置鍵
call Delay
jb AlarmSetKey,CheckMinuteKey ;按下的時間超過500ms嗎?
setb ClockMode ;置為鬧時設置模式
call AlarmSet
CheckMinuteKey:
jb MinuteKey,CheckHourKey ;分設置鍵按下了嗎?沒有則轉去檢測小時設置鍵
;如按下調用蜂鳴器發音程序
mov a,Minute
add a,#1; 如果按下則將分鍾加一 十進制調整
mov Minute,a;
cjne a,#3ch,NotOver1; 到60分鍾了嗎?
mov Minute,#0; 到60分鍾則將分鍾清0
NotOver1: ;以下等待按鍵釋放及防抖動
jnb MinuteKey,$
CheckHourKey:
jb HourKey,CheckDataKey;
; 如按下調用蜂鳴器發音程序
mov a,Hour
add a,#1; 如果按下則將小時加1
mov Hour,a
cjne a,#18h,NotOver2
mov Hour,#0; 到24小時則將小時清0
NotOver2: ;以下等待按鍵釋放及防抖動
jnb HourKey,$
CheckDataKey:
jb DataSetKey,CheckAlarm
call Delay
jb DataSetKey,CheckAlarm
setb DataMode
call Dataset
CheckAlarm:
jnb AlarmTimeOn,ToReturn
call AlarmProcess
ToReturn:
ajmp MainLoop
;**********************************************
; 定時器Timer0中斷服務程序(此程序每8ms執行一次)
;**********************************************
TimeInt:
mov th0,#0E3h; 重新載入定時參數
mov tl0,#5Dh;
push acc
push psw; 保護累加器及程序狀態字的內容
setb rs0; 選擇工作寄存器組1,
clr rs1; 這樣可保護原工作寄存器組(0組)的內容
djnz OneSecondCounter,NotoneSecond; 中斷了125次了嗎?即夠1秒了嗎?
mov OneSecondCounter,#125; 如夠1秒則重新設置"OneSecondCounter"計數器
call Clock ; 調用將時鍾內容加1秒的子程序
call Daynum
call ConvertoBuffer ; 調用將時鍾內容轉換到顯示緩沖區子程序
NotoneSecond:
call ScanDisplay ; 調用掃描顯示子程序
pop psw
pop acc ; 恢復累加器及程序狀態字的內容
reti ; 中斷返回
;*********************************************
; 掃描顯示子程序
;*********************************************
ScanDisplay:
MOV R1,#DisplayBuffer ;指向顯示數據首址
MOV R5,#0FEH ;掃描控制字初值
PLAY:
MOV A,R5 ;掃描字放入A
MOV P2,A ;從P2口輸出
MOV A,@R1 ;取顯示數據到A
MOV DPTR,#TAB ;取段碼表地址
MOVC A,@A+DPTR ;查顯示數據對應段碼
MOV P1,A ;段碼放入P1口

LCALL Delay

INC R1 ;指向下一地址
MOV A,R5 ;掃描控制字放入A
JNB ACC.7,ENDOUT ;掃到第六位時結束
RL A ;A中數據循環左移
MOV R5,A ;放回R5內
AJMP PLAY ;跳回PLAY循環
ENDOUT: MOV P2,#0FFH ;一次顯示結束,P2口復位
MOV P1,#00H ;P1口復位
RET ;子程序返回
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H,39h
;共陰段碼表 "0""1""2" "3""4""5""6""7" "8""9""-""c"
;****************************************************
; 時鍾內容加1秒的子程序
;****************************************************
Clock:
mov a,Second; 將原秒值送入a
add a,#1; 加1秒

mov Second,a
cjne a,#3cH,NotOverFlow; 夠60秒了嗎?
mov Second,#0; 夠了則將秒值清0
;
mov a,Minute
add a,#1
mov Minute,a; 分鍾加1
cjne a,#3cH,NotOverFlow; 夠60分了嗎?
mov Minute,#0; 夠了則將分值清0
;
mov a,Hour
add a,#1
mov Hour,a; 小時加1
cjne a,#18H,NotOverFlow; 夠24小時嗎?
mov Hour,#0; 夠了則將小時值清0
;
mov a,Day
add a,#1
mov Day,a
cjne a,Dnum,NotAlarm
mov Day,#1
;
mov a,Month
add a,#1
mov Month,a
cjne a,#13,NotAlarm
mov Month,#1
;
mov a,Year
add a,#1
mov Year,a
cjne a,#11,NotAlarm
mov Year,#0
NotOverFlow:
jnb AlarmOnOff,NotAlarm; 鬧鍾開啟了嗎?如沒有開啟則無需理會是否到鬧時時間
mov a,Second
jnz NotAlarm; 秒為零嗎?
mov a,Minute
cjne a,AlarmMinute,NotAlarm; 時間分鍾值和鬧時設置分鍾值相等嗎?
mov a,Hour
cjne a,AlarmHour,NotAlarm; 時間小時值和鬧時設置小時值相等嗎?
setb AlarmTimeOn; 到了鬧時時間則將「鬧時時間到」標志設為1
NotAlarm:
ret

;**************************************************************************
; 將時鍾內容或鬧時設置值轉換到顯示緩沖區子程序
;**************************************************************************
ConvertoBuffer:
mov r1,#DisplayBuffer
jnb dataMode,TimeDisp
mov a,Day
mov DispSecond,a
mov a,Month
mov DispMinute,a
mov a,Year
mov DispHour,a
ajmp Convert
TimeDisp: jb ClockMode,DispAlarmSet; 判斷時鍾模式,以決定是顯示實時時間還是鬧時時間
mov a,Second;
mov DispSecond,a;
mov a,Minute;
mov Dispminute,a;
mov a,Hour;
mov DispHour,a; 顯示實時時間
;
ajmp Convert
DispAlarmSet:
jb AlarmOnOff,AlarmOn
mov DispSecond,#00h
ajmp Next
AlarmOn:
mov DispSecond,#11; 顯示鬧時時間及顯示鬧鍾狀態:顯示「00」表示關閉鬧鍾,
Next: ;「11」表示開啟鬧鍾
mov a,AlarmMinute;
mov Dispminute,a;
mov a,AlarmHour;
mov DispHour,a;
;
Convert:
mov a,DispSecond; 取秒值
mov b,#10
div ab
mov @r1,b;
inc r1; 緩沖寄存器的地址加1
mov @r1,a; 將秒值的十位值存入緩沖區
;
inc r1
mov a,DispMinute
mov b,#10
div ab
mov @r1,b;
inc r1; 緩沖寄存器的地址加1
mov @r1,a; 將秒值的十位值存入緩沖區
;
inc r1
mov a,DispHour
mov b,#10
div ab
mov @r1,b;
inc r1; 緩沖寄存器的地址加1
mov @r1,a; 將秒值的十位值存入緩沖區
ret;
;*******************************************************
;天數判斷,平年,閏年
;*******************************************************
Daynum: mov a,Month
mov dptr,#TABL
movc a,@a+dptr
mov Dnum,a
mov a,Year
mov b,#4
div ab
mov a,b
cjne a,#0,BB
mov a,Month
cjne a,#2,BB
inc Dnum
BB: RET
TABL: DB 31,32,29,32,31,32,31,32,32,31,32,31,32

;**************************************************
; 鬧時設置子程序
;**************************************************
AlarmSet:
jnb AlarmSetKey,$
call Delay; 等待「AlarmSetKey」鍵釋放
CheckArmMinuteKey: ;
jb MinuteKey,CheckArmHourKey; 分設置鍵按下了嗎?沒有則轉去檢測小時設置鍵
setb AlarmOnOff
mov 37h,#0
mov a,AlarmMinute
add a,#1; 如果按下則將分鍾加1 十進制調整
mov AlarmMinute,a;
cjne a,#3ch,ArmNotOver1; 到60分鍾了嗎?
mov AlarmMinute,#0; 到60分鍾則將分鍾清0
ArmNotOver1: ;以下等待按鍵釋放及防抖動
jnb MinuteKey,$
CheckArmHourKey:
jb HourKey,AlarmSetEnd; 小時設置鍵按下了嗎?沒有則返回反復檢測
setb AlarmOnOff
mov a,AlarmHour
add a,#1; 如果按下則將小時加1
mov AlarmHour,a
cjne a,#18h,ArmNotOver2
mov AlarmHour,#0; 到24小時則將小時清0
ArmNotOver2: ;以下等待按鍵釋放及防抖動
jnb HourKey,$
AlarmSetEnd:
jb AlarmSetKey,AlarmSet; 設置完畢了嗎?
jnb AlarmSetKey,$;
clr ClockMode; 從設置模式轉為走時模式
ret
;*********************************************
; 日期調整
;*********************************************
DataSet:
jnb DataSetKey,$
call Delay
CheckDataYearKey:
jb HourKey,CheckDataMonthKey
mov a,Year
add a,#1
mov Year,a
cjne a,#11,DataNotOver1
mov Year,#0
DataNotOver1:
jnb HourKey,$
CheckDataMonthKey:
jb MinuteKey,CheckDataDayKey
mov a,Month
add a,#1
mov Month,a
cjne a,#13,DataNotOver2
mov Month,#1
DataNotOver2:
jnb MinuteKey,$
CheckDataDayKey:
jb AlarmSetKey,DataSetEnd
mov a,day
add a,#1
mov Day ,a
cjne a,Dnum,DataNotOver3
mov Day,#1
DataNotOver3:
jnb AlarmSetKey,$
DataSetEnd:
jb DataSetKey,DataSet
jnb DataSetKey,$
clr DataMode
ret

;**************************************************
; 鬧時服務子程序
;**************************************************
AlarmProcess:
clr RelayOut;
jb AlarmSetKey,AlarmReturn; 停止鬧時鍵(即鬧時設置鍵)按下了嗎?
clr AlarmOnOff
jnb AlarmSetKey,$;
setb RelayOut; 如停止鬧時鍵按下則停止鬧時
clr AlarmTimeOn;
mov 37h,#11
mov AlarmMinute,#00
mov AlarmHour,#00
AlarmReturn:
ret
;**************************************************
; 延時子程序
;**************************************************
Delay:
mov r6,#2
Del:
mov r7,#124
djnz r7,$
djnz r6,Del
ret
DL1s: mov r3,#4
dd: call Delay
djnz r3,dd
ret
end

3. 關於ARM中匯編與C程序的混合編程的參數傳遞問題!

匯編跳至C語言代碼執行,自動調用R0,R1等來傳遞參數,比如R0傳遞給a,R1傳遞給b,以此類推。返回時自動用R0傳遞返回值。希望對你有幫助

閱讀全文

與arm匯編延時子程序相關的資料

熱點內容
射手播放器字幕文件夾 瀏覽:60
如何查看cad原文件的字體 瀏覽:260
蘋果平板型號a1395 瀏覽:116
html中添加php代碼 瀏覽:712
tidb資料庫 瀏覽:763
supersu二進制更新文件 瀏覽:293
怎麼製作app圖標 瀏覽:801
信用村的數據如何實現更新 瀏覽:238
瀏覽器工具在哪 瀏覽:579
月度數據包含哪些 瀏覽:875
成都公積金app為什麼下載不了 瀏覽:621
2014微雲版本 瀏覽:903
文件保存路徑規范 瀏覽:827
vb編程如何新建excel 瀏覽:83
穿越火線文件名字 瀏覽:750
最新款快手如何無水印網站視頻 瀏覽:625
劍靈到50級後怎麼升級 瀏覽:671
文本文件內容開機以後發現沒了 瀏覽:593
ie單文件英文 瀏覽:865
如何修改數據表的數據 瀏覽:476

友情鏈接