声明:由青岛理工大学建电16级某同学上传,请同班同学注意不要雷同
误差控制在了百分之三到百分之十,还是很大的,会随着采样时间的增加而减小,简要做了个误差处理,很粗糙,希望大神留言改进,谢谢。
该系统由定时器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,
0xc6,0xa1,0x86,0x8e};
void delay1(int z)//延时子程序
{
int q,w;
for(q=z;q>0;q--)
for(w=110;w>0;w--);
}
void delay2(uint x)//按键消抖
{
uint s;
uchar w;
for(s=0;s7))//闸门时间范围从2s到7秒,并且循环
m=2;
if(m<2)
m=7;
zhamen1();
zhamen2();
if(t1==250)//定时器1计时时间=250*0.004*m
{
t1=0;
EA=0;//中断关闭
TR0=0;//定时器0关闭
flag=1;//标签标志置位
}
// if((m>7))//闸门时间范围从2s到7秒,并且循环
// m=2;
// if(m<2)
// m=7;
// zhamen1();
// zhamen2();
if(m==2)
n=m*1.49999994;
if(m==3||m==4)//根据不同的闸门时间减小误差
n=m*1.08;
if(m==5||m==6||m==7)
n=m*1.08;
daimao=(TH0*256+TL0+t0*65536)/n;//计算频率
daimao=daimao%100000;//赋值
s2=daimao/10000;
daimao=daimao%10000;
s3=daimao/1000;
daimao=daimao%1000;
s4=daimao/100;//赋值
daimao=daimao%100;
s5=daimao/10;
daimao=daimao%10;
s6=daimao%10;
if(flag==1)//动态扫描数码管显示
{
P2=0;//全灭
w1=1;//w1控制的灯亮
P0=table1[m];//通过闸门时间数组选择数字
delay1(shu);//延时1ms
P2=0;
w2=1;
P0=table1[s2];//通过频率数组选择数字
delay1(shu);
P2=0;
w3=1;
P0=table1[s3];
delay1(shu);
P2=0;
w4=1;
P0=table1[s4];
delay1(shu);
P2=0;
w5=1;
P0=table1[s5];
delay1(shu);
P2=0;
w6=1;
P0=table1[s6];
delay1(shu);
daimao=0;
if(s==0)//二次启动
{
delay2(10);
while(s!=0);
a++;
}
if(a==2)
{
a=0;
goto loop;
}
}
}
}
}
void timer0() interrupt 1//定时器0初始化
{
TH0=0x00;
TL0=0x00;
t0++;
}
void timer1() interrupt 3//定时器1初始化
{
TH1=(65536-4000*m)/256;
TL1=(65536-4000*m)%256;
t1++;
}
仿真图