OpenEdv-开源电子网

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

HAL库中SysTick使用问题,以及delay_us函数的疑惑

[复制链接]

1

主题

1

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2019-9-5
在线时间
6 小时
发表于 2020-11-2 11:23:12 | 显示全部楼层 |阅读模式
1金钱
用的MCU为STM32F103RBT6,在使用正点原子提供的SYSTEM函数库delay API出现了问题。
问题描述如下:
先贴主函数
  1. int main(void) {
  2.         u32 RxLen = 0;
  3.         u32 tickVAL;
  4.         HAL_Init();                                                                //初始化HAL库
  5.         Stm32_Clock_Init(RCC_PLL_MUL9);                        //设置时钟72MHz
  6.         delay_init(72);                                                        //初始化delay函数
  7.         uart_init(115200);                                                //初始化串口
  8.        
  9.         while (1) {

  10.     printf("Wait for input...\r\n");
  11.     ///delay_us(2000);
  12.     HAL_Delay(2000);
  13.     RxLen = HAL_GetTick();
  14.     printf("%d\r\n", RxLen);
  15.     tickVAL = SysTick->VAL;
  16.     printf("tickVal:%d\r\n", tickVAL);
  17.         }
  18.         //return 0;
  19. }
复制代码
问题源于在while死循环中调用delay_ms()导致程序卡死,于是定位问题到了delay_us()函数。
delay_us()是利用Systick定时,于是我在主函数中打印出了SysTick->VAL,发现该值一直为0
问题.PNG
于是delay卡死的原因找到了:
  1. void delay_us(u32 nus)
  2. {               
  3.         u32 ticks;
  4.         u32 told,tnow,tcnt=0;
  5.         u32 reload=SysTick->LOAD;                                //LOAD的值                     
  6.         ticks=nus*fac_us;                                                 //需要的节拍数
  7.         delay_osschedlock();                                        //阻止OS调度,防止打断us延时
  8.         told=SysTick->VAL;                                        //刚进入时的计数器值
  9.         while(1)
  10.         {
  11.                 tnow=SysTick->VAL;       
  12.                 if(tnow!=told)
  13.                 {            
  14.                         if(tnow<told)tcnt+=told-tnow;        //这里注意一下SYSTICK是一个递减的计数器就可以了.
  15.                         else tcnt+=reload-tnow+told;            
  16.                         told=tnow;
  17.                         if(tcnt>=ticks)break;                        //时间超过/等于要延迟的时间,则退出.
  18.                 }  
  19.         };
  20.         delay_osschedunlock();                                        //恢复OS调度                                                                                            
  21. }  
复制代码
tnow一直等于told,一直为0,不会执行if逻辑所以卡死在这里。
我感到疑惑的是利用HAL函数HAL_GetTick()可以获取到SysTick当前值,而SysTick->VAL的值一直为0,这是为什么?

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2020-11-3 00:46:18 | 显示全部楼层
不要用HAL的delay,不然我们的delay就不好用了。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-21 20:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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