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

楼主: fuluoce

STM32的HAL库的HAL_Delay问题和UART接受数据问题

[复制链接]

6

主题

321

回帖

0

蝴蝶豆

金牌会员

最后登录
2020-11-11
发表于 2015-7-2 15:20:54 | 显示全部楼层
本帖最后由 广州星翼-萌主 于 2015-7-2 15:22 编辑

uwTick是无符号32位,开机要不断运行49天才会溢出,你要是觉得短的话把uwTick改为u64类型的不就行了,这样就再也不用担心溢出了,至于HAL库中其他地方需要timeout做超时判断的地方,你应该不会设置超时49天吧,所以u32的timeout就可以了。
回复 支持 反对

使用道具 举报

60

主题

2051

回帖

31

蝴蝶豆

版主

最后登录
2020-12-9
发表于 2015-7-2 17:12:20 | 显示全部楼层
ST在最新的HAL库里面已经修复了这个bug,新的延时函数如下:
  1. __weak void HAL_Delay(__IO uint32_t Delay)
  2. {
  3.   uint32_t tickstart = 0;
  4.         uwTick = 0xFFFFFFFF;
  5.   tickstart = HAL_GetTick();
  6.   while((HAL_GetTick() - tickstart) < Delay)
  7.   {
  8.   }
  9. }
复制代码
测试如下:

回复 支持 反对

使用道具 举报

47

主题

3404

回帖

30

蝴蝶豆

版主

最后登录
2020-12-7
发表于 2015-7-2 17:30:50 | 显示全部楼层
多谢,楼上。
回复 支持 反对

使用道具 举报

227

主题

601

回帖

32

蝴蝶豆

金牌会员

最后登录
2020-11-10
发表于 2016-1-6 10:24:33 | 显示全部楼层
fuluoce 发表于 2015-1-30 10:50
而且这bug不好改! 太多的地方调用uint32_t HAL_GetTick(void)函数了,,又不能随便给uwTick;清零 ...

这个问题确实是比较难解决,比较调用共用的太多了,

或者建立一个定时器表,各自都分配一个id,更具不同的定时器id判断各自的定时时间,估计这样会比较好,
回复 支持 反对

使用道具 举报

0

主题

2

回帖

0

蝴蝶豆

新手上路

最后登录
2016-1-9
发表于 2016-1-9 17:29:05 | 显示全部楼层
转自21
一楼的写法的确是有BUG的,并非是溢出问题,假设延时 30ms  0x1E:
void HAL_Delay(__IO uint32_t Delay)
{
   __IO uint32_t timingdelay;

   timingdelay = uwTick + Delay;             //假设此时uwTick=0xFFFFFFF0  Delay=0x1E 则 timingdelay=0x1 0000000E,溢出后保留32位=0x0000000E。
   //while(HAL_GetTick() < timingdelay)
         while(uwTick < timingdelay)          //此时的uwTick仍是0xFFFFFFF0或任何小于0xFFFFFFFF的值,则 if(0xFFFFFFF0<0x0000000E) 为假,立即退出,并没有延时30ms。
   {;
   }
}

正确的写法应该是这样,仍然假设延时 30ms  0x1E:
__weak void HAL_Delay(__IO uint32_t Delay)
{
  uint32_t tickstart = 0;
  tickstart = HAL_GetTick();                         //假设此时uwTick=0xFFFFFFF0  Delay=0x1E 则 tickstart=0xFFFFFFF0。
  while((HAL_GetTick() - tickstart) < Delay)   //此时的uwTick仍是0xFFFFFFF0或任何小于0xFFFFFFFF的值时,假如是0xFFFFFFF5-0xFFFFFFF0=0x05,if(0x05<0x1E)为真,继续等待。
                                                                 //如果溢出后 uwTick=0x0000000D,则0x0000000D-0xFFFFFFF0=0x1D,if(0x1D<0x1E)为真,继续等待。
                                                                 //继续 uwTick=0x0000000E,则0x0000000E-0xFFFFFFF0=0x1E,if(0x1E<0x1E)为假,延时完成,退出。
  {
  }
}

个人感觉这个解答很好,新版本的HAL也确实是按照他说的这个改的。改了后uwTick的溢出对这个延迟函数没有任何影响。但这个uwTick的溢出是否在别的地方有影响还不好说。得看具体情况了。
回复 支持 反对

使用道具 举报

0

主题

2

回帖

0

蝴蝶豆

新手上路

最后登录
2016-1-9
发表于 2016-1-9 17:31:19 | 显示全部楼层
creep 发表于 2015-7-2 17:12
ST在最新的HAL库里面已经修复了这个bug,新的延时函数如下:
测试如下:

这样改了应该不行的吧       每次调用这个延迟函数的时候都改变了uwTick的值,但这个uwTick不光是在这个延迟函数里用的啊   在别的地方还有用到呢   
回复 支持 反对

使用道具 举报

60

主题

2051

回帖

31

蝴蝶豆

版主

最后登录
2020-12-9
发表于 2016-1-11 08:44:53 | 显示全部楼层
jiaozhu88 发表于 2016-1-9 17:31
这样改了应该不行的吧       每次调用这个延迟函数的时候都改变了uwTick的值,但这个uwTick不光是在这个 ...

不小心把我测试的代码也添加进去了,应该是下面这样的!
  1. __weak void HAL_Delay(__IO uint32_t Delay)
  2. {
  3.   uint32_t tickstart = 0;
  4.   tickstart = HAL_GetTick();
  5.   while((HAL_GetTick() - tickstart) < Delay)
  6.   {
  7.   }
  8. }
复制代码


回复 支持 反对

使用道具 举报

76

主题

5715

回帖

4

蝴蝶豆

论坛元老

最后登录
2020-10-15
发表于 2016-1-11 09:45:42 | 显示全部楼层
不清零,很多地方者阿以使用。
清零了,就只有一个地方可以使用。

权衡一下,还是不要清零的好。。。
回复 支持 反对

使用道具 举报

15

主题

206

回帖

6

蝴蝶豆

金牌会员

最后登录
2018-9-26
发表于 2016-1-11 09:48:47 | 显示全部楼层
creep 发表于 2016-1-11 08:44
不小心把我测试的代码也添加进去了,应该是下面这样的!

改成这样确实不会有问题了!
回复 支持 反对

使用道具 举报

15

主题

206

回帖

6

蝴蝶豆

金牌会员

最后登录
2018-9-26
发表于 2016-1-11 09:50:34 | 显示全部楼层
jiaozhu88 发表于 2016-1-9 17:29
转自21
一楼的写法的确是有BUG的,并非是溢出问题,假设延时 30ms  0x1E:
void HAL_Delay(__IO uint32_t D ...

这个讲解很耐心
回复 支持 反对

使用道具 举报

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