打印
[AT32A403A]

关于gpio_bits_toggle函数的错误

[复制链接]
281|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
linjinming2000|  楼主 | 2025-8-5 14:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  * @brief  toggle the selected data port bits.
  * @param  gpio_x: to select the gpio peripheral.
  *         this parameter can be one of the following values:
  *         GPIOA, GPIOB, GPIOC, GPIOD, GPIOE.
  * @param  pins: gpio pin number
  *         parameter can be any combination of gpio_pin_x, gpio_pin_x as following values:
  *         - GPIO_PINS_0
  *         - GPIO_PINS_1
  *         - GPIO_PINS_2
  *         - GPIO_PINS_3
  *         - GPIO_PINS_4
  *         - GPIO_PINS_5
  *         - GPIO_PINS_6
  *         - GPIO_PINS_7
  *         - GPIO_PINS_8
  *         - GPIO_PINS_9
  *         - GPIO_PINS_10
  *         - GPIO_PINS_11
  *         - GPIO_PINS_12
  *         - GPIO_PINS_13
  *         - GPIO_PINS_14
  *         - GPIO_PINS_15
  *         - GPIO_PINS_ALL
  * @retval none
  */
void gpio_bits_toggle(gpio_type *gpio_x, uint16_t pins)
{
  gpio_x->odt ^= pins;
}

上面是新增的引脚翻转函数,但是该函数不是原子操作的,再反转过程中由于中断中修改了该ODT寄存器的值后会导致中断中修改的值错误,正确的做法是下面的代码:

void gpio_bits_toggle(gpio_type *gpio_x, uint16_t pins)
{
  uint32_t odt = gpio_x->odt;
  gpio_x->scr =  ((odt&pins) << 16) | (~odt&pins);
}

使用特权

评论回复
沙发
mark一江水| | 2025-8-5 18:36 | 只看该作者
感谢提醒,我们后续会再做优化。

使用特权

评论回复
板凳
丙丁先生| | 2025-8-6 04:43 | 只看该作者
流水灯吗

使用特权

评论回复
地板
xch| | 2025-8-6 11:27 | 只看该作者
本帖最后由 xch 于 2025-8-6 11:28 编辑

void gpio_bits_toggle(gpio_type *gpio_x, uint16_t pins)
{
__disable_irq();
  gpio_x->odt ^= pins;
__enable_irq();
}

怕中断就关闭中断。不行吗?一共加两字节长度,两条指令

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

125

帖子

2

粉丝