问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

蓝桥杯单片机专题:揭开NE555脉冲定时的奥秘与应用

创作时间:
作者:
@小白创作中心

蓝桥杯单片机专题:揭开NE555脉冲定时的奥秘与应用

引用
CSDN
1.
https://blog.csdn.net/2301_79437046/article/details/145706146

在蓝桥杯单片机竞赛中,NE555定时器模块是一个基础而强大的工具。它不仅能作为经典的定时器和脉冲生成器,还在实际项目中扮演着重要角色。掌握NE555的应用不仅能提高实际操作能力,还能在遇到相关考题时快速解决问题。本文将详细介绍NE555的原理、配置方法及具体应用。

NE555原理图

触发和复位

  • 当引脚2 ( TR ) 的电压低于1/3 VCC时,NE555被触发,输出引脚3 ( Q ) 变为高电平。
  • 当引脚4 ( R ) 被拉低时,NE555被复位,输出引脚3 ( Q ) 变为低电平。

定时和振荡

  • 通过电阻RB3、R8和电容C14、C16的组合,可以控制NE555的定时和振荡频率。
  • 当引脚6 (THR) 的电压高于2/3 VCC时,NE555的定时周期结束,输出引脚3 (Q) 变为低电平。

放电

  • 引脚7 (DIS) 用于放电,当NE555处于定时周期时,该引脚会将电容C14放电。

保护和滤波

  • 二极管D2和D3用于保护电路,防止反向电压对电路造成损害。
  • 电容C19和C20用于滤波,稳定电源电压,减少噪声干扰。

NE555在蓝桥杯的考点

脉冲发生器

NE555定时器在该电路中配置为产生一个脉冲输出信号。这个信号的频率取决于电阻RB3、R8和电容C14的值。NE555的输出引脚3 (Q) 会输出一个周期性的高电平和低电平信号。

配合定时器(此时定时器配置成计数器模式)读取NE555的输出频率。

连接单片机P34到NE555输出

将单片机的P34引脚连接到NE555的输出引脚3 (Q)。这样,单片机可以通过P34引脚读取NE555产生的脉冲信号。

通过这两张原理图可以看到,在使用NE555模块时要先将引脚3也就是NET_SIG与单片机的P34口通过跳线帽短接。

一般来说,比赛时板子的跳线帽有5个,一个接在J5控制按键模式(矩阵键盘或独立键盘),一个接在J13控制扩展方式(IO模式、MM模式),一个接在J6控制继电器、蜂鸣器电源,最后两个接在J2控制使用超声波模块或者红外传感模块。所以是没有多余的跳线帽来短接NE555的,这个时候,J5、J13跳线帽是一定不能拿下来的,因为题目的基本要求就是这两个要短接,没有短接扣分甚至0分,一般来说,在省赛中超声波模块和NE555是二选一的,所以我们可以摘下超声波模块的跳线帽来短接NE555。

这样做可以直接使用定时器0的计数模式来读取NE555输出脉冲的频率

在板子上配置如下:

配置定时器

定时器0

在使用NE555时,需要使用到两个定时器,一个用作计数,一个用作计时。一般我们默认定时器0计数,定时器1计时。

红色方框内的就是我们要配置的,关于为什么要配置16位不可重装载模式的问题,后续会出一篇文章详细介绍定时器的内容里面会介绍。所以配置TMOD为0000 0101也就是05H。

在stc-isp中直接生成定时器0的函数

这样生成出来的代码是需要改动的,改动如下:

void Timer0_Init(void)		//1毫秒@12.000MHz
{
    AUXR &= 0x7F;			//定时器时钟12T模式
    TMOD &= 0xF0;			//设置定时器模式
    TMOD |= 0x05;			//改动处
    TL0 = 0;				//改动处 设置定时初始值为0,即不定时只计数
    TH0 = 0;				//改动处 设置定时初始值为0,即不定时只计数
    TF0 = 0;				//清除TF0标志
    TR0 = 1;				//使能定时器0中断
    //EA = 1; //不用使能中断
}

定时器1

定时器1配置如下:

void Timer1_Isr(void) interrupt 3
{
}

void Timer1_Init(void)		//1毫秒@12.000MHz
{
    AUXR &= 0xBF;			//定时器时钟12T模式
    TMOD &= 0x0F;			//设置定时器模式
    TL1 = 0x18;				//设置定时初始值
    TH1 = 0xFC;				//设置定时初始值
    TF1 = 0;				//清除TF1标志
    TR1 = 1;				//定时器1开始计时
    ET1 = 1;				//使能定时器1中断
    EA = 1;//改动处
}

定时器0大概是1s溢出一次,所以在定时器1的中断服务函数中,应该定时1s执行一次测量频率。

执行完测量频率后,要及时复位TL0、TH0重新计时。

idata unsigned int Time_1000ms; //定时1s
idata unsigned int f;//NE555频率

