STM32G431系列微秒级delay(延时)函数编写

目录

前言:

思考:

代码实现:

delay.c:

delay.h:


前言:

最近需要用STM32G4系列的单片机做个项目,因为之前一直用的标准库,也是第一次用G4的芯片,所以打算先从简单的做起,比如说把温湿度显示到OLED屏上。那么现在问题来了,DHT11需要us级的延时,hal库自带的是ms级延时,需要自己写us级延时函数。

思考:

我想到了两种方法:一种是使用STM32G431上的定时器来产生精确的us级延时;另一种是使用SysTick定时器。这里我选用了第二种,SysTick定时器是一个内置于Cortex-M内核中的定时器,可以节省通用和基本定时器资源。

delay函数涉及到单片机本身的systick,而F1和G4主频不同,F1最高72MHZ,G4最高170MHZ

这里直接使用了正点原子F103的HAL库版本的delay函数,STM32F1系列是采用ARM-CortexM3的架构,G4是ARM-CortexM4的架构,Cortex-M4(继承了Cortex-M3内核的特性)比Cortex-M3多了 数字信号处理(DSP);单精度浮点运算。所以可以直接使用。

代码实现:

delay.c:

#include "delay.h"


static uint32_t g_fac_us = 0;       /* us延时倍乘数 */


/**
 * @brief     初始化延迟函数
 * @param     sysclk: 系统时钟频率, 即CPU频率(rcc_c_ck), 72MHz
 * @retval    无
 */  

void delay_init(uint16_t sysclk)
{
    g_fac_us = sysclk;                                  /* 由于在HAL_Init中已对systick做了配置,所以这里无需重新配置 */
	
}



/**
 * @brief     延时nus
 * @note      无论是否使用OS, 都是用时钟摘取法来做us延时
 * @param     nus: 要延时的us数
 * @note      nus取值范围: 0 ~ (2^32 / fac_us) (fac_us一般等于系统主频, 自行套入计算)
 * @retval    无
 */

void delay_us(uint32_t nus)
{
    uint32_t ticks;
    uint32_t told, tnow, tcnt = 0;
    uint32_t reload = SysTick->LOAD;        /* LOAD的值 */
    ticks = nus * g_fac_us;                 /* 需要的节拍数 */

    told = SysTick->VAL;                    /* 刚进入时的计数器值 */
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow;        /* 这里注意一下SYSTICK是一个递减的计数器就可以了 */
            }
            else
            {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks) 
            {
                break;                      /* 时间超过/等于要延迟的时间,则退出 */
            }
        }
    }

}

/**
 * @brief     延时nms
 * @param     nms: 要延时的ms数 (0< nms <= (2^32 / fac_us / 1000))(fac_us一般等于系统主频, 自行套入计算)
 * @retval    无
 */
void delay_ms(uint16_t nms)
{
    delay_us((uint32_t)(nms * 1000));                   /* 普通方式延时 */
	
}


/**
 * @brief       HAL库内部函数用到的延时
 * @note        HAL库的延时默认用Systick,如果我们没有开Systick的中断会导致调用这个延时后无法退出
 * @param       Delay : 要延时的毫秒数
 * @retval      None
 */
void HAL_Delay(uint32_t Delay)
{
     delay_ms(Delay);
}

delay.h:

#ifndef __DELAY_H
#define __DELAY_H 			   
	 
#include "stm32g4xx_hal.h"


void delay_init(uint16_t sysclk);       /* 初始化延迟函数 */
void delay_ms(uint16_t nms);            /* 延时nms */
void delay_us(uint32_t nus);            /* 延时nus */






#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄奕子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值