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

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

[复制链接]
fuluoce 提问时间:2015-1-12 18:35 /

void HAL_IncTick(void)
{
  uwTick++;
}
中断函数是1ms进来一次,也就是说uwTick+1就代表1ms
void SysTick_Handler(void)
{
  HAL_IncTick();
}
void HAL_Delay(__IO uint32_t Delay)
{
  __IO uint32_t timingdelay;

  timingdelay = uwTick + Delay;
  //while(HAL_GetTick() < timingdelay)
        while(uwTick < timingdelay)
  {;
  }
}
在HAL库里 我就没看到哪里对uwTick溢出进行处理,也就是说uwTick=0xffffffff的时候 再加1就是uwTick=0了  那这一时刻的延时不就延时不准确了吗?



收藏 1 评论30 发布时间:2015-1-12 18:35

举报

30个回答
jiaozhu88 回答时间: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的溢出是否在别的地方有影响还不好说。得看具体情况了。
gkcclm 回答时间:2015-5-22 22:42:36
这个bug感觉理论上无法解决。这种定时应该只能通过中断程序来实现(在SysTick_Handler中来处理)。

  1. uint32_t g_delay_request_flag = 0;
  2. uint32_t g_delay_timeout_flag = 0;
  3. uint32_t g_delay_target_tick;

  4. void HAL_Delay(__IO uint32_t Delay)
  5. {
  6.   HAL_SuspendTick();        //先停止定时器,或者禁止中断
  7.   
  8.   g_delay_target_tick = HAL_GetTick() + Delay;
  9.   
  10.   g_delay_timeout_flag = 0;
  11.   
  12.   g_delay_request_flag = 1;
  13.   
  14.   HAL_ResumeTick();
  15.   
  16.   while(!g_delay_timeout_flag)
  17.   {
  18.   }
  19. }

  20. /**
  21. * @brief This function handles System tick timer.
  22. */
  23. void SysTick_Handler(void)
  24. {
  25.   /* USER CODE BEGIN SysTick_IRQn 0 */

  26.   /* USER CODE END SysTick_IRQn 0 */
  27.   HAL_IncTick();
  28.   HAL_SYSTICK_IRQHandler();
  29.   /* USER CODE BEGIN SysTick_IRQn 1 */

  30.   if(g_delay_request_flag && g_delay_target_tick == HAL_GetTick())
  31.   {
  32.         g_delay_request_flag = 0;
  33.        
  34.         g_delay_timeout_flag = 1;
  35.   }
  36.   /* USER CODE END SysTick_IRQn 1 */
  37. }
复制代码
fuluoce 回答时间:2015-1-30 17:59:47
a208hlc-57526 发表于 2015-1-30 14:18
一般不会出现这种问题,只要你的应用中不延时46天就行,系统运行不受46天限制,比如你从FFFFFF00,开始定时1 ...

uwTick的值范围是不是   0- 0xffffffff;uwTick每1ms加1
当uwTick=0xfffffff0;的时候 延时0xff ms  你就会发现延时不了

void HAL_Delay(__IO uint32_t Delay)  // Delay=0xff
{
  __IO uint32_t timingdelay;

  timingdelay = uwTick + Delay;  //假如此刻uwTick =0xfffffff0 Delay=0xff  timingdelay=0xef;
  //while(HAL_GetTick() < timingdelay)
        while(uwTick < timingdelay)   //这里不会等待延时 直接跳出去
  {;
  }
}

不知道你看懂了没有
fuluoce 回答时间:2015-1-13 12:46:09
在HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)函数里使能的 是   __HAL_UART_ENABLE_IT(huart, UART_IT_TC);传输完成中断  这里发送数据不应该是    __HAL_UART_ENABLE_IT(huart, UART_IT_TXE);  传输数据寄存器空中断才对
很费解 求解答
巅峰残狼 回答时间:2015-1-13 12:57:51
你用的是滴答定时器延时,看一下滴答定时器介绍就明白了
fuluoce 回答时间:2015-1-13 14:01:18
巅峰残狼 发表于 2015-1-13 12:57
你用的是滴答定时器延时,看一下滴答定时器介绍就明白了

这里的滴答定时器 只是1ms中断一次 就是说1ms uwTick加1 这并没有把我的问题解决
fuluoce 回答时间:2015-1-14 15:03:45
顶一个!!!!!!!!!!!!
fuluoce 回答时间:2015-1-29 17:31:21
uint32_t HAL_GetTick(void)
{
  return uwTick;  
}  
这函数,很多库文件调用,用来timeout 延时
我觉得调用了uint32_t HAL_GetTick(void)函数的延时都是有问题的
不过我算了一下 要连接上电46天多才会出现bug (0xffffffff个ms)
fuluoce 回答时间:2015-1-29 17:33:57
这ST官方库的bug  不小
所有文件都涉及到这延时  延时的bug
cxtarm 回答时间:2015-1-29 17:42:02
嗯,延时这个确实是个bug
ataudio 回答时间:2015-1-30 09:33:38
真是bug吗?关注。以后再测。

二十四节气~大雪

二十四节气~大雪
fuluoce 回答时间:2015-1-30 10:50:00
而且这bug不好改! 太多的地方调用uint32_t HAL_GetTick(void)函数了,,又不能随便给uwTick;清零
a208hlc-57526 回答时间:2015-1-30 14:18:15
一般不会出现这种问题,只要你的应用中不延时46天就行,系统运行不受46天限制,比如你从FFFFFF00,开始定时10天,这个函数也是不会错的,仔细想一下吧
fuluoce 回答时间:2015-2-4 09:33:18
顶一个!  求解决
foxglove 回答时间:2015-2-11 12:29:40
uint32_t timingdelay
wamcncn 回答时间:2015-2-11 12:46:00
fuluoce 发表于 2015-1-13 14:01
这里的滴答定时器 只是1ms中断一次 就是说1ms uwTick加1 这并没有把我的问题解决 ...

滴答定时器到0后,自动+载的吧,另外滴答是的24位计数器,uwTick++达不到uwTick=0xffffffff的吧
123下一页

所属标签

相似问题

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