关于STM32的HAL库中超时函数中的tick溢出后产生的问题的思考及求证

命题:

引用变量及函数:

__IO uint32_t uwTick;
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

 源代码:

__weak void HAL_Delay(__IO uint32_t Delay)
{
  uint32_t tickstart = 0;
  tickstart = HAL_GetTick();
  while((HAL_GetTick() - tickstart) < Delay)
  {
  }
}
求证:

如下假设:

由题设可知: 当每个时间Tick(滴答时钟)  到来时uwTick加1;

需要延时Delay = 0x0D;

此时 获得 tickstart = 0xFFFF FFFF - 0x0A==》因此可知此时 uwTick = 0xFFFF FFFF - 0x0A;

经过0x0B次滴答时钟后,uwTick =  0xFFFF FFFF - 0x0A + 0x0B) = 0x1 0000 0000==》此时数据溢出uwTick = 0;

(uint32_t)uwTick - (uint32_t)(tickstart)=  0x00 -  (0xFFFF FFFF - 0x0A)  = 0x00 +  (uint32_t) 0xA - 0xFFFF FFFF = (uint32_t) 0x ‭FFFFFFFF00000001‬ = 0x01;

滴答时钟再加(+)1;

(uint32_t)uwTick - (uint32_t)(tickstart)=  0x01 -  (0xFFFF FFFF - 0x0A)  = 0x01 -  (uint32_t) 0xA - 0xFFFF FFFF = (uint32_t) 0x ‭FFFFFFFF00000002‬ = 0x02;

再(+)1;

(uint32_t)uwTick - (uint32_t)(tickstart)=  0x01 -  (0xFFFF FFFF - 0x0A)  = 0x02 -  (uint32_t) 0xA - 0xFFFF FFFF = (uint32_t) 0x ‭FFFFFFFF00000003‬ = 0x03;

…… 继续累加到0xD

(uint32_t)uwTick - (uint32_t)(tickstart)=  0x0D-  (0xFFFF FFFF - 0x0A)  = 0x0D -  (uint32_t) 0xA - 0xFFFF FFFF = (uint32_t) 0x ‭FFFFFFFF00000003‬ = 0x0D;

延时时间到

(HAL_GetTick() - tickstart) = uwTick - tickstart = 0x0D ==》等于要求的延时 Delay = 0x0D ,定时到退出while循环;

从而显然可知:

当Tick溢出为0后,变为:(0 - tickstart ) > Timeout,一个负数会大于一个正数么? 系统Tick频率设置为1毫秒中断一次,那么0xFFFFFFFF毫秒大约为49.71026961805556天,也就是49天以后会产生第一次溢出

不成立

后记

延时时间Delay不能超过溢出数据类型的最大长度,否则while将永远的循环;


参考内容:

1.、http://www.stmcu.org/module/forum/thread-605615-1-1.html


wiwa 2016.12.13


STM32HAL,没有与 Arduino 的 `SoftwareSerial.readBytes()` 函数完全相对应的函数,但是可以通过不同的函数组合来实现类似的功能。 `SoftwareSerial.readBytes()` 函数从串行接口读取指定长度的字节,并将它们存储在缓冲区。在 STM32HAL,您可以使用以下函数来实现类似的功能: 1. `HAL_UART_Receive()` 函数:从串口接收指定长度的字节,并将它们存储在指定的缓冲区。 ``` HAL_UART_Receive(&huart, buffer, length, timeout); ``` 上述代码将从 `huart` 所表示的串口接收 `length` 个字节,并将它们存储在 `buffer` 缓冲区。`timeout` 参数指定超时时间,单位为毫秒。 2. `HAL_UART_Transmit()` 函数:向串口发送指定长度的字节。 ``` HAL_UART_Transmit(&huart, buffer, length, timeout); ``` 上述代码将向 `huart` 所表示的串口发送 `length` 个字节,数据来源于 `buffer` 缓冲区。`timeout` 参数指定超时时间,单位为毫秒。 使用上述函数,您可以编写一个函数来读取指定长度的字节,并将它们存储在缓冲区。例如: ``` void readBytes(UART_HandleTypeDef *huart, uint8_t *buffer, uint16_t length, uint32_t timeout) { HAL_UART_Receive(huart, buffer, length, timeout); } ``` 上述代码定义了一个名为 `readBytes()` 的函数,它使用 `HAL_UART_Receive()` 函数从串口接收指定长度的字节,并将它们存储在 `buffer` 缓冲区。您可以根据自己的需求修改函数参数和实现细节。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值