//********************************************************************
//频率计程序,计数9999Hz,大于显示"E "
//p3.5计数输入
//laosong 2007.5.3.pm 在mcs51u实验板测试通过
#include <reg51.h>
sbit dat=P1^0; //定义驱动74595的数据脚为p1.0
sbit clk=P1^1; //74595的时钟
sbit lat=P1^2; //栓锁
sbit gw=P1^3; //个位显示控制脚
sbit sw=P1^4; //十位
sbit bw=P3^3; //百位
sbit qw=P3^4; //千位
unsigned char msec; //闸门
union{
unsigned char c[2];
unsigned int i;
}Freq;
//------字表------------------------------
unsigned char code tab[]=
{ 0x3F,0x06,0x5B,0x4F, //"0","1","2","3"
0x66,0x6D,0x7D,0x07, //"4","5","6","7"
0x7F,0x6F,0x77,0x7c, //"8","9","A","B"
0x39,0x5e,0x79,0x71, //"C","D","E","F"
0x00, //" "
} ;
//----初始化------------------------------
void Init(void)
{
TMOD=0x51; //T1=16位外部计数器,T0=定时方式1
TH1=TL1=0; //计数器清0
TH0=0x3C;TL0=0xB0; //12.0000MHz@50mS
ET0=1;
}
//------闸门中断--------------------------
void Timer0(void) interrupt 1
{ TH0=0x3C;TL0=0xB0; //12.0000MHz@50mS
msec++; //50mS +1
if (msec>=20) //1秒闸门
{
TR1=0; //停止计数
EA=0;
Freq.c[0]=TH1;
Freq.c[1]=TL1;
TH1=TL1=0;
TH0=0x3C;TL0=0xB0;
msec=0; //开始下次计数
EA=1;
TR1=1; //开始计数
}
}
//------显示延时--------------------------
ds1ms()
{
unsigned char d;
for(d=0;d<250;d++); //大约1ms@12M
}
//------送出循环-------------------------
dsout(unsigned char j)
{
unsigned char i;
for(i=0;i<8;i++)
{
dat=j&0x80; //高位在前
clk=1;
clk=0;
j<<=1;
}
lat=1;
lat=0; //锁存
}
//----74HC595显示程序--------------------
display(unsigned char sjqw,sjbw,sjsw,sjgw)
{
dsout(tab[sjgw]);gw=0;ds1ms();gw=1; //查表得到数据段码送显示
dsout(tab[sjsw]);sw=0;ds1ms();sw=1;
dsout(tab[sjbw]);bw=0;ds1ms();bw=1;
dsout(tab[sjqw]);qw=0;ds1ms();qw=1;
}
//---------------------------------------
main()
{
unsigned int t;
unsigned char qwb,bwb,swb,gwb; //结果
Init();
EA=1; //允许闸门中断
TR0=1; //开计时闸门
TR1=1; //开始计数
while(1)
{
qwb=Freq.i/1000; //得到千位
t=Freq.i%1000; //取余
bwb=t/100; //得到百位
t=t%100;
swb=t/10; //得到十位
gwb=t%10; //得到个位
if(qwb>9) //如果千位大于9
{
qwb=0x0e;bwb=0x10;swb=0x10,gwb=0x10; //显示E,报错
}
display(qwb,bwb,swb,gwb);//显示
}
}