互动
最近评论
其乐融融弗雷德0D3S
stonewu
哥哥是不是没写完啊, 缺了函数注释啊, 类似的插件有:FileComments。
文档阅读者
stonewu
static uint32_t next_tick = 0; 原: if(HAL_GetTick() >= next_tick) { next_tick = HAL_GetTick() + 100; HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); }//未处理边界条件,溢出导致逻辑非预期。 改动: if(HAL_GetTick()-next_tick <= UINT32_MAX/2 ) { next_tick = HAL_GetTick() + 100; HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); } ***代码分析:以上代码的作用是每隔一段时间翻转IO口。其巧妙之处,在于利用减法配合溢出将原本因为溢出而需要 考虑的【边界判断省去】了。 ***通用处理: static uint32_t next_tick = 0; #define INTERVAL 100 if(HAL_GetTick()-next_tick <= (UINT32_MAX+1-INTERVAL) ) { next_tick = HAL_GetTick() + INTERVAL; HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); } ***【边界判断省去】原理分析: 原式HAL_GetTick()≥next_tick, 移项变形得到HAL_GetTick()-next_tick≥0, *当HAL_GetTick()等于或者略大于next_tick的时候上式无问题,但是当next_tick增加, *HAL_GetTick()小于next_tick时,由于均是uint32_t,不等式左边的值应是恒≥0的,就比原式错得更多了(原式好歹是边界条件时出错,这直接一开始就出错了),但是仔细观察,next_tick+100后大于HAL_GetTick(),那么HAL_GetTick()-next_tick的值是大于2^32-100的, *那么只需要继续变形为HAL_GetTick()-next_tick<=(2^32-100)是不是就可以了呢? 以上不考虑边界条件,考虑边界条件,则分为两种情况: ①next_tick先溢出, next_tick变得很小,而HAL_GetTick()很大,HAL_GetTick()-next_tick则是一个比较大的值,记其值最小情况为UPLIMIT,为了排除此情况,HAL_GetTick()-next_tick应该<或者≤UPLIMIT。 ②HAL_GetTick()、next_tick均溢出, 此情况就同不考虑边界条件时的分析,HAL_GetTick()-next_tick<=(2^32-100)就可以了。 那么最后,HAL_GetTick()-next_tick是应该<还是≤ UINT32_MAX/2,UPLIMIT,(2^32-100)呢?或者说UPLIMIT应该是多少呢? UINT32_MAX/2是怎么来的,不做考究,当INTERVAL的值大于UINT32_MAX/2则HAL_GetTick()-next_tick <= UINT32_MAX/2 会出错; 当INTERVAL取值100,HAL_GetTick()-next_tick应该和(2^32-100)做比较, 即UPLIMIT应取值(2^32-INTERVAL),<或者≤就自己思考吧。 ***温馨提示or思考:以上代码中两次HAL_GetTick()的值可能是不一样的,也就是翻转IO的周期可能不是简单的INTERVAL*2;还有当INTERVAL取值特别大时,代码可能失效,例如HAL_GetTick()-next_tick<=0或者 <=1时,由于时序问题,调用HAL_GetTick()的时机可能很难满足式子成立。 记HAL_GetTick()为A,记next_tick为B,记INTERVAL为c, 当A=A0=B0>=2^32-c时,B1=B0+c-2^32, B=B1、A>A0→A-B=A-B1=A-(B0+c-2^32)>A0-(B0+c-2^32)=2^32-c; 当A=A2=B2<2^32-c时,B3=B2+c, B=B3、B3>A>A2→[A-B]=[A-B3]=[A-(B2+c)]=A-(B2+c)+2^32>A2-(B2+c)+2^32=2^32-c;
标签
寻找感兴趣的领域
Halo1 网盘1 单片机1 OpenResty2 ecs1 端口转发1 tableview1 rtthread1 font1 1Panel4 iar1 xfce1 nmap1 modbus1 efsm1 vscode2 版本控制3 单元测试2 git6 IAP2 MDK1 rsync1 proxy1 version1 自启1 exfat1 truncate1 lvgl4 rt-thread1 LABEL0 C语言4 docker1 软件1 uart1 UI1 linux0 e2label1 fifo1 lvm4 sspi1
文章
  • 三月 2025
    9 篇
  • 二月 2025
    3 篇
  • 十二月 2024
    1 篇
  • 十一月 2024
    4 篇
  • 十月 2024
    4 篇
  • 九月 2024
    6 篇
  • 八月 2024
    5 篇
  • 七月 2024
    3 篇
  • 六月 2024
    2 篇
  • 五月 2024
    5 篇
  • 四月 2024
    15 篇
  • 三月 2024
    15 篇
  • 二月 2024
    13 篇
  • 微信
    微信
  • 支付宝
    支付宝
