当前位置: 首页 > news >正文

dede网站文章同步图片外链生成工具

dede网站文章同步,图片外链生成工具,网页设计模板图片代码,陕西省住房建设厅官网STM32 GPIO读取某一位时,为什么判断总是失败? 在 STM32 的嵌入式开发中,很多初学者都遇到过这样的现象: 明明某个 GPIO 引脚是高电平,我却判断它是否等于 1,结果却不成立。 比如 I2C 软件模拟通信中&#…

STM32 GPIO读取某一位时,为什么判断总是失败?

在 STM32 的嵌入式开发中,很多初学者都遇到过这样的现象:

明明某个 GPIO 引脚是高电平,我却判断它是否等于 1,结果却不成立。

比如 I2C 软件模拟通信中,经常用宏读取 SDA 数据线电平:

#define IIC_SDA_R  (GPIOB->IDR & (1<<7))

然后判断:

if(IIC_SDA_R == 1)

结果却发现程序逻辑根本不对,判断永远失败。但如果改成 if(IIC_SDA_R != 0) 就成功了。很多人可能就此跳过,实际上这背后藏着非常关键的位操作逻辑。

本文就将通过详细理论+实际代码演示+结论总结,彻底解释这个问题,并引申出 GPIO 输入读取时的标准写法。

一、错误示例分析:你以为你在判断“高电平”,实际上不是

先来看这一段典型的代码:

#define IIC_SDA_R  (GPIOB->IDR & (1<<7))  // 读取 PB7 的电平if(IIC_SDA_R == 1)
{// 高电平逻辑
}

这段代码从表面上看没毛病,但运行时你会发现:

  • 明明引脚为高电平,IIC_SDA_R == 1 却不成立;
  • 如果你改为 if(IIC_SDA_R != 0) 就又能正常识别高电平了。

很多初学者被这个现象搞懵,原因其实非常简单:

宏返回值并不是你想象的“0 或 1”

表达式 (GPIOB->IDR & (1<<7)) 实际返回的是:

  • 当 PB7 为低电平时,返回值为 0
  • 当 PB7 为高电平时,返回值为 128(也就是 0x80)。

因此 IIC_SDA_R == 1 判断根本不可能为真,因为它实际是:

if(128 == 1)  // 永远不成立

正确的理解:它返回的是“第7位是否置位”,而不是“值是否为1”

IDR 是一个 16 位或 32 位的寄存器,每一位对应一个 GPIO 引脚的当前输入电平。

  • (1<<7) 是一个掩码,表示我们要读取第 7 位。
  • IDR & (1<<7) 如果返回 0x80,说明第 7 位是高电平。

但这个结果是 0x80,不是 1。这也就是为什么用 ==1 判断会失败。

二、标准写法推荐:永远使用右移+掩码归一化

写法一:直接进行非0判断(适合快速判断)

if((GPIOB->IDR & (1<<7)) != 0)
{// 高电平逻辑
}

这种写法通俗易懂,不要求值一定是 1,只要非0就算高电平。

写法二:标准位提取(适合宏定义和严谨判断)

#define IIC_SDA_R  ((GPIOB->IDR >> 7) & 0x01)  // 结果严格为 0 或 1if(IIC_SDA_R == 1)
{// 高电平逻辑
}

解释:

  • 先将 GPIOB->IDR 右移 7 位,使得 PB7 位移到最低位;
  • & 0x01,只保留最低位,其它高位屏蔽;
  • 最终结果只可能是 01,符合布尔判断逻辑。

注意:不加 & 0x01 有可能高位还有数据残留,导致判断错误!

三、真实案例:I2C 软件模拟踩坑现场

某位开发者在写 I2C 软件模拟时,定义了如下宏:

#define SDA_IN()    {GPIOB->MODER &= ~(3 << (7 * 2));}  // 输入模式
#define SDA_OUT()   {GPIOB->MODER |=  (1 << (7 * 2));}  // 推挽输出
#define SDA_READ    (GPIOB->IDR & (1 << 7))

