[STM32F1]

定时器实现微秒延时(us)函数

[复制链接]
1866|57
手机看帖
扫描二维码
随时随地手机跟帖
kkzz|  楼主 | 2022-10-26 22:00 | 显示全部楼层 |阅读模式
STM32CubeMX设置
  • RCC设置外接HSE,时钟设置为72M
  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
  • PG11设置为GPIO推挽输出模式、上拉、高速
  • 激活TIM7,预分频因子设为72-1,向上计数,自动重载值为65535;因此计数器CNT_CLK = 1MHz,计数器周期为1us
v2-8684c7e1670567699f19538f2823bf80_720w.jpg 在tim.c文件下实现微秒延时(us)函数
void delay_us(uint16_t us){
    uint16_t differ = 0xffff-us-5;              
    __HAL_TIM_SET_COUNTER(&htim7,differ);   //设定TIM7计数器起始值
    HAL_TIM_Base_Start(&htim7);     //启动定时器

    while(differ < 0xffff-5){   //判断
        differ = __HAL_TIM_GET_COUNTER(&htim7);     //查询计数器的计数值
    }
    HAL_TIM_Base_Stop(&htim7);
}



使用特权

评论回复
討厭和人归類| | 2022-11-20 01:12 | 显示全部楼层
ST有内置的滴答定时器的,可以实现微秒延时吧

使用特权

评论回复
一枝香| | 2022-11-20 01:44 | 显示全部楼层
我一般都是用while实现一个微秒,使用nop

使用特权

评论回复
晚晚皆安| | 2022-11-20 02:16 | 显示全部楼层
微秒延时是不是都为了I2C或者SPI的时序啊?

使用特权

评论回复
岁月反驳| | 2022-11-20 02:48 | 显示全部楼层
定时器可以的,这个OK的,准确而且还好用

使用特权

评论回复
cubemx创建的工程属实简单哦

使用特权

评论回复
情和欲| | 2022-11-20 03:52 | 显示全部楼层
一般定义到毫秒就行了,微秒基本上都用不到的,时序太严格了

使用特权

评论回复
地下縱情搖擺| | 2022-11-20 04:24 | 显示全部楼层
我知道之前完WS2812的时候,用到了微秒级延时

使用特权

评论回复
偷吻月亮| | 2022-11-20 04:56 | 显示全部楼层
定时器7是不是有的单片机没有这个啊?

使用特权

评论回复
笨蛋无需搭理| | 2022-11-20 05:28 | 显示全部楼层
挺好的,除了定时器也可以用空指令跑,但是把,那个就不会很准

使用特权

评论回复
笨蛋无需搭理| | 2022-11-20 06:00 | 显示全部楼层
挺好的,除了定时器也可以用空指令跑,但是把,那个就不会很准

使用特权

评论回复
林间有新绿| | 2022-11-20 06:32 | 显示全部楼层
配置PG11干啥,其实就配置定时器就好了

使用特权

评论回复
sdlls| | 2024-6-5 21:36 | 显示全部楼层
SysTick是STM32的一个系统定时器,它可以用于实现微秒级别的延时,但精度会受到CPU时钟频率的影响。

使用特权

评论回复
uytyu| | 2024-6-7 08:40 | 显示全部楼层
void delay_us(uint32_t us)
{
    uint32_t timeout = us * (SystemCoreClock / 1000000) - 1; // 计算超时值
    TIM_SetCompare(TIMx, timeout); // 设置比较值
    TIM_EnableUpdateInterrupt(TIMx); // 开启更新中断
    __enable_irq(); // 开启全局中断
    while (TIM_GetCapture(TIMx) != timeout); // 等待定时器溢出
    TIM_DisableUpdateInterrupt(TIMx); // 关闭更新中断
}

使用特权

评论回复
timfordlare| | 2024-6-7 10:27 | 显示全部楼层
在多任务环境下,使用定时器中断可能会导致任务调度的不确定性。

使用特权

评论回复
ingramward| | 2024-6-7 15:22 | 显示全部楼层
由于定时器的计数器分辨率和预分频器设置可能会影响延时的精度,你需要根据实际情况调整定时器参数以获得所需的延时精度。

使用特权

评论回复
ingramward| | 2024-6-7 19:58 | 显示全部楼层
#include "stm32f1xx_hal.h" // 根据你的STM32系列选择正确的头文件  
  
// 配置SysTick以提供微秒级别的延时  
void SysTick_Config_For_Microseconds(uint32_t us) {  
    // 获取当前的系统时钟频率(例如,72MHz)  
    uint32_t clk_rate = HAL_RCC_GetHCLKFreq();  
      
    // 计算SysTick的加载值(注意:这里是一个简化的例子,可能需要进一步调整)  
    uint32_t reload = (clk_rate / 1000000) * us - 1; // 减1是因为SysTick是从0开始计数的  
      
    // 配置SysTick  
    HAL_SYSTICK_Config(reload);  
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); // 使用HCLK作为SysTick的时钟源  
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); // 设置SysTick的中断优先级  
    HAL_SYSTICK_EnableIT(); // 启用SysTick中断  
    HAL_SYSTICK_Enable(); // 启用SysTick定时器  
      
    // 等待SysTick中断发生  
    while (!(__HAL_SYSTICK_GET_FLAG(&hSystickHandle, SYSTICK_FLAG_SVCALL) == RESET));  
    __HAL_SYSTICK_CLEAR_FLAG(&hSystickHandle, SYSTICK_FLAG_SVCALL); // 清除SysTick中断标志  
      
    // 禁用SysTick  
    HAL_SYSTICK_Disable();  
}  
  
// 注意:上述代码是一个简化的示例,并且可能需要进行调整和优化以满足你的具体需求。  
// 例如,你可能需要禁用SysTick的中断功能,并使用轮询方式检查SysTick的状态。

使用特权

评论回复
lzbf| | 2024-6-8 09:09 | 显示全部楼层
为了得到微秒级精度,你需要确保定时器的时钟频率足够高。

使用特权

评论回复
albertaabbot| | 2024-6-8 12:22 | 显示全部楼层
STM32提供了多种类型的定时器,包括基本定时器、通用定时器和高级定时器。

使用特权

评论回复
wilhelmina2| | 2024-6-8 15:37 | 显示全部楼层
需要设置定时器的预分频器和自动重载寄存器(ARR)来实现所需的微秒延时。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

315

主题

10751

帖子

13

粉丝