Rabbitoose 发表于 2024-2-3 16:49:59

请教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:00:34

本帖最后由 youkebing 于 2024-2-3 17:07 编辑

仔细看看手册就懂了, 一个读的是输出状态,一个读的是输入状态

gyzzg2030 发表于 2024-2-3 17:24:05

读ODR不行,可能会被外部拉低

68336016 发表于 2024-2-3 17:25:57

库函数都可以读取
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;
}

kinoko 发表于 2024-2-3 17:42:37

正如3楼所说,ODR并不反映IO的状态

fcm32 发表于 2024-2-3 18:08:43

只有4楼看懂了楼主的问题。

LZ不是问的IO状态和输出值是不是一致,而是对于输出,通过IDR能读到引脚状态,ODR为什么不行?

通过BSRR肯定会改变ODR的,你打开寄存器看一下,如果ODR读不到置1的结果,应该是程序出了问题。

lb0857 发表于 2024-2-3 18:26:22

古二真   

zchong 发表于 2024-2-3 18:45:38

管脚配置成输出状态后,其状态可以通过BSRR或ODR两个途径设置,ODR并不反映管脚状态。

wye11083 发表于 2024-2-3 19:14:47

gyzzg2030 发表于 2024-2-3 17:24
读ODR不行,可能会被外部拉低
(引用自3楼)

通常情况下mcu io的ODR寄存器直接挂在总线输出后面,是一个内部寄存器,只反映最后一次写入的值。io不管怎么拉都不会变。。类似的还包括TDR(三态控制)。只有读IDR时,才会从io进来数据。

lixin91985 发表于 2024-2-3 21:46:24

如果IO是OC 输出,不管你如何设置ODR,如果外面没上拉,你ODR读出来和实际的IO电平不一定对。

ODR 反应的是程序要求的输出状态。IDR 才是IO实际的状态。

Rabbitoose 发表于 2024-2-3 22:55:32

感谢大家热情回复。

发完贴就出去吃饭了,现在七荤八素的。我明天测试一下再回复。{:dizzy:}

Rabbitoose 发表于 2024-2-4 12:34:58

今天我又测试一下,实现现象确实如大家所说那样。

我昨天所遇到的问题也无法复现了,我是说,我把一个GPIO配置为输出状态来驱动一个BJT作为开关,按道理我用ODR也可以正确得到当前状态的,虽然用IDR更科学一点。昨天我感觉从ODR没正确读到,但今天就可以了。

所以bug一定是我脑子造成的。

不过经此讨论,对这几个寄存器的记忆更加深了。😌😌

lb0857 发表于 2024-2-4 16:32:47

驱动三极管,原理图看看。b基电阻多大呢
页: [1]
查看完整版本: 请教STM32通过寄存器获取GPIO状态的基本问题