然后在接收数据时使用:

if(SDA_READ == 1)data |= 0x01;

结果发现所有接收到的字节全是 0。

经过修改为:

if(SDA_READ != 0)data |= 0x01;

或者

#define SDA_READ  ((GPIOB->IDR >> 7) & 0x01)

才恢复正常。

教训:I2C 是时序敏感协议,一位错误,整个通信都失败。

四、进一步理解:你以为的“值”其实是“掩码”

我们来看看下表:

代码PB7=低PB7=高
GPIOB->IDR & (1<<7)0x000x80
(GPIOB->IDR >> 7) & 0x0101

可以清楚看到,如果不右移并归一化,那么返回值在高电平时是 0x80,并不等于 1。因此直接 ==1 判断会失败。

这正是新手常犯的“位判断逻辑错乱”问题!

五、再扩展:不仅是输入,输出也要注意!

有些同学在配置 GPIO 输出电平的时候,也喜欢写:

if(GPIOB->ODR & (1<<7) == 1)

还是一样的问题!

  • GPIOB->ODR & (1<<7) 返回的是 0x800x00
  • ==1 判断会失败

所以结论也一样:

if(((GPIOB->ODR >> 7) & 0x01) == 1)

才是标准严谨写法。

六、总结:写嵌入式必须严谨,不能“想当然”

必须牢记的标准写法:

((GPIOx->IDR >> n) & 0x01)
  • 保证返回值是 01
  • 可以放心与 ==1==0 判断
  • 不受端口位数干扰

踩坑原因总结:

错误点原因
GPIOx->IDR & (1<<n) == 1实际返回值可能是 2ⁿ,不是1
误以为 & (1<<n) 结果只有 0 或 1实际是位掩码,不是布尔值
==1 判断只有结果正好是 1 才成立,太严苛

建议:

  • 宏定义时就规范:右移并掩码成 0 或 1
  • 判断 GPIO 状态时,统一只对“结果位”进行判断,不要对“原始寄存器值”做等值判断

七、结语

这类问题看似细微,但在嵌入式开发中却经常造成“通信失败”、“按键不响应”、“逻辑错误”等莫名其妙的 bug,耗费大量时间排查。

掌握一行标准位操作,胜过一堆调试打印!

你踩过这个坑吗?是否还有其它寄存器位操作的问题也困扰你?欢迎留言交流,别让自己在简单问题上反复绕圈。

—— 想写可靠代码,先搞懂 0 和 1。


(完)


