野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 8716|回复: 7

关于Systick中优先级的问题

[复制链接]
发表于 2016-9-22 14:52:09 | 显示全部楼层 |阅读模式
        今天终于有点儿时间继续玩一下平衡车的代码了,在写按键驱动的时候遇到一个问题:就是按键使用外部中断,延时使用Systick中断精确延时,而正常中断优先级为15,中断时候使用了Delay_ms的函数。那么问题来了,外部中断的优先级高于延时的优先级,导致这个延时函数不能正常使用,而如果把Systick中断优先级提高到0,那么它是否会导致在延时的过程中错过了很多其它函数的运行?


回复

使用道具 举报

 楼主| 发表于 2016-9-22 15:32:44 | 显示全部楼层
使用systick时候设置优先级必须要写在Systick_Config()函数的后面才行,否则不起作用
void SysTick_Init(void)
{
//        NVIC_SetPriority(SysTick_IRQn, 0);放到这里就死翘翘了
        if (SysTick_Config(72))       
        {
                /* Capture error */
                while (1);
        }
        NVIC_SetPriority(SysTick_IRQn, 0);
        SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;       
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-22 15:35:08 | 显示全部楼层
牧梦苍穹 发表于 2016-9-22 15:32
使用systick时候设置优先级必须要写在Systick_Config()函数的后面才行,否则不起作用
void SysTick_Init(v ...

我想讨论的是,大伙儿使用Systick做延时函数的话,它的优先级和其它优先级怎么设置更合适?如果延时优先级设置最高,是否有时候因为中断嵌套中使用了延时导致遗漏IO口检测或者使其它函数运行滞后?
回复 支持 反对

使用道具 举报

发表于 2016-9-22 15:56:15 | 显示全部楼层
systick一般是1ms延时一次,不怕影响吧

关于systick中断优先级配置:
systick的优先级到底比外设的优先级高还是低,目前只有2人答对。高手在哪里
http://www.firebbs.cn/forum.php? ... 3724&fromuid=64
(出处: 野火论坛)
回复 支持 反对

使用道具 举报

发表于 2016-9-22 17:19:46 | 显示全部楼层
牧梦苍穹 发表于 2016-9-22 15:35
我想讨论的是,大伙儿使用Systick做延时函数的话,它的优先级和其它优先级怎么设置更合适?如果延时优先 ...

延时的优先级是设置的最高的。
回复 支持 反对

使用道具 举报

发表于 2016-9-22 17:25:31 | 显示全部楼层
你的问题:而如果把Systick中断优先级提高到0,那么它是否会导致在延时的过程中错过了很多其它函数的运行?

1-如果systick的优先级为最高,但是在延时的时候又有其他的中断来了,那么这个中断就会出问题
2-如果延时是精确延时,那么优先级必须是最高,如果不是精确延时,那么可以不使用中断,而是使用查询的延时方法,具体看下面的代码

systick不使用中断实现精确延时,但是会被其他的中断打断
  1. // couter 减1的时间 等于 1/systick_clk
  2. // 当counter 从 reload 的值减小到0的时候,为一个循环,如果开启了中断则执行中断服务程序,
  3. // 同时 CTRL 的 countflag 位会置1
  4. // 这一个循环的时间为 reload * (1/systick_clk)

  5. void SysTick_Delay_Us( __IO uint32_t us)
  6. {
  7.         uint32_t i;
  8.         SysTick_Config(SystemCoreClock/1000000);
  9.        
  10.         for(i=0;i<us;i++)
  11.         {
  12.                 // 当计数器的值减小到0的时候,CRTL寄存器的位16会置1       
  13.                 while( !((SysTick->CTRL)&(1<<16)) );
  14.         }
  15.         // 关闭SysTick定时器
  16.         SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
  17. }

  18. void SysTick_Delay_Ms( __IO uint32_t ms)
  19. {
  20.         uint32_t i;       
  21.         SysTick_Config(SystemCoreClock/1000);
  22.        
  23.         for(i=0;i<ms;i++)
  24.         {
  25.                 // 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
  26.                 // 当置1时,读取该位会清0
  27.                 while( !((SysTick->CTRL)&(1<<16)) );
  28.         }
  29.         // 关闭SysTick定时器
  30.         SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
  31. }
复制代码
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-9-22 19:30:47 | 显示全部楼层
fire 发表于 2016-9-22 17:25
你的问题:而如果把Systick中断优先级提高到0,那么它是否会导致在延时的过程中错过了很多其它函数的运行? ...

哈哈,火哥威武,这回答太赞了。
正常而言中断函数不应该使用延时,否则中断执行时间太长,容易导致其它函数阻塞。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-22 19:53:38 | 显示全部楼层
fire 发表于 2016-9-22 17:25
你的问题:而如果把Systick中断优先级提高到0,那么它是否会导致在延时的过程中错过了很多其它函数的运行? ...

72MHz时钟源下滴答时钟Systick初始化函数如果使用SysTick_Config(72)配置滴答定时器中断时间为1us,这里若是配置时钟为8分频
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
SysTick_Config(9);
上述两句一样是配置为1uS定时,程序跑不起来。何解?


而单独配置时钟源是可以的,如下:
/*SysTick时钟源由HCLK/8提供,当系统频率为72MHz时最小计数周期为1/9MHz,
计满9次为1us,fac_us以9为单位*/
void SysTick_Init(void)
{
        SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//72MHz/8 = 9MHz
        NVIC_SetPriority(SysTick_IRQn, 0);
        fac_us = 9;              //9次1uS
}

void Delay_us(u32 us)
{
//        volatile uint32_t temp;
        SysTick->LOAD = (u32)us * fac_us;
        SysTick->VAL  = 0x00;//清空计数器
        SysTick->CTRL = 0x01;//开始计数
//        temp  = SysTick->VAL;
        //当计数器的值减小到0的时候,CTRL寄存器的位16会置1
        while((SysTick->CTRL & (0x01 << 16)) == 0);
        SysTick->CTRL = 0x00;//停止计数
        SysTick->VAL  = 0x00;//清空计数器
}
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-2 07:30 , Processed in 0.031311 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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