请教STM32通过寄存器获取GPIO状态的基本问题
大家小年后一天好!已知STM32操作gpio状态主要通过ODR、IDR、BSRR三个寄存器。
我现在的疑问是关于ODR的。在结构图中可以看到ODR是在状态输出控制路径上的。
如果一个引脚配置为GPIO输出模式,那么按道理我通过BSRR设置了引脚状态后,通过ODR寄存器获取状态是可以的啊,因为ODR寄存器是r/w都可以的。
我刚才测试了一下,通过ODR获取不到,而通过IDR就能正确获取。我理解应该是两个寄存器都能获取才对。
我的判断方法是
if ((GPIOA->ODR & PIN) > 0) ...
是我理解有误吗?
顺祝大家新年筹备工作顺利! 本帖最后由 youkebing 于 2024-2-3 17:07 编辑
仔细看看手册就懂了, 一个读的是输出状态,一个读的是输入状态 读ODR不行,可能会被外部拉低 库函数都可以读取
u8 GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, u16 GPIO_Pin)
{
u8 bitstatus = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
if ((GPIOx->ODR & GPIO_Pin) != (u32)Bit_RESET)
{
bitstatus = (u8)Bit_SET;
}
else
{
bitstatus = (u8)Bit_RESET;
}
return bitstatus;
}
正如3楼所说,ODR并不反映IO的状态 只有4楼看懂了楼主的问题。
LZ不是问的IO状态和输出值是不是一致,而是对于输出,通过IDR能读到引脚状态,ODR为什么不行?
通过BSRR肯定会改变ODR的,你打开寄存器看一下,如果ODR读不到置1的结果,应该是程序出了问题。 古二真 管脚配置成输出状态后,其状态可以通过BSRR或ODR两个途径设置,ODR并不反映管脚状态。 gyzzg2030 发表于 2024-2-3 17:24
读ODR不行,可能会被外部拉低
(引用自3楼)
通常情况下mcu io的ODR寄存器直接挂在总线输出后面,是一个内部寄存器,只反映最后一次写入的值。io不管怎么拉都不会变。。类似的还包括TDR(三态控制)。只有读IDR时,才会从io进来数据。 如果IO是OC 输出,不管你如何设置ODR,如果外面没上拉,你ODR读出来和实际的IO电平不一定对。
ODR 反应的是程序要求的输出状态。IDR 才是IO实际的状态。
感谢大家热情回复。
发完贴就出去吃饭了,现在七荤八素的。我明天测试一下再回复。{:dizzy:} 今天我又测试一下,实现现象确实如大家所说那样。
我昨天所遇到的问题也无法复现了,我是说,我把一个GPIO配置为输出状态来驱动一个BJT作为开关,按道理我用ODR也可以正确得到当前状态的,虽然用IDR更科学一点。昨天我感觉从ODR没正确读到,但今天就可以了。
所以bug一定是我脑子造成的。
不过经此讨论,对这几个寄存器的记忆更加深了。😌😌 驱动三极管,原理图看看。b基电阻多大呢
页:
[1]