你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

自己写的利用systick进行us定时,请问是否有问题?

[复制链接]
红白菜 提问时间:2016-6-23 20:47 /
#include "delay_us.h"

delay_us(n_us)
{
    uint32_t load_ms, load_us, n_us_tick, a_tick, end_tick, now_tick;
    load_ms=systick->LOAD;
    load_us=systick->LOAD/1000;
    n_us_tick=n_us*load_us;
    a_tick=systick->VAL;
    if(a_tick>=n_us_tick)
    {
        end_tick=a_tick-n_us_tick;
        do
        {
            now_tick=systick->VAL;
        }while (now_tick<end_tick);
    }
    else
    {
        end_tick=load_ms-n_us_tick+a_tick;
        do
        {
            now_tick=systick->VAL;
        }while ((now_tick>n_us_tick)&&(now_tick<end_tick));        
    }
}


收藏 1 评论8 发布时间:2016-6-23 20:47

举报

8个回答
回答时间:2016-6-24 17:01:30
直接用
a = systick->VAL;
while(systick->VAL-a<x)
{}
kelly-395249 回答时间:2016-6-26 12:29:00
安 发表于 2016-6-24 17:01
直接用
a = systick->VAL;
while(systick->VAL-a

以前这么用过, 后来觉得有点不妥,假如延时开始, 不巧进入了一个中断, 中断里也有延时函数, 那中断返回后会不会出问题?
或者延时开始后进入中断,中断返回时systick已经重载过了
kelly-395249 回答时间:2016-6-26 13:15:27
感觉可以这样: systick时钟定义为系统时钟,假设72M, 定义一个全局的U64 Tickcount,systick自动加载值设为0xffffff, systick中断里, Tickcount=Tickcount+(1<<25), 延时函数里当前系统tick值=Tickcount+systick->VAL, 延时2毫秒就等到Tickcount+systick->VAL>=当前系统tick值+2*(72000000/1000), 64位按照72M的 频率计数, 要8千多年,  systick中断一秒中断4-5次,系统影响也不大,不过中断级别一定要高,至少要高于任何用到延时的中断优先级,个人感觉这样用问题不大

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

kelly-395249 回答时间:2016-6-26 13:16:43
kelly-395249 发表于 2016-6-26 13:15
感觉可以这样: systick时钟定义为系统时钟,假设72M, 定义一个全局的U64 Tickcount,systick自动加载值设 ...

延时2u秒就等到Tickcount+systick->VAL>=当前系统tick值+2*(72000000/1000000)
pener 回答时间:2016-6-26 13:52:41
在中断里延迟说明这代码有需要优化的地方
kelly-395249 回答时间:2016-6-26 22:50:31
有道理, 不过总觉得这是一个bug,万一碰到这个问题,可能要花费很多时间查, 特别是中断后转了很多函数后。。比如USB通信函数里面, 往24C02里写了一个字节,一切行云流水,  不过就在你无意识的情况下发生了中断里延时了10ms,
回答时间:2016-6-27 08:56:54
中断中就不要加延时了。如果中断加了延时,会影响其他的中断。
红白菜 回答时间:2016-7-2 19:13:39
经过优化改成如下:
void delay_us(uint16_t us)
{
         uint32_t load_ms,n_us_tick,a_tick,end_tick;
                        a_tick=SysTick->VAL;
                load_ms=SysTick->LOAD;
                n_us_tick=load_ms/1000*us;
                if(a_tick>=n_us_tick)
                {
                        end_tick=a_tick-n_us_tick;
                        while(SysTick->VAL>end_tick);
                }
                else
                {
                        end_tick=load_ms-n_us_tick+a_tick;
                        while(SysTick->VAL <a_tick);
                        while(SysTick->VAL>end_tick);
                }       
}
经测试这个代码在延时1000us内只差内个TICK。

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版