蓝桥杯模块学习3——蜂鸣器与继电器(深夜学习——单片机)

目录

目录

一、硬件部分:

1、138译码器和573锁存器:

2、ULN2003达林顿管:

(1)原理图:

 (2)作用:

(3)为什么要用达林顿管改变电路特性,不能直接用IO口像驱动LED灯一样 ,驱动蜂鸣器和继电器吗?(需要一定的电路知识)

3、整体电路理解:

二、 参考代码:

1、代码思路:

2、宏定义:

 3、主函数:(更直观代码)

4、主函数:(模块化代码) 

5、补充代码:


一、硬件部分:

1、138译码器和573锁存器:

具体可回顾之前LED灯的文章:

(1条消息) 蓝桥杯模块学习2——LED灯(深夜学习——单片机)_佛科院深夜学习的博客-CSDN博客https://blog.csdn.net/weixin_63568691/article/details/128431461?spm=1001.2014.3001.5501

2、ULN2003达林顿管:

(1)原理图:

 (2)作用:

(1)改变电路特性,以提供大电流大电压

(2)由下图可知,ULN2003是反输出

(3)为什么要用达林顿管改变电路特性,不能直接用IO口像驱动LED灯一样 ,驱动蜂鸣器和继电器吗?(需要一定的电路知识)

(a)使用戴维南等效法,可将单片机IO口等效为一个5V电压源和一个十分大电阻组成的二端口网络,当外部电路接入IO口时,尽管它得到的是5V的电压,但是电流十分小,导致驱动功率即能量极小,所以除了LED灯,单片机基本都是用作控制器,而不是驱动器

(b)由于蜂鸣器和继电器需要较高的功率以支撑它们完成高频振动、产生较强的磁力,所以需要用ULN2003来驱动

3、整体电路理解:

                           蜂鸣器                                                                   继电器

(1)在硬件平台并没有找到J6接口,应该是默认把2、3连接的

(2)VB指的使两个相连,即蜂鸣器和继电器一端都接VCC,我们只需要提供低电平就可以使二者工作(具体步骤不再分析,跟驱动LED同理)

二、 参考代码:

        实现功能:8路LED灯闪烁三次后熄灭,接着依次点亮LED灯,继电器吸合一会后断开,然后依次熄灭LED灯,蜂鸣器鸣叫一会后关闭

1、代码思路:

        与点亮lLED类似,利用138译码器将573锁存器LE置高电平,然后将相应的口置高电平就行

2、宏定义:

#ifndef _PUBLIC_H
#define _PUBLIC_H

#include <reg52.h>

#define u8 unsigned char
#define u16 unsigned int

void Delay_1ms(u16 num);
	
#endif
#include "Public.h"
// 延时函数(最小约1ms@12MHz)
void Delay_1ms(u16 num)
{
  unsigned int i;
  while(num--)
    for(i=0; i<628; i++);
}

 3、主函数:(更直观代码)

// 使用程序前,将J13调整为IO模式(2-3脚短接)
#include "reg52.h"
#include "Public.h"

sbit HC138_A2 = P2^7;
sbit HC138_A1 = P2^6;
sbit HC138_A0 = P2^5;


#define buzzer 0X01<<6//相当于二进制01000000,代表P06
#define relay  0X01<<4
#define LED_LE_ON 4//相当于Y4
#define Buzzer_Relay_LE_ON 5
#define LE_OFF 0

void HC138_Y(u8 num);