void Timer1_Isr(void) interrupt 3
{
    if(++Time_1000ms == 1000)
    {
        Time_1000ms = 0;
        f = (TH0 << 8 | TL0);
        TH0 = TL0 = 0;
    }
}

完整代码

idata unsigned int f;
idata unsigned int Time_1000ms;

/* 定时器0只用于计数 */
void Timer0_Init(void)		//1毫秒@12.000MHz
{
    TMOD &= 0xF0;			//设置定时器模式
    TMOD |= 0x05;
    TL0 = 0;				//设置定时初始值
    TH0 = 0;				//设置定时初始值
    TF0 = 0;				//清除TF0标志
    TR0 = 1;				//定时器0开始计时
}

/* 定时器1用于计时 */
void Timer1_Init(void)		//1毫秒@12.000MHz
{
    AUXR &= 0xBF;			//定时器时钟12T模式
    TMOD &= 0x0F;			//设置定时器模式
    TL1 = 0x18;				//设置定时初始值
    TH1 = 0xFC;				//设置定时初始值
    TF1 = 0;				//清除TF1标志
    TR1 = 1;				//定时器1开始计时
    ET1 = 1;
    EA = 1;
}

/* 定时器1中断服务函数 */
void Timer1_Server() interrupt 3
{
    /* NE555 */
    if(++Time_1s == 1000)
    {
        Time_1s = 0;
        f = (TH0 << 8) | TL0;
        TH0 = TL0 = 0;
    }
}

应用

题目:通过单片机P34引脚测量NE555输出的脉冲信号频率,用数码管的后五位显示(不考虑高位熄灭问题)。

#include <STC15F2K60S2.H>
#include "Init.h"
#include "LED.h"
#include "Key.h"
#include "Seg.h"

/* 变量声明区 */
unsigned char Key_Slow; //按键减速变量 10ms 
unsigned char Key_Val, Key_Down, Key_Up, Key_Old; //按键检测四件套
unsigned int Seg_Slow; //数码管减速变量 500ms
unsigned char Seg_Buf[] = {10,10,10,10,10,10,10,10,10,10};//数码管缓存数组
unsigned char Seg_Pos;//数码管缓存数组专用索引
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};//数码管小数点使能数组
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//LED显示数据存放数组
unsigned int Time_1s, f;

/* 按键处理函数 */
void Key_Proc()
{
    if(Key_Slow) return;
    Key_Slow = 1; //按键减速
    
    Key_Val = Key();
    Key_Down = Key_Val & ~Key_Old;	 
    Key_Up = ~Key_Val & Key_Old;
    Key_Old = Key_Val;
}

/* 信息处理函数 */
void Seg_Proc()
{
    if(Seg_Slow) return;
    Seg_Slow = 1; //数码管减速
    
    Seg_Buf[0] = 10;
    Seg_Buf[1] = 10;
    Seg_Buf[2] = 10;
    Seg_Buf[3] = f / 10000 % 10;
    Seg_Buf[4] = f / 1000 % 10;
    Seg_Buf[5] = f / 100 % 10;
    Seg_Buf[6] = f / 10 % 10;
    Seg_Buf[7] = f % 10;
}

/* 其他显示函数 */
void Led_Proc()
{
    ucLed[0] = 1;
}

/* 定时器0只用于计数 */
void Timer0_Init(void)		//1毫秒@12.000MHz
{
    TMOD &= 0xF0;			//设置定时器模式
    TMOD |= 0x05;
    TL0 = 0;				//设置定时初始值
    TH0 = 0;				//设置定时初始值
    TF0 = 0;				//清除TF0标志
    TR0 = 1;				//定时器0开始计时
}

/* 定时器1用于计时 */
void Timer1_Init(void)		//1毫秒@12.000MHz
{
    AUXR &= 0xBF;			//定时器时钟12T模式
    TMOD &= 0x0F;			//设置定时器模式
    TL1 = 0x18;				//设置定时初始值
    TH1 = 0xFC;				//设置定时初始值
    TF1 = 0;				//清除TF1标志
    TR1 = 1;				//定时器1开始计时
    ET1 = 1;
    EA = 1;
}

/* 定时器1中断服务函数 */
void Timer1_Server() interrupt 3
{
    if(++Key_Slow == 10) Key_Slow = 0; //按键延迟
    if(++Seg_Slow == 100) Seg_Slow = 0; //数码管延迟
    if(++Seg_Pos == 8) Seg_Pos = 0;	   //数码管显示
    Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
    LED_Disp(ucLed);
    
    /* NE555 */
    if(++Time_1s == 1000)
    {
        Time_1s = 0;
        f = (TH0 << 8) | TL0;
        TH0 = TL0 = 0;
    }
}

void main()
{
    Init();
    Timer0_Init();
    Timer1_Init();
    while(1)
    {
        Key_Proc(); 
        Seg_Proc();
        Led_Proc();
    }
}

结果演示:

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号