[PIC®/AVR®/dsPIC®产品] 使用变参数函数置位或清零寄存器的位

[复制链接]
2188|8
 楼主| wgtwgtwgt 发表于 2023-7-12 18:53 | 显示全部楼层 |阅读模式
针对avr-libc框架,代码如下:

  1. void set_register_bits(volatile uint8_t *mcu_register, int n, ...)
  2. {
  3.     uint8_t i = 0, temp = 0x00;
  4.     va_list pointer;
  5.     va_start(pointer, n);
  6.     for( i = 0; i < n; i++)
  7.     {
  8.         temp |= _BV( va_arg(pointer, int) );
  9.     }
  10.     *mcu_register |= temp;
  11. }
  12. void clear_register_bits(volatile uint8_t *mcu_register, int n, ...)
  13. {
  14.     uint8_t i = 0, temp = 0xff;
  15.     va_list pointer;
  16.     va_start(pointer, n);
  17.     for( i = 0; i < n; i++)
  18.     {
  19.         temp &= ~_BV( va_arg(pointer, int) );
  20.     }
  21.     *mcu_register &= temp;
  22. }
代码中的n表示要置位或清零的位个数。
例如,设置寄存器PORTB的bit5为1:
  1. set_register_bits(&PORTB, 1, PB5);
设置PORTB寄存器的bit5、bit4为1:
  1. set_register_bits(&PORTB, 2, PB4, PB5);


清零寄存器的某些位clear_register_bits()函数用法类似。

这种方法的优点是直观,缺点是增加了代码开销。

wakayi 发表于 2024-6-5 09:13 | 显示全部楼层
个人感觉使用这个函数的意义并不是很大
tpgf 发表于 2024-6-5 09:53 | 显示全部楼层
这样做首先就是要对寄存器的各个位非常的熟悉
guanjiaer 发表于 2024-6-5 10:26 | 显示全部楼层
这种操作方式适用于所有不同的寄存器吗
木木guainv 发表于 2024-6-5 12:32 | 显示全部楼层
有些寄存器不能手动清零的 会产生报错信息吗
xiaoqizi 发表于 2024-6-5 22:50 | 显示全部楼层
总感觉不如直接上寄存器的那种直观
wowu 发表于 2024-6-5 23:23 | 显示全部楼层
wakayi 发表于 2024-6-5 09:13
个人感觉使用这个函数的意义并不是很大

当然有好处了  每次调用都能明确是对哪个进行的操作
原来是wjc 发表于 2024-9-28 22:48 | 显示全部楼层
充分体验3 nm工艺技术提供高性能和低功耗性能。
桃乐丝 发表于 2025-11-3 14:57 | 显示全部楼层
可用变参数函数实现寄存器位操作:定义函数接收寄存器地址、位号,通过宏或函数内计算掩码(置位用 |=,清零用 &=~)。例如,void set_bit (void *reg, uint8_t bit) { (volatile uint32_t) reg |= 1 <<bit;},同理写清零函数。变参支持多寄存器 / 位操作,需注意寄存器 volatile 属性,避免编译器优化导致操作失效,适用于简化重复位操作代码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

191

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部