#include "reg51.h"
#define uchar unsigned char
uchar disp[8]={0,0,0,0,0,0,0,0}
uchar T0count,T1count
void delay(void)
{
uchar i
for(i=250i>0i--)
}
void display()
{
//uchar i,j,k=0x80
uchar dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
uchar i,k
k=0x80
for(i=0i<8i++)
{
P2=0
P0=dispcode[disp[i]]
P0=~P0
P2=k
k=k>>1
delay()
}
P2=0
}
void calc()
{
uchar i
long frequency
frequency=(T0count*256+TH0)*256+TL0
for(i=7i>0i--)
{
disp[i]=frequency%10
frequency=frequency/10
}
disp[0]=frequency
}
void init()
{
T0count=0
T1count=0
TH0=0
TL0=0
}
void main()
{
init()
TMOD=0x15
TH1=(65536-5*110592/12)/256
TL1=(65536-5*110592/12)/256%10
ET1=1
ET0=1
EA=1
TR1=1
TR0=1
//以下四句的作用是在P1.0引脚上形成1000Hz的脉冲,用导线连接到P3.4作为测试用,如果是AT89S51,则四句不用。将其中
//高8位和低8位的初始值更改后可输出不同频率的脉冲。
/*
T2MOD=0x2
RCAP2H=245
RCAP2L=74
TR2=1
*/
while(1)
{
display()
}
}
void time0() interrupt 1
{
T0count++
}
void time1() interrupt 3
{
TH1=(65536-5*110592/12)/256
TL1=(65536-5*110592/12)/256%10
if(T1count==19)
{
calc()
init()
}
else T1count++
}
这里有一个四位数码管的频率计,供参考
#include <reg52.h>#define uchar unsigned char
#define uint unsigned int
uchar duan[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90} //所需的段的位码
//uchar wei[4]={0XEf,0XDf,0XBf,0X7f} //位的控制端 (开发板)
uchar wei[4]={0X80,0X40,0X20,0X10} //位的控制端 (仿真)
uint z,x,c,v, date //定义数据类型
uint dispcount=0
uint lck=0
uint disp=0
/******************************************************************
延时函数
******************************************************************/
void delay(uchar t)
{
uchar i,j
for(i=0i<ti++)
{
for(j=13j>0j--)
{
}
}
}
/**********************************************************************
数码管动态扫描
*********************************************************************/
void xianshi()
{
/*****************数据转换*****************************/
z=date/1000 //求千位
x=date%1000/100 //求百位
c=date%100/10 //求十位
v=date%10 //求个位
P2=wei[0]
P0=duan[z]
delay(50)
P2=wei[1]
P0=duan[x]
delay(50)
P2=wei[2]
P0=duan[c]
delay(50)
P2=wei[3]
P0=duan[v]
delay(50)
}
/*************************************************************************
定时器初值1ms
**************************************************************************/
void initTimer(void)
{
TMOD=0x0
TH0=0xe3
TL0=0xc
}
/*************************************************************************
定时器函数
**************************************************************************/
void timer0(void) interrupt 1
{
TH0=0xe3
TL0=0xc
lck++
if(lck==1000)
{
disp=dispcount
lck=0
dispcount=0
}
}
/*************************************************************************
中断函数
**************************************************************************/
void int0(void) interrupt 0
{
dispcount++ //每一次中断,计数加一
}
/*************************************************************************
主函数
**************************************************************************/
void main(void)
{
IT0=1 //INT0下降沿中断
EX0=1 //允许INT1中断
initTimer() //装入初值
TR0=1
ET0=1
EA=1
while(1)
{
date=disp
xianshi()
}
}
定时器1对外部脉冲计数时TMOD高4位设置应该是5
因此TMOD=0x51
以下我的频率计程序:
#include <reg52.h>//因没用到STC12C5410专有特殊功能寄存器,此处用52或51的头文件均可
#define unit unsigned int
#define uchar unsigned char
//定义以I/O口的功能
sbit beiguang=P3^2//液晶屏背光
sbit rs=P1^3//液晶屏写选择,0命令 1数据
sbit rw=P1^4//液晶屏读写选择
sbit lcden=P1^5//液晶屏使能
sbit fm=P1^7//蜂鸣器
#define db P2 //定义P2为数据输出口,写数据时用db代替P2,增加液晶屏程序的通用性
//更改硬件接线时,只更改此处,而不必去更改液晶屏读写子程序
uchar aa,bb,cc//变量声明
unit dd,ee
void Delay1ms(unsigned int i) //1ms延时程序
{
unsigned int j
for(i>0i--)
{
for(j=0j<125j++)
{}
}
}
void init()//初始化设置
{
TMOD=0x15//定时器0作为计数器,定时器1作为定时器用
TH0=0//计数器清0
TL0=0
EA=1//开总中断
ET1=1//允许定时器1中断
TH1=0x4c
TL1=0x5c
TR0=1//启动计数器
TR1=1//启动定时器
aa=0
}
void write_com(uchar com)//向液晶屏写命令
{
db=com
rs=0
rw = 0
lcden=0
Delay1ms(10*12)
lcden=1
Delay1ms(10*12)
lcden=0
}
void write_date(uchar date)//向液晶屏写数据
{
db=date
rs=1
rw = 0
lcden=0
Delay1ms(10*12)
lcden=1
Delay1ms(10*12)
lcden=0
}
void init2()//液晶屏初始化
{
beiguang=0
rw=0
write_com(0x38)
Delay1ms(10*12)
write_com(0x0f)
Delay1ms(10*12)
write_com(0x06)
Delay1ms(10*12)
write_com(0x01)
Delay1ms(10*12)
}
void display4(unsigned int number) //单行多位显示程序
{
uchar A1,A2,A3,A4,A5
init2()//液晶屏初始化
A1=number/10000%10//分离出万,千,百,十,个,对于int型数据,最大不超过65535
A2=number/1000%10
A3=number/100%10
A4=number/10%10
A5=number%10
write_com(0x80)//第1个数据的位置设定,第1行第1列
Delay1ms(10)
write_date(0x30+A1)//写数据
Delay1ms(10)
write_date(0x30+A2)
Delay1ms(10)
write_date(0x30+A3)
Delay1ms(10)
write_date(0x30+A4)
Delay1ms(10)
write_date(0x30+A5)
Delay1ms(10)
write_com(0x87)//第6个数据'H'的位置,中间空85和86 二格
write_date('H')
Delay1ms(10)
write_date('z')
Delay1ms(10)
}
void main()//主程序很简单
{
init()//初始化
while(1)//循环程序
{
dd=bb*256+cc//0.5S的计数值
ee=2*dd//换算为1秒钟的计数值
if(aa==1)
{
if(TH0>12)//预判断,50ms内TH0>12,1s内计数值将超过可计数的最大值65535
fm=0//报警
}
display4(ee)//显示
fm=1//报警停止
}
}
void timer1()interrupt 3//注意:定时器1的中断序号为3
{
aa++
TH1=0x4c//11.0592Mhz
TL1=0x5c
if(aa==10)//中断10次,共0.5S
{
TR0=0//暂停计数
aa=0
bb=TH0//读出计数器数据
cc=TL0
TL0=0//计数器清0
TH0=0
TR0=1//重新启动
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)