STM32------数码管显示
模块化编程


共阴极数码管,三八译码器控制位选
采用标准库
关键代码
Delay.h
c
#ifndef __DELAY_H
#define __DELAY_H
void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);
#endif
Delay.c
c
#include "stm32f10x.h"
/**
* @brief 微秒级延时
* @param xus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief 毫秒级延时
* @param xms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief 秒级延时
* @param xs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
main.c
c
#include "stm32f10x.h"
#include "Delay.h"
/* ========== 硬件引脚定义(便于移植) ========== */
#define SEG_PORT GPIOA
#define SEG_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | \
GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7)
#define SEL_PORT GPIOB
#define SEL_PIN_A GPIO_Pin_14
#define SEL_PIN_B GPIO_Pin_13
#define SEL_PIN_C GPIO_Pin_12
/* ========== 共阴极段码表(数字1~8) ========== */
static const uint8_t segCode[8] = {
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F // 8
};
/* ========== 位选设置(n = 0~7) ========== */
// 硬件连接为 PB12->A2, PB13->A1, PB14->A0
// 映射 n 的 bit0->PB14, bit1->PB13, bit2->PB12
static void SetDigitSelect(uint8_t n)
{
// 先清零三个位选引脚(BRR 写1清零)
SEL_PORT->BRR = SEL_PIN_A | SEL_PIN_B | SEL_PIN_C;
// 按位设置,通过与或操作获取对应三八译码器的三位输入的值
if (n & 0x01) SEL_PORT->BSRR = SEL_PIN_A; // bit0 -> PB14
if (n & 0x02) SEL_PORT->BSRR = SEL_PIN_B; // bit1 -> PB13
if (n & 0x04) SEL_PORT->BSRR = SEL_PIN_C; // bit2 -> PB12
}
/* ========== 动态扫描函数(每调用一次刷新一位) ========== */
static void DisplayDigits(void)
{
static uint8_t index = 0; // 当前显示的位(0~7)
// 1. 关闭所有段(消影)
SEG_PORT->BRR = SEG_PINS;
// 2. 选择位
SetDigitSelect(index);
// 3. 输出段码(BSRR 只置1,BRR 已清零,故无需额外复位)
SEG_PORT->BSRR = segCode[index];
// 4. 指向下一位
index++;
if (index >= 8) index = 0;
}
/* ========== 主函数 ========== */
int main(void)
{
// 使能 GPIOA、GPIOB 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
// 配置段引脚(PA0~PA7 推挽输出)
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = SEG_PINS;
GPIO_Init(SEG_PORT, &GPIO_InitStruct);
// 配置位选引脚(PB12~PB14 推挽输出)
GPIO_InitStruct.GPIO_Pin = SEL_PIN_A | SEL_PIN_B | SEL_PIN_C;
GPIO_Init(SEL_PORT, &GPIO_InitStruct);
// 主循环:每隔 1ms 刷新一位(总周期 8ms → 刷新率 125Hz,无闪烁)
while (1)
{
DisplayDigits();
Delay_ms(1); // 每位点亮 1ms,总周期 8ms
}
}
标准库相关定义

下载程序,效果如下