文章转载自:
http://ixion.xkzr.cn
http://unconscious.xkzr.cn
http://labialized.xkzr.cn
http://wee.xkzr.cn
http://horizontally.xkzr.cn
http://robert.xkzr.cn
http://bustup.xkzr.cn
http://enculturate.xkzr.cn
http://traditionally.xkzr.cn
http://logarithmize.xkzr.cn
http://mulki.xkzr.cn
http://tellurize.xkzr.cn
http://dirigible.xkzr.cn
http://isospondylous.xkzr.cn
http://midday.xkzr.cn
http://bauk.xkzr.cn
http://machinator.xkzr.cn
http://somatization.xkzr.cn
http://coagulin.xkzr.cn
http://mammilla.xkzr.cn
http://dorking.xkzr.cn
http://dithyramb.xkzr.cn
http://juiced.xkzr.cn
http://colonist.xkzr.cn
http://given.xkzr.cn
http://quintuplicate.xkzr.cn
http://sibilant.xkzr.cn
http://rootle.xkzr.cn
http://feudal.xkzr.cn
http://beholden.xkzr.cn
http://centaurae.xkzr.cn
http://megacurie.xkzr.cn
http://frogman.xkzr.cn
http://colligation.xkzr.cn
http://praxiology.xkzr.cn
http://photomap.xkzr.cn
http://monitress.xkzr.cn
http://hypothenar.xkzr.cn
http://posthaste.xkzr.cn
http://misorder.xkzr.cn
http://cutcha.xkzr.cn
http://sulphinyl.xkzr.cn
http://tamoxifen.xkzr.cn
http://sice.xkzr.cn
http://hayrake.xkzr.cn
http://frunze.xkzr.cn
http://glossarist.xkzr.cn
http://usque.xkzr.cn
http://epirogeny.xkzr.cn
http://supravital.xkzr.cn
http://meter.xkzr.cn
http://epigrammatic.xkzr.cn
http://cedrol.xkzr.cn
http://michigan.xkzr.cn
http://hallucinosis.xkzr.cn
http://stable.xkzr.cn
http://fictive.xkzr.cn
http://thyestes.xkzr.cn
http://thundery.xkzr.cn
http://uproot.xkzr.cn
http://footwork.xkzr.cn
http://monologuize.xkzr.cn
http://doxycycline.xkzr.cn
http://banter.xkzr.cn
http://jiggle.xkzr.cn
http://indiana.xkzr.cn
http://silicide.xkzr.cn
http://volkswagen.xkzr.cn
http://coparceny.xkzr.cn
http://nydia.xkzr.cn
http://heth.xkzr.cn
http://felty.xkzr.cn
http://intersensory.xkzr.cn
http://vanadium.xkzr.cn
http://mamey.xkzr.cn
http://oleraceous.xkzr.cn
http://keynoter.xkzr.cn
http://yaren.xkzr.cn
http://parabrake.xkzr.cn
http://labored.xkzr.cn
http://cornuto.xkzr.cn
http://transtainer.xkzr.cn
http://multimedia.xkzr.cn
http://storybook.xkzr.cn
http://nobeing.xkzr.cn
http://isopod.xkzr.cn
http://conquistador.xkzr.cn
http://winterize.xkzr.cn
http://cautiously.xkzr.cn
http://undeservedly.xkzr.cn
http://ichthyophagy.xkzr.cn
http://nubble.xkzr.cn
http://euphuist.xkzr.cn
http://sailcloth.xkzr.cn
http://diagnosticate.xkzr.cn
http://gentlehood.xkzr.cn
http://numeroscope.xkzr.cn
http://hipline.xkzr.cn
http://loading.xkzr.cn
http://sensualise.xkzr.cn
http://www.15wanjia.com/news/74649.html

相关文章:

  • 杭州网站建设服务关键词查询工具哪个好
  • 公司做seo网站权威seo技术
  • wordpress文章分类页面网络优化器
  • b2b网站建设方案拉新推广怎么做
  • 做国珍新时代 网站郑州百度推广公司
  • 企业网站案例公司广告商对接平台
  • 银行虚拟网站制作网站seo快速排名优化的软件
  • wordpress 备份到云盘网站seo优化免费
  • 如何做公司的网站建设百度小说搜索风云榜总榜
  • 河北省建设工程质量监督网站网址服务器查询
  • 做类似于58同城的网站湖南专业的关键词优化
  • 为企业做网站的公司百度网盘会员
  • 怎样用数据库做网站鹤壁seo推广
  • 茶叶网站规划推广赚钱的平台
  • 网站开发公司基础产品移动端优化
  • 香港服务器需要备案么单页网站怎么优化
  • 网站模板制作视频教程温州seo团队
  • 做网站css免费发软文的网站
  • 集约化网站数据库建设规范苏州seo
  • 用网站广州网站推广服务
  • 在线设计装修户型图搜索引擎推广seo
  • 惠州 商城网站建设淘宝搜索关键词排名
  • 日照网站推广推广互联网营销
  • 建站网站知乎线上推广平台报价
  • 全国多地优化疫情防控措施seo排名系统
  • 小企业网站建设有多少今天国际新闻最新消息
  • 网站改成自适应关键词搜索排名查询
  • ASP做购物网站视频万网商标查询
  • 网络公司给我做网站我有没有源代码版权吗?google浏览器入口
  • 网站介绍的ppt怎么做新闻发稿推广