打印
[应用相关]

分享一个我常用的at32定时延时程序

[复制链接]
2456|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zpwang|  楼主 | 2023-12-25 22:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zpwang 于 2023-12-26 20:10 编辑

#include "timer_delay.h"

/* **************************************************************            
函数功能: 通用定时器6初始化/定时中断,提供 systick 以外的定时延时

说明:               
        定时器没有使能定时中断,杜绝了非阻塞延时频繁的中断抢占CPU资源  
        120MHz APB1时钟分频12分频后为定时器时钟10MHz
        定时没计数一次为0.1uS.以提高非阻塞us级定时响应速度而减少误差
        TMR6 为16位定时器,其最大计数值 0xFFFF        
*************************************************************** */
void Delay_tmr_init(void)
{
          crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, ENABLE);
         
          tmr_base_init(TMR6, 0xFFFF, 11);
          tmr_cnt_dir_set(TMR6, TMR_COUNT_UP);
         
         tmr_counter_enable(TMR6, ENABLE);
}

uint16_t get_delay_cont(void)
{
        return(tmr_counter_value_get(TMR6));
}

void tmr_delay_us(uint16_t xus)
{
        uin616_t delay_us = 0;        
        uint16_t delay_start= get_delay_cont();
        while(delay_us < xus)
        {
                if(get_delay_cont() > delay_start)
                {
                        delay_us = (get_delay_cont() - delay_start)/10;
                }
                else
                {
                        delay_us = (MAX_DEAY - delay_start + get_delay_cont())/10;
                }
        }
               
        return;
}

void tmr_delay_ms(uint16_t xms)            
{
        uint16_t delay_ms = 0;                        
        uint16_t delay_start= get_delay_cont();
        
        while(delay_ms < xms)
        {
                if(get_delay_cont() > delay_start)
                {
                        if((get_delay_cont() - delay_start) == 10000)
                        {
                                delay_ms ++;                               delay_start= get_delay_cont();
                        }
                }
                else
                {
                        if((MAX_DEAY - delay_start + get_delay_cont()) == 10000)
                        {
                                delay_ms ++;
                                 delay_start= get_delay_cont();
                        }
                }               
        }
}

void tmr_delay_s(uint16_t xs)            
{
        uint16_t delay_s = 0;                        
        uint16_t delay_start= get_delay_cont();
        
        while(delay_s < xs)
        {
                if(get_delay_cont() > delay_start)
                {
                        if((get_delay_cont() - delay_start) == 10000)
                        {
                                delay_ms ++;
                                delay_start= get_delay_cont();
                        }
                }
                else
                {
                        if((MAX_DEAY - delay_start + get_delay_cont()) == 10000)
                        {
                                delay_ms ++;
                                delay_start= get_delay_cont();
                        }
                }        
                if(delay_ms == 1000)
                {
                        delay_ms = 0;
                        delay_s ++;
                }        
        }
}

/* ******************************************************************************
//非阻塞型定时延时,以达到延时不独占CPU资源目的.
调用延时前需先调用起始函数初始化,再根据延时函数是否返回set判断定时到期.
******************************************************************************* */
uint16_t ub_delay_us = 0;

void ub_delay_us_start(void)
{
        ub_delay_us = 0;        
        delay_start= get_delay_cont();
}

FlagStatus ub_delay_us(uin16_t nus)
{
        if(ub_delay_us < xus)
        {
                if(get_delay_cont() > delay_start)
                {
                        ub_delay_us = (get_delay_cont() - delay_start)/10;
                }
                else
                {
                        ub_delay_us = (MAX_DEAY - delay_start + get_delay_cont())/10;
                }
        }
        else
        {
                return SET;
        }        
        
        return RESET;
}

uint16_t ub_delay_ms = 0;

void ub_delay_ms_start(void)
{
        ub_delay_ms = 0;        
        delay_start= get_delay_cont();
}

FlagStatus ub_delay_ms(uin16_t nms)
{
        if(ub_delay_ms < xms)
        {
                if(get_delay_cont() > delay_start)
                {
                        if((get_delay_cont() - delay_start) >= 10000)
                        {
                                ub_delay_ms ++;
                                delay_start= get_delay_cont();
                        }
                }
                else
                {
                        if((MAX_DEAY - delay_start + get_delay_cont()) >= 10000)
                        {
                                ub_delay_ms ++;
                                delay_start= get_delay_cont();
                        }
                }               
        }
        else
        {
                return SET;
        }        
        
        return RESET;
}

使用特权

评论回复
评论
xch 2023-12-26 11:12 回复TA
BUG 大神 
沙发
zpwang|  楼主 | 2023-12-25 23:19 | 只看该作者
纠正:几处相等应改成大于或等于,如 if((get_delay_cont() - delay_start) == 10000),应该改为if((get_delay_cont() - delay_start) >= 10000).

使用特权

评论回复
板凳
jobszheng| | 2023-12-26 16:49 | 只看该作者
不错,不错。
肯分享就相当好!
有bug慢慢修改

使用特权

评论回复
地板
zpwang|  楼主 | 2023-12-26 19:46 | 只看该作者
贴中代码存在很多逻辑错误之处.本来打算早上自己把贴删了.结果删不了,误导大家了见谅.

使用特权

评论回复
5
万能的互联网| | 2023-12-26 23:12 | 只看该作者
感谢分享,非阻塞延时是好东西,代码错误可以编辑帖子修改的。

使用特权

评论回复
6
zpwang|  楼主 | 2024-9-1 00:13 | 只看该作者
本帖最后由 zpwang 于 2024-9-1 17:49 编辑

感谢 jobszheng 和 万能的互联网 的理解和支持! 发贴代码BUG多误导人,凡事应有始有终,重新整理以将码打包重新发.开发环境使用的是VSCode+CMake,调试器是最廉价的DAP-LINK. 代码基于at32f423. 非阻塞延时精度较低,大多数场合应该是够用.
libraries.zip (2.29 MB)

systick_test.zip (1.45 MB)

BSP.zip (173.62 KB)


使用特权

评论回复
评论
muyichuan2012 2024-9-2 09:41 回复TA
这么好的分享,要单独发一个主题或许效果会更好 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

60

帖子

1

粉丝