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

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

(仿真+程序+原理图+PCB+设计报告)

功能介绍

本系统由STC89C52单片机+信号输入+74HC14整形电路+74HC390分频电路+LCD1602显示模块+电源构成。

具体功能:

1、能检测出三角波、正弦波或方波等波形的频率;

2、频率的测量范围为1Hz—12MHz,并且能检测幅度最小值为1Vpp的信号;

3、使用LCD1602来显示检测到的即时频率数值(最高8位数,单位为Hz)。

​演示视频:

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

#include <reg52.h>
unsigned long int fre; 
unsigned char time;
unsigned int count;
unsigned int count1;
sbit   LCD_RS=P1^0;	  //片选信号 
sbit   LCD_RW=P1^1;	  //读写信号 
sbit   LCD_E=P1^2; 	  //使能信号 
#define LCD_DB  P0	//数据信号 
unsigned char character[10]={0};//在屏幕上显示的字符串 
unsigned char character_1[]={"fre= Hz"};
unsigned char FLAG = 0;  //是否分频选择标志
void LCD_init(void);//初始化函数   
void LCD_write_command(unsigned char command);//写指令函数	 
void LCD_write_data(unsigned char dat);//写数据函数	   
void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
void delay_n40us(unsigned int n);//延时函数
void timer_init();            //中断初始化函数  
//-----------------------------延时函数---------------------------
void delay_n40us(unsigned int n)		  //延时函数 
{
	unsigned int i;
	unsigned char j;            
	for(i=n;i>0;i--)
	for(j=0;j<2;j++);          
} 
void delay_1s()
{
	unsigned int i,j;
	for(i = 0;i<100;i++)
		for(j = 0;j<1000;j++);
} 
//---------------------lcd1602液晶显示函数--------------------                                     
void LCD_init(void)	 //液晶初始化函数 
{
	LCD_write_command(0x38);//设置8位格式,2行,5x7
	LCD_write_command(0x38);//设置8位格式,2行,5x7
	LCD_write_command(0x38);//设置8位格式,2行,5x7
	LCD_write_command(0x0c);//整体显示,关光标,不闪烁 
	LCD_write_command(0x06);//设定输入方式,增量不移位
	LCD_write_command(0x01);//清除屏幕显示	  
	delay_n40us(100);//清屏延时 
} 
void LCD_write_command(unsigned char dat)  //写命令函数 
{
	LCD_DB=dat;
	LCD_RS=0;//指令	 
	LCD_RW=0;//写入	 
	LCD_E=1; //使能 	 
	LCD_E=0;
	delay_n40us(1);//写命令延时   
}	 
void LCD_write_data(unsigned char dat)	  //写数据函数 
{
	LCD_DB=dat;
	LCD_RS=1;//数据	  
	LCD_RW=0;//写入	  
	LCD_E=1;//使能  
	LCD_E=0;
	delay_n40us(1);	 //写数据延时 
}
void LCD_disp_char(unsigned char x,unsigned char y,unsigned char dat)//显示一个字符 
{
	unsigned char address;
	if(y==1)
	         address=0x80+x;	 //显示在第一排的时候的x的地址 
	else
	         address=0xc0+x;	 //显示在第二排的时候的x的地址 
	LCD_write_command(address);	 //输入地址 
	LCD_write_data(dat);		 //输入数据 
}
void LCD_disp_num(unsigned char x,unsigned char y,unsigned char dat)//显示一个数字
{
	unsigned char address;
	if(y==1)
	         address=0x80+x;	 //显示在第一排的时候的x的地址 
	else
	         address=0xc0+x;	 //显示在第二排的时候的x的地址 
	LCD_write_command(address);	 //输入地址 
	LCD_write_data(dat+48);		 //输入数据 
}
void dis_num(void)
{
	unsigned char i=0,j=0,k=0;
	LCD_write_command(0x01);//清除屏幕显示
	character[0] = fre/10000000;
	character[1] = fre/1000000%10;
	character[2] = fre/100000%10;
	character[3] = fre/10000%10;
	character[4] = fre/1000%10;
	character[5] = fre/100%10;
	character[6] = fre/10%10;
	character[7] = fre%10;
    character[8] = 'H';
	character[9] = 'z';
	for(i = 0;i<4;i++)		 //显示“fre=”
	{
	 	LCD_disp_char(i+0,1,character_1[i]);
	}
	for(i = 0;i<10;i++)	 //判断第一个不为0的数
	{
		if(character[i]!=0)
			break;
	}
	k = 8-i;
	for(j = 0;j<k;j++)	 //显示所有的数字
	{
			LCD_disp_num(4+j,1,character[i++]);	
	}
    for(i = 5;i<7;i++)	 //显示“Hz”
	{
	 	LCD_disp_char(j+4,1,character_1[i]);
		j++;
	}
}
//----------------主函数--------------------
void main()
{ 
	unsigned char i;
	LCD_init();
	timer_init();             //定时/计数器初始化 
	for(i = 0;i<4;i++)
	{
	 	LCD_disp_char(i+0,1,character_1[i]);
	}
	while(1)
	{
		dis_num();         //显示
		delay_1s();
	}
}
//-------------------定时/计数器初始化--------------
void timer_init(void)         //定时/计数器初始化
{ 
	TMOD=0x66;                //计数器0和计数器1工作工作方式2,自动重装初值 
	TH0=0;                    //计数器初值为0
	TL0=0;
	TR0=1;                    //计数器开始计数	    
	ET0=1;                    //打开计数器0中断   
	TH1=0;                    //计数器初值为0
	TL1=0;
	TR1=1;                    //计数器开始计数	    
	ET1=1;                    //打开计数器1中断   
	RCAP2H=(65536-62500)/256; //在程序初始化的时候给RCAP2L和RCAP2H赋值, 
	RCAP2L=(65536-62500)%256; //TH2和TL2将会在中断产生时自动使TH2=RCAP2H,TL2=RCAP2L。 
	TH2=RCAP2H;               //12M晶振下每次中断62.5ms(1s=1000ms=62.5ms×16)
	TL2=RCAP2L;
	ET2=1;                    //打开定时器2中断	 
	TR2=1;                    //定时器2开始计时  
	EA=1;                     //开总中断   
} 
//------------------中断函数----------------------
void timer2(void) interrupt 5 //定时器2中断(62.5ms)
{
	time++;
	TF2=0;                    //定时器2的中断标志位TF2不能够由硬件清零,所以要在中断服务程序中将其清零
	if (time==16)             //定时1s时间到  
	{
	   time=0;                //计时清0
	   EA=0;                  //关中断		 
	   fre=(long)count1*256+TL1;     //count*256强制转换成long型,否则将不产生进位~先判断分频后(计数器1)
	   FLAG = 0; 
	  
	   if(fre<2000)//如果不到200KHz则读取分频前(计数器0)频率(200K÷100=2000)
	   {
	   		fre = (long)count*256+TL0;
			FLAG = 1;          
	   } 
		if(!FLAG)
		{
			fre = fre *100;//100分频
		}
	   TL0=0;                 //清零计数器0计数	    
	   TH0=0;
	   TL1=0;
	   TH1=0; 
	   count=0;               //清零计数器0计数	  
	   count1=0;
	   EA=1;                  //开中断	    
	}
} 
//----------------------------------------------------------------
void timer0(void) interrupt 1 //计数器0中断(100分频前)	 
{
	count++;
}		
//----------------------------------------------------------------
void timer1(void) interrupt 3 //计数器1中断(100分频后) 
{
	count1++;
}

硬件设计

使用元器件:

单片机:STC89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

1602LCD液晶屏 ;

排阵16P ;排阵4P ;

排母16P ;DIP40插座 ;

74HC390;74HC14 ;

DIP14;DIP16;

电阻300 、3K、1K 、75 ;

电容470UF、 0.1UF、10UF、30P;

排阻103;电位器103;

三极管8050;按键;

晶振12M;DC电源座子;

USB转DC线;电路板7*9 ;

导线12匝 ;电路图 ;

铜柱;自锁开关;

导线:若干;

流程图:

设计资料

01 仿真图

本设计使用proteus8.9版本设计,没有软件在本公众号获取,无需担心!具体如图!

02 原理图

本系统原理图采用Altium Designer19设计,具体如图!

03 程序

本设计使用软件keil4和keil5两个版本编程设计,无需担心!具体如图!

04 设计报告

八千字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

05 设计资料

        资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、AD原理图、pcb电路图、开题报告、参考论文、流程图、任务书等。具体内容如下,全网最全! !

资料获取请观看前面演示视频!

点赞分享一起学习成长。

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值