// 主函数
void main(void)
{
	u8 i;
  while(1)
  { 
		//关闭蜂鸣器和继电器
		HC138_Y(Buzzer_Relay_LE_ON);
		P0=0x00;	
		//全部连续闪三下
		HC138_Y(LED_LE_ON);
    for(i=0;i<3;i++)
		{
			P0=0x00;
			Delay_1ms(300);
			P0=0xff;
			Delay_1ms(300);
		}		
		Delay_1ms(800);
		//顺序点亮
		HC138_Y(LED_LE_ON);
		for(i=0;i<=8;i++)
		{
			P0=0XFF<<i;
			Delay_1ms(100);
		}
		Delay_1ms(800);
		//继电器闭合一段时间
		HC138_Y(Buzzer_Relay_LE_ON);
		P0=relay;//realy是宏定义的01000000,即P06
		Delay_1ms(300);
		P0=0x00;
		Delay_1ms(800);
		//顺序熄灭
		HC138_Y(LED_LE_ON);
		for(i=0;i<=8;i++)
		{
			P0=~(0XFF<<i);
			Delay_1ms(100);
		}
		Delay_1ms(800);
		//蜂鸣器鸣叫一段时间
		HC138_Y(Buzzer_Relay_LE_ON);
    P0=buzzer;
		Delay_1ms(300);
		P0=0x00;
		Delay_1ms(800);
		
		HC138_Y(LE_OFF);
  }
}
/*
	输入变量:4-7
	输出变量:无
	功能:操作138译码器,4-7分别对应Y4-Y7,其余都会使译码器不起作用
*/
void HC138_Y(u8 num)
{
	 switch(num)
	 {
		 case 4:HC138_A2=1;HC138_A1=0;HC138_A0=0;break;
		 case 5:HC138_A2=1;HC138_A1=0;HC138_A0=1;break;
		 case 6:HC138_A2=1;HC138_A1=1;HC138_A0=0;break;
		 case 7:HC138_A2=1;HC138_A1=1;HC138_A0=1;break;
		 default:HC138_A2=0;HC138_A1=0;HC138_A0=0;
	 }
}

4、主函数:(模块化代码) 、

// 使用程序前,将J13调整为IO模式(2-3脚短接)
#include "reg52.h"
#include "Public.h"

sbit HC138_A2 = P2^7;
sbit HC138_A1 = P2^6;
sbit HC138_A0 = P2^5;


#define buzzer 0X01<<6//相当于二进制01000000,代表P06
#define relay  0X01<<4
#define LED_LE_ON 4//相当于Y4
#define Buzzer_Relay_LE_ON 5
#define LE_OFF 0

void Ouput_P0(u8 channel,u8 dat);

// 主函数
void main(void)
{
	u8 i;
  while(1)
  { 
		//关闭蜂鸣器和继电器
		Ouput_P0(Buzzer_Relay_LE_ON,0x00);
		//全部连续闪三下
    for(i=0;i<3;i++)
		{
			Ouput_P0(LED_LE_ON,0x00);
			Delay_1ms(300);
			Ouput_P0(LED_LE_ON,0xff);
			Delay_1ms(300);
		}		
		Delay_1ms(800);
		//顺序点亮
		for(i=0;i<=8;i++)
		{
			Ouput_P0(LED_LE_ON,0XFF<<i);
			Delay_1ms(100);
		}
		Delay_1ms(800);
		//继电器闭合一段时间
		Ouput_P0(Buzzer_Relay_LE_ON,relay);//realy是宏定义的01000000,即P06
		Delay_1ms(300);
		Ouput_P0(Buzzer_Relay_LE_ON,0x00);
		Delay_1ms(800);
		//顺序熄灭
	
		for(i=0;i<=8;i++)
		{
			Ouput_P0(LED_LE_ON,~(0XFF<<i));
			Delay_1ms(100);
		}
		Delay_1ms(800);
		//蜂鸣器鸣叫一段时间
		Ouput_P0(Buzzer_Relay_LE_ON,buzzer);
		Delay_1ms(300);
		Ouput_P0(Buzzer_Relay_LE_ON,0x00);
		Delay_1ms(800);
		
		Ouput_P0(LE_OFF,0x00);
  }
}
/*
	输入变量:4-7
	输出变量:无
	功能:操作138译码器,4-7分别对应Y4-Y7,其余都会使译码器不起作用
*/
void HC138_Y(u8 num)
{
	 switch(num)
	 {
		 case 4:HC138_A2=1;HC138_A1=0;HC138_A0=0;break;
		 case 5:HC138_A2=1;HC138_A1=0;HC138_A0=1;break;
		 case 6:HC138_A2=1;HC138_A1=1;HC138_A0=0;break;
		 case 7:HC138_A2=1;HC138_A1=1;HC138_A0=1;break;
		 default:HC138_A2=0;HC138_A1=0;HC138_A0=0;
	 }
}

