一、NE555电路图
NE555也称555定时器,本文主要利用NE555产生方波发生电路。整个电路相当于频率可调的方波发生器。
通过调整电位器的阻值,方波的频率也随之改变。
RB3在开发板的位置如下图
测量方波信号的引脚为SIGHAL,由上面的电路图可知,NE555已经构成完整的方波发生电路,不需要单片机进行控制,只需要采集方波信号即可。
下面讲述测量方波信号频率的计数器,计数器并不是一个芯片,而是单片机内部的一个功能,根据测量一秒之内传入几个脉冲来计算频率,频率与时间的关系如下。
- t——时间
- f——频率
- n——脉冲数
二、计数器与定时器
1.两者区别
计数器 | 定时器 |
记录未知频率的脉冲信号 | 记录时间 |
已知时间 | 已知频率 |
2.配置方法
- GATE 置0即可,置1是更高级的配置
- C/T C——counter 计数器,T——timer 定时器上面一横代表低电平有效,所以计数器高电平有效
- M1,M0有四种模式,本次将M1和M0配置为0 1,进入16位不可重装载模式,TL0.TH0全用
3.定时器和计数器内部结构图
- SYSclk 系统主时钟,频率已知,可以对其进行12分频或者1分频,若12分频传入的就是原来1/12的频率,如果是1分频,传入的频率不变。分频与否通过AUXR的第七位进行配置。
- T0 Pin是外部端口,这里是单片机的引脚,所以后面的开关就可以选择,可以选择连接到系统的主时钟,也可以选择连接到外部端口。置0,则工作在定时器的模式下;置1,工作在计数器的模式下,就可以取统计通过外部端口输入的信号有多少个脉冲。
- GATE 若为0,非门取反就是1,传入1,然后是或门,输出1,传入与门,最终只与TR0相关,如果TR0是0,那么就是0,control开关打开;如果TR0是1,最后就输出1,control开关闭合。
- TL0和TH0为16位存储器,当溢出时,就会通过TF0触发中断
三、模块代码
#include "tim.h"
//void Timer0Init(void) //1毫秒@12.000MHz
//{
// AUXR |= 0x80; //定时器时钟1T模式
// TMOD &= 0xF0; //设置定时器模式
// TL0 = 0x20; //设置定时初值
// TH0 = 0xD1; //设置定时初值
// TF0 = 0; //清除TF0标志
// TR0 = 1; //定时器0开始计时
// ET0=1; //定时器0中断开关
//}
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初值
TH1 = 0xD1; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
}
void Timer0Init(void)
{
TMOD &= 0xF0; //保证高四位不变,即不改变定时器1模式
TMOD |= 0x05;//将定时器0设置为计数器模式
TL0=0;
TH0=0;//将数据清零
TR0=1;//将开关打开
}
四、主函数代码
注意:unsigned int对应的输出格式为%u,所以不要用%d,输出位数多时会出现错误
#include "seg.h"
#include "tim.h"
#include "init.h"
//Seg
unsigned char pucSeg_Buf[12],pucSeg_Code[9],pucSeg_Pos=0;//字符数组以/0结尾,所以要有9位
void Seg_Proc(void);
//Timer
unsigned long ulms =0;
unsigned int uiSeg_Dly=0;
//NE555
unsigned int freq=0;
void main(void)
{
Cls_Peripheral();
Timer0Init();
Timer1Init();
EA=1;
while(1)
{
Seg_Proc();
}
}
void Seg_Proc(void)
{
if(uiSeg_Dly<200)
return;
uiSeg_Dly =0;
sprintf(pucSeg_Buf,"%5u ",freq);//将指定的内容打印到字符数组里
Seg_Tran(pucSeg_Buf,pucSeg_Code);
}
void Time_1(void) interrupt 3
{
ulms++;
uiSeg_Dly++;
if(ulms % 2==0)
{
pucSeg_Pos=(pucSeg_Pos+1)%8;//实现pucSeg_Pos从0-7循环的操作
Seg_Disp(pucSeg_Code,pucSeg_Pos);
}
if(ulms%1000==0)//整秒时,读取TL0和TH0的数量
{
freq=((TH0<<8)|TL0);
TL0=0;
TH0=0;
}
}
五、与矩阵键盘共用的注意点
由于两者共用NE555的引脚,所以会产生相互影响
则需要将P34=0修改为=1