蓝桥杯单片机开发及应用-基础模块18-NE555定时器以及频率测量

目录

一、相关知识

        1.关于NE555定时器

        2.注意事项

二、所要实现的功能

三、代码实现

        1.参数定义

        2.138译码器通道选择函数

        3.初始化系统

        4.延时函数

        5.单个数码管显示函数

        6.数码管动态显示

        7.定时器初始化函数

        8.定时器0和1的中断执行函数

        9.完整代码

四、运行图片


关于共阳数码管、定时器等部分已在之前的文章中介绍过了,此处不再介绍了。

一、相关知识

        1.关于NE555定时器

                首先,NE555定时器的名字,来源于NE555内部存在三个5KΩ的电阻分压。NE555是一个纯硬件的设计,一旦硬件电路确定了就没有可编程的部分。NE555在电子电路设计中得到广泛应用,例如用作时钟电路、脉冲发生器、脉冲宽度调制器等。

                NE555有多种工作模式,但最常见的是单稳态和振荡器模式

                在单稳态模式下,NE555可以产生一个短暂的单脉冲信号。当触发端(TRIG)接收到一个低电平脉冲时,输出端(OUT)产生一个高电平脉冲,持续时间由外部的电阻和电容决定

                在振荡器模式下,NE555可以产生稳定的方波信号。通过调节外部的电阻和电容值,可以控制输出信号的频率和占空比。

                在蓝桥杯的板子上我们要使用的就是振荡器模式,通过拧电阻器RB3来改变控制输出信号的频率。

蓝桥杯单片机开发及应用-基础模块18-NE555定时器以及频率测量_第1张图片

        2.注意事项

                所谓频率,就是在单位时间内的周期数。NE555定时器的频率的单位是Hz。那么就需要用两个定时器,一个定时器负责计时1s,另一个定时器负责在这一秒内计数。结合单片机引脚的原理图和NE555定时器的原理图我们可以看到,NE555定时器的输出脚时P3.4,刚好是定时器T0的脚,那么我们就用定时器T0来计数,定时器T1来计时。

蓝桥杯单片机开发及应用-基础模块18-NE555定时器以及频率测量_第2张图片

二、所要实现的功能

        用跳线帽将板子右侧排针的SIGNAL引脚和P3.4进行短接,也就是将NE555发生的信号输入到单片机P3.4引脚。调节电阻器RB3来调节信号的频率,将频率数据用数码管进行显示,最左边的数码管显示频率的缩写“F”进行标识。

三、代码实现

        1.参数定义

#include 
#include "Delay_ms.h"


unsigned int count_f = 0;		// 测得频率
unsigned int last_count_f = 0;	// 频率传递
unsigned char i = 0;			// 计数值


// 不加 “code” 会影响单片机运行速度,会改变RAM,加了 code 之后內容就固定不变了,不会占用RAM
unsigned char code SMG_Duanma[19] = 
{
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
	0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0x00
};	// 0~F - . 全部

// 带点显示的数
unsigned char code SMG_Dian[10] = 
{
	0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10
};	// 0.~9.

        2.138译码器通道选择函数

// 通道选择函数
void HC138_Init( unsigned char channel )
{
	switch( channel )
	{
		case 0:
			P2 = (P2 & 0x1f) | 0x00;	// 0
		break;
		case 4:
			P2 = (P2 & 0x1f) | 0x80;	// Y4C
		break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;	// Y5C
		break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;	// Y6C
		break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;	// Y7C
		break;
	}
}

        3.初始化系统

// 初始化系统
void System_Init(void)
{
    // 关闭LED灯
	HC138_Init( 4 );
	P0 = 0xff;
 
    // 关闭蜂鸣器和继电器
	HC138_Init( 5 );
	P0 = 0xaf;		    // 1010 1111
	
    // 关闭通道选择
	HC138_Init( 0 );
}

        4.延时函数

void Delay_tms( unsigned int t )
{
	int i;
	while( t-- )
	{
		for( i=115 ; i>0 ; i-- )
		{}
	}
}

        5.单个数码管显示函数

// 数码管显示
void SMG_Light( unsigned char pos , unsigned char dat)
{
	HC138_Init( 6 );
	P0 = 0x01 << pos;
	HC138_Init( 7 );
	P0 = dat;
}

        6.数码管动态显示

