08 蓝桥杯单片机设计与开发_基础模块_NE555

一、前言

07 蓝桥杯单片机设计与开发_基础模块_串口通信-CSDN博客,承接上文,本文将继续介绍剩余蓝桥杯涉及模块(NE555以及超声波测距),为大家做出详细编程指导。

二、NE555

NE555,也称为LM555,是一种经典的集成电路(IC)芯片,是一款常用的定时器和脉冲宽度调制(PWM)发生器。NE555被广泛应用于各种电子电路中,例如时钟电路、脉冲发生器、电子闹钟、计时器、PWM控制器等,是蓝桥杯比赛中常见的一道题目。

1、NE555原理剖析

NE555实现起来较简单,只需设置一个定时器1用于计时,计数器0用于计数,每秒计算NE555接收脉冲数,实现频率计算,代码如下所示。

2、整体代码

由于考虑初学者基础较为薄弱,因此将完整的 main.cpp 代码贴出来,包含中断函数、矩阵键盘、数码管显示等,并且在关键处进行了注释,希望对大家有所帮助。

// 包含头文件
#include "STC15F2K60S2.h"
// 数据类型定义
#define u8 unsigned char
#define u16 unsigned int
// 8位数码管状态
u8 dspbuf[8] = {10,10,10,10,10,10,10,10};  
u8 code tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
    
u8 dspcom = 0;
bit key_flag = 0,NE555_flag = 0;
// 573锁存器封装成函数
void door(u8 choose,input)
{
	P2 = (P2 & 0x1f) | choose;
	P0 = input;
	P2 &= 0x1f;	
}
// 关数码管
void clo_num()
{
	dspbuf[0] = 10;
	dspbuf[1] = 10;
	dspbuf[2] = 10;
	dspbuf[3] = 10;
	dspbuf[4] = 10;
	dspbuf[5] = 10;
	dspbuf[6] = 10;
	dspbuf[7] = 10;
}
// 关灯、蜂鸣器
void all_init()
{
 	door(0x80,0xff);
	door(0xa0,0xaf);
	clo_num();
}
// 数码管显示函数
void display()
{			  
	door(0xe0,0xff);

	door(0xc0,0x01<<dspcom);
	door(0xe0,tab[dspbuf[dspcom++]]);
	
	if(dspcom >= 8)
		dspcom = 0;
}
// 矩阵键盘,接KBD
u8 keypress = 0,keyvalue = 0xff,keyread = 0;
u8 Read_key()
{
    u8 key_m,cal;
    
    P3 = 0xf0;P42 = 1;P44 = 1;
  	P36 = P42;P37 = P44;
    key_m = P3&0xf0;

    if(key_m != 0xf0) 
        keypress++;
   else
        keypress = 0; 
    
    if(keypress == 3)
    {
		  keypress = 0;
	  	keyread = 1;
		  switch(key_m)
        {
            case 0x70:cal = 0;break;                
            case 0xb0:cal = 1;break;    
            case 0xd0:cal = 2;break;    
            case 0xe0:cal = 3;break;
        }
        
        P3 = 0x0f;P42 = 0;P44 = 0;
        key_m = P3&0x0f;
        
			switch(key_m)
					{
							case 0x0e:keyvalue = (4*cal+7);break;                
							case 0x0d:keyvalue = (4*cal+6);break;    
							case 0x0b:keyvalue = (4*cal+5);break;    
							case 0x07:keyvalue = (4*cal+4);break;
					}
    }

    P3 = 0x0f;P42 = 0;P44 = 0;
    key_m = P3&0x0f;
	
    if((keyread) && (key_m == 0x0f))
    {
        keyread = 0;
        return keyvalue;	
    }
    return 0xff; 
}

// 定时器1、计数器0 初始化函数
void Timer_Init(void)		//2毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	//△注意:需要用 |=
	TMOD |= 0x05;		//定时器T1(00:自动重装载)  计数器T0(01:16位不重装,TL0、TH0全用)    0000 0101(第3、6位,0:定时,1:计数)
	TL1 = 0x40;		//设置定时初值
	TH1 = 0xA2;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	
  TR0 = 1;        //开计数器0
	ET0 = 1;
	ET1 = 1;
	EA = 1;         //打开总中断        
}


void main()          //****************************************************************************************************
{
	u8 key_re,NE555_w = 0;
	u16 freq = 0;        //定义频率
	
	all_init();
	Timer_Init();
	
	while(1)
	{
		if(key_flag)
		{
			key_flag = 0;
			key_re = Read_key();
			
			if(key_re != 0xff)
			{
				switch(key_re)
				{
					case 7:NE555_w ^= 1;break;   //用不了num_close()
					case 6:;break;
					case 5:;break;
					case 4:door(0x80,0x55);break;
				}
			}
		}
		// 每秒计算NE555频率
		// 短接signal和P34,改变Rb3可改变频率
		if(NE555_flag)
		{
			NE555_flag = 0;
			TR0 = 0;      //关计数器0
			
			freq = TL0+TH0*256;
			
			TH0 = 0;      //清空计数
			TL0 = 0;      //清空计数
			
			TR0 = 1;      //打开计数器0
		}
		// 数码管实时显示NE555检测的频率值
		if((key_flag) && (NE555_w))
		{
			key_flag = 0;
			
			dspbuf[0] = freq/10000;
			dspbuf[1] = freq%10000/1000;
			dspbuf[2] = freq%1000/100;
			dspbuf[3] = freq%100/10;
			dspbuf[4] = freq%10;
		}
	}
}
// 定时器 1 中断服务函数
void timer1() interrupt 3
{
	static u8 t_20ms = 0;
	static u16 t_1000ms = 0;

	display();
	
	t_20ms++;
	t_1000ms++;
	
	if(t_20ms >= 10)
	{
		t_20ms = 0;
		key_flag = 1;
	}
	// 1s计时,用于统计1s内NE555接收脉冲数->计算频率
	if(t_1000ms >= 500)
	{
		t_1000ms = 0;
		NE555_flag = 1;
	}
}

至此,本次 NE555 已介绍完毕。

你可能感兴趣的:(蓝桥杯,STC89C52单片机入门,蓝桥杯,单片机)