数字频率计单片机Proteus仿真

硬件电路图
可以通过数码管输入频率。
原理:
1、T0 作计数器使用,被测信号从 P3.4 引脚输入
2、T1 作定时器使用,1ms,数码管刷新
3、T2 作定时器使用,定时读取 T0 的值,两次 T0 的值之差/定时就是频率(定时测频)。
4、T2 中断的优先级要高于 T1 的中断优先级

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char

//计数在1s内通过的脉冲数即高电平数目
sbit In = P3^4;//作为信号输入
uchar T1RH = 0;
uchar T1RL = 0;
uchar T2RH = 0;
uchar T2RL = 0;
uchar resultH = 0;
uchar resultL = 0;
unsigned long num = 0;
bit flag1s = 0;

uchar code LedChar[] = {//数码管显示字符转换表
	0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
	0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};

uchar LedBuff[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

void ConfigTimer1(uint ms);//定时1s
void ConfigTimer2(uint ms);
void Display(unsigned long fre);//计算数码管每个数目的函数
void LedScan();//扫描显示函数

void main()
{
	EA = 1;//总中断打开
	TMOD = 0x15;//T1为定时器刷新数码管,T0为计数器,被测信号从P3^4输入
	PT2 = 1;//定时器T2优先	
	ConfigTimer1(1);//只能定时1ms
	ConfigTimer2(50);
	Display(0);
	TR0 = 1;
	while(1)
	{	
		if(flag1s == 1)
		{
			flag1s = 0;
			num = resultH * 256 + resultL;
			Display(num);	
		}			
	}
}

void ConfigTimer1(unsigned int ms)
{
	unsigned long tmp;
	tmp = 12000000 / 12;
	tmp = (tmp * ms) / 1000;
	tmp = 65536 - tmp;
	T1RH = (uchar)(tmp>>8);
	T1RL = (uchar) tmp;
	TH1 = T1RH;
	TL1 = T1RL;
	ET1 = 1;
	TR1 = 1;
}

void ConfigTimer2(unsigned int ms)
{
	unsigned long tmp;
	tmp = 12000000 / 12;
	tmp = (tmp * ms) / 1000;
	tmp = 65536 - tmp;
	T2RH = (uchar)(tmp>>8);
	T2RL = (uchar) tmp;
	TH2 = RCAP2H = T2RH;//T2也定时1ms
	TL2 = RCAP2L = T2RL;
	ET2 = 1;
	TR2 = 1;
}

void Display(unsigned long fre)//不显示小数
{
	signed char i;
	uchar buf[6];
	buf[0] = fre%10;
	buf[1] = (fre/10)%10;
	buf[2] = (fre/100)%10;
	buf[3] = (fre/1000)%10;
	buf[4] = (fre/10000)%10;
	buf[5] = (fre/100000)%10;
	for(i=5; i>=1; i--)
	{
		if (buf[i] == 0)
			LedBuff[i] = 0x00;
		else
			break;
	}
	for(; i>= 0; i--)
	{
		LedBuff[i] = LedChar[buf[i]];
	}
}

void LedScan()
{
	//static uchar i = 0xfe;//写进中断
	static uchar count = 0;
	P0 = 0x00;//显示消隐
	/*P2 = i;
	P0 = LedBuff[count];
	if (count<5)
	{
	    i<<=1;
		count++;
	}
	else
	{
		i=0xfe;
		count = 0;
	} */
	switch (count)
	{
		case 0:P2 = 0xfe; count++; P0=LedBuff[0];break;
		case 1:P2 = 0xfd; count++; P0=LedBuff[1];break;
		case 2:P2 = 0xfb; count++; P0=LedBuff[2];break;
		case 3:P2 = 0xf7; count++; P0=LedBuff[3];break;
		case 4:P2 = 0xef; count++; P0=LedBuff[4];break;
		case 5:P2 = 0xdf; count=0; P0=LedBuff[5];break;
	}
}

void InterruptTimer1() interrupt 3//使用定时器T1
{
	TH1 = T1RH;
	TL1 = T1RL;
	LedScan();//T1刷新数码管显示	
}

void InterruptTimer2() interrupt 5//使用定时器T2
{
	static uchar i =0;
	TF2 = 0;//清除溢出缓冲
	i++;
	if(i==20)//1s
	{
		flag1s = 1;
		//TR0 = 0;//先暂停计数,不应该停住
		resultH = TH0;
		resultL = TL0;
		//TR0 = 1;
		TH0 = 0;
		TL0 = 0;
		i = 0;
	}
}

结果:
结果
和Proteus内置频率计的结果相同。

  • 10
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值