51单片机的数字频率计

51单片机的数字频率计,第1张

该系统由定时器0中断子函数、定时器1中断子函数、延时子函数、按键消抖子函数、闸门控制子函数、主函数和数据定义这几部分组成。

      闸门时间由定时器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 告诉编译器本程序到此结束。

-----------------------------------------------------------------


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12537721.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存