在做一个频率计,有个地方不知道怎么回事,想请问大家一下谢谢
但是void display()里面num一乘以double型变量就显示出错了,强制转换(uint)(num*x)类型也没用,还是显示不对。请问该怎么改?
//四位方波频率计
#include<reg52.h>
sbit dula=P2^6;
sbit wela=P2^7;
#define uint unsigned int
#define uchar unsigned char
uint num,a,b,c,d,k;//num作为一个全局变量//a b c d是千位到个位
//double num;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
/*函数声明*/
void delay(uint);
void display();
uint read1();
/*主函数*/
void main()
{
TMOD=0x15; //0001 0101 定时器1,计数器0
TH1=(65536-45872)/256; //11.0592MHZ下装入45872才是50ms
TL1=(65536-45872)%256;
TH0=0;
TL0=0; //要用1个计数器,1个定时器
ET1=1;
EA=1;
TR0=1;
TR1=1;
while(1);
}
/*定时1s函数*/
void timer0() interrupt 3
{
TR1=0;
TH1=(65536-45872)/256;
TL1=(65536-45872)%256;
k++;
if(k==20)
{
num=read1(); //num是计数个数
display();
k=0;
TH0=0;
TL0=0;
}
TR1=1;
}
/*前4位数码管显示函数*/
void display()
{
uint i;
for(i=100;i>0;i--)
{
num=(num*1); //在此处num乘以修正系数,不修正时NUM乘1
a=(num/1000);
b=((num%1000)/100);
c=(((num%1000)%100)/10);
d=(((num%1000)%100)%10);
dula=1; //千位
P0=table[a];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;//1111 10
wela=0;
delay(5);
dula=1; //百位
P0=table[b];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;//1111 01
wela=0;
delay(5);
dula=1; //十位
P0=table[c];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;//1110 11
wela=0;
delay(5);
dula=1; //个位
P0=table[d];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;//1101 11
wela=0;
delay(5);
wela=1;
P0=0xff;//1101 11
wela=0;
delay(5);
}
}
uint read1() //读计数器1的值
{
uint t1_1,th1_1,th2_1;
uint val_1;
while(1)
{
th1_1=TH0;
t1_1=TL0;
th2_1=TH0;
if(th1_1==th2_1)
break;
}
val_1=th1_1*256+t1_1;
return val_1;
}
/*延时函数*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
你算一个数的具体位数是多少没有算对,所以才显示不对
你这个程序好神奇,都没看到你从哪个IO口检测方波,寄存器比较一下就可以测出方波频率!
正常是使用定时器的外部中断,方波加到中断IO口,利用下降沿触发中断,记下触发时的定时器值;然后根据相邻2次的定时器值相减,得到方波的频率。
如果是较低频率的,定时器一个周期记不下的,还要添加定时器溢出中断的次数。
我是用一个单片机发出方波,从P2.0口输入到频率计P3.4口,这个口是单片机内部已经定义好做计数器外部输入的,所以程序里面没有写出来,直接连一根杜邦线就可以了。我现在就想把num乘以一个浮点数后再拿去数码管显示,不然误差太大,但是一乘之后最后显示出来的数就不断地在变,不知道怎么改
谢谢,现在这个错误已经改过来了
正在改进中,完全做好后会再把代码发在此贴
//四位方波频率计 ,初学者,做得比较粗糙,精确的应该用FPGA来做
//由于是拿郭天祥C51单片机做的,段选P2.6位选,P2.7,6位数码管,选前四位显示频率。外部方波输入是P3.4口
//由于51单片机机器周期比较长,所以在测频率的时候会产生误差,而且待测频率越大,误差越大。测1000HZ以内时误差可稳定在1%100以内。测很高频率时候请自行乘以修正函数。我下面程序里面没有写,乘完之后显示的频率误差会小很多。
#include<reg52.h>
sbit dula=P2^6;
sbit wela=P2^7;
#define uint unsigned int
#define uchar unsigned char
double num,a,b,c,d,k;//num作为一个全局变量//a b c d是千位到个位
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
/*函数声明*/
void delay(uint);
void display();
uint read1();
/*主函数*/
void main()
{
TMOD=0x15; //0001 0101 定时器1,计数器0
TH1=(65536-45872)/256; //11.0592MHZ下装入45872才是50ms
TL1=(65536-45872)%256;
TH0=0;
TL0=0; //要用1个计数器,1个定时器
ET1=1;
EA=1;
TR0=1;
TR1=1;
while(1);
}
/*定时1s函数*/
void timer0() interrupt 3
{
TR1=0;
TH1=(65536-45872)/256;
TL1=(65536-45872)%256;
k++;
if(k==20)
{
num=read1(); //num是计数个数
display();
k=0;
TH0=0;
TL0=0;
}
TR1=1;
}
/*前4位数码管显示函数*/
void display()
{
uint i;
if(num<=200) num=num*1+num*(0.001);
if(num>200&&num<=500) num=num*1+num*(0.003); //在此处num乘以修正系数
if(num>500&&num<=1000) num=num*1+num*(0.008);
for(i=100;i>0;i--)
{
a=((uint)num/1000);
b=((uint)((uint)((uint)num%1000))/100);
c=((uint)((uint)((uint)num%1000)%100)/10);
d=((uint)((uint)((uint)num%1000)%100)%10);
dula=1; //千位
P0=table[(uint)a];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;//1111 10
wela=0;
delay(5);
dula=1; //百位
P0=table[(uint)b];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;//1111 01
wela=0;
delay(5);
dula=1; //十位
P0=table[(uint)c];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;//1110 11
wela=0;
delay(5);
dula=1; //个位
P0=table[(uint)d];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;//1101 11
wela=0;
delay(5);
wela=1;
P0=0xff;//1101 11
wela=0;
delay(5);
}
}
uint read1() //读计数器1的值
{
uint t1_1,th1_1,th2_1;
uint val_1;
while(1)
{
th1_1=TH0;
t1_1=TL0;
th2_1=TH0;
if(th1_1==th2_1)
break;
}
val_1=th1_1*256+t1_1;
return val_1;
}
/*延时函数*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
你这个补偿方法不可取,测不准是程序不对
谢谢。