|
仿真数字频率计时1khz以下正常显示,超过1khz数码管显示就出现闪烁。这是怎么回事?
#include <reg51.H> // 包含头文件
unsigned char code dispbit[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//定义数码管位选码
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40}; //定义数码管段码
unsigned char dispbuf[8]={0,0,0,0,0,0,0,0};//显示数码组,因为只用了六个数码管,所以将最后两位赋值为10,对应的段码为0x00,表示不亮。
unsigned char temp[8];//暂存数组
unsigned char dispcount;//扫描位的记录
unsigned char T0count;//计数次数
unsigned char timecount;//定时器5ms中断的次数
bit flag; //定义标志位
unsigned long x; //定义变量用来存放频率值
void main(void) //主函数
{
unsigned char i;//定义变量
TMOD=0x15; //设置定时工作模式 T1为定时1模式,T0为计数器1模式
TH0=0; // 计数器高8位赋值为0
TL0=0;// 计数器低8位赋值为0 所以最大可以输入65535
TH1=(65536-5000)/256;// 定时器1高8位赋初值
TL1=(65536-5000)%256;// 定时器1低8位赋初值
TR1=1;//启动定时器1
TR0=1;// 启动计数器0
ET0=1;//开启定时器0中断
ET1=1;// 开启定时器1中断
EA=1;//开启总中断
while(1)// 大循环
{
if(flag==1)// 如果定时时间到1s
{
flag=0;// 标志位清零
x=T0count*65536+TH0*256+TL0;//获得整数的频率值,T0count计数器在1s内溢出的次数,每溢出一次就
//就计数了T0count*65536次,再加上当前计数寄存器的值即为实际计数总数
for(i=0;i<8;i++) //
{
temp[i]=0; // 暂存缓冲区清零
}
i=0; //
while(x/10) //将频率值的每一位分离出来,存进temp数组,例如63239分离为6、3、2、3、9
{
temp[i]=x%10;//
x=x/10;//
i++;//
}
temp[i]=x;//
for(i=0;i<6;i++)//
{
dispbuf[i]=temp[i];//将暂存数组的数据赋给显示数组
}
timecount=0;//计时清零
T0count=0;//计数清零
TH0=0;// 计数器初值清零
TL0=0;// 计数器初值清零
TR0=1;// 重启计数器
}
}
}
void t0(void) interrupt 1 using 0 // 计数器中断
{
T0count++;//
}
void t1(void) interrupt 3 using 0 // 定时器中断4ms中断一次
{
TH1=(65536-5000)/256;// 定时器高8位赋初值
TL1=(65536-5000)%256; // 定时器低8位赋初值
timecount++;// 时间变量++
if(timecount==200)// 判断中断250次为1s
{
TR0=0;// 关闭计数器0
timecount=0;//清零重新计数中断次数
flag=1;// 标志位置1通知主程序1s已到
}
//因为放在该中断程序中,故4秒扫描一次数码管
P2=0xff;//先关闭所有数码管 //
// P2=dispbit[dispcount];//送入位码
P0=dispcode[dispbuf[dispcount]];// 先确定相应数码管的段码,送入段码
P2=dispbit[dispcount];//送入位码
dispcount++;// 下一次应该扫描下一位数码管所以要加一
if(dispcount==8)//因为只有8只数码管,判断是否送入8次。
{
dispcount=0;// 使变量清零
}
}
|
|