STM32精准延时全解析:从微秒到秒的LED闪灯控制实战 | 零基础入门STM32第二十七步

主题 内容 教学目的/扩展视频
延时程序的介绍 什么是嘀嗒定时器,延时函数的原理分析,延时函数的调用方法。 了解延时的意义,实现原理,调用方法即可。先不讲中断延时。

师从洋桃电子,杜洋老师


📑文章目录

  • 🔍 核心要点
  • ⏱️ 延时函数深度解析
  • 1. 微秒级延时(72MHz主频示例)
  • 2. 毫秒/秒级延时实现
  • 💡 LED闪灯实战应用
  • 1. 基础闪灯程序(1Hz频率)
  • 2. 频率调节技巧
  • 🛠️ 关键优化技巧
  • 🔧 调试与验证
  • 📚 学习建议
  • 🔗 相关资源

  • 🔍 核心要点

    本文通过SysTick定时器🔍(嘀嗒定时器)实现三级延时控制,重点解决以下问题:

    1. 不同时间粒度的延时函数实现原理
    2. 系统主频与延时精度的关系
    3. 阻塞式延时的优化方案
    4. LED闪灯频率的精准控制

    ⏱️ 延时函数深度解析

    1. 微秒级延时(72MHz主频示例)

    #define AHB_INPUT  72  //请按RCC中设置的AHB时钟频率填写到这里(单位MHz)
    
    void delay_us(u32 uS){ //uS微秒级延时程序(参考值即是延时数,72MHz时最大值233015)	
    	SysTick->LOAD=AHB_INPUT*uS;      //重装计数初值(当主频是72MHz,72次为1微秒)
    	SysTick->VAL=0x00;        //清空定时器的计数器
    	SysTick->CTRL=0x00000005;//时钟源HCLK,打开定时器
    	while(!(SysTick->CTRL&0x00010000)); //等待计数到0
    	SysTick->CTRL=0x00000004;//关闭定时器
    }
    

    参数说明

  • 最大支持延时:233015μs(约0.23秒)
  • 误差范围:±3个时钟周期
  • 2. 毫秒/秒级延时实现

    // 毫秒级延时(基于微秒函数)
    void delay_ms(u16 ms){ //mS毫秒级延时程序(参考值即是延时数,最大值65535)	 		  	  
    	while( ms-- != 0){
    		delay_us(1000);	//调用1000微秒的延时
    	}
    }
    
    // 秒级延时(基于毫秒函数) 
    void delay_s(u16 s){ //S秒级延时程序(参考值即是延时数,最大值65535)	 		  	  
    	while( s-- != 0){
    		delay_ms(1000);	//调用1000毫秒的延时
    	}
    } 
    

    💡 LED闪灯实战应用

    1. 基础闪灯程序(1Hz频率)

    int main (void){//主程序
    	RCC_Configuration(); //时钟设置
    	LED_Init();
    	while(1){
    		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //取反LED1
    		delay_ms(500); //延时1秒
    	}
    }
    

    ▲ 完整代码⏬四种方法实现的LED闪灯程序

    2. 频率调节技巧

    闪灯模式 延时配置 应用场景
    高频闪烁 delay_us(100000) 状态指示
    呼吸灯效果 渐变调整delay_us参数 视觉效果优化
    超长间隔 delay_s(10) 设备状态监测

    🛠️ 关键优化技巧

    1. 非阻塞式延时
      使用SysTick中断实现后台计时,释放CPU资源

      volatile uint32_t timing_delay = 0;
      
      void SysTick_Handler(void) {
          if(timing_delay != 0x00) timing_delay--;
      }
      
    2. 主频自适应
      动态计算LOAD值,适配不同时钟频率:

      #define CPU_FREQ 72000000  // 当前主频72MHz
      SysTick->LOAD = (CPU_FREQ/8000000)*us; 
      
    3. 误差补偿方案
      通过示波器测量实际延时,添加补偿系数:

      #define DELAY_COMPENSATE 1.02  // 实测补偿系数
      uint32_t adj_us = us * DELAY_COMPENSATE;
      

    🔧 调试与验证

    1. GPIO翻转法测量

      GPIO_Toggle(LED_PORT); 
      delay_us(1000);
      GPIO_Toggle(LED_PORT);
      
    2. 用示波器捕获方波宽度验证延时精度
    3. 变量观测法
      在调试模式下观察timing_delay变量递减过程

    4. 逻辑分析仪追踪
      通过SWD接口捕获GPIO状态变化时序


    📚 学习建议

    实践路线
    1. 修改delay_us参数观察LED闪烁变化
    2. 尝试实现10Hz/1kHz不同频率的闪灯
    3. 移植FreeRTOS验证延时精度
    4. 开发PWM调光呼吸灯

    硬件验证

  • 万用表测量电压变化
  • 示波器捕获波形时序
  • 电流表监测功耗变化

  • 🔗 相关资源

    [1] 洋桃电子B站课程-STM32入门100步
    [2] STM32F103xx官方数据手册
    [3] STM32F103X8-B数据手册(中文)
    [4] STM32F103固件函数库用户手册(中文)
    [5] 四种方法实现的LED闪灯程序


    💬 技术讨论(请在评论区留言~)


    📌 下期预告:下一期将探讨LED呼吸灯程序重点课程,欢迎持续关注!

    点击查阅🔍往期【STM32专栏】文章

    版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
    实测开发版:洋桃1号开发版(基于STM32F103C8T6)
    更新日志

  • v1.0 初始版本(2025-02-25)
  • 作者:触角01010001

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32精准延时全解析:从微秒到秒的LED闪灯控制实战 | 零基础入门STM32第二十七步

    发表回复