基于51单片机的数字频率计


      误差控制在了百分之三到百分之十,还是很大的,会随着采样时间的增加而减小,简要做了个误差处理,很粗糙,希望大神留言改进,谢谢。

软件设计的组成

      该系统由定时器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;s<x;s++)
		for(w=0;w<110;w++);
}


void zhamen1()//闸门时间加
	

	{
	   if(jia==0)
		 { while(jia!=1);
		    m=m+1;}
		 
  }
	void zhamen2()//闸门时间减
	{		
	if(jian==0)
		 {while(jian!=1);
			  m=m-1;}
	}

void iint()//初始化
 {
 flag=0;
 TMOD=0x15;//t1为定时器,t0为计数器模式
 TH1=(65536-4000*m)/256;//设初始值
 TL1=(65536-4000*m)%256;
 TH0=0;
 TL0=0;      
 EA=1; //允许中断
 ET0=1;//定时器0的中断允许
 ET1=1;//定时器1的中断允许
 TR1=1;//定时器1启动
 TR0=1;//定时器0启动
}
 void main()
{ 
loop:  if(s==0)//按键启动
         {
					delay2(10);
          while(s!=1);//按键松开
          a++;
         }
  if(a==1)
 {
   iint(); 
   while(1)
        { 
					if((m>7))//闸门时间范围从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++;
}
 

仿真图



猜你喜欢

转载自blog.csdn.net/qq_41168326/article/details/80949015