有大神能幫我看看是哪兒出問題了嗎,想弄一個脈沖頻率計,顯示有問題啊,只有不輸入頻率時是對的
- ;********************************************************************************
- ;頻率計———六位數碼管顯示 *
- ;喇叭接p3.7口,數碼管數據p0,數碼管控制p2 *
- ;p3.5為頻率輸入端。p1.4是控制信號輸出端 *
- ;在不增加任何外部計數硬件的情況下,本試驗測試軟件可測最高頻率達到460KHz。 *
- ;用一根1pin排線短接P1.4 → P3.5 顯示:; 000066(Hz) *
- ;工作原理: *
- ;1S 鐘內對輸入脈沖所計數的次數則為頻率值。 *
- ;16位二進制加法計數器的最大計數值為 65535。 *
- ;設置定時器 0 工作在定時方式1,定時1S。 *
- ;設置定時器 1 工作在計數方式1,對輸入脈沖進行計數,溢出產生中斷。 *
- ;將定時器 1 中斷定義為優先。在中斷處理程序里對中斷次數進行計數。1S到后, *
- ;將中斷次數和計數器里的計數值取出進行綜合數據處理,處理后的數據送數碼管顯示。 *
- ;信號來源: *
- ;1、軟件里對 P1.4 定時取反,形成輸出脈沖,接到 P3.5 可自測。 *
- ;包含:外部中斷設置,中斷服務程序,定時程序,定時服務程序 *
- ;以及數據處理,顯示,包括三位十進制數轉化為四位BCD碼, *
- ;********************************************************************************
- BEEP BIT P3.7 ;蜂鳴器控制線
- S1 BIT P2.7 ;數碼管位線
- S2 BIT P2.6
- S3 BIT P2.5
- S4 BIT P2.4
- S5 BIT P2.3
- S6 BIT P2.2
- S7 BIT P2.1
- S8 BIT P2.0
- LED_DATA EQU P0 ;數碼管數據定義
- ;--------------------------------------------------------------
- TIMER_H EQU 46H ;定時器高位字節單元
- TIMER_L EQU 47H ;定時器低位字節單元
- TIMCOUNT EQU 48H ;時間中斷數
- INT_H EQU 45H ;T1計數緩沖單元高地址
- INT_L EQU 44H ;T1計數緩沖單元低地址
- INT_G EQU 43H ;T1計數溢出次數計數
- T_G EQU 63H
- T_H EQU 60H ;數據顯示的高位
- T_S EQU 61H ;數據顯示中位
- T_M EQU 62H ;數據顯示低位
- DISSTART EQU 70H ;顯示單元首地址
- ;--------------------------------------------------------------
- ORG 00H
- JMP MAIN ;主程序開始
- ORG 0BH
- JMP TIMER_INT ;定時器T0中斷服務程序
- ORG 1BH
- JMP TIMER1 ;定時器T1中斷服務程序
- ORG 030H
- ;-------------------------------------------------------------
- ;主程序
- ;-------------------------------------------------------------
- MAIN: MOV SP,#30H ; 設置SP指針
- LCALL PRO_SET ;初始化
- LCALL TIM_T0
- MLP:
- LCALL EX_PRO ;外部中斷數據轉換
- LCALL EX_DISPLAY ;外部中斷數據顯示
- ;我們利用它來進行中斷計數操作
- JMP MLP
- ;---------------------------------------------------------
- ;初始化程序
- ;---------------------------------------------------------
- PRO_SET:
- MOV A,#00H
- MOV B,#00H
- MOV 2AH,A
- MOV P0,#0FFH
- MOV P1,#0FFH
- MOV P2,#0FFH
- MOV INT_H,#00H
- MOV INT_L,#00H
- MOV INT_G,#00H
- MOV T_S,#00H
- MOV T_H,#00H
- MOV T_M,#00H
- MOV T_G,#00H
- MOV TIMCOUNT,#00H
- MOV TIMER_H,#4CH ;定時 50 MS
- MOV TIMER_L,#0FH
- CLR BEEP
- SETB P3.5 ;3.5端口(T1)置輸入狀態
- RET
- ;--------------------------------------------------------
- ;對T1溢出產生中斷的次數進行計數
- ;計滿65535,產生一次溢出中斷。
- ;--------------------------------------------------------
- TIMER1:
- INC 2AH
- RETI
- ;--------------------------------------------------------
- ;定時/計數器設置
- ;--------------------------------------------------------
- TIM_T0: MOV TMOD,#0D1H ;
- MOV TH0,TIMER_H ;設置定時初值高位
- MOV TL0,TIMER_L ;設置定時初值低位
- MOV TH1,#00H ;清T1計數器
- MOV TL1,#00H
- MOV IE,#8AH ;開中斷總允許,允許T1溢出中斷
- SETB PT1 ;TIMER1優先
- SETB TR1
- SETB TR0 ;定時器開始工作
- RET
- ;-------------------------------------------------------
- ;定時器0中斷服務程序
- ;-------------------------------------------------------
- TIMER_INT:
- CLR TR0 ;關閉定時器
- MOV TL0,TIMER_L ;重新賦初值
- MOV TH0,TIMER_H ;
- INC TIMCOUNT ;定時1S,時間單位
- MOV A,TIMCOUNT ;查看數量值
- CJNE A,#20,T_END ;如果沒有到1S返回
- CLR TR1
- MOV TIMCOUNT,#00H ;到1S則清零
- MOV INT_L,TL1 ;取出計數值
- MOV INT_H,TH1 ;
- MOV INT_G,2AH
- MOV TH1,#00H
- MOV TL1,#00H
- MOV 2AH,#00H
- SETB TR1
- T_END: SETB TR0 ;重新開始定時操作
- RETI
- ;-------------------------------------------------------
- ;-------------------------------------------------------
- EX_DISPLAY:
- MOV R0,#DISSTART ;獲得顯示單元首地址
- MOV R1,#0BFH ;從第二個數碼管開始
- MOV R2,#06H ;共顯示6位數碼管
- DISLP: MOV LED_DATA,@R0 ;讀取顯示單元數據
- INC R0 ;取下一個單元地址
- MOV P2,R1 ;開始顯示當前位
- MOV A,R1 ;準備顯示下一位
- RR A ;
- MOV R1,A ;下一位
- LCALL DELAY5MS ;延時 5 MS
- DJNZ R2,DISLP ;重復顯示下一個
- RET ;顯示完成,返回
- ;-----------------------------------------------------
- ;時間處理,主要為 BCD碼轉換,查表
- ;-----------------------------------------------------
- EX_PRO: SETB PSW.3 ;準備 寄存器
- CLR PSW.4 ;
- MOV R6,INT_H ;得到高位數據
- MOV R7,INT_L ;得到低位數據
- MOV R5,INT_G
- LCALL DATA_PRO ;開始轉換
- LCALL BCD ;轉換完成后,開始進行碼型變換
- MOV R0,#DISSTART ;開始填充顯示單元
- MOV R2,#06H ;共計填充 6 位
- PRLP: MOV A,@R0 ;獲得當前位地址
- MOV DPTR,#TAB_NU ;獲得表頭
- MOVC A,@A+DPTR ;獲得編碼數據
- MOV @R0,A ;保存編碼數據
- INC R0 ;指向下一個帶轉換數據
- DJNZ R2,PRLP ;繼續轉換,直到完成
- RET ;轉換完成,返回
- ;-------------------------------------------------------------
- ;兩位 十六進制 轉化為 2 位 BCD 碼
- ;高位 ->R6 低位 ->R7,轉化后 從高到低 T_S,T_M,T_H
- ;-------------------------------------------------------------
- DATA_PRO:
- PUSH PSW
- SETB PSW.3 ;設置當前寄存器
- CLR PSW.4
- CLR A ;清累加器
- MOV T_G,A
- MOV T_H,A ;清除出口單元,準備轉換
- MOV T_M,A
- MOV T_S,A
- MOV R2,#24 ;共計轉換24位
- HB3: MOV A,R7 ;獲得低位數據
- RLC A ;帶位左移,高位數據在CY中
- MOV R7,A ;保存數據
- MOV A,R6 ;取得高位數
- RLC A ;帶進位左移
- MOV R6,A ;保存數據
- MOV A,R5 ;取得高位數
- RLC A ;帶進位左移
- MOV R5,A
- MOV A,T_S ;得到低位數據
- ADDC A,T_S ;累加
- DA A ;十進制調整
- MOV T_S,A ;保存數據
- MOV A,T_M ;得到第二位數據
- ADDC A,T_M ;累加
- DA A ;十進制調整
- MOV T_M,A ;保存結果
- MOV A,T_H ;得到第三位
- ADDC A,T_H ;累加
- DA A
- MOV T_H,A ;保存
- MOV A,T_G ;得到第四位
- ADDC A,T_G ;累加
- MOV T_G,A
- DJNZ R2,HB3 ;沒有轉換完畢,重復轉換
- POP PSW ;轉換完畢,恢復PSW
- RET ;返回
- ;-----------------------------------------------------------
- ;碼型變換,將帶轉換的數據分成,不同的數位,并轉換成單位BCD碼
- ;-----------------------------------------------------------
- BCD: MOV R0,#DISSTART ;獲得首地址
- MOV A,T_S ;獲得待轉化的低位
- MOV B,#10 ;轉化進制,如果要進行十進制轉換 改為 10
- DIV AB ;計算 A/B
- MOV @R0,B ;第一位轉換完畢,保存低位轉化后的數據
- INC R0 ;自增
- MOV @R0,A ;保存高位
- INC R0 ;取第二個數據地址
- MOV A,T_M ;獲得第二個需要轉換的數據
- MOV B,#10 ;十六進制
- DIV AB ;計算
- MOV @R0,B ;存低位
- INC R0
- MOV @R0,A ;存高位
- INC R0 ;第三位
- MOV A,T_H ;獲得第三個需要轉換的數據
- MOV B,#10 ;十六進制
- DIV AB ;計算
- MOV @R0,B ;存低位
- INC R0
- MOV @R0,A ;存高位
- RET ;完畢,返回
- ;---------------------------------------------------
- ;定時 5MS
- ;---------------------------------------------------
- DELAY5MS:
- PUSH PSW
- CLR PSW.3
- SETB PSW.4
- MOV R0,#250
- MOV R1,#2
- D20: DJNZ R0,D20
- MOV R0,#250
- DJNZ R1,D20
- POP PSW
- RET
- ;----------------------------------------------------------------
- ;這是數字顯示表格,其中 帶小數點的數字比不帶小數點的數字小20
- ; 比如 0 的顯示代碼為 28;那么 0.的顯示代碼為 8;如此類推
- ;----------------------------------------------------------------
- TAB_NU:
- DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;3FH,06H,5BH,04FH,66H,6DH,7DH,07H,7FH,6FH;28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h,30h,25h,0a9h,26h,0a1h,0b1h;
- ;DB 8H,5eH,82H,42H,54H,41H,1H,5aH,00H,40H,00,00,00,00,00,00;帶小數點
- ;-----------------------------------------------------------------
- END ;告訴編譯器本程序到此結束。
復制代碼
|