利用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();
}
}
版权声明:本文为CSDN博主「行不地上」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_53889131/article/details/122824655
暂无评论