OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5566|回复: 3

关于SysTick延时卡死问题的解决

[复制链接]

23

主题

52

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2015-1-19
在线时间
28 小时
发表于 2016-5-28 09:31:37 | 显示全部楼层 |阅读模式
http://www.openedv.com/thread-75729-1-1.html
在上贴我分享了32外设的一个小程序,但是用SysTick定时器生成的延时函数在主函数和中断中同时使用时,会造成中断完成之后返回主函数时,延时函数卡死,究其原因,先看代码:
[mw_shl_code=c,true]/*****************************
* @fileelay.c
* @brief:initializing SysTick registers as base time for delay and set us&ms delay
* @author:zx
* @date: 2016/5/18
* @version: V0.1
* @attention: none
*****************************/
#include "Delay.h"

void SysTick_Init(void)
{  
    //SysTick_CLKSource_HCLK  72MHz
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);  //配置SysTick时钟源为8分频 即 72MHz/8 也可选择不分频
    SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;          //计数器减到0时 不产生异常中断   
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;           //关定时器
      SysTick->CTRL &= ~SysTick_CTRL_COUNTFLAG_Msk;    //异常标志位清零
     
      SysTick->LOAD = 9; // 72MHz/8/9 = 1us 我要每1us产生一次异常则就在重装寄存器中存9
     
    SysTick->VAL = 0;  //默认计数器内容是0
}

void Delay_us(u32 us)
{
     SysTick->VAL = 0;
     SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开定时器
     while(us--)
     {
        while(!(SysTick->CTRL&SysTick_CTRL_COUNTFLAG_Msk)); //判断标志位是否置位,没有就等待
    }
     
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关定时器
}

void Delay_ms(u32 ms)
{
while(ms--)
    {
     Delay_us(1000); // 延时1ms
    }
}[/mw_shl_code]


      上面是问题代码,在,顺序执行延时的时候一点事也不会有,但是一旦产生了延时嵌套,就造成了主函数卡死。
      我先说说原因:systick定时器是一个递减计数器,我在Delay_us代码中,先开定时器,延时之后再关定时器,所以当主函数正在延时时(此时定时器开),中断发生,并且中断内也调用了延时函数,那么此时他也会对systick进行开——关的操作,注意:问题就是关操作,当中断关掉定时器后,返回主函数的延时,延时由于一直在等待标志位而一直处于while等待,但是此时,定时器是关闭的,也就是说,主函数永远也不可能等到标志位置位的发生,所以陷入了无限循环,导致程序卡死。


     思考:从主函数延时到中断延时,再到返回中断延时,对于主函数延时的精度会有什么样的影响呢?由于跳出中断以及主函数发生中断时计数器内的计数值的不确定性,导致返回中断会有几百纳秒的延时。
     其次,程序的卡死看似解决,但是多次测试之后发现还会有那么几次会卡死,有待进一步探索。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

23

主题

52

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
218
金钱
218
注册时间
2015-1-19
在线时间
28 小时
 楼主| 发表于 2016-5-28 09:33:55 | 显示全部楼层
是主函数延时到中断延时再返回主函数延时,存在误差,上面思考打错了几个字。
回复 支持 反对

使用道具 举报

24

主题

695

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1666
金钱
1666
注册时间
2016-4-29
在线时间
266 小时
发表于 2016-5-28 09:59:13 | 显示全部楼层
mark mark
回复 支持 反对

使用道具 举报

8

主题

145

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2016-12-14
在线时间
75 小时
发表于 2017-4-20 16:50:09 | 显示全部楼层
12366666666666
书山有路勤为径,学海无涯苦作舟!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-8 05:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表