使用STM32单片机控制通道选择器74HC4051

使用STM32单片机控制通道选择器74HC4051

前言

最近做了一个改装某厂家遥控器的项目,该遥控器使用了一款2.4G串口透传模块,按下遥控器上的按键,模块IO就会接地,然后发射控制信号,改装主要是使用MCU去控制该模块的IO。

控制方法有很多,最简单的方法是使用8个GPIO直连该模块,出于兼容不同MCU的目的,使用了74HC4051这款通道选择器对串口透传模块进行控制,且节约了四个IO,因为这款通道选择器仅需四个控制信号。

74HC4051介绍

74HC4051是一款通道选择器,采用CMOS工艺制造。它包含一个8选1模拟开关、3个控制输入端和一个使能端。

image-20240806175535220

image-20240806175551705

E:使能端,低电平时芯片工作,高电平时芯片处于关闭状态。

S0-S2:控制输入端,用于选择8个通道中的一个。

Y:输出端,输出所选通道的模拟信号。

Z:公共端,与所选通道的模拟信号相连。

一般情况下GND和VEE可以接在一起

真值表如下图所示

image-20240806180306166

原理图示例如下

image-20240806175943132

网络标签Y0-Y7连接了八个LED灯,如下图所示

image-20240806180038808

理论上同一时间只有一颗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循环往复亮起。

效果展示

在这里插入图片描述
在这里插入图片描述

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32是意法半导体公司提供的一系列高性能32位单片机控制器,HAL代表硬件抽象层,是一种软件库,用于简化底层硬件的访问和控制。74HC595是一种串行输入、并行输出的移位寄存器芯片,常用于扩展I/O口。 使用STM32 HAL库驱动74HC595芯片控制LED可以实现对多个LED的灯光控制。 首先,需要通过STM32 HAL库中GPIO库的函数设置74HC595芯片的串行输入数据引脚(如DS引脚)、时钟输入引脚(如SHCP引脚)和存储器锁存使能引脚(如STCP引脚)为输出模式。然后,使用STM32 HAL库的GPIO库函数将DS引脚输出的数据序列加载到74HC595芯片的移位寄存器中。最后,使用STM32 HAL库的GPIO库函数将相应的数据序列时钟输入到74HC595芯片,将寄存器中的数据并行输出到控制LED的引脚上。 通过这种方式,可以利用74HC595芯片的扩展性,实现对大量LED的灯光控制,减少了STM32芯片上I/O口资源的占用。同时,使用STM32 HAL库的函数可以简化编程的复杂性,提高开发效率。 综上所述,通过STM32 HAL库驱动74HC595芯片控制LED可以实现灯光控制的灵活性和扩展性,并且减少了编程的复杂度。 ### 回答2: STM32是一种微控制器系列,而HAL代表STM32的硬件抽象层(Hardware Abstraction Layer)。74HC595是一种8位串行输入/并行输出移位寄存器,可以用来驱动LED灯。 在使用STM32 HAL和74HC595驱动LED的过程中,首先需要将74HC595连接到STM32上。可以通过将STM32的引脚与74HC595的输入引脚连接起来来实现。然后,通过STM32 HAL提供的库函数,可以通过SPI或GPIO控制器来传输数据到74HC595。 使用STM32 HAL和74HC595驱动LED的方法如下: 1. 初始化SPI或GPIO控制器。根据具体的STM32型号和使用的接口,选择合适的SPI或GPIO控制器,并进行初始化设置。 2. 定义和初始化74HC595相关的引脚。使用STM32 HAL提供的库函数,设置74HC595的数据引脚(DS)、时钟引脚(SHCP)以及锁存引脚(STCP或RCLK)为输出。 3. 编写发送函数。使用STM32 HAL提供的库函数,编写一个发送函数来发送数据到74HC595。如果使用SPI控制器,可以使用HAL_SPI_Transmit函数发送数据;如果使用GPIO控制器,可以使用HAL_GPIO_WritePin函数控制引脚的电平。 4. 编写控制函数。编写一个控制函数,将需要展示的LED灯的状态信息写入数据缓冲区,并调用发送函数将数据发送到74HC595。 5. 在主函数中调用控制函数。在主函数中调用控制函数来控制LED灯的状态。可以通过循环调用控制函数,实现LED的闪烁等效果。 综上所述,使用STM32 HAL和74HC595驱动LED需要连接硬件和编写相应的控制函数,并通过SPI或GPIO控制器来实现数据的传输和发送。通过控制LED灯的状态,可以实现各种效果,如开关、闪烁等。 ### 回答3: STM32单片机)是一种基于ARM Cortex-M内核的微控制器系列,提供了丰富的硬件外设和HAL(硬件抽象层)库,用于简化软件开发过程。 74HC595是一种串行输入并行输出的移位寄存器,常用于扩展输出口的数量。它可以通过串行数据输入来控制多个LED灯的点亮状态。通过STM32的HAL库,我们可以轻松地控制74HC595来控制LED灯。 首先,我们需要设置STM32的引脚用作SPI(串行外设接口)的输出引脚。然后,我们需要初始化SPI外设,并设置参数如数据大小、控制模式等。接下来,我们可以使用HAL库中提供的函数来发送数据到74HC595。 当我们想要控制LED灯时,我们可以将需要点亮的LED编号、引脚电平等信息转换为二进制形式,然后通过SPI发送给74HC595。通过移位寄存器的功能,我们可以依次将每一位数据输出到74HC595的串行输入引脚,然后通过控制引脚的上升沿时钟信号来将数据发送到并行输出引脚。 这样,通过循环发送数据到74HC595,我们可以控制多个LED的点亮状态。例如,可以将某一位的状态设置为高电平来点亮对应的LED灯。 总而言之,使用STM32的HAL库和74HC595移位寄存器,我们能够简化控制多个LED灯的过程,使得硬件开发更加高效。通过设置引脚和使用SPI通信,我们可以实现对LED灯的灵活控制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值