0

我正在为基于 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)了,但没有得到预期的结果。我认为它仅适用于配置为输入的引脚。

有没有推荐的解决方案?

4

3 回答 3

1

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

您还可以查看定义port_pin_get_output_level并检查他们是如何做到的,并将其转换为该板/供应商/HAL 进行寻址的方式。

更新:

查看SAM G55G/J 的数据表时。第 340 页为我们提供了所需的答案。

I/O 线上驱动的电平可以通过写入设置输出数据寄存器 (PIO_SODR) 和清除输出数据寄存器 (PIO_CODR) 来确定。这些写操作分别设置和清除输出数据状态寄存器 (PIO_ODSR),它代表 I/O 线上驱动的数据

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

于 2019-10-22T08:26:29.363 回答
1

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

16.5.4 输出控制

... I/O 线上驱动的电平可以通过写入设置输出数据寄存器 (PIO_SODR) 和清除输出数据寄存器 (PIO_CODR) 来确定。这些写操作分别设置和清除输出数据状态寄存器 (PIO_ODSR),它代表 I/O 线上驱动的数据。...

16.5.8 输入

每个 I/O 线上的电平可以通过 PIO_PDSR 读取。该寄存器指示 I/O 线的电平,无论其配置如何,无论是唯一作为输入,还是由 PIO 控制器驱动,还是由外设驱动。读取 I/O 线电平需要启用 PIO 控制器的时钟,否则 PIO_PDSR 会读取在时钟被禁用时出现在 I/O 线上的电平。

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

然而,无论驱动器配置如何,都可以从引脚数据状态寄存器 (PIO_PDSR) 中读取引脚的真实状态(取决于在任何给定应用中可能相关或不相关的重新同步延迟)。

于 2019-10-24T13:53:51.917 回答
0

快速谷歌搜索为 Atmel/AVR 控制器提供了两个选项:

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

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

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

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

于 2019-10-22T12:40:07.843 回答