同学们大家好,周一周二两天,大Z比较忙,因此耽误了发帖,跟大家说声抱歉。今天忙里偷闲继续更帖~
本节我们主要讲一下蓝桥杯开发板上的NE555这个器件,测量频率这个要求在以往的比赛中有所涉及,虽然出现的频率不是那么高,但是也不排除以后还会再考的可能性,因此有必要介绍基于NE555的频率计的基本实现方法。
首先,频率这个量的单位是HZ,是单位时间内完成周期性变化的次数;对于我们考试中所要求产生的方波信号来说,其实就是在1秒内,该方波信号重复的次数。至于实现方法,我们有如下两种方法,下面对这两种方法进行简要介绍。
方法一:用定时器中断和外部中断来实现
通过观察电路图不难发现,我们的这个方法需要用杜邦线将NET_SIG和外部中断接口P32或是P33连接。中断方式选择下降沿触发,定时器中断采用10ms中断一次,计数100次(一秒)采集一次中断次数(频率)。
首先,定时器0和外部中断0的初始化:
void initTime0() { TMOD=0x01; //定时器0 16位定时器模式 TH0=0xdc; TL0=0x00; //10ms中断一次 EA=1; //开总中断 ET0=1; //开定时器0中断 EX0=1; //开外部中断0 IT0=1; //外部中断触发方式:跳边沿触发 TR0=1; //开启计时 }
然后就是中断服务函数:
void outTouch() interrupt 0 { exCounter++; //全局变量 无符号整形,最大65535 计数 if(exCounter >=65535) { exCounter=0; //限制测量最大频率(理论)为这么多 } } void time0() interrupt 1 { TH0=0xdc; TL0=0x00; //重装数据 counter++; //全局变量,无符号字符型,计满100次为1s if(counter==100) { fre= exCounter; //获取频率数据,可以通过数码管显示 exCounter=0; //清零计数。 } }
主要实现步骤就这么多了,其实这个主要难点是协同其它的功能一起完成整个程序,其中由于这个频率采集往往会占用很大的单片机资源,所以在资源分配方面是非常棘手的。因此在程序内部有时候也要控制TMOD、TCON、IE 这些寄存器的值,来实现分配资源的目的。
方法二:计数器和定时器中断来实现
这里我们设置C/T(计数定时器)0为计数器模式,C/T 1为定时器模式,因为C/T 0计数器模式的触发IO口就与NET_SIG相邻,因此用一个跳线帽连接即可。
C/T 0、1的初始化代码
void initTimer() { TMOD=0x15; // C/T 1 16位定时器模式 C/T 0 16位计数器模式 TH1=0xdc; TL1=0x00; //定时器1 10ms中断一次 TH0=0; TL0=0; //初始化计数器计数值 EA=1; ET1=1; TR0=TR1=1; }
定时器1 中断服务函数:
void timer1() interrupt 3 { TH1=0xdc; TL1=0x00; counter++; //全局变量,无符号字符型,计满100次为1s if(counter==100) { fre=(TH0<<8)|TL0; //获取频率数据最大65535,定义 fre为16位数据 TH0=TL0=0; //清零计数。 } }
当然,如果不考虑单片机工作频率的话(无限),可以无限的测量频率,只需检测计数溢出标志位TF0 即可,但是一般情况下单片机采集最大频率是有限的,所以就不存在无限的情况了…
学到现在,同学们应该能发现,模块化编程变得越来越重要,因为单片机的资源有限,要用有限的资源来做很多事情其实是很难的,非常考验一个人的逻辑思维能力以及对单片机编程的熟悉程度,所以千里之行始于足下,多多敲代码,提高自己的动手与独立解决问题的能力,期待同学们的好成绩!