// 数码管动态显示
void SMG_Show(void)
{
	SMG_Light( 0 , SMG_Duanma[ 15 ] );	// F
	Delay_tms( 10 );
	SMG_Light( 1 , 0xff );
	Delay_tms( 10 );
	SMG_Light( 2 , 0xff );
	Delay_tms( 10 );

	if( last_count_f > 9999 )	// 最高五位数,到了几位就亮几位
	{
		SMG_Light( 3 , SMG_Duanma[ last_count_f / 10000 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 999 )
	{
		SMG_Light( 4 , SMG_Duanma[ ( last_count_f / 1000 ) % 10 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 99 )
	{
		SMG_Light( 5 , SMG_Duanma[ ( last_count_f / 100 ) % 10 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 9 )
	{
		SMG_Light( 6 , SMG_Duanma[ ( last_count_f / 10 ) % 10 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 0 )
	{
		SMG_Light( 7 , SMG_Duanma[ last_count_f % 10 ] );
		Delay_tms( 10 );
	}
}

        7.定时器初始化函数

// 定时器初始化
void Timer_Init(void)
{
	TMOD = 0x16;	// 0001 0110
	ET0 = 1;
	ET1 = 1;
	EA = 1;
	TR0 = 1;
	TR1 = 1;
	
	// 定时器0用作计数,8位自动重装载,只要随机外来一个脉冲信号就溢出
	TH0 = 0xff;
	TL0 = 0xff;
	
	// 定时器1用作定时
	TH1 = ( 65535 - 50000 ) / 256;
	TL1 = ( 65535 - 50000 ) % 256;
}

        8.定时器0和1的中断执行函数

// 定时器0中断函数
void Timer0() interrupt 1
{
	count_f++;
}


// 定时器1中断函数
void Timer1() interrupt 3
{
	TH1 = ( 65535 - 50000 ) / 256;
	TL1 = ( 65535 - 50000 ) % 256;
	i++;
	if( i == 20 )	// 1s时间到
	{
		i = 0;					// 计数清零
		last_count_f = count_f;	// 取出频率
		count_f = 0;			// 下一秒频率又重新测,即清零
	}
}

        9.完整代码

#include 
#include "Delay_ms.h"


unsigned int count_f = 0;		// 测得频率
unsigned int last_count_f = 0;	// 频率传递
unsigned char i = 0;			// 计数值


// 不加 “code” 会影响单片机运行速度,会改变RAM,加了 code 之后內容就固定不变了,不会占用RAM
unsigned char code SMG_Duanma[19] = 
{
	0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
	0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0x00
};	// 0~F - . 全部

// 带点显示的
unsigned char code SMG_Dian[10] = 
{
	0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10
};	// 0.~9.


// 通道选择函数
void HC138_Init( unsigned char channel )
{
	switch( channel )
	{
		case 0:
			P2 = (P2 & 0x1f) | 0x00;	// 0
		break;
		case 4:
			P2 = (P2 & 0x1f) | 0x80;	// Y4C
		break;
		case 5:
			P2 = (P2 & 0x1f) | 0xa0;	// Y5C
		break;
		case 6:
			P2 = (P2 & 0x1f) | 0xc0;	// Y6C
		break;
		case 7:
			P2 = (P2 & 0x1f) | 0xe0;	// Y7C
		break;
	}
}


// 初始化系统
void System_Init(void)
{
    // 关闭LED灯
	HC138_Init( 4 );
	P0 = 0xff;
 
    // 关闭蜂鸣器和继电器
	HC138_Init( 5 );
	P0 = 0xaf;		    // 1010 1111
	
    // 关闭通道选择
	HC138_Init( 0 );
}


// 定时器初始化
void Timer_Init(void)
{
	TMOD = 0x16;	// 0001 0110
	ET0 = 1;
	ET1 = 1;
	EA = 1;
	TR0 = 1;
	TR1 = 1;
	
	// 定时器0用作计数,8位自动重装载,只要随机外来一个脉冲信号就溢出
	TH0 = 0xff;
	TL0 = 0xff;
	
	// 定时器1用作定时
	TH1 = ( 65535 - 50000 ) / 256;
	TL1 = ( 65535 - 50000 ) % 256;
}


// 定时器0中断函数
void Timer0() interrupt 1
{
	count_f++;
}


// 定时器1中断函数
void Timer1() interrupt 3
{
	TH1 = ( 65535 - 50000 ) / 256;
	TL1 = ( 65535 - 50000 ) % 256;
	i++;
	if( i == 20 )	// 1s时间到
	{
		i = 0;					// 计数清零
		last_count_f = count_f;	// 取出频率
		count_f = 0;			// 下一秒频率又重新测,即清零
	}
}


// 数码管显示
void SMG_Light( unsigned char pos , unsigned char dat )
{
	HC138_Init( 6 );
	P0 = 0x01 << pos;
	HC138_Init( 7 );
	P0 = dat;
}


// 数码管动态显示
void SMG_Show(void)
{
	SMG_Light( 0 , SMG_Duanma[ 15 ] );	// F
	Delay_tms( 10 );
	SMG_Light( 1 , 0xff );
	Delay_tms( 10 );
	SMG_Light( 2 , 0xff );
	Delay_tms( 10 );

	if( last_count_f > 9999 )	// 最高五位数,到了几位就亮几位
	{
		SMG_Light( 3 , SMG_Duanma[ last_count_f / 10000 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 999 )
	{
		SMG_Light( 4 , SMG_Duanma[ ( last_count_f / 1000 ) % 10 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 99 )
	{
		SMG_Light( 5 , SMG_Duanma[ ( last_count_f / 100 ) % 10 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 9 )
	{
		SMG_Light( 6 , SMG_Duanma[ ( last_count_f / 10 ) % 10 ] );
		Delay_tms( 10 );
	}
	if( last_count_f > 0 )
	{
		SMG_Light( 7 , SMG_Duanma[ last_count_f % 10 ] );
		Delay_tms( 10 );
	}
}




int main(void)
{
	System_Init();
	Timer_Init();
	while(1)
	{
		SMG_Show();
	}
}

四、运行图片

蓝桥杯单片机开发及应用-基础模块18-NE555定时器以及频率测量_第3张图片

你可能感兴趣的:(#,蓝桥杯基础模块,蓝桥杯,单片机,51单片机,c语言)