在 SAMDG55 上读取输出引脚电平
Posted
技术标签:
【中文标题】在 SAMDG55 上读取输出引脚电平【英文标题】:Reading output pin level on SAMDG55 【发布时间】:2019-10-21 15:27:09 【问题描述】:我正在为基于 Atmel/Microchip AT SAMG55 的设备构建固件。
在一个简单的函数中,触发一些连接到 GPIO 引脚的继电器。 因为要互锁不同的I/O,避免2个特定的输出同时为高电平,所以需要知道我之前设置的pin电平。
在另一个项目中,基于 SAMD21,有一个读取输出引脚状态的函数
static inline bool port_pin_get_output_level(const uint8_t gpio_pin)
ASF 中的 SAMG55 端口库完全不同,所以我尝试了ioport_get_pin_level(pin)
,但没有得到预期的结果。我认为它仅适用于配置为输入的引脚。
有没有推荐的解决方案?
【问题讨论】:
为什么不简单地在设置 GPIO 引脚时设置一个变量? @markus-nm 谢谢。我是这样考虑的。顺便说一句,如果可能的话,我宁愿找到一个更具体的解决方案,直接读取引脚电平。即使在库中被一些指令修改,它也会让我更有信心获得真实的状态。 【参考方案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 输入
可以通过 PIO_PDSR 读取每条 I/O 线上的电平。该寄存器指示 I/O 线的电平,而不管它们的 配置,无论是唯一作为输入,还是由 PIO 驱动 控制器,或由外设驱动。读取 I/O 线电平 需要启用 PIO 控制器的时钟,否则 PIO_PDSR 读取 I/O 线上的电平,此时 时钟被禁用。
因此,只要引脚配置为使引脚上的实际电平始终对应于我们试图驱动的电平 - 不是集电极开路配置的情况,例如 - 那么 Tarick Welling 的回答是正确的:您可以从输出数据状态寄存器 (PIO_ODSR) 读取输出状态。
但是,无论驱动器配置如何,都可以从引脚数据状态寄存器 (PIO_PDSR) 读取引脚的真实状态(受制于在任何给定应用中可能相关或不相关的重新同步延迟)。
【讨论】:
【参考方案2】:您可以进行一些低级编程。您可以使用高级 HAL 功能来配置、设置和重置引脚,但在您这样做之前您会这样做。通过寻址寄存器的数据值来读取引脚的值。在 AVR 中,这将通过阅读 PORTx
来完成。在 STM32 中,这可以通过读取 GPIOx->ODR
的值来完成。您当然需要提取正确的引脚,但这可以做到。
您还可以查看 port_pin_get_output_level
的定义并检查他们是如何做到的,并将其转换为该板/供应商/HAL 的寻址方式。
更新:
在查看the datasheet for the SAM G55G/J 内部时。第 340 页为我们提供了所需的答案。
在 I/O 线上驱动的电平可以通过写入设置输出数据寄存器 (PIO_SODR) 和 清除输出数据寄存器 (PIO_CODR)。这些写操作分别设置和清除输出数据 状态寄存器(PIO_ODSR),代表I/O线上驱动的数据。
因此我们可以通过写入PIO_SODR
和PIO_CODR
来分别设置和重置引脚来驱动输出。但也可以从 PIO_ODSR
读取这是一个包含引脚状态的寄存器。
【讨论】:
【参考方案3】:通过 google 快速搜索,Atmel/AVR 控制器有两个选项:
从用于设置输出值的同一位置回读(PORTx 寄存器) 这将为您提供您之前写入寄存器的值。
使用 PINx 寄存器读取实际值 这将为您提供可以在设备上实际测量的值。
两者之间的区别可能很重要:如果您将下拉至低于逻辑电压阈值(即如果连接到 GND)的 GPIO 设置为 HIGH,则 PORTx 将读取 HIGH(您设置的值),而 PINx 将读取LOW(实际值)。
https://www.avrfreaks.net/forum/reading-pin-set-output
【讨论】:
这适用于 AVR mcus,但这是 ARM 的,因此 PORT/PIN/DDR 不存在。以上是关于在 SAMDG55 上读取输出引脚电平的主要内容,如果未能解决你的问题,请参考以下文章