基于STM32F103微控制器驱动74HC595芯片控制数码管显示

基于STM32F103微控制器驱动74HC595芯片控制数码管显示


一、硬件连接方案

1. 引脚映射(以双数码管为例)

STM32引脚 功能 74HC595引脚 数码管连接
PA5 DS(数据) 14 (DS) 段选信号
PA6 SH_CP(时钟) 11 (SH_CP)  
PA7 ST_CP(锁存) 12 (ST_CP)  
PB0 位选控制 Q7'(级联) 公共端控制

2. 电路设计要点


二、软件实现方案

1. 初始化配置(HAL库)

// 74hc595.h
#ifndef __74HC595_H
#define __74HC595_H

#include "stm32f1xx_hal.h"

#define DS_PIN    GPIO_PIN_5  // PA5
#define SHCP_PIN  GPIO_PIN_6  // PA6
#define STCP_PIN  GPIO_PIN_7  // PA7
#define DATA_PORT GPIOA

void HC595_Init(void);
void HC595_SendByte(uint8_t data);
void HC595_Display(uint8_t num);

#endif

2. 底层驱动实现

// 74hc595.c
#include "74hc595.h"

void HC595_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    // 配置数据/时钟/锁存引脚为推挽输出
    GPIO_InitStruct.Pin = DS_PIN | SHCP_PIN | STCP_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(DATA_PORT, &GPIO_InitStruct);
    
    // 初始状态:输出高电平
    HAL_GPIO_WritePin(DATA_PORT, DS_PIN | SHCP_PIN | STCP_PIN, GPIO_PIN_SET);
}

void HC595_SendByte(uint8_t data) {
    for (uint8_t i = 0; i < 8; i++) {
        // 发送高位优先
        HAL_GPIO_WritePin(DATA_PORT, DS_PIN, (data & 0x80) ? GPIO_PIN_SET : GPIO_PIN_RESET);
        
        // 产生时钟脉冲
        HAL_GPIO_WritePin(DATA_PORT, SHCP_PIN, GPIO_PIN_RESET);
        HAL_Delay(1);  // 最小脉冲宽度20ns
        HAL_GPIO_WritePin(DATA_PORT, SHCP_PIN, GPIO_PIN_SET);
        
        data <<= 1;  // 左移准备发送下一位
    }
}

void HC595_Display(uint8_t num) {
    // 共阳数码管段码表(0-9)
    const uint8_t SEG_CODE[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 
                                0x92, 0x82, 0xF8, 0x80, 0x90};
    
    // 发送段选数据
    HC595_SendByte(SEG_CODE[num % 10]);  // 个位
    HAL_GPIO_WritePin(DATA_PORT, STCP_PIN, GPIO_PIN_RESET);
    HAL_Delay(1);
    HAL_GPIO_WritePin(DATA_PORT, STCP_PIN, GPIO_PIN_SET);
    
    HAL_Delay(2);  // 保持时间
    
    // 发送位选控制(假设控制单个数码管)
    HAL_GPIO_WritePin(DATA_PORT, STCP_PIN, GPIO_PIN_RESET);
    HAL_Delay(1);
    HAL_GPIO_WritePin(DATA_PORT, STCP_PIN, GPIO_PIN_SET);
}

3. 主程序示例

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    
    HC595_Init();
    
    while (1) {
        for (uint8_t i = 0; i < 10; i++) {
            HC595_Display(i);
            HAL_Delay(1000);
        }
    }
}

参考代码 STM32F103 驱动74HC595控制数码管显示程序 www.youwenfan.com/contentcsi/60499.html

三、调试

1. 示波器验证时序

2. 常见问题解决

现象 可能原因 解决方案
显示残影 锁存信号未及时更新 增加ST_CP脉冲宽度至5μs
段码显示错误 数据位顺序颠倒 检查SEG_CODE表与硬件连接
电流不足 驱动能力不够 添加ULN2803A驱动芯片

3. 性能优化


四、扩展

1. 多级联控制

// 控制4位数码管(2片74HC595级联)
void HC595_Send16Bit(uint16_t data) {
    for (uint8_t i = 0; i < 16; i++) {
        HAL_GPIO_WritePin(DATA_PORT, DS_PIN, (data & 0x8000) ? GPIO_PIN_SET : GPIO_PIN_RESET);
        HAL_GPIO_WritePin(DATA_PORT, SHCP_PIN, GPIO_PIN_RESET);
        HAL_Delay(1);
        HAL_GPIO_WritePin(DATA_PORT, SHCP_PIN, GPIO_PIN_SET);
        data <<= 1;
    }
}

2. 中断刷新机制

void TIM2_IRQHandler(void) {
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
        // 定时刷新显示
        HC595_Display(current_value);
    }
}

五、硬件设计验证

  1. 电源滤波:在VCC和GND间添加10μF电解电容+0.1μF陶瓷电容

  2. 信号完整性

    • 段选信号串联33Ω电阻
    • 时钟信号添加10pF负载电容
  3. PCB布局建议

    • 电源层与地平面分割
    • 高频信号走线最短化

六、调试工具推荐

  1. 逻辑分析仪:Saleae捕获DS-SH_CP-ST_CP时序
  2. 电流检测:使用万用表测量595芯片供电电流(正常<80mA)
  3. 协议分析:Total Phase Aardvark验证SPI通信

 

专注于matlab/simulink,电子电路,编程