一、首先,用STM32CbueMX来生成时钟代码,当然不止三位数码管都可以
1、新建工程什么的应该都会,来到重点配置环节,时钟记得配置为72M


2、最终选择LL库,然后生成代码。

3、打开main.c代码,在此位置整段复制以下代码即可,

// 共阳数码管段码表(0-9)
const uint8_t SEGMENT_CODE[] =
{
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90 // 9
};
// 共阴数码管段码表(0-9)不带小数点,通过注释选择不要的代码,共阳共阴二选一。
// const uint8_t SEGMENT_CODE[] = {
// 0x3F, // 0
// 0x06, // 1
// 0x5B, // 2
// 0x4F, // 3
// 0x66, // 4
// 0x6D, // 5
// 0x7D, // 6
// 0x07, // 7
// 0x7F, // 8
// 0x6F // 9
// };
//(OE):输出使能控制,低电平有效 默认自行下拉,不额外设置控制引脚
#define HC595_SER_PIN LL_GPIO_PIN_5 //具体控制引脚,通过修改PIN_* 后的数字 (SER):串行数据输入引脚
#define HC595_SRCLK_PIN LL_GPIO_PIN_6 //具体控制引脚,通过修改PIN_* 后的数字 (SRCLK):移位寄存器时钟输入引脚,
#define HC595_RCLK_PIN LL_GPIO_PIN_7 //具体控制引脚,通过修改PIN_* 后的数字 (RCLK):存储器存储时钟输入引脚
#define HC595_GPIO_PORT GPIOA //引脚字母,修改GPIO* 的字母
#define MAX_DIGITS 3 //级联数码管位数
void HC595_Init(void)//初始化:
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA); //开启对应IO口时钟,注意修改此处GPIO*以其对应
GPIO_InitStruct.Pin = HC595_SER_PIN | HC595_SRCLK_PIN | HC595_RCLK_PIN;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; //输出
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH; //对应IO口翻转速度HIGH高
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(HC595_GPIO_PORT, &GPIO_InitStruct);
}
void HC595_WriteByte(uint8_t data) //写一位数据 底层1 不要修改,是为Display_Number显示函数服务的
{
for(uint8_t i = 0; i < 8; i++) {
LL_GPIO_ResetOutputPin(HC595_GPIO_PORT, HC595_SRCLK_PIN);
// 高位先发送
if(data & 0x80)
LL_GPIO_SetOutputPin(HC595_GPIO_PORT, HC595_SER_PIN);
else
LL_GPIO_ResetOutputPin(HC595_GPIO_PORT, HC595_SER_PIN);
data <<= 1;
LL_GPIO_SetOutputPin(HC595_GPIO_PORT, HC595_SRCLK_PIN);
}
}
void HC595_Send(const uint8_t* data, uint8_t len, int reverse_order) //底层2 不要修改,是为Display_Number显示函数服务的
{
int8_t step, start, end;
LL_GPIO_ResetOutputPin(HC595_GPIO_PORT, HC595_RCLK_PIN);/* 发送顺序逻辑 */
step = reverse_order ? -1 : 1;
start = reverse_order ? (len-1) : 0;
end = reverse_order ? -1 : len;
for(int8_t i = start; i != end; i += step)
{
HC595_WriteByte(data[i]);
}
LL_GPIO_SetOutputPin(HC595_GPIO_PORT, HC595_RCLK_PIN);
}
void Display_Digits(const uint8_t* digits, uint8_t num_digits)//底层3 不要修改,是为Display_Number显示函数服务的
{
uint8_t seg_data[MAX_DIGITS]; uint8_t i;
for(i = 0; i < num_digits && i < MAX_DIGITS; ++i)
{
seg_data[i] = SEGMENT_CODE[digits[i] % 10];
}
HC595_Send(seg_data, num_digits, 1); // 1表示逆序 0表示顺序,一般不用改
}
void Display_Number(uint8_t num) //显示函数 ,底下为百十千三位实现,可自行添加位数
{
uint8_t digits[] =
{
(uint8_t)(num / 100), // 百位 再次自行添加其他位数,或者删减
(uint8_t)((num / 10) % 10),// 十位
(uint8_t)(num % 10) // 个位
};
Display_Digits(digits, sizeof(digits));
}
4、在主函数中添加以下代码,实现效果为显示三位数字每秒加一
int main(void)
{
HC595_Init(); //初始化
uint8_t counter = 0;
while(1)
{
Display_Number(counter++);
if(counter > 999) counter = 0;
LL_mDelay(1000);
}
}
相应注释都有,应该比较明了了,
