📄 file13.asm
字号:
;这是频率计的例子程序,包含:外部中断设置,中断服务程序,定时程序,定时服务程序
;以及数据处理,显示,包括 两位十进制数转化为三位BCD码,
;这里是一个高精度频率计的设计程序
;现象:数码管led1不断闪烁,同时,数码管显示当前计数的频率值!
;只要我们把p1.0(假想的信号源)和p3.2(外部中断0)直接相连,就可以在数码管看到频率值
beep bit p3.7
segdata equ p0 ;数据 输出
sege equ p2.7 ;显示 选中
segb equ p2.6 ;位 选
segd equ p2.5 ;段 选
timer_h equ 46h ;定时器高位字节单元
timer_l equ 47h ;定时器低位字节单元
timcount equ 48h ;时间中断数
count_h equ 49h ;计数值高位
count_l equ 4ah ;计数值低位
int_h equ 45h ;中断计数缓冲单元高地址
int_l equ 44h ;中断计数缓冲单元低地址
int_data equ 43h ;用来刷新LED指示的数据单元
t_h equ 60h ;数据显示的高位
t_s equ 61h ;数据显示中位
t_m equ 62h ;数据显示低位
disstart equ 70h ;显示单元首地址
flag equ 71h ;显示结果
org 00h ;代码开始地址
jmp main ;主程序开始
org 03h ;外部中断EX0入口地址
jmp ex_int0 ;中断服务程序
org 1bh
jmp timer_int ;定时器T1中断服务程序
org 030h
main:mov sp,#30h ; 设置sp指针
lcall pro_set ; 初始化
lcall pro_int0 ; 外部中断0工作初始化
lcall tim_t1 ; 定时器T1工作方式设定
mlp:lcall ex_pro ; 外部中断数据转换
lcall ex_display ; 外部中断数据显示
cpl p1.0 ; 取反 p1.0 获得外部脉冲
; 我们利用它来进行中断计数操作
jmp mlp
pro_set:mov a,#00h ;初始化程序
mov b,#00h
mov p1,0ffh ;p1 = 255 (十进制,写成十六进制 0FFH )
mov int_h,#00h
mov int_l,#00h
mov t_s,#00h
mov t_h,#00h
mov t_m,#00h
mov timcount,#20
mov timer_h,#3ch ;定时 50 ms
mov timer_l,#0c1h
mov count_l,#0
mov count_h,#0 ;
clr beep
ret
; ************** 定时器设置 ************************
tim_t1: mov tmod,#10h ;设置定时器,定时1s
setb et1 ;允许定时中断
mov th1,timer_h ;设置定时初值高位
mov tl1 ,timer_l ;设置定时初值低位
setb tr1 ;定时器开始工作
ret
; *********** 定时器中断服务程序 *******************
timer_int:
clr tr1 ;定时器中断服务,关闭定时器
mov tl1,timer_l ;重新赋初值
mov th1,timer_h
mov r0,timcount
djnz r0,t_end
mov timcount,#20 ;到1s
mov int_l,count_l ;刷新显示部分
mov int_h,count_h
mov count_l,#0
mov count_h,#0 ;
t_end:mov timcount,r0
setb tr1 ;重新开始定时操作
reti
; ***************** 外部中断服务程序 ****************
ex_int0:
inc count_l ;将中断缓冲区低地址加1
mov a,count_l ;判断是否有进位
jnz int_end ;没有则返回
inc count_h ;否则,将高地址加1
int_end: reti ;中断返回
;***********************************
;******* 设置中断 ****************
pro_int0:
clr c ;清进位标志
setb it0 ;设置中断触发方式:脉冲触发
setb ea ;总的中断允许
setb ex0 ;允许外部中断EX0中断
clr ex1 ;禁止外部中断EX1中断
ret ;返回
; **********************************
ex_display:
mov r0,#disstart ;获得显示单元首地址
mov r1,#01h ;从第一个数码管开始
mov r2,#06h ;共显示6位数码管
clr sege
dislp:mov segdata,@r0 ;读取显示单元数据
setb segd
nop
clr segd
inc r0 ;取下一个单元地址
mov segdata,r1 ;开始显示当前位
setb segb
nop
clr segb
mov a,r1 ;准备显示下一位
rl a ;
mov r1,a ;下一位
lcall delay5ms ;延时 5 ms
djnz r2,dislp ; 重复显示下一个
mov segdata,#0 ;不显示
setb segb
nop
clr segb
ret ;显示完成,返回
;ex_pro 数据处理,主要为 bcd码转换,查表
ex_pro: clr ea
setb psw.3 ;准备 寄存器
clr psw.4 ;
mov r6,int_h ;得到高位数据
mov r7,int_l ;得到低位数据
mov r0,#disstart ;开始填充显示单元
mov a,r7 ;获得低3位数据
mov b,#10 ;变换的原理是如果a=0xff(十六进制)
div ab ;那么就相当于255(十进制),每次除以10取余数就可以分开成三个2,5,5
mov r5,b ;保存第一位(个位)
mov b,#10
div ab
mov r4,b ;十位
mov r3,a ;百位
mov a,r5
mov @r0,a
inc r0
mov a,r4
mov @r0,a
inc r0
mov a,r3
mov @r0,a
inc r0
;//////////////////////////////////////////
mov a,r6 ;获得高3位数据
mov b,#10
div ab
mov r5,b ;保存第一位(个位)
mov b,#10
div ab
mov r4,b ;十位
mov r3,a ;百位
mov a,r5
mov @r0,a
inc r0
mov a,r4
mov @r0,a
inc r0
mov a,r3
mov @r0,a
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 ;继续转换,直到完成
setb ea
ret ;转换完成,返回
;************ 250 ms 延时(粗略) ******************8
delay:push psw ; 保存原来的寄存器单元
clr psw.3 ; 设置新的寄存器
setb psw.4 ;
mov r0,#2 ; 延时参数1
mov r1,#250 ; 延时参数2
mov r2,#2 ; 延时参数3
dl1:djnz r0,dl1 ; 延时循环1
mov r0,#250 ; 重新设置循环数据
dl2:djnz r1,dl1 ; 开始第二道循环
mov r0,#240 ;
mov r1,#248 ;
dl3:djnz r2,dl1 ; 第三道循环
nop ; 修正定时精度
pop psw ; 恢复原来的寄存器组
ret ; 返回
; ***********************************************
;************** 定时 5ms ************
delay5ms: ;参见上面说明
push psw
clr psw.3
setb psw.4
mov r0,#250
mov r1,#3
d20:djnz r0,d20
mov r0,#250
djnz r1,d20
pop psw
ret
; ****************************************
;这是数字显示表格,其中 带小数点的数字比不带小数点的数字大16
; 比如 0 的显示代码为 0;那么 0.的显示代码为 16;如此类推
tab_nu: db 0c0h,0f9h, 0a4h, 0b0h, 99h , 92h , 82h, 0f8h ; number 0 to 7 no dp..
db 80h , 90h, 88h , 83h , 0c6h, 0a1h, 86h, 8eh ; number 8 to f no dp..
db 40h , 79h, 24h , 30h , 19h , 12h , 02h, 78h ; number 0 to 7 with dp..
db 00h , 10h, 08h , 03h , 46h , 21h , 06h, 0eh ; number 8 to f with dp..
end ;告诉编译器本程序到此结束,一定需要加上,否则编译通不过。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -