AT89C51程序

用此单片机设计一个数字频率计的程序,跪求!

频率计———六位数码管显示 *
;喇叭接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码, *
;* 日期: 2007-3-25 *
;* 版本: 3.0 *
;* 作者: 深圳学林电子有限公司 专业8051单片机教学站 *
;* 邮箱: [email protected] *
;* 网站: http://www.51c51.com http://www.8951.com 更多例程请登陆网站 *
;********************************************************************************
;* 硬件:此程序在本公司xlisp系列单片机实验仪运行通过 *
;* 【版权】 Copyright(C)深圳学林电子有限公司 www.51c51.com All Rights Reserved *
;* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! *
;********************************************************************************
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 ;外部中断数据显示
CPL P1.4 ;取反 P1.4 获得外部脉冲
;我们利用它来进行中断计数操作
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 ;P3.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,#16 ;转化进制,如果要进行十进制转换 改为 10
DIV AB ;计算 A/B
MOV @R0,B ;第一位转换完毕,保存低位转化后的数据
INC R0 ;自增
MOV @R0,A ;保存高位
INC R0 ;取第二个数据地址
MOV A,T_M ;获得第二个需要转换的数据
MOV B,#16 ;十六进制
DIV AB ;计算
MOV @R0,B ;存低位
INC R0
MOV @R0,A ;存高位
INC R0 ;第三位
MOV A,T_H ;获得第三个需要转换的数据
MOV B,#16 ;十六进制
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 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 ;告诉编译器本程序到此结束。
温馨提示:答案为网友推荐,仅供参考