十八、555定时器与频率测量

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KGM5LiN5Zyw5LiK,size_20,color_FFFFFF,t_70,g_se,x_16

利用NE555产生方波信号并测量其频率,要求如下:

①上电开机运行时,关闭蜂鸣器、继电器、8个LED指示灯。

②用跳线帽将J3中的NAL与P34短接,NE555发生的信号输入到单片机的P34(定时器0)引脚。

③单片机测量信号频率,并显示在数码管中,频率数据显示用5位数码管单位是Hz,当显示长度不足5位时,未使用到的数码管熄灭,在最左边的1位数码管用“F”作为提示符。

用两个定时器:

T0定时器计数:1S计数多少次 => 频率(在单位时间内完成周期性变化的次数叫做频率)

T1定时器定时:1S

#include "reg52.h"

unsigned char code SMG_duanma[18] = {
	//  0   1    2    3    4    5    6    7
		0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
	//  8   9    A10  B11  C12  D13  E14  F15
		0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,
	// -16  .17
		0xbf,0x7f};  //共阳数码管

unsigned char Hz = 0;		
		
void InitHC138(unsigned char n)
{
	switch(n)
	{
		case 4://LED
			P2 = (P2 & 0x1f) | 0x80;
		break;
		case 5://蜂鸣器与继电器
			P2 = (P2 & 0x1f) | 0xa0;
		break;
		case 6://数码管位置
			P2 = (P2 & 0x1f) | 0xc0;
		break;
		case 7://数码管段码
			P2 = (P2 & 0x1f) | 0xe0;
		break;
	}
}

//****************************************************************************
void Init_Timer()
{
	TMOD = 0x16;//查手册
	
//定时器0:用作计数(8位重装模式)
	TH0 = 0xff;
	TL0 = 0xff;
	ET0 = 1;
	TR0 = 1;
	
//定时器1:用作定时(1Hz:1s一个频率;1s = 1000ms = 20*50ms)	
	TH1 = (65535 - 50000 + 1) / 256;
	TL1 = (65535 - 50000 + 1) % 256;//+1:有1us的误差
	ET1 = 1;
	TR1 = 1;
	
	EA = 1;//打开总中断
}

unsigned int count_Hz = 0;//计算频率(又要计算下一秒的频率)
unsigned int dat_Hz = 0;//缓存上一秒的频率
unsigned char count = 0;//1s

void ServiceTimer0() interrupt 1//定时器0中断服务函数(计数)
{
	count_Hz++;
}

void ServiceTimer1() interrupt 3//定时器1中断服务函数(定时)
{
	TH1 = (65535 - 50000 + 1) / 256;
	TL1 = (65535 - 50000 + 1) % 256;//无自动重装
	
	count++;
	if (count == 20)//1s
	{
		dat_Hz = count_Hz;//1s时间到,把计算出的频率取出来
		count_Hz = 0;//清零,计算下一秒频率
		count = 0;
	}
}

//****************************************************************************

void InitSystem()//初始化系统
{
	InitHC138(4);//关LED
	P0 = 0xff;
	InitHC138(5);//关闭蜂鸣器、继电器
	P0 = 0x00;
}

void SMG_Bit(unsigned pos, unsigned char dat)
{
	InitHC138(7);
	P0 = 0xff;//消影
	InitHC138(6);
	P0 = 0x01 << pos;
	InitHC138(7);
	P0 = dat;
}

void DelaySMG(unsigned int t)
{
	while(t--);
}

//12345
//个位:12345 % 10 = 1234.5 = 5
//十位:12345 / 10 = 1234.5 = 1234 % 10 = 123.4 = 4
//百位:12345 / 100 = 123.45 = 123 % 10 = 12.3 = 3
//千位:12345 / 1000 = 12.345 = 12 % 10 = 1.2 = 2
//万位:12345 / 10000 = 1.2345 = 1
void ShowSMG()//数码管动态显示频率
{
	SMG_Bit(7,SMG_duanma[dat_Hz%10]);//个位1
	DelaySMG(500);
	if (dat_Hz > 9)//9 => 9 / 10 = 0.9 = 0 % 10 = 0
	{
		SMG_Bit(6,SMG_duanma[(dat_Hz/10)%10]);//十2(12 / 10 = 1.2 = 1 % 10 = 0.1 = 1)
		DelaySMG(500);
	}
	if (dat_Hz > 99)
	{
		SMG_Bit(5,SMG_duanma[(dat_Hz/100)%10]);//百3
		DelaySMG(500);
	}
	if (dat_Hz > 999)
	{
		SMG_Bit(4,SMG_duanma[(dat_Hz/1000)%10]);//千4
		DelaySMG(500);
	}
	if (dat_Hz > 9999)
	{
		SMG_Bit(3,SMG_duanma[dat_Hz/10000]);//万5
		DelaySMG(500);
	}
	
	SMG_Bit(2,0xff);//不显示
	DelaySMG(500);
	SMG_Bit(1,0xff);//不显示
	DelaySMG(500);
	if (dat_Hz < 10000)
	{
		SMG_Bit(0,SMG_duanma[15]);//“F”提示符
		DelaySMG(500);
	}
}

void main()
{
	InitSystem();
	Init_Timer();
	while(1)
	{
		ShowSMG();
	}
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行不地上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值