蓝桥杯备战——11.NE555测频

1.分析原理图

蓝桥杯备战——11.NE555测频_第1张图片
我们可以看到,上图就是一个NE555构建的方波发生电路,输出方波频率=1.44/2(R8+Rb3)C,如果有不懂NE555内部结构,工作原理的,可以到B站学习。实在不懂仿真也行,比如我下面就是仿真结果:
蓝桥杯备战——11.NE555测频_第2张图片
然后就是下图,NE555输出的方波信号输入到电容二极管组成的负压生成电路,产生大概4.3V的负压Vee供运放使用。这与本节内容无关,我只是一起讲了。
蓝桥杯备战——11.NE555测频_第3张图片
再看下图:NE555输出方波信号也接到了排针J3上,而且旁边就是P34引脚,又由于比赛时好像不会提供杜邦线,所以我们也只能用跳线帽将NET_SIG和P34连在一起,然后单片机通过P34引脚来测输出频率。
蓝桥杯备战——11.NE555测频_第4张图片

2.定时器测频

这里我就不得不狠狠的吐槽一波这板子的设计人员,既然你都用STC15F2K61S2了,为什么不能想着兼容设计把P34改成P35呢?我们知道,定时器0可以对P34引脚输入脉冲计数,定时器1可以对P35引脚输入脉冲计数,STC89C52和STC15F都是一样的。但是STC15F还有一个更好用,更灵活的外设:PCA
在这里插入图片描述
但是呢,槽点来了,CCP功能切换不到P34引脚,只能把PCA计数脉冲源切换到P34引脚,就很无语,你把P34替换成P35,既能兼容STC89C52使用定时器1对外部脉冲计数,也能兼容STC15F使用CCP功能,就不能好好阅读一下STC15F的用户手册嘛?
蓝桥杯备战——11.NE555测频_第5张图片
不过现在我也不打算就用定时器0来对外部输入脉冲计数,因为我的初衷是把板子上面的各个外设都封装一遍且互不干扰,现在定时器0已经被我用做前后台功能了,所以我得另寻他法。别说,还真有。
这里真的不得不佩服STC芯片的设计者们,使用一个PCA计数阵列就能实现脉冲捕获,PWM输出,软16位定时器,外部中断,D/A功能。关于此外设具体如何使用,请阅读STC15F用户手册!
蓝桥杯备战——11.NE555测频_第6张图片
蓝桥杯备战——11.NE555测频_第7张图片

我这里就是使用的PCA计数阵列对P34输入的脉冲进行计数,然后每1S获取计数值,计数值即频率。

3.代码封装库

代码注释即解析,请一定先仔细阅读PCA外设章节。

#include "capture.h"

u32 frequency=0;	//得出频率,单位HZ
u8 Overflow=0;		//PCA计数溢出次数

//PCA软件定时器对P34输入脉冲计数
void Capture_Init()
{
	P_SW1 &=0XCF;	//清除CCP_S1,CCP_S0位
	P_SW1 |=0X10;	//CCP在P34/ECI_2
	CCON = 0;     //清除CF标志 PCA定时器停止 清除模块0/1/2中断标志
	CL = 0;CH = 0;	//复位PCA计数值
	CMOD = 0x07; //设置PCA时钟源:ECI输入,允许PCA溢出中断
	CR = 1;	//启动PCA计数器阵列计数
	EA = 1; //开总中断
}

void PCA_isr() interrupt 7	//发生匹配中断
{
  CF = 0;	//清中断标志
  CL = 0;CH = 0;	//复位PCA计数值
  Overflow++;
}

//每1S获取一次计数值,即频率
void Get_Frequency()
{
	frequency = (Overflow<<16) | (CH<<8) |CL;
	CL = 0;CH = 0;Overflow=0;
}

4.使用示例

#include "main.h"

bit KeyScan_Flag=0;
extern u32 frequency;	//测得频率

void System_Init(void);
void Timer0_Init(void);

void main()
{
	System_Init();
	Timer0_Init();
	Capture_Init();
	while(1)
	{
		Nixie_Display(1,(frequency%100000000)/100000);	
		Nixie_Display(2,(frequency%10000000)/10000);
		Nixie_Display(3,(frequency%1000000)/10000);	
		Nixie_Display(4,(frequency%100000)/10000);	
		Nixie_Display(5,(frequency%10000)/1000);	
		Nixie_Display(6,(frequency%1000)/100);	
		Nixie_Display(7,(frequency%100)/10);	
		Nixie_Display(8,frequency%10);	
	}
}

void Timer0_Isr() interrupt 1	//1ms中断一次
{
	static u16 count1=0;
	if(++count1==1000)	//每1S获取一次计数值
	{
		Get_Frequency();
		count1=0;
	}
}

void Timer0_Init()		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;			//12T模式
	TMOD &= 0xF0;			//定时器0:16位自动重装载
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;
	TF0 = 0;	//清除TF0标志
	ET0 = 1;	//使能定时器0中断
	EA = 1;		//开总中断
	TR0 = 1;	//定时器0开始计时
}

void System_Init()//系统上电初始化
{
	//先锁存蜂鸣器,继电器所在573输出低电平,防止上电乱叫
	P25=1;P26=0;P27=1; //74HC138-->Y5=0,else=1-->Y5C=1,else=0
	P04=0;P06=0;	//ULN2003输入经过非门送入达林顿管,低电平有效
	P25=0;P26=0;P27=0;//锁存数据
	
	//关闭所有LED灯
	P25=0;P26=0;P27=1; //74HC138-->Y4=0,else=1-->Y4C=1,else=0
	P0=0XFF;
	P25=0;P26=0;P27=0;//锁存数据
}

我们通过旋转滑动变阻器RB3就能改变输出频率,演示效果如下,由于手头没有示波器,只能到学校再验证误差了。

NE555测频演示

你可能感兴趣的:(蓝桥杯,单片机,嵌入式硬件)