前两天省赛结束,总结下省赛的内容
涉及模块:
1、ad 模拟电压输入
2、数码管
3、led指示灯指示状态
4、NE555脉冲计数器
5、按键模块
其中除去NE555模块的其他部分我在前文的博客中也提到了这次重点来说下NE555,让人呜呜呜的555(额,考前复习没有复习到这个模块,当时编写的时候也很懵逼。。)
下面来看一下蓝桥杯板子上NE555模块
桥杯这个NE555频率发生计其实设计的挺鸡肋的,和我之前在数电书上看到的都不太一样,为了便于分析,我们先来看一下NE555模块的内部结构图
蓝桥杯板子上NE555原理
NE555是因为它内部三个电阻为5k的电阻而命名的,其实根据原理来说只要是三个电阻一样的都可以用,比如内部为三个6k的电阻,不过早期的设计出来的时候就用的是5k,所以名字也就没有变过。首先来看一下基本原理,蓝桥杯板子上,26脚相接,5脚接电容后接地,4脚和8脚接VCC,3脚接一个滑动变阻器后再加一个100Ω的电阻接到26脚上,7脚悬空。好了看了连接后,我们来看一下原理,(注意测量的时候是板子上右边排针SIGNAL和P34两个用跳帽相连)单片机启动后,3脚为高电平,通过滑动变阻器和固定电阻来给电容C14充电,当充电电压大于2/3VCC时,Vc1为0,Vc2为1,这时Q为0,G3为1,G4为0,输出V0也为0即低电平,这个时候C14通过滑动变阻器和固定电阻来放电,当其电压低于1/3VCC的时候,Vc1为1,Vc2位0,Q为1,G3为0,G4为1,输出V0为1即为高电平,这个时候C14又来进行充电,以此往复,形成脉冲,可以得出这是一个频率可变,而占空比不变的振荡信号。
那么可变频率的范围是多少呢?这个频率的改变是通过滑动变阻器Rb3来改变的,通过改变充电和放电的总时间而改变周期从而改变频率,最小频率对应为最大周期,是滑动变阻器和固定电阻和和最大的时候产生的即50100Ω,最大频率也就是为100Ω,因为我计算出来始终和正确值有所偏差,所以,我直接进行了测量,这是很准确的范围。看图
最低为57HZ左右
最高为24kHZ左右
这里知道了范围大家也没必要去算了,测出来后对照一下就知道是不是正确的了。关于官方说的
频率范围为500-20K我还是保持怀疑的,毕竟是测过的,我想官方的这个题的意思应该是,用500Hz-20KHZ作为标准来检验吧。
NE555代码分析
说完了这个我们来说一下代码具体如何去测量,既然我们是计算频率,那么我们能够通过测量周期然后换算为频率,毕竟我们是能够在时域上去下功夫,频域上我们都是通过换算得到的。
我们先来看一下P34的管脚功能有哪些
从这我们可以看出P34有4个功能,第一 :普通IO口、第二 :作为T0定时器/计数器的外部输入,第三 :作为T1时钟输出(可分频)、第四 :作为PCA模块的计数器外部脉冲输入脚。这里面一眼看去只有2脚和4脚可以使用,其中的原理也都差不多,不过值得注意的是,P34作为输入,是需要初始化切换的,因为它不是默认的输入脚
所以我们还是用定时器0来的方便些,而配置思路也比较清晰,让T0工作在计数模式下,而计数的引脚就是我们的P34,进行频率测量的时候,将定时器初值设为0,然后利用另外一个定时器来限定时间在1S或者几秒内,在规定时间完后,停止技术,将定时器0的值取出来,看有多少个脉冲,然后用总脉冲量/总时间,得出的即为脉冲的周期。
#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsfrAUXR=0x8e; ucharcodetab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; voidsmg_xianshi(ucharyi,er,san,si,wu,liu,qi,ba); ucharyi,er,san,si,wu,liu,qi,ba; voiddelay(uintx); voidclose (); voidTimer0Init(void); voidzd_t1(); voidTimer1Init(void); uinttime,fre; voidmain() { Timer1Init(); Timer0Init(); EA=1; ET1=1; while(1) { yi=11;er=11;san=11; si=fre/10000; wu=(fre%10000)/1000; liu=(fre%1000)/100; qi=(fre%100)/10; ba=(fre%100)%10; smg_xianshi(yi,er,san,si,wu,liu,qi,ba); } } voidzd_t1() interrupt3 { time++; if(time==1000) { TR0=0; time=0; fre=TH0*256+TL0; TH0=0; TL0=0; TR0=1; } } voidTimer1Init(void) //1毫秒@11.0592MHz { AUXR&=0xBF; //定时器时钟12T模式TMOD&=0x0F; //设置定时器为定时模式TL1=0x66; //设置定时初值TH1=0xFC; //设置定时初值TF1=0; //清除TF1标志TR1=1 ; //定时器1开始计时 } voidTimer0Init(void) { AUXR&=0x7F; //定时器时钟12T模式TMOD|=0x05; //设置定时器为计数模式TL0=0x00; //设置定时初值TH0=0x00; //设置定时初值TF0=0; //清除TF0标志TR0=1; //定时器0开始计时 } voiddelay(uintx) { uchari; while(x--) { for(i=0;i<120;i++); } } voidclose () { P2=0x80; P0=0xff; P2=0x1f; P2=0xa0; P0=0x00; P2=0x1f; } voidsmg_xianshi(ucharyi,er,san,si,wu,liu,qi,ba) { P2=0xc0; P0=0x01; P2=0xe0; P0=tab[yi]; delay(5); P2=0xc0; P0=0x02; P2=0xe0; P0=tab[er]; delay(5); P2=0xc0; P0=0x04; P2=0xe0; P0=tab[san]; delay(5); P2=0xc0; P0=0x08; P2=0xe0; P0=tab[si]; delay(5); P2=0xc0; P0=0x10; P2=0xe0; P0=tab[wu]; delay(5); P2=0xc0; P0=0x20; P2=0xe0; P0=tab[liu]; delay(5); P2=0xc0; P0=0x40; P2=0xe0; P0=tab[qi]; delay(5); P2=0xc0; P0=0x80; P2=0xe0; P0=tab[ba]; delay(5); }