正弦信号频率测量

 单片机的课程设计NO.1

项目功能

测量正弦信号源的信号频率,并用LCD1062显示

 项目代码


#include<reg51.h>
#include<intrins.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
#define correct  1950				 //计时器修正值
sbit TEXT = P1^0;						 
uchar TimeH = (65536 - 50000 +correct)/256;		//数码管刷新间隔
uchar TimeL = (65536 - 50000 +correct)%256;
unsigned long int Frequency=0;		//Frequency频率,Counter计数器
uchar a[]="0,000,000",b[]="Ready!",c[]="Frequency:",m[]="Measureing...",z[]="0,000,000";
bit renovate_frequency_flag=0;		//刷新频率值的标志位
bit show_m_flag=0;
void send(uchar *s);
/*LCD显示函数*/
#define out P2
sbit RS = P1^5;				//LCD1602寄存器选择
sbit RW = P1^6;				//LCD1602读写操作选择
sbit E = P1^7;				//LCD1602使能信号
void lcd_initial(void);		//LCD初始化函数
void check_busy(void);		//检查忙标志函数
void write_command(uchar com);		//写命令函数
void write_data(uchar dat);			//写数据函数
void string(uchar ad,uchar *s);		//显示字符串函数
void delay(uint j);
/*以上*/
void main( )
{
	lcd_initial();
	TMOD = 0X21;	
	TH1 = 0XFD;			//波特率9600
	TL1 = 0XFD;
	SCON = 0X50;	
	PCON = 0X00;		
	TR1 = 1;			//接通T1			
	EA = 1;				//总中断开			
	ET0 = 1;			//T0中断开
	EX1 = 1;			//外部中断1开
	IT0 = 1;			//外部中断0下降沿触发
	IT1 = 1;			//外部中断1下降沿触发	
	ES = 1;				//串口中断开	
	string(0x80,b);			
	while(1)
	{
		if(show_m_flag)
		{
			write_command(0x01);		//清屏
			string(0x80,m);
			show_m_flag=0;
		}
		if(renovate_frequency_flag)
		{
			Frequency *= 10;
			strcpy(a,z);
			a[0] += (Frequency/1000000)%10;
			a[2] += (Frequency/100000)%10;
			a[3] += (Frequency/10000)%10;
			a[4] += (Frequency/1000)%10;
			a[6] += (Frequency/100)%10;
			a[7] += (Frequency/10)%10;			
			renovate_frequency_flag=0;
			write_command(0x01);		//清屏
			string(0x80,c);
			string(0xc0,a);
			TI=1;
		}								//对频率按位分解
	}
}

void INT0_Interrupt()	 interrupt 0	//外部中断0,统计待测信号的脉冲数量
{
	 Frequency++;
}
void INT2_Interrupt()	 interrupt 2	   //重启测量程序,由外部按钮控制
{
	Frequency=0;				//重置频率计
	TH0 = TimeH; 				//重置计时器
	TL0 = TimeL;
	show_m_flag=1;
	EX0=1;					   	//开启外部中断,开始脉冲计数
	TR0=1;						//开启计时器

}
void T0_Interrupt()	interrupt 1
{
	
	static uint cnt = 0;
	TH0 = TimeH; 			
	TL0 = TimeL;
	cnt++;	
	if(cnt==20)		   			//计时50ms*20=1s,计时完成
	{	
		EX0=0;				//关闭外部中断,结束测量
		cnt=0;
		renovate_frequency_flag=1;
		TR0=0;
		
	}
		
}



void TRX_Interrupt() interrupt 4		//串口通信
{
	if(RI)				
	{
	 	RI = 0;				  																
    }

	if(TI)				
	{
		TI = 0;
		send(a);
	}
}

void send(uchar *s)		//串口发送函数
{
	static uchar i=0;
	if(i<strlen(s))
	{
		SBUF=*(s+i);
		i++;
	}
	else 
	{
		i=0;
	}			 	
}


/* ---------------------------

   	LCD1602显示函数

----------------------------*/
void delay(uint j)				//延时函数
{
	uchar i = 250;
	for(;j>0;j--)
	{
		while(--i);
		i=249;
		while(--i);
		i=250;
	}
}


void check_busy(void)		//检查忙标志函数
{
	uchar dt;
	do
	{
		dt = 0xff;
		E = 0;
		RS = 0;
		RW = 1;
		E = 1;
		dt = out;
	}while(dt&0x80);
	E = 0;
}

void write_command(uchar com)			//写命令函数
{
	check_busy();
	E = 0;
	RS = 0;
	RW = 0;
	out = com;
	E = 1;
	_nop_();
	E = 0;
	delay(1);
}

void write_data(uchar dat)			//写显示数据函数
{
	check_busy();
	E = 0;
	RS = 1;
	RW = 0;
	out = dat;
	E = 1;
	_nop_();
	E = 0;
}

void lcd_initial(void)		//LCD初始化函数
{
	write_command(0x38);			//写入命令0x38:8位两行显示,5*7点阵字符
	write_command(0x0c);			//写入命令0x0c:开整体显示,光标关,无闪烁
	write_command(0x06);			//写入命令0x06:光标右移
	write_command(0x01);			//写入命令0x01:清屏
	delay(1);
}

void string (uchar ad,uchar *s)				//输出显示字符串的函数
{
	write_command(ad);
	while(*s>0)
	{
		write_data(*s++);
	}
}

Proteus仿真电路

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值