闸门时间由定时器1控制,初始为2s,可以通过按键加减,范围为2s到7秒。闸门时间就是采样时间,闸门时间越长,测量精度越准确。
由P3.4输入信号,低电平有效,触发T0外部中断。当T0触衡森发中断的时候执行的程序。这里只进行了一个 *** 作,t0++。所以,t0的值表示触发了几次中断,也就表示接受到的脉冲几次从0到65536。所以会有t0*65536。 另外,由于计时的机制是THO++、TL0++,所以,吵坦THOTL0就表示当前的计数值。THOTLO- 初值就可以确定没有触发中断定时多少。TH0*256==TH0*2^8,实质就是左移8位,就是拼接TH0跟TL0的处理。
所以频率的核心算法为
daimao=(t0*65536+TH0*256+TL0)/n
程序框图
总源程序
#include "reg52.h"
#define uchar unsigned char
typedef unsigned int uint
sbit w1=P2^0
sbit w2=P2^1
sbit w3=P2^2
sbit w4=P2^3
sbit w5=P2^4
sbit w6=P2^5
sbit jia=P1^6
sbit jian=P1^7
sbit s=P3^7//启动
bit flag//标签
uchar s1,s2,s3,s4,s5,s6, shu=1//控制数组取值升拦桐
uchar t0,t1,t2,a
unsigned long m=5,n//m为闸门时间
int y
unsigned long daimao//频率
unsigned char code table1[]={0xc0,0xf9,0xa4,0xb0, //闸门时间数组0-f
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e}
unsigned char code table2[]={0xc0,0xf9,0xa4,0xb0, //频率数组0-f
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
********************************************************************
* ME300B单片机开发系统演示程序-1602LCD显示数字频率计 *
**
* 邮箱: gguoqing@willar.com *
* 网站: http://www.willar.com *
* 作者: gguoqing*
* 时间: 2006/06/03 *
**
*【版权】COPYRIGHT(C)伟纳电子 www.willar.com ALL RIGHTS RESERVED *
*【声明】此程序仅用于学习与参考,引用请注明版权和作者信并前息! *
**
******************************************************************
------------------------------------------------------------
频率计的程序
包含:外部中断设置,中断服务程序,定时程序,定时服务程序
以及数据处理,显示,包括 三位十进制数转化为四位BCD码,
------------------------------------------------------------
BEEPBIT P3.7
LCD_RS BIT P2.0
LCD_RW BIT P2.1
LCD_EN BIT P2.2
LCD_X EQU 3FHLCD 地址变量
TIMER_H EQU 30H定时器高位字节单元
TIMER_L EQU 31H定时器低位字节单元
TIMCOUNT EQU 32H时间中断数
INT_G EQU 35H中断计数空蔽做缓冲单元高地址
INT_H EQU 34H中断计数缓冲单元中地址
INT_L EQU 33H中断计数缓冲单元低地址
T_S EQU 36H数据显示低位
T_M EQU 37H数据显示中位
T_H EQU 38H数据显示高位
T_G EQU 39H数据显示最高位
----------------------------------------------------------
ORG 0000H
JMP MAIN主程序开始斗衡
ORG 000BH
JMP TIMER_INT定时器T0中断服务程序
ORG 001BH 定时器T1中断服务程序
JMP TIMER1
ORG 0030H
----------------------------------------------------------
MAIN:
MOV SP,#60H 设置SP指针
LCALL PRO_SET 初始化
CALL SET_LCD
LCALL TIM_T0
-----------------------------------------------------------
LCD1602是慢速显示器件,故100MS显示一次。
-----------------------------------------------------------
MAIN1:
MOV R5,40
MAIN2:
ACALL DELAY13ms
DJNZ R5,MAIN2
ACALL SBIN_SBCD
CALL CONV
JMP MAIN1
------------------------------------------------------------
T1计数器中断服务子程序
计T1计数器溢出次数
------------------------------------------------------------
TIMER1:
INC 2AH
RETI
------------------------------------------------------------
初始化程序
------------------------------------------------------------
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,#04CH 定时 50 MS
MOV TIMER_L,#10H
CLR BEEP
SETB P3.5P3.5端口置输入状态
RET T1(TIMER1的外部输入脚)
-----------------------------------------------------
LCD 初始化设置
-----------------------------------------------------
SET_LCD:
CLR LCD_EN
CALL INIT_LCD 初始化 LCD
CALL DELAY1
MOV DPTR,#INFO1 指针指到显示信息1
MOV A,#1 显示在第一行
CALL LCD_SHOW
MOV DPTR,#INFO2 指针指到显示信息2
MOV A,#2 显示在第二行
CALL LCD_SHOW
RET
-----------------------------------------------------
INFO1: DB "CYMOMETER ",0 LCD 第一行显示信息
INFO2: DB "FREQ:HZ ",0 LCD 第二行显示信息
-----------------------------------------------------
LCD 接口初始化
8位I/O控制
-----------------------------------------------------
INIT_LCD:
MOV A,#38H 双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#38H 双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#38H 双列显示,字形5*7点阵
CALL WCOM
CALL DELAY1
MOV A,#0CH 开显示,关光标,
CALL WCOM
CALL DELAY1
MOV A,#01H 清除 LCD 显示屏
CALL WCOM
CALL DELAY1
RET
----------------------------------------------------
LCD_SHOW: 在LCD的第一行或第二行显示信息字符
CJNE A,#1,LINE2 判断是否为第一行
LINE1: MOV A,#80H 设置 LCD 的第一行地址
CALL WCOM写入命令
CALL CLR_LINE清除该行字符数据
MOV A,#80H 设置 LCD 的第一行地址
CALL WCOM写入命令
JMP FILL
LINE2: MOV A,#0C0H 设置 LCD 的第二行地址
CALL WCOM写入命令
CALL CLR_LINE清除该行字符数据
MOV A,#0C0H 设置 LCD 的第二行地址
CALL WCOM
FILL: CLR A填入字符
MOVC A,@A+DPTR 由消息区取出字符
CJNE A,#0,LC1判断是否为结束码
RET
LC1:CALL WDATA 写入数据
INC DPTR 指针加1
JMP FILL 继续填入字符
RET
---------------------------------------------------
CLR_LINE: 清除该行 LCD 的字符
MOV R0,#24
CL1: MOV A,#' '
CALL WDATA
DJNZ R0,CL1
RET
-----------------------------------------------------
写指令、数据使能子程序
-----------------------------------------------------
ENABLE:写指令使能
CLR LCD_RS RS=L,LCD_RW=L,D0-D7=指令码,E=高脉冲
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
ENABLE1: 写数据使能
SETB LCD_RSRS=H,RW=L,D0-D7=数据,E=高脉冲
CLR LCD_RW
SETB LCD_EN
CALL DELAY0
CLR LCD_EN
RET
DELAY0: MOV R7,#250 延时500微秒
DJNZ R7,$
RET
----------------------------------------------------
写入命令子程序
----------------------------------------------------
WCOM: 以8位控制方式将命令写至LCD
MOV P0,A 写入命令
CALL ENABLE
RET
----------------------------------------------------
写入数据子程序
----------------------------------------------------
WDATA:以8位控制方式将数据写至LCD
MOV P0,A 写入数据
CALL ENABLE1
RET
---------------------------------------------------
在 LCD 第二行显示字符
A=ASC DATA, B=LINE X POS
---------------------------------------------------
LCDP2:在LCD的第二行显示字符
PUSH ACC
MOV A,B 设置显示地址
ADD A,#0C0H 设置LCD的第二行地址
CALL WCOM 写入命令
POP ACC 由堆栈取出A
CALL WDATA 写入数据
RET
-------------------------------------------------------
ASCII 转换并在第二行显示数字子程序
-------------------------------------------------------
CONV:MOV A,T_G
MOV LCD_X,#6 设置位置
CALL SHOW_DIG2
MOV A,T_H
INC LCD_X 加载小时数据
CALL SHOW_DIG2显示数据
MOV A,T_M 加载分钟数据
INC LCD_X 设置位置
CALL SHOW_DIG2显示数据
MOV A,T_S加载秒数数据
INC LCD_X 设置位置
CALL SHOW_DIG2显示数据
RET
----------------------------------------------------
SHOW_DIG2:
MOV B,#16
DIV AB
ADD A,#30H
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
MOV A,B
ADD A,#30H
INC LCD_X
MOV B,LCD_X
CALL LCDP2
RET
-----------------------------------------------------
DELAY1:延时3MS
MOV R6,#15
D2:MOV R7,#100
DJNZ R7,$
DJNZ R6,D2
RET
----------------- 定时器设置 ------------------------
设置定时器0工作在定时方式1,定时器1工作在计数方式1
---------------------------------------------------------
TIM_T0: MOV TMOD,#0D1H
MOV TH0,TIMER_H设置定时初值高位
MOV TL0,TIMER_L设置定时初值低位
MOV TH1,#00H 清T1计数器
MOV TL1,#00H
MOV IE,#8AH 开中断总允许,允许T0溢出中断
SETB PT1
SETB TR1
SETB TR0 定时器开始工作
RET
--------------------------------------------------------
定时器0中断服务程序
--------------------------------------------------------
TIMER_INT:
CLR TR0 关闭定时器
MOV TL0,TIMER_L 重新赋初值
MOV TH0,TIMER_H
INC TIMCOUNT定时1S,时间单位
MOV A,TIMCOUNT 查看数量值
CPL P1.4 产生自测信号
CJNE A,#20,T_END如果没有到1S返回
CLR TR1关闭计数器T1
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
---------------------------------------------------------------
三字节二进制整数转换成四字节BCD码子程序
二进制数从低位到高位分别存放在INT_L、INT_H、INT_G单元中
BCD码从低位到高位分别存放在T_S、T_M、T_H、T_G 单元中
---------------------------------------------------------------
SBIN_SBCD:
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 R5,INT_G
MOV R7,INT_L设置二进制数起始地址
MOV R6,INT_H
MOV R2,#24
CLR C
HH1:
MOV A,R7
RLC A
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 累加
DA A
MOV T_G,A
DJNZ R2,HH1
POP PSW
RET
----------------------------------------------------------------
END 告诉编译器本程序到此结束。
-----------------------------------------------------------------
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)