?? mcu.asm
字號:
mov SCON,#50h ;設置串口工作方式1,REN=1,允許接收。
setb TR1 ;定時器開始工作。
ret ;返回。
;;;;;;;;;;;;;;;;初始化串口子程序結束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;毫秒表子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>資源占用報告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>臨時占用a,c,dptr,bank0區r2~r6
;>>>>>>>>>>>>>>>報告完畢>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;'''''''''''''''操作指南''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
;1:當程序處于毫秒表功能時,按下BUTTON_MIL鍵開始毫秒計時,再次按下結束計時。
;2:如果您打算返回主菜單,首先按下鍵盤任意鍵,然后再連續按下兩次BUTTON_MIL鍵。
;'''''''''''''''指南完畢''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
FUNCTION7: mov a,STATUS ;
anl a,#0FEh ;進入毫秒表功能。
mov STATUS,a ;
mov dptr,#8100h ;
movx @dptr,a ;
nop ;
nop ;
call ENABLEINT1 ;開啟外部中斷1。
FUNCTION7_1: mov a,RETURNFLAG ;檢查返回標志,決定是否返回。
jz FUNCTION7_CON ;
jmp main ;
FUNCTION7_CON: mov r2,#00h ;r2,r3,r4,r5保存計時值。
;足夠計時1個多小時。您不會
;為了測試一下而讓Proteus仿真
;1個小時吧:(
mov r3,#00h ;
mov r4,#00h ;
mov r5,#00h ;
FUNCTION7_2: mov a,MILSTART ;MILSTART保存計時標志,第一次
;按下BUTTON_MIL鍵后觸發外部中
;斷1,將MILSTART設定為0FFh,開
;始計時。再次按下BUTTON_MIL鍵
;后觸發外部中斷1,將MILSTART設
;定為00h。
jz FUNCTION7_2 ;
FUNCTION7_3: clr c ;=====這部分程序是進行4個字節
mov a,r5 ;=====的加1操作。r2是最高字節,
addc a,#01h ;=====r5是最低字節。
mov r5,a ;=====這部分程序占用16個機器周
mov a,r4 ;=====期,所以計時后的r2r3r4r5
addc a,#00h ;=====乘以16便是以微秒為單位的
mov r4,a ;=====時間。注意時鐘晶體=12MHz。
mov a,r3 ;=====
addc a,#00h ;=====
mov r3,a ;=====
mov a,r2 ;=====
addc a,#00h ;=====
mov r2,a ;=====
mov a,MILSTART ;=====
jnz FUNCTION7_3 ;=====
mov r6,#04h ;
FUNCTION7_4: clr c ;>>>>>這部分程序完成乘以16的操作,
mov a,r5 ;>>>>>乘以16不就是向左移4bit嗎。
rlc a ;>>>>>
mov r5,a ;>>>>>
mov a,r4 ;>>>>>
rlc a ;>>>>>
mov r4,a ;>>>>>
mov a,r3 ;>>>>>
rlc a ;>>>>>
mov r3,a ;>>>>>
mov a,r2 ;>>>>>
rlc a ;>>>>>
mov r2,a ;>>>>>
djnz r6,FUNCTION7_4 ;>>>>>
mov r0,#DIVD4ADDRESS0 ;以下顯示結果,唯一需要解釋的就是刪
mov r1,#DIVD4ADDRESS4 ;去最低2位數字不顯示,精確到0.1mS。
mov a,r2 ;
mov @r1,a ;
inc r1 ;
mov a,r3 ;
mov @r1,a ;
inc r1 ;
mov a,r4 ;
mov @r1,a ;
inc r1 ;
mov a,r5 ;
mov @r1,a ;
inc r1 ;
mov @r1,#00h ;
inc r1 ;
mov @r1,#00h ;
inc r1 ;
mov @r1,#00h ;
inc r1 ;
mov @r1,#0Ah ;
mov dptr,#LCD0 ;
call DIVD4 ;
call DIVD4 ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULTA,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT8,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT7,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT6,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT5,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT4,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT3,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT2,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT1,a ;
mov a,#0Dh ;
movc a,@a+dptr ;
mov RESULT9,a ;
mov a,#10h ;
movc a,@a+dptr ;
mov RESULTB,a ;
mov a,#11h ;
movc a,@a+dptr ;
mov RESULTC,a ;
mov a,#00h ;
mov RESULTD,a ;
mov a,#LCD_CLS ;
call WRCMD ;
call WRRESULT ;
jmp FUNCTION7_1 ;
;;;;;;;;;;;;;;;;毫秒表子程序結束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;馬達驅動子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>資源占用報告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>臨時占用a,dptr,bank0區r5~r7
;>>>>>>>>>>>>>>>報告完畢>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;???????????????以下程序只是小小的演示。作者正在構思一個充滿想象力的設計,敬請留意。????????????
FUNCTION8: mov dptr,#8100h ;
mov a,STATUS ;
orl a,#10h ;
anl a,#0DFh ;
mov STATUS,a ;
movx @dptr,a ;右轉左不轉。
call F8DELAY ;
mov a,RETURNFLAG ;檢查返回標志,決定是否返回。
jz FUNCTION8_1 ;
jmp main ;
FUNCTION8_1: mov a,STATUS ;
orl a,#20h ;
anl a,#0EFh ;
mov STATUS,a ;
movx @dptr,a ;左轉右不轉。
call F8DELAY ;
mov a,RETURNFLAG ;檢查返回標志,決定是否返回。
jz FUNCTION8_2 ;
jmp main ;
FUNCTION8_2: mov a,STATUS ;
anl a,#0CFh ;
mov STATUS,a ;
movx @dptr,a ;兩個都不轉。
call F8DELAY ;
mov a,RETURNFLAG ;檢查返回標志,決定是否返回。
jz FUNCTION8_3 ;
jmp main ;
FUNCTION8_3: mov a,STATUS ;
orl a,#30h ;
mov STATUS,a ;
movx @dptr,a ;兩個都在轉。
call F8DELAY ;
mov a,RETURNFLAG ;檢查返回標志,決定是否返回。
jz FUNCTION8_4 ;
jmp main ;
FUNCTION8_4: jmp FUNCTION8 ;
F8DELAY: mov r5,#10h ;
D18: mov r6,#0FFh ;
D19: mov r7,#0FFh ;
D20: djnz r7,D20 ;
djnz r6,D19 ;
djnz r5,D18 ;
ret ;
;;;;;;;;;;;;;;;;馬達驅動子程序結束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;頻率測量子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>資源占用報告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>臨時占用a,b,c,dptr,bank0區r5~r7
;>>>>>>>>>>>>>>>報告完畢>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
FUNCTION9: mov a,RETURNFLAG ;檢查返回標志,決定是否返回。
jz FUNCTION9_CON ;
jmp main ;
FUNCTION9_CON: mov dptr,#0000h ;初始化計數值。
setb c ;
mov p3.5,c ;使得p3.5端口處于高阻態,準備讀取數據。
FUNCTION9_1: mov c,p3.5 ;
jc FUNCTION9_1 ;=====這部分程序的功能是等待待測信號,
FUNCTION9_2: mov c,p3.5 ;=====直到上升沿的到來。
jnc FUNCTION9_2 ;=====
FUNCTION9_3: inc dptr ;>>>>>這部分程序的功能是在待側信號的一
mov c,p3.5 ;>>>>>個周期內計數。inc dptr指令需要2
jc FUNCTION9_3 ;>>>>>個機器周期,mov c,p3.5指令需要1
FUNCTION9_4: inc dptr ;>>>>>個機器周期,jc FUNCTION9_3和
mov c,p3.5 ;>>>>>jnc FUNCTION9_4需要2個機器周期。
jnc FUNCTION9_4 ;>>>>>所以待側信號周期=5xdptr微秒。注意
;使用12MHz晶體。那么待側信號頻率=
;1000000/5/dptr=200000/dptr赫茲。
mov a,FREQLOW ;FREQHIGH和FREQLOW存儲上一次掃描的dptr
;數值,如果頻率沒有變化,那么前后兩次掃
;描數值相同,不更新LCD顯示。
;實際上,即使您不改變待測信號頻率,前后
;兩次掃描的dptr也不相同。因為這里采用的
;是等待上升沿到來再計數,哪有這么幸運,
;恰好讓您趕上精確的上升沿時刻,總有些誤
;差。
anl a,#0FCh ;所以,屏蔽最低2bit數值,降低精度,模糊
;比較。這樣做會不會降低測量的精度呢?用
;這里的方法測量頻率本身就有誤差,頻率越
;高誤差越大。所以屏蔽不屏蔽2bit不是主要
;矛盾所在。注意,本電路圖測量的頻率范圍
;不要超過10000Hz,最大誤差大約30-50Hz。
;再強調一次,頻率越高誤差越大,您自己思
;考為什么。
;那又沒有其它的算法或者電路設計能夠做到
;比較精確而且測量頻率范圍更大呢?有啊,
;但是作者現在不想告訴您:(
mov FREQLOW,a ;
mov a,dpl ;
anl a,#0FCh ;
xrl a,FREQLOW ;把dpl和FREQLOW做異或運算,得到結果暫存b中。
mov b,a ;
mov a,dph ;
xrl a,FREQHIGH ;把dph和FREQHIGH做異或運算,得到結果暫存a中。
orl a,b ;把a和b做或運算,如果結果為零,說明前后
;兩次掃描數值相同。
jz FUNCTION9 ;
mov FREQHIGH,dph ;將本次dptr掃描數值存儲。
mov FREQLOW,dpl ;
mov r0,#DIVD4ADDRESS0 ;以下求頻率并顯示,類似前面的程序,不多
;解釋了。
mov r1,#DIVD4ADDRESS4 ;
mov a,#00h ;
movx @r1,a ;
inc r1 ;
mov a,#03h ;
mov @r1,a ;
inc r1 ;
mov a,#0Dh ;
mov @r1,a ;
inc r1 ;
mov a,#40h ;
mov @r1,a ;
inc r1 ;
mov a,#00h ;
mov @r1,a ;
inc r1 ;
mov @r1,a ;
inc r1 ;
mov @r1,dph ;
inc r1 ;
mov @r1,dpl ;
call DIVD4 ;
mov r1,#DIVD4ADDRESS8 ;
mov @r1,#00h ;
inc r1 ;
mov @r1,#00h ;
inc r1 ;
mov @r1,#00h ;
inc r1 ;
mov @r1,#0Ah ;
mov dptr,#LCD0 ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT5,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT4,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT3,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT2,a ;
call DIVD4 ;
mov a,DIVD4ADDRESS3 ;
movc a,@a+dptr ;
mov RESULT1,a ;
mov a,#0Eh ;
movc a,@a+dptr ;
mov RESULT6,a ;
mov a,#0Fh ;
movc a,@a+dptr ;
mov RESULT7,a ;
mov a,#00h ;
mov RESULT8,a ;
mov a,#LCD_CLS ;
call WRCMD ;
call WRRESULT ;
F9DELAY: mov r5,#05h ;
D26: mov r6,#0FFh ;
D27: mov r7,#0FFh ;
D28: djnz r7,D28 ;
djnz r6,D27 ;
djnz r5,D26 ;
jmp FUNCTION9 ;
;;;;;;;;;;;;;;;;頻率測量子程序結束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;正弦波顯示子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>資源占用報告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>臨時占用a,bank0區r7
;>>>>>>>>>>>>>>>報告完畢>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;'''''''''''''''友情提示''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
;1:您不能指望51單片機進行正弦函數計算(sin),51單片機只是8位機,算術運算指令弱,
;運算速度慢。不是不能做出正弦子程序,而是不能實時計算出來。如果您非要實時計算,建
;議您換一顆奔騰的芯,或者用TMS320XXXX。
;2:這里采用查表的方法。用C語言編寫程序,事先算好,粘貼在這里。您察看一下壓縮包里
;面有一個名稱為SineTable的可執行程序和源文件,您可以按照自己的需要修改。為了減小
;壓縮包體積,完整的C++工程文件沒有給出,只有.cpp的源文件。
;3:在Proteus下,也許您運行顯示正弦波的功能時,示波器更新很慢,CPU資源100%占用,畫
;面極不流暢的情況。原因是這樣:在作者這個軟件運行時,首先顯示菜單,然后您選擇功能,
;當切換到正弦波的時候,Proteus反映就很慢,這是Proteus固有的缺點。解決的方法:您可以
;重新寫一個程序,刪去所有其它功能,一上來就顯示正弦波,那樣還比較流暢
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -