读取 SAMDG55 上的输出引脚电平

Reading output pin level on SAMDG55

我正在为基于 Atmel/Microchip AT SAMG55 的设备构建固件。

在一个简单的函数中,触发一些连接到 GPIO 引脚的继电器。 因为我想互锁不同I/O,避免2个特定输出同时为高电平,我需要知道我之前设置的引脚电平。

在另一个项目中,基于SAMD21,有一个读取输出引脚状态的函数

static inline bool port_pin_get_output_level(const uint8_t gpio_pin)

ASF 中的 SAMG55 端口库非常不同,所以我尝试了 ioport_get_pin_level(pin),但没有得到预期的结果。我认为它只适用于配置为输入的引脚。

有什么推荐的解决方案吗?

您可以进行一些低级编程。您可以使用高级 HAL 函数来配置、设置和重置引脚,但在此之前您会这样做。通过寻址寄存器的数据值来读取引脚的值。在 AVR 中,这将通过读取 PORTx 来完成。在 STM32 中,这可以通过读取 GPIOx->ODR 的值来完成。您当然需要提取正确的 pin,但这是可以做到的。

您还可以查看 port_pin_get_output_level 的定义并检查它们是如何实现的并将其转换为此 board/vendor/HAL 进行寻址的方式。

更新:

向内看时the datasheet for the SAM G55G/J。第 340 页为我们提供了所需的答案。

The level driven on an I/O line can be determined by writing in the Set Output Data Register (PIO_SODR) and the Clear Output Data Register (PIO_CODR). These write operations, respectively, set and clear the Output Data Status Register (PIO_ODSR), which represents the data driven on the I/O lines.

所以我们可以通过写入 PIO_SODRPIO_CODR 分别设置和重置引脚来驱动输出。但也可以从 PIO_ODSR 中读取,这是一个包含引脚状态的寄存器。

快速 google 搜索发现 Atmel/AVR 控制器的两个选项:

  1. 从用于设置输出值的相同位置回读(PORTx 寄存器) 这将为您提供之前写入寄存器的值。

  2. 使用 PINx 寄存器读取实际值 这将为您提供您可以在设备上实际测量的值。

两者之间的区别可能很重要:如果将下拉到逻辑电压阈值以下(即,如果连接到 GND)的 GPIO 设置为高电平,则 PORTx 将读取高电平(您设置的值),而 PINx将读取低(实际值)。

https://www.avrfreaks.net/forum/reading-pin-set-output

参考 SAMG55 数据 sheet 中的图 16-2,以及第 16.5.4 和 16.5.8 节:

16.5.4 Output Control

... The level driven on an I/O line can be determined by writing in the Set Output Data Register (PIO_SODR) and the Clear Output Data Register (PIO_CODR). These write operations, respectively, set and clear the Output Data Status Register (PIO_ODSR), which represents the data driven on the I/O lines. ...

16.5.8 Inputs

The level on each I/O line can be read through PIO_PDSR. This register indicates the level of the I/O lines regardless of their configuration, whether uniquely as an input, or driven by the PIO Controller, or driven by a peripheral. Reading the I/O line levels requires the clock of the PIO Controller to be enabled, otherwise PIO_PDSR reads the levels present on the I/O line at the time the clock was disabled.

因此,只要配置引脚,使引脚上的实际电平始终对应于我们尝试驱动的电平 - 不是例如,集电极开路配置 - 那么 Tarick Welling 的回答是正确的:您可以从输出数据状态寄存器 (PIO_ODSR) 中读取输出状态。

但是,无论驱动程序配置如何,都可以从引脚数据状态寄存器(PIO_PDSR).