/*
	输入变量:
		channel:4-7,对应Y4-Y7
		dat:0-65535,P0口输出数据
	输出变量:无
	功能:操作138译码器,同时控制P0输出
*/
void Ouput_P0(u8 channel,u8 dat)
{
	HC138_Y(channel);
	P0=dat;
}

5、补充代码:

(1)我们都知道与“0”相与为“0”, 与“1”相与不变;与“1”相或为“1”, 与“0”相与不变

(2)具体到位与、位或中就可以使实现对具体某几位进行操作,如在操作135译码器时,我想直接对P05-P27操作:

//等价于HC138_A2=1;HC138_A1=0;HC138_A0=0;
P0 = (P0 & 0x1f) | 0x80;

(3)官方给的例程也是这样操作的,但是就我自己而言,更喜欢把每一位定义出来操作,这样会更直观

更新:真香警告!终于明白这样操作的原因了,这样可以尽可能提高可移植性,我只需要把这段代码直接一直到其他地方就能直接用,而不需要修改或者需要把位定义也要复制过去

6、最新代码:(本来想把全部定义都去删掉的,但是我想了一下,封装好的函数才有移植的必要,如果是要整个功能都要移植的话,只需要整个文件移植就行,不用管宏定义)

// 使用程序前,将J13调整为IO模式(2-3脚短接)
#include "reg52.h"
#include "Public.h"

#define buzzer 0X01<<6//相当于二进制01000000,代表P06
#define relay  0X01<<4
#define LED_LE_ON 4//相当于Y4
#define Buzzer_Relay_LE_ON 5
#define LE_OFF 0

void Ouput_P0(u8 channel,u8 dat);
void Close_All(void);
// 主函数
void main(void)
{
	u8 i;
  while(1)
  { 
		//关闭蜂鸣器和继电器
		Close_All();
		//全部连续闪三下
    for(i=0;i<3;i++)
		{
			Ouput_P0(LED_LE_ON,0x00);
			Delay_1ms(300);
			Ouput_P0(LED_LE_ON,0xff);
			Delay_1ms(300);
		}		
		Delay_1ms(800);
		//顺序点亮
		for(i=0;i<=8;i++)
		{
			Ouput_P0(LED_LE_ON,0XFF<<i);
			Delay_1ms(100);
		}
		Delay_1ms(800);
		//继电器闭合一段时间
		Ouput_P0(Buzzer_Relay_LE_ON,relay);//realy是宏定义的01000000,即P06
		Delay_1ms(300);
		Ouput_P0(Buzzer_Relay_LE_ON,0x00);
		Delay_1ms(800);
		//顺序熄灭
	
		for(i=0;i<=8;i++)
		{
			Ouput_P0(LED_LE_ON,~(0XFF<<i));
			Delay_1ms(100);
		}
		Delay_1ms(800);
		//蜂鸣器鸣叫一段时间
		Ouput_P0(Buzzer_Relay_LE_ON,buzzer);
		Delay_1ms(300);
		Ouput_P0(Buzzer_Relay_LE_ON,0x00);
		Delay_1ms(800);
		
		Ouput_P0(LE_OFF,0x00);
  }
}
/*
	输入变量:4-7
	输出变量:无
	功能:操作138译码器,4-7分别对应Y4-Y7,其余都会使译码器不起作用
*/
void HC138_Y(u8 num)
{
	 switch(num)
	 {
		 case 4:P2 = (P2 & 0x1f) | 0x80;break;
		 case 5:P2 = (P2 & 0x1f) | 0xA0;break;
		 case 6:P2 = (P2 & 0x1f) | 0xC0;break;
		 case 7:P2 = (P2 & 0x1f) | 0xE0;break;
		 default:P2 = (P2 & 0x1f) | 0x00;
	 }
}

/*
	输入变量:
		channel:4-7,对应Y4-Y7
		dat:0-65535,P0口输出数据
	输出变量:无
	功能:操作138译码器,同时控制P0输出
*/
void Ouput_P0(u8 channel,u8 dat)
{
	HC138_Y(channel);
	P0 = dat;
}

/*
	输入变量:无
	输出变量:无
	功能:关闭蜂鸣器和继电器
*/
void Close_All(void)
{
	P2 = (P2 & 0x1f) | 0xA0;
	P0 = 0x00;
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值