使用STM32单片机控制通道选择器74HC4051
前言
最近做了一个改装某厂家遥控器的项目,该遥控器使用了一款2.4G串口透传模块,按下遥控器上的按键,模块IO就会接地,然后发射控制信号,改装主要是使用MCU去控制该模块的IO。
控制方法有很多,最简单的方法是使用8个GPIO直连该模块,出于兼容不同MCU的目的,使用了74HC4051这款通道选择器对串口透传模块进行控制,且节约了四个IO,因为这款通道选择器仅需四个控制信号。
74HC4051介绍
74HC4051是一款通道选择器,采用CMOS工艺制造。它包含一个8选1模拟开关、3个控制输入端和一个使能端。
E:使能端,低电平时芯片工作,高电平时芯片处于关闭状态。
S0-S2:控制输入端,用于选择8个通道中的一个。
Y:输出端,输出所选通道的模拟信号。
Z:公共端,与所选通道的模拟信号相连。
一般情况下GND和VEE可以接在一起
真值表如下图所示
原理图示例如下
网络标签Y0-Y7连接了八个LED灯,如下图所示
理论上同一时间只有一颗LED导通,所以只用了一颗限流电阻。
另外一颗HC4051的Y0-Y7接入了透传模块的IO,公共端接地,通过使能端和S0-S2,即可把相应的IO口拉低
示例代码
HC4051.h文件代码如下
#include "sys.h"
//以下为IO定义
#define GPIO_Clk_EN RCC_APB2Periph_GPIOA
#define GPIO_Port_EN GPIOA
#define GPIO_Pin_EN GPIO_Pin_1
#define GPIO_Clk_S0 RCC_APB2Periph_GPIOA
#define GPIO_Port_S0 GPIOA
#define GPIO_Pin_S0 GPIO_Pin_2
#define GPIO_Clk_S1 RCC_APB2Periph_GPIOA
#define GPIO_Port_S1 GPIOA
#define GPIO_Pin_S1 GPIO_Pin_3
#define GPIO_Clk_S2 RCC_APB2Periph_GPIOA
#define GPIO_Port_S2 GPIOA
#define GPIO_Pin_S2 GPIO_Pin_4
//以下为函数定义
void HC4051_Init(void);//初始化HC4051
void HC4051_SetChannel(uint8_t channel);//设置HC4051的通道
void HC4051_Enable(void);//使能HC4051
void HC4051_Disable(void);//禁止HC4051
HC4051.c文件代码如下
#include "HC4051.h"
void HC4051_Init(void)//初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(GPIO_Clk_EN | GPIO_Clk_S0 | GPIO_Clk_S1 | GPIO_Clk_S2, ENABLE);//使能GPIO时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_EN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIO_Port_EN, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_S0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIO_Port_S0, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_S1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIO_Port_S1, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_S2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIO_Port_S2, &GPIO_InitStructure);
//IO输出高电平,放止误触发
GPIO_SetBits(GPIO_Port_EN, GPIO_Pin_EN);
GPIO_SetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_SetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_SetBits(GPIO_Port_S1, GPIO_Pin_S2);
}
void HC4051_Disable(void)
{
GPIO_SetBits(GPIO_Port_EN, GPIO_Pin_EN);
}
void HC4051_Enable(void)
{
GPIO_ResetBits(GPIO_Port_EN, GPIO_Pin_EN);
}
void HC4051_SetChannel(uint8_t channel)
{
switch (channel)
{
case 0:
GPIO_ResetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_ResetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_ResetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
case 1:
GPIO_SetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_ResetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_ResetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
case 2:
GPIO_ResetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_SetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_ResetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
case 3:
GPIO_SetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_SetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_ResetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
case 4:
GPIO_ResetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_ResetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_SetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
case 5:
GPIO_SetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_ResetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_SetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
case 6:
GPIO_ResetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_SetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_SetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
case 7:
GPIO_SetBits(GPIO_Port_S0, GPIO_Pin_S0);
GPIO_SetBits(GPIO_Port_S1, GPIO_Pin_S1);
GPIO_SetBits(GPIO_Port_S2, GPIO_Pin_S2);
break;
}
}
main.c文件代码如下
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "HC4051.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600); // 串口初始化为9600
delay_init(); // 延时函数初始化
HC4051_Init(); // HC4051初始化
while (1)
{
HC4051_Disable();
HC4051_SetChannel(0);
HC4051_Enable();
delay_ms(1000);
HC4051_Disable();
HC4051_SetChannel(1);
HC4051_Enable();
delay_ms(1000);
HC4051_Disable();
HC4051_SetChannel(2);
HC4051_Enable();
delay_ms(1000);
HC4051_Disable();
HC4051_SetChannel(3);
HC4051_Enable();
delay_ms(1000);
HC4051_Disable();
HC4051_SetChannel(4);
HC4051_Enable();
delay_ms(1000);
HC4051_Disable();
HC4051_SetChannel(5);
HC4051_Enable();
delay_ms(1000);
HC4051_Disable();
HC4051_SetChannel(6);
HC4051_Enable();
delay_ms(1000);
HC4051_Disable();
HC4051_SetChannel(7);
HC4051_Enable();
delay_ms(1000);
}
}
其功能就是每隔1s换一个通道,具体效果就是LED1-LED8循环往复亮起。
效果展示