STM32 60秒倒计时代码详解(适合初学者) 完整代码+仿真图
创作时间:
作者:
@小白创作中心
STM32 60秒倒计时代码详解(适合初学者) 完整代码+仿真图
引用
CSDN
1.
https://blog.csdn.net/m0_48940120/article/details/146302570
本文将详细解析一个基于STM32的60秒倒计时功能代码,通过数码管动态扫描显示时间。代码结构简单,适合初学者理解GPIO控制、数码管驱动和基础计时逻辑。
代码整体流程
头文件与延时函数
代码开头引入STM32标准库头文件,并定义了一个简单的软件延时函数Delay()
。该函数通过循环空操作消耗时间,精度较低但实现简单。数码管码表定义
定义数组tab[]
,存储0-9的数码管段码(共阳极数码管编码)。例如:0xc0
对应数字“0”的段码。GPIO初始化
- 启用GPIOB和GPIOA的时钟(
RCC_APB2PeriphClockCmd
)。 - 配置GPIO为推挽输出模式(
GPIO_Mode_Out_PP
),用于控制数码管的段选(GPIOB)和位选(GPIOA)。
- 主循环逻辑
- 动态显示:交替点亮十位和个位数码管,利用人眼视觉暂留效果实现“同时显示”。
- 计时逻辑:通过变量
count
计数到100次后,增加倒计时数值number
,60秒后归零。
核心思想详解
1. 数码管驱动原理
- 段选与位选
- 段选(GPIOB):控制数码管的各段(a-g)亮灭,通过写入
tab[]
中的段码值显示具体数字。 - 位选(GPIOA):选择当前点亮的数码管位置(PA0控制十位,PA1控制个位)。
- 动态扫描:快速切换位选信号(十位→个位→十位…),每次只点亮一个数码管,但因切换速度快(约1ms),人眼会认为两者同时亮起。
// 示例:显示十位
GPIO_ResetBits(GPIOA, GPIO_Pin_1); // 关闭个位
GPIO_SetBits(GPIOA, GPIO_Pin_0); // 开启十位
GPIO_Write(GPIOB, tab[number/10]); // 输出十位段码
Delay(1000); // 短暂延时保持显示
2. 倒计时实现
- 计时逻辑
count
变量用于记录循环次数,每循环100次(约200ms延时×100=20秒)后,number
加1。- 当
number
达到60时归零,实现60秒循环。 - 注意:此方法依赖软件延时,实际时间精度较低(受循环执行速度影响),适合学习基础原理,实际项目建议使用硬件定时器。
++count;
if (count == 100) { // 每100次循环增加1秒(具体时间由Delay参数决定)
++number;
count = 0;
}
if (number >= 60) { // 60秒归零
number = 0;
}
3. 软件延时的局限性
- 问题:
Delay()
函数通过空循环消耗时间,期间CPU无法执行其他任务(阻塞式延时)。 - 改进方向:实际项目中可使用定时器中断或SysTick定时器实现非阻塞延时,提高系统效率。
代码优化建议(拓展知识点)
硬件定时器
STM32的定时器(如TIM3)可配置为1秒中断,在中断服务函数中更新计时值,精度更高且不阻塞主循环。数码管消隐
在切换位选信号时,可先关闭所有位选,避免切换过程中的残影。按键控制
可增加按键中断功能,实现暂停、重置等交互操作。
完整代码
//头文件
#include "stm32f10x.h"
//=============================================================================
//函数名称:Delay
//功能概要:延时函数
//参数说明:无
//函数返回:无
//=============================================================================
void Delay (uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
//=============================================================================
//函数名称:main
//功能概要:主函数
//参数说明:无
//函数返回:int
//=============================================================================
int main(void)
{
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管码表
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All;//PB1
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_Init(GPIOA,&GPIO_InitStruct);
int number = 0,count=0 ;
while(1){
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
GPIO_SetBits(GPIOA,GPIO_Pin_0);
GPIO_Write(GPIOB,tab[number/10]) ;
Delay(1000);
GPIO_ResetBits(GPIOA,GPIO_Pin_0);
GPIO_SetBits(GPIOA,GPIO_Pin_1);
GPIO_Write(GPIOB,tab[number%10]) ;
Delay(1000);
++count ;
if(count == 100){
++number ;
count = 0 ;
}
if(number >= 60){
number = 0 ;
}
}
while(1){
GPIO_SetBits(GPIOB,GPIO_Pin_1);
Delay(99000);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
Delay(99000);
}
}
仿真图
总结
本代码通过GPIO控制数码管动态显示,结合简单计数实现60秒倒计时。核心思想是动态扫描显示和软件计数计时,适合初学者理解嵌入式开发的基础逻辑。后续可在此基础上学习定时器、中断等进阶内容,提升代码效率和功能复杂度。
热门推荐
郑和下西洋,有哪些你不知道的秘密?
网络安全中等保,风险评估,安全测评都是什么意思,有哪些联系
汽车需要购买哪些商业险?商业险种类如何选择?
用车知识:如何正确购买汽车保险
焦虑情绪会遗传吗?从遗传到环境,全方位解析焦虑成因与应对方法
3DS错误代码003-2101怎么办?多种实用解决方案帮你轻松应对网络连接问题
纯净水可以用来浇花吗?(科学解析纯净水对植物生长的影响)
珍贵!点亮旧照,看湛江百年历史
过敏性鼻炎又犯了,该怎么办(上)
汽车手套箱是什么
观音菩萨、日光菩萨、准提菩萨、虚空藏菩萨分别掌管什么?早了解
短视频更新频率如何安排?科学提升播放量与用户粘性!
AI生图五大乱象|打不完的官司:创作或剽窃,版权谁来定
解码MP3的关键:深入了解MP3解码芯片的工作原理
邓丽君《満ち潮》:温柔海浪中的永恒吟唱
粟裕完成了自己“最复杂、最剧烈、最艰苦”的一场战役,逆转了整个中原!
家庭娱乐必备:如何选择理想的4K投影仪指南
楷书的起源和演变,是如何广为流传的?
动漫产业的娘化趋势:萌文化如何影响现代审美
乾隆行宫探秘:穿越历史的皇家文化遗产
学中国史的朋友福音来啦-朝代记忆大全(图文并茂 有顺口溜)!
期货交易风险控制全攻略:从止损到仓位管理
如何唤醒顾客产品的需求
疼痛能被测量吗?几级疼痛的说法准确吗?
二手手机检测方法大揭秘(全面了解二手手机的检测方式及注意事项)
个人信息保护实用技巧:识别“山寨App”篇
PMOS开关典型电路工作原理及分析
如何使用 Git 进行多人协作开发(全流程图解)
焦距,光圈,景深以及最短对焦距离的原理解释
SCI期刊论文:文献综述的格式与写法