功能
显示模式
关于
  • gitea
  • 网盘
标签
Halo1 网盘1 单片机1 OpenResty2 ecs1 端口转发1 tableview1 rtthread1 font1 1Panel4 iar1 xfce1 nmap1 modbus1 efsm1 vscode2 版本控制3 单元测试2 git6 IAP2 MDK1 rsync1 proxy1 version1 自启1 exfat1 truncate1 lvgl4 rt-thread1 LABEL0 C语言4 docker1 软件1 uart1 UI1 linux0 e2label1 fifo1 lvm4 sspi1
播放音乐
蒙蒙plus个人博客
黑曜石Obsidian笔记软件
首页
关于
gitea
网盘
tb店铺
二次元入口
友链
登录
0
cover
原创 软件分享
版本控制

黑曜石Obsidian笔记软件

蒙蒙plus 字数: 691 阅读耗时: 1 分钟 2024/02/29 2024/02/29 博客独享 热度: 116 评论: 0

本文最后更新于 2024-02-29,文章好久没更新了。

黑曜石Obsidian

官网地址:Obsidian - Sharpen your thinking

打赏作者
    感谢你赐予我前进的力量
    • 微信
      微信
    • 支付宝
      支付宝
    赞赏者名单
    因为你们的支持让我意识到写文章的价值🙏
使用手机访问这篇文章
版本控制 3
原创 黑曜石Obsidian笔记软件
黑曜石Obsidian笔记软件
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 蒙蒙plus
cover
上一篇
git版本控制软件
cover
下一篇
字节对齐
阅读建议
cover
2024-03-13
iar版本下载地址
cover
2024-03-07
UsbEAm Hosts Editor [多平台hosts修改]
cover
2024-02-29
git版本控制软件
cover
2024-02-07
Keil v5 C51 MDK包 共存合并方式
cover
2024-02-06
OneNote停靠功能
cover
2024-02-06
【软件包合集】keil C51 C251 MDK V5 V4 v3 v2 所有版本软件包下载【官网地址】

评论
匿名评论 隐私政策
你无需删除空行,直接评论以获取最佳展示效果
你好啊!我是
蒙蒙plus的个人博客
了解更多
文章目录
最新评论
头像
哥哥是不是没写完啊, 缺了函数注释啊, 类似的插件有:FileComments。
其乐融融弗雷德0D3S /
头像
static uint32_t next_tick = 0; 原: if(HAL_GetTick() >= next_tick) { next_tick = HAL_GetTick() + 100; HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); }//未处理边界条件,溢出导致逻辑非预期。 改动: if(HAL_GetTick()-next_tick <= UINT32_MAX/2 ) { next_tick = HAL_GetTick() + 100; HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); } ***代码分析:以上代码的作用是每隔一段时间翻转IO口。其巧妙之处,在于利用减法配合溢出将原本因为溢出而需要 考虑的【边界判断省去】了。 ***通用处理: static uint32_t next_tick = 0; #define INTERVAL 100 if(HAL_GetTick()-next_tick <= (UINT32_MAX+1-INTERVAL) ) { next_tick = HAL_GetTick() + INTERVAL; HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); } ***【边界判断省去】原理分析: 原式HAL_GetTick()≥next_tick, 移项变形得到HAL_GetTick()-next_tick≥0, *当HAL_GetTick()等于或者略大于next_tick的时候上式无问题,但是当next_tick增加, *HAL_GetTick()小于next_tick时,由于均是uint32_t,不等式左边的值应是恒≥0的,就比原式错得更多了(原式好歹是边界条件时出错,这直接一开始就出错了),但是仔细观察,next_tick+100后大于HAL_GetTick(),那么HAL_GetTick()-next_tick的值是大于2^32-100的, *那么只需要继续变形为HAL_GetTick()-next_tick<=(2^32-100)是不是就可以了呢? 以上不考虑边界条件,考虑边界条件,则分为两种情况: ①next_tick先溢出, next_tick变得很小,而HAL_GetTick()很大,HAL_GetTick()-next_tick则是一个比较大的值,记其值最小情况为UPLIMIT,为了排除此情况,HAL_GetTick()-next_tick应该<或者≤UPLIMIT。 ②HAL_GetTick()、next_tick均溢出, 此情况就同不考虑边界条件时的分析,HAL_GetTick()-next_tick<=(2^32-100)就可以了。 那么最后,HAL_GetTick()-next_tick是应该<还是≤ UINT32_MAX/2,UPLIMIT,(2^32-100)呢?或者说UPLIMIT应该是多少呢? UINT32_MAX/2是怎么来的,不做考究,当INTERVAL的值大于UINT32_MAX/2则HAL_GetTick()-next_tick <= UINT32_MAX/2 会出错; 当INTERVAL取值100,HAL_GetTick()-next_tick应该和(2^32-100)做比较, 即UPLIMIT应取值(2^32-INTERVAL),<或者≤就自己思考吧。 ***温馨提示or思考:以上代码中两次HAL_GetTick()的值可能是不一样的,也就是翻转IO的周期可能不是简单的INTERVAL*2;还有当INTERVAL取值特别大时,代码可能失效,例如HAL_GetTick()-next_tick<=0或者 <=1时,由于时序问题,调用HAL_GetTick()的时机可能很难满足式子成立。 记HAL_GetTick()为A,记next_tick为B,记INTERVAL为c, 当A=A0=B0>=2^32-c时,B1=B0+c-2^32, B=B1、A>A0→A-B=A-B1=A-(B0+c-2^32)>A0-(B0+c-2^32)=2^32-c; 当A=A2=B2<2^32-c时,B3=B2+c, B=B3、B3>A>A2→[A-B]=[A-B3]=[A-(B2+c)]=A-(B2+c)+2^32>A2-(B2+c)+2^32=2^32-c;
文档阅读者 /
最近发布
控制台logo
控制台logo 2025-03-25 17:24:07
vscode 生成标准化注释
vscode 生成标准化注释 2025-03-05 10:08:36
check单元测试
check单元测试 2025-03-02 20:33:25
check 单元测试框架
check 单元测试框架 2025-03-02 20:29:08
分类
  • 新闻资讯 2
  • 嵌入式开发 24
  • 硬件设计 0
  • rt-thread 5
  • 开源仓库 4
  • GUI 2
  • 编程设计 6
  • openharmony 1
  • 网站运维 16
  • linux 6
  • git 11
  • 软件分享 7
©2024 - 2025 By 蒙蒙plus的个人博客
©2024 - 2025 By 蒙蒙plus的个人博客
本网站由   custom_cloud   提供CDN加速/云存储服务 订阅 主题 关于 ICP备2024061630号 豫公网安备41160302000113号
复制选中文本
粘贴文本
引用到评论
新窗口打开
复制链接地址
复制此图片
下载此图片
新窗口打开图片
站内搜索
百度搜索
播放音乐
切换到上一首
切换到下一首
查看所有歌曲
复制歌名
随便逛逛 博客分类 文章标签
复制地址
关闭热评
深色模式
轉為繁體