如题:“基于
单片机的频率计设计”我的程序编译的时候有错误(汇编语言)希望大神帮忙修改一下
;程序功能说明:
;1.通过 IO 口 P1.0,P1.1 控制 74ls153 四选一译码器,对待测频率选择合适的频率衰减档位,
; 计数并显示在 LED 上面.
;2.频率检测范围:1Hz-1MHz.
; 其中:1Hz-2kHz,CPU 直接检测; 2KHz-20KHz,衰减 10 倍测量;
; 20KHz-200KHz,衰减 100 倍测量; 200KHz-999KHz,衰减 1000 倍测量。
;3.显示数据更新:每 1S 刷新一次。
;******************************************************************
;P153_BA,00 衰减 1000 倍,01 衰减 100 倍,10 衰减 10 倍,11 衰减 0 倍。
P153_A EQU P1.1
P153_BEQU P1.0
FREQ_LOSS EQU 30H ; 用于存放当前的频率衰减档位 0--3
PORT_LED EQU P0 ; LED 驱动端口
PORT_LED_138 EQU P2 ; LED 位选择口
DISPLAY_DATA_ADDR EQU 31H ; 用于存放算好的显示代码首地址
DISPLAY_DATA0EQU 31H ; 用于存放算好的显示代码
DISPLAY_DATA1EQU 32H;
DISPLAY_DATA2EQU 33H;
DISPLAY_DATA3EQU 34H;
DISPLAY_DATA4EQU 35H;
DISPLAY_DATA5EQU 36H;
COUNTER_DISPLAYEQU 37H ; 用于存放当前显示的是第几位
DATA_ADDR EQU 38H;
DATA0 EQU 38H ; 用于存放计数器所计数据转 10 进制后的数据
DATA1 EQU 39H
DATA2 EQU 3AH
DATA3 EQU 3BH
DATA4 EQU 3CH
DATA5 EQU 3DH
TEMP1EQU 40H
TEMP2EQU 41H
TEMP3EQU 42H
TEMP4EQU 43H
COUNTER_BUF_H EQU 50H ; 用于存放计数器的值
COUNTER_BUF_L EQU 51H
tiMES_50MS EQU 53H ;50 毫秒计数器,每 50 毫秒加 1
TIMES_1S EQU 54H ;1 秒计数器,每秒加 1
COUNT_DELAY1 EQU 55H ; 用于延时计数
COUNT_DELAY2 EQU 56H ; 用于延时计数
;******** BIT RAM (20~2F) flag defined ********
B _T1IF EQU
00H
; 定时器 1 溢出标记位
;==========================================================
;*********************************** PROGRAM *******************
ORG 0
LJMP INITIAL
ORG 1BH
LJMP TIMER1_INT ;T0 FOR IR
;******************************************************************
; ------------------------------- TIMER1_INT ---------------------
;******************************************************************
; 定时器 1 中断,中断周期: 50ms。读取一次计时器内容, 50ms 中断次数累加 器
TIMES_50MS 加 1
;50ms 中断溢出标记置 1
TIMER1_INT:
PUSH ACC
PUSH PSW
MOV TH1,#03CH
MOV TL1,#0AFH
MOV COUNTER_BUF_H,TH0
MOV COUNTER_BUF_L,TL0
CLR C
MOV A,TH0
CJNE A, COUNTER_BUF_H,INT1
SJMP INT2
INT1: MOV COUNTER_BUF_H,A
INT2:
INC TIMES_50MS
SETB B _T1IF ;50ms 中断溢出标记置 1
POP PSW
POP ACC
RETI
;******************************************************************
; ------------------------------- INITIAL -------------------------------------
;******************************************************************
INITIAL: MOV IE , #00H
MOV SP, #0E0H
MOV R0, #01H
CLR_RAM: MOV @R0, #00H ;clr RAM(01H~FFH)
INC R0
CJNE R0,#00H,CLR_RAM
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2, 0
MOV TMOD,#00010101B ; 设置 T0 十六位定时器,T1 十六位
计数器
MOV TH0, #00H
MOV TL0, #00H
MOV TH1, #03CH
MOV TL1, #0AFH ; 定时时间 50MS
SETB TR0
SETB TR1
CLR ET0
SETB ET1
SETB EA
SETB P153_A
SETB P153_B
CLR A
MOV FREQ_LOSS,A
;******************************************************************
; ------------------------------- MAIN -------------------------------------
;******************************************************************
MAIN: NOP
CALL DISPLAY0 ;LED 动态显示刷新
CALL DELAY100
JNB B _T1IF,MAIN ; 每 50ms 处理一次。
;======================================
CLR B _T1IF
MOV A,TIMES_50MS
CJNE A,#20,NO_1S
JMP YES_1S ; 满 20 次即为一秒钟
;=====================================
NO_1S:
MOV A,TIMES_50MS
CJNE A,#1,NO_1S_END ;TIMES_50MS 不为 1,返回
;当 TIMES_50MS 为 1 时,判断当前所选档位是否过高或者过低
; 若计数器 BUF 大于 100,则说明满 1 秒时必然大于 2000,则提前调高频率衰减档
位,
;并清零各计数值,重新在新档位测量
MOV A, COUNTER_BUF_H
JNZ NO_1S_1 ; 计数器高位不为 0,说明超 100
MOV A, COUNTER_BUF_L
CJNE A, #100,NO_1S_0
NO_1S_0:
JC NO_1S_LOW ; 计数器 BUF 小于 100,继续跳转 到
NO_1S_LOW 判断是否需要调低档位
NO_1S_1:
MOV A,FREQ_LOSS ; 超量程,判断当前频率衰减档位,若
小于 3 则加一档
CJNE A, #3,NO_1S_2
JMP NO_1S_END
NO_1S_2 : JC NO_1S_3
MOV A , #3
MOV FREQ_LOSS,A ; 档位大于 3,则修正为 3
NO_1S_3:
INC FREQ_LOSS ; 频率衰减档位加 1
MOV A, FREQ_LOSS
CJNE A, #1,NO_1S_4
SETB P153_B ; FREQ_LOSS=1
CLR P153_A
JMP NO_1S_20
NO_1S_4: CJNE A,#2,NO_1S_5
CLR P153_B ;FREQ_LOSS=2
SETB P153_A
JMP NO_1S_20
NO_1S_5:
CLR P153_B ;FREQ_LOSS=3
CLR P153_A
JMP NO_1S_20
;========================================
NO_1S_LOW:
MOV A, COUNTER_BUF_L
CJNE A, #10,NO_1S_10
NO_1S_10: JNC NO_1S_END ; 偏低,则判断是否需要降低频率衰
减档位
MOV A, FREQ_LOSS;
JZ NO_1S_END ; 已经是最低档,无需调整
DEC FREQ_LOSS ; 减一档
MOV A, FREQ_LOSS
CJNE A, #0, NO_1S_11
SETB P153_B ; FREQ_LOSS=0
SETB P153_A
JMP NO_1S_20
NO_1S_11: CJNE A,#1,NO_1S_12
SETB P153_B ; FREQ_LOSS=1
CLR P153_A
JMP NO_1S_20
NO_1S_12:
CLR P153_B ; FREQ_LOSS=2
SETB P153_A
JMP NO_1S_20
NO_1S_20: ; 调整档位后,重新计数
CLR A
MOV TIMES_50MS, A
MOV COUNTER_BUF_L, A
MOV COUNTER_BUF_H, A
NO_1S_END: JMP MAIN
;===================================
;===================================
YES_1S:
;把计数器的数转换成 10 进制,并根据当前档位设定好要显示的 6 个数字,
;存放在 DISPLAY_DATA1-DISPLAY_DATA6中。
;
MOV A, COUNTER_BUF_H
MOV R7,A
MOV A, COUNTER_BUF_L
MOV R6, A
CALL CHANGE16_10
;====================================
;在频率衰减控制下,计数器数据不会超出 2000 多少,因此只取转换后的低 4 位转
换成数据显示
MOV A , R3
ANL A, #0FH
MOV TEMP1, A
MOV A, R3
ANL A, #0F0H
SWAPA
MOV TEMP2, A
MOV A , R4
ANL A , #0FH
MOV TEMP3, A
MOV A, R4
ANL A, #0F0H
SWAPA
MOV TEMP4, A
;====================================
;根据频率衰减档位调整数位
MOV A,FREQ_LOSS
CJNE A,#0,LOSS_1
CLR A
MOV DATA4,A
MOV DATA5,A
JMP LOSS_END
LOSS_1:
CJNE A,#1,LOSS_2
MOV A,DATA3
MOV DATA4,A
MOV A,DATA2
MOV DATA3,A
MOV A,DATA1
MOV DATA2,A
MOV A,DATA0
MOV DATA1,A
CLR A
MOV DATA0,A
MOV DATA5,A
JMP LOSS_END
LOSS_2:
CJNE A,#2,LOSS_3
MOV A,DATA3
MOV DATA5,A
MOV A,DATA2
MOV DATA4,A
MOV A,DATA1
MOV DATA3,A
MOV A,DATA0
MOV DATA2,A
CLR A
MOV DATA0,A
MOV DATA1,A
JMP LOSS_END
LOSS_3:
MOV A, DATA2
MOV DATA5, A
MOV A, DATA1
MOV DATA4, A
MOV A ,DATA0
MOV DATA3, A
CLR A
MOV DATA0, A
MOV DATA1, A
MOV DATA2, A
LOSS_END:
;高位若为 0,则置为 11,取出显示代码为 LED 全灭
MOV R0,#DATA5 ; 取最高位数据地址
MOV R2, #5
LOOP_CLR:
MOV A,@R0
JNZ DISCD
MOV A, #11
MOV @R0, A
DEC R0
DJNZ R2, LOOP_CLR
;====================================
;取表找相应显示代码
DISCD:
MOV R0, #DATA_ADDR;
MOV R1, #DISPLAY_DATA_ADDR;
MOV R2, #6;
MOV DPTR, #TAB
DILP: MOV A,@R0
MOVC A,@A+DPTR
MOV @R1, A
INC R0
INC R1
DJNZ R2,DILP
;=======================================
;重新计数
CLR A
MOV TIMES_50MS, A
MOV COUNTER_BUF_L, A
MOV COUNTER_BUF_H, A
JMP MAIN
TAB: ;/ 显示码码表/
DB 3FH ,06H,5BH,4FH,66H;
DB 6DH ,7DH,07H,7FH,6FH,0FFH;
RETI
;***********************************************************************
*********
; ------------------------------- 显示子程序 ----------------------------------
;***********************************************************************
********
DISPLAY0:
MOV A,#0FFH
MOV PORT_LED,A ; 变换数据前先灭 LED,以消除闪动
MOV A,COUNTER_DISPLAY
MOV PORT_LED_138,A
MOV R1,#DISPLAY_DATA_ADDR
ADD A,#DISPLAY_DATA_ADDR ; 计算当前要显示数据的地址,初始地
址加相应位数
MOV R1,A
MOV A,@R1 ; 取出要显示的相应位的数据
MOV PORT_LED,A ; 送出显示数据
MOV A,COUNTER_DISPLAY
INC A
CJNE A,#6,DISPLAY1
DISPLAY1: JC DISPLAY2
CLR A
DISPLAY2: MOV COUNTER_DISPLAY,A ; 显示位加 1
RETI
;******************************************************************
; ------------------------------- DELAY----------------------------------
;******************************************************************
DELAY100:
MOV A,#2000
DELAY1:
JB B_T1IF,DELAY2
DEC A
JNZ DELAY1
DELAY2: RETI
;******************************************************************
; ------------------------------- 16 进制转 10 进制 ----------------------------
;******************************************************************
;双字节十六进制整数转换成双字节BCD码整数
;入口条件:待转换的双字节十六进制整数在 R6、R7 中。
;出口信息:转换后的三字节BCD码整数在 R3、R4、R5 中。
;影响资源:PSW、A、R2~R7 堆栈需求: 2字节
CHANGE16_10:
CLR A ; BCD码初始化
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#10H
; 转换双字节十六进制整数
CHANG_1:
MOV A,R7; 从高端移出待转换数的一位到 CY 中
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R5; BCD码带进位自身相加,相当于乘2
ADDC A,R5
DA A;十进制调整
MOV R5,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R3
ADDC A,R3
MOV R3,A ; 双字节十六进制数的万位数不超过6,不用调整
DJNZ R2, CHANG_1 ; 处理完16bit
RET
END
一周热门 更多>