zoukankan      html  css  js  c++  java
  • [HAL]5.中断里调用HAL_Delay()进入死循环的原因

    中断里调用HAL_Delay()进入死循环的原因 

    摘自:http://blog.csdn.net/alwxkxk/article/details/47204677

    CUBE生成的程序中, SysTick是中断型延时(利用中断来查询时间到了没)。

      /* Use systick as time base source and configure 1ms tick (default clock after Reset is MSI) */

      HAL_InitTick(TICK_INT_PRIORITY);

    #define  TICK_INT_PRIORITY            ((uint32_t)0x000F)    /*!< tick interrupt priority */    

    SysTick是内核中断,优先级别默认最低。

    (可以用内核函数来修改~   当然,这就要看内核M3的书了,而不是看STM32的参考手册那么简单。暂时就不深入研究,日后更新。)

    总结起来就是,就是传说中优先级别默认最低,虽然SysTick一直在跑,但是没进入到中断来读取它的值~

    (不知是哪里让我潜意识地认为SysTick级别比外设都高,导致这问题)

    如果中断里调用HAL_Delay就会停在那里,因为根本不会进入那个级别更低的中断。

     资料补充:

     网上还有一种写 法是时间摘取法,是一直读取SysTick产生延时函数~(原子的例程就是用这种方法)

    其次,有人提到,中断里面不应该使用延时,中断所占的时间越短越好~有道理~

    附上原子的时间摘取法的程序,很有学习价值~

      1 //////////////////////////////////////////////////////////////////////////////////  
      2 
      3 //本程序只供学习使用,未经作者许可,不得用于其它任何用途
      4 
      5 //Mini STM32开发板
      6 
      7 //使用SysTick的普通计数模式对延迟进行管理
      8 
      9 //包括delay_us,delay_ms
     10 
     11 //正点原子@ALIENTEK
     12 
     13 //技术论坛:www.openedv.com
     14 
     15 //修改日期:2010/5/27
     16 
     17 //版本:V1.2
     18 
     19 //版权所有,盗版必究。
     20 
     21 //Copyright(C) 正点原子 2009-2019
     22 
     23 //All rights reserved
     24 
     25 //********************************************************************************
     26 
     27 //V1.2修改说明
     28 
     29 //修正了中断中调用出现死循环的错误
     30 
     31 //防止延时不准确,采用do while结构!
     32 
     33 //////////////////////////////////////////////////////////////////////////////////  
     34 
     35 static u8  fac_us=0;//us延时倍乘数
     36 
     37 static u16 fac_ms=0;//ms延时倍乘数
     38 
     39 //初始化延迟函数
     40 
     41 //SYSTICK的时钟固定为HCLK时钟的1/8
     42 
     43 //SYSCLK:系统时钟
     44 
     45 void delay_init(u8 SYSCLK)
     46 
     47 {
     48 
     49 SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟  HCLK/8
     50 
     51 fac_us=SYSCLK/8;     
     52 
     53 fac_ms=(u16)fac_us*1000;
     54 
     55 }     
     56 
     57 //延时nms
     58 
     59 //注意nms的范围
     60 
     61 //SysTick->LOAD为24位寄存器,所以,最大延时为:
     62 
     63 //nms<=0xffffff*8*1000/SYSCLK
     64 
     65 //SYSCLK单位为Hz,nms单位为ms
     66 
     67 //对72M条件下,nms<=1864 
     68 
     69 void delay_ms(u16 nms)
     70 
     71 {        
     72 
     73 u32 temp;    
     74 
     75 SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
     76 
     77 SysTick->VAL =0x00;           //清空计数器
     78 
     79 SysTick->CTRL=0x01 ;          //开始倒数  
     80 
     81 do
     82 
     83 {
     84 
     85 temp=SysTick->CTRL;
     86 
     87 }
     88 
     89 while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   
     90 
     91 SysTick->CTRL=0x00;       //关闭计数器
     92 
     93 SysTick->VAL =0X00;       //清空计数器        
     94 
     95 }   
     96 
     97 //延时nus
     98 
     99 //nus为要延时的us数.         
    100 
    101 void delay_us(u32 nus)
    102 
    103 {
    104 
    105 u32 temp;       
    106 
    107 SysTick->LOAD=nus*fac_us; //时间加载     
    108 
    109 SysTick->VAL=0x00;        //清空计数器
    110 
    111 SysTick->CTRL=0x01 ;      //开始倒数   
    112 
    113 do
    114 
    115 {
    116 
    117 temp=SysTick->CTRL;
    118 
    119 }
    120 
    121 while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   
    122 
    123 SysTick->CTRL=0x00;       //关闭计数器
    124 
    125 SysTick->VAL =0X00;       //清空计数器  
    126 
    127 }
    128 
    129  
    如果问题解决起来不妥或者有更好的解决办法,麻烦请告知,帮助曾经和你一样的入门者,谢谢。
  • 相关阅读:
    Android对包名和类名是否存在的判断
    Android权限表
    论艺术的背后还有纪律
    jeecgboot/IDEA中 debug不行,run可以
    java集合类
    HashMap、HashTable、LinkedHashMap和TreeMap用法和区别
    protobuf序列化算法原理
    谁能帮我看看着究竟是什么问题呀,我在本机运行都是好好的,但在别人的机子上运行就出这个呢?我快疯了!!!
    VS删除空白行
    POJ 2516 Minimum Cost
  • 原文地址:https://www.cnblogs.com/ourran/p/4809892.html
Copyright © 2011-2022 走看看