1、概述

74HC4051是- -款八选一模拟开关电路,内置3个地址选择端(A0~ A2), 低有效的使能输入端(E),8路独立的输入/输出端(Y0~Y7) 及公共输入/输出端(Z)。

电路内部有8个双向模拟开关,每个开关的一-端连接到独立的输入输出(Y0~Y7)端,另一端连
接到公共的输入/输出(Z) 端。

当E为低电平时,通过A0 ~ A2选择- - 个通路的开关处于低阻导通状态。当E为高电平时,A0 ~ A2设置无效,所有开关处于高阻关断状态。如果需要切换开关状态,就必须使用使能输入端( E), VpD和Vss是连接到数字控制输入端(A0 ~ A2和E)的电源电压。(Vpp-Vs)的范围是3~9V。

模拟输入输出(Y0~Y7和Z)能够在最高VpD, 最低VEe之间变化。VpD-VEE不会超过9V.
对于用做数字多路选择开关,VEE 和Vss是连在一起的(通常接地)。
74HC4051主要应用于模拟多路选择开关、数字多路选择开关及信号选通。

[单片机框架] [drivers] [hc4051] 8路模拟分流器_嵌入式硬件

/********************************************************************************
* @file multiplexer_8ch_core.c
* @author jianqiang.xue
* @version V1.0.0
* @date 2022-02-09
* @brief multiplexer简称mux
1. 通过A0-A2电平,控制X0-7中哪个脚接入公共脚Z0
2. A0-A2电平组成0-7,对应X0-7。
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

/* Private Includes ----------------------------------------------------------*/
#include "multiplexer_8ch_core.h"
#include "hc4051.h"
#include "log.h"
#include "business_gpio.h"
#include "business_function.h"
/* Private Define ------------------------------------------------------------*/
/* Private Typedef -----------------------------------------------------------*/
/* Private Macro -------------------------------------------------------------*/
/* Private Variables ---------------------------------------------------------*/
#if BS_MULTIPLEXER_8CH_SWITCH
static const mux_gpio_t g_gpio_init[BS_MULTIPLEXER_8CH_NUM] =
{
#if (BS_MULTIPLEXER_8CH_NUM > 0)
{
.en_pin = {BS_MUX0_EN_GPIO_PORT, BS_MUX0_EN_PIN, BS_MUX0_EN_GPIO_CLK, BS_MUX0_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX0_A0_GPIO_PORT, BS_MUX0_A0_PIN, BS_MUX0_EN_GPIO_CLK, BS_MUX0_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX0_A1_GPIO_PORT, BS_MUX0_A1_PIN, BS_MUX0_EN_GPIO_CLK, BS_MUX0_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX0_A2_GPIO_PORT, BS_MUX0_A2_PIN, BS_MUX0_EN_GPIO_CLK, BS_MUX0_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
#if (BS_MULTIPLEXER_8CH_NUM > 1)
{
.en_pin = {BS_MUX1_EN_GPIO_PORT, BS_MUX1_EN_PIN, BS_MUX1_EN_GPIO_CLK, BS_MUX1_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX1_A0_GPIO_PORT, BS_MUX1_A0_PIN, BS_MUX1_EN_GPIO_CLK, BS_MUX1_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX1_A1_GPIO_PORT, BS_MUX1_A1_PIN, BS_MUX1_EN_GPIO_CLK, BS_MUX1_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX1_A2_GPIO_PORT, BS_MUX1_A2_PIN, BS_MUX1_EN_GPIO_CLK, BS_MUX1_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
#if (BS_MULTIPLEXER_8CH_NUM > 2)
{
.en_pin = {BS_MUX2_EN_GPIO_PORT, BS_MUX2_EN_PIN, BS_MUX2_EN_GPIO_CLK, BS_MUX2_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX2_A0_GPIO_PORT, BS_MUX2_A0_PIN, BS_MUX2_EN_GPIO_CLK, BS_MUX2_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX2_A1_GPIO_PORT, BS_MUX2_A1_PIN, BS_MUX2_EN_GPIO_CLK, BS_MUX2_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX2_A2_GPIO_PORT, BS_MUX2_A2_PIN, BS_MUX2_EN_GPIO_CLK, BS_MUX2_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
#if (BS_MULTIPLEXER_8CH_NUM > 3)
{
.en_pin = {BS_MUX3_EN_GPIO_PORT, BS_MUX3_EN_PIN, BS_MUX3_EN_GPIO_CLK, BS_MUX3_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX3_A0_GPIO_PORT, BS_MUX3_A0_PIN, BS_MUX3_EN_GPIO_CLK, BS_MUX3_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX3_A1_GPIO_PORT, BS_MUX3_A1_PIN, BS_MUX3_EN_GPIO_CLK, BS_MUX3_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX3_A2_GPIO_PORT, BS_MUX3_A2_PIN, BS_MUX3_EN_GPIO_CLK, BS_MUX3_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
#if (BS_MULTIPLEXER_8CH_NUM > 4)
{
.en_pin = {BS_MUX4_EN_GPIO_PORT, BS_MUX4_EN_PIN, BS_MUX4_EN_GPIO_CLK, BS_MUX4_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX4_A0_GPIO_PORT, BS_MUX4_A0_PIN, BS_MUX4_EN_GPIO_CLK, BS_MUX4_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX4_A1_GPIO_PORT, BS_MUX4_A1_PIN, BS_MUX4_EN_GPIO_CLK, BS_MUX4_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX4_A2_GPIO_PORT, BS_MUX4_A2_PIN, BS_MUX4_EN_GPIO_CLK, BS_MUX4_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
#if (BS_MULTIPLEXER_8CH_NUM > 5)
{
.en_pin = {BS_MUX5_EN_GPIO_PORT, BS_MUX5_EN_PIN, BS_MUX5_EN_GPIO_CLK, BS_MUX5_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX5_A0_GPIO_PORT, BS_MUX5_A0_PIN, BS_MUX5_EN_GPIO_CLK, BS_MUX5_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX5_A1_GPIO_PORT, BS_MUX5_A1_PIN, BS_MUX5_EN_GPIO_CLK, BS_MUX5_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX5_A2_GPIO_PORT, BS_MUX5_A2_PIN, BS_MUX5_EN_GPIO_CLK, BS_MUX5_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
#if (BS_MULTIPLEXER_8CH_NUM > 6)
{
.en_pin = {BS_MUX6_EN_GPIO_PORT, BS_MUX6_EN_PIN, BS_MUX6_EN_GPIO_CLK, BS_MUX6_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX6_A0_GPIO_PORT, BS_MUX6_A0_PIN, BS_MUX6_EN_GPIO_CLK, BS_MUX6_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX6_A1_GPIO_PORT, BS_MUX6_A1_PIN, BS_MUX6_EN_GPIO_CLK, BS_MUX6_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX6_A2_GPIO_PORT, BS_MUX6_A2_PIN, BS_MUX6_EN_GPIO_CLK, BS_MUX6_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
#if (BS_MULTIPLEXER_8CH_NUM > 7)
{
.en_pin = {BS_MUX7_EN_GPIO_PORT, BS_MUX7_EN_PIN, BS_MUX7_EN_GPIO_CLK, BS_MUX7_EN_VALID_LEVEL, 0, 0, 0, 0, 0},
.a0_pin = {BS_MUX7_A0_GPIO_PORT, BS_MUX7_A0_PIN, BS_MUX7_EN_GPIO_CLK, BS_MUX7_A0_VALID_LEVEL, 0, 0, 0, 0, 0},
.a1_pin = {BS_MUX7_A1_GPIO_PORT, BS_MUX7_A1_PIN, BS_MUX7_EN_GPIO_CLK, BS_MUX7_A1_VALID_LEVEL, 0, 0, 0, 0, 0},
.a2_pin = {BS_MUX7_A2_GPIO_PORT, BS_MUX7_A2_PIN, BS_MUX7_EN_GPIO_CLK, BS_MUX7_A2_VALID_LEVEL, 0, 0, 0, 0, 0},
},
#endif
};
#endif
/* Private Function Prototypes -----------------------------------------------*/
/* Public Function Prototypes ------------------------------------------------*/
/**
* @brief 8路分流器初始化 使能引脚时钟 配置为推免输出
*/
void mux_init(void)
{
uint8_t i;

for (i = 0; i < BS_MULTIPLEXER_8CH_NUM; i++)
{
/* Enable the GPIO Clock */
bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].en_pin.periph, true);
/* Configure the GPIO pin */
bsp_gpio_init_output(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, BSP_GPIO_PIN_OUT_PP);
/* Reset PIN to switch off the */
bsp_gpio_set_pin(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].en_pin.level);

/* Enable the GPIO Clock */
bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].a0_pin.periph, true);
/* Configure the GPIO pin */
bsp_gpio_init_output(g_gpio_init[i].a0_pin.port, g_gpio_init[i].a0_pin.pin, BSP_GPIO_PIN_OUT_PP);
/* Reset PIN to switch off the */
bsp_gpio_set_pin(g_gpio_init[i].a0_pin.port, g_gpio_init[i].a0_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a0_pin.level);

/* Enable the GPIO Clock */
bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].a1_pin.periph, true);
/* Configure the GPIO pin */
bsp_gpio_init_output(g_gpio_init[i].a1_pin.port, g_gpio_init[i].a1_pin.pin, BSP_GPIO_PIN_OUT_PP);
/* Reset PIN to switch off the */
bsp_gpio_set_pin(g_gpio_init[i].a1_pin.port, g_gpio_init[i].a1_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a1_pin.level);

/* Enable the GPIO Clock */
bsp_gpio_set_clk(GPIO_APBx, g_gpio_init[i].a2_pin.periph, true);
/* Configure the GPIO pin */
bsp_gpio_init_output(g_gpio_init[i].a2_pin.port, g_gpio_init[i].a2_pin.pin, BSP_GPIO_PIN_OUT_PP);
/* Reset PIN to switch off the */
bsp_gpio_set_pin(g_gpio_init[i].a2_pin.port, g_gpio_init[i].a2_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].a2_pin.level);
}
}

/**
* @brief 8路分流器反初始化 将引脚配置为浮空输入
*/
void mux_deinit(void)
{
uint8_t i;

if (BS_MULTIPLEXER_8CH_NUM == 0)
{
return;
}

for (i = 0; i < BS_MULTIPLEXER_8CH_NUM; i++)
{
/* Turn off */
bsp_gpio_set_pin(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].en_pin.level);
/* DeInit the GPIO pin */
bsp_gpio_deinit(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin);
}
}

/**
* @brief 设置指定通道至公共点
* @param id: 器件号
* @param ch: 设置ch到公共点
*/
void mux_set_ch(uint8_t id, uint8_t ch)
{
/* 关闭使能 */
bsp_gpio_set_pin(g_gpio_init[id].en_pin.port, g_gpio_init[id].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[id].en_pin.level);
/* 绑定指定通道至公共点 */
bsp_gpio_set_pin(g_gpio_init[id].a0_pin.port, g_gpio_init[id].a0_pin.pin, ch & 0x01);
bsp_gpio_set_pin(g_gpio_init[id].a0_pin.port, g_gpio_init[id].a0_pin.pin, (ch >> 1) & 0x01);
bsp_gpio_set_pin(g_gpio_init[id].a0_pin.port, g_gpio_init[id].a0_pin.pin, (ch >> 2) & 0x01);
/* 打开使能 */
bsp_gpio_set_pin(g_gpio_init[id].en_pin.port, g_gpio_init[id].en_pin.pin, (bsp_gpio_pin_state_t)g_gpio_init[id].en_pin.level);
}

/**
* @brief 关闭所有器件
*/
void mux_close_all_ic(void)
{
uint8_t i;

for (i = 0; i < BS_MULTIPLEXER_8CH_NUM; i++)
{
bsp_gpio_set_pin(g_gpio_init[i].en_pin.port, g_gpio_init[i].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[i].en_pin.level);
}
}

/**
* @brief 关闭指定器件
*/
void mux_close_ic(uint8_t id)
{
bsp_gpio_set_pin(g_gpio_init[id].en_pin.port, g_gpio_init[id].en_pin.pin, (bsp_gpio_pin_state_t)!g_gpio_init[id].en_pin.level);
}
/********************************************************************************
* @file multiplexer_8ch_core.h
* @author jianqiang.xue
* @version V1.0.0
* @date 2022-02-09
* @brief multiplexer简称mux
1. 通过A0-A2电平,控制X0-7中哪个脚接入公共脚Z0
2. A0-A2电平组成0-7,对应X0-7。
********************************************************************************/

#ifndef __MULTIPLEXER_8CH_CORE_H
#define __MULTIPLEXER_8CH_CORE_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include "bsp_gpio.h"
/* Public enum ---------------------------------------------------------------*/
/* Public Struct -------------------------------------------------------------*/
typedef struct
{
bsp_gpio_t en_pin; // 使能脚

bsp_gpio_t a0_pin; // 选择脚0
bsp_gpio_t a1_pin; // 选择脚1
bsp_gpio_t a2_pin; // 选择脚2
}mux_gpio_t;
/* Public Function Prototypes ------------------------------------------------*/

void mux_init(void);
void mux_deinit(void);

void mux_set_ch(uint8_t id, uint8_t ch);
void mux_close_all_ic(void);
void mux_close_ic(uint8_t id);
#endif