我无法理解宏的逻辑及其工作方式...因此我可以创建mcp2515_init()
函数。如果有人可以解释,我很乐意倾听,谢谢您的时间。
#define true 1
#define false 0
#define True 1
#define False 0
typedef _Bool bool;
#define RESET(x) _XRS(x)
#define SET(x) _XS(x)
#define TOGGLE(x) _XT(x)
#define SET_OUTPUT(x) _XSO(x)
#define SET_INPUT(x) _XSI(x)
#define IS_SET(x) _XR(x)
#define PORT(x) _port2(x)
#define DDR(x) _ddr2(x)
#define PIN(x) _pin2(x)
#define _XRS(x,y) PORT(x) &= ~(1<<y)
#define _XS(x,y) PORT(x) |= (1<<y)
#define _XT(x,y) PORT(x) ^= (1<<y)
#define _XSO(x,y) DDR(x) |= (1<<y)
#define _XSI(x,y) DDR(x) &= ~(1<<y)
#define _XR(x,y) ((PIN(x) & (1<<y)) != 0)
#define _port2(x) PORT ## x
#define _ddr2(x) DDR ## x
#define _pin2(x) PIN ## x
我将尝试对其进行分解,您所拥有的是一组位操作宏,它们在端口上翻转/设置/清除一个位,它们是一种通用的宏,并不特定于SPI驱动程序。
位清除(重置)
#define _XRS(x,y) PORT(x) &= ~(1<<y)
AND端口的每一位都期望端口y
上的位x
。
位设置
#define _XS(x,y) PORT(x) |= (1<<y)
OR端口,仅设置了y位。这将置位y
,而其他位不受影响。
肘
#define _XT(x,y) PORT(x) ^= (1<<y)
与1进行异或运算将其值切换为0将保持其状态。
此宏列表仅包含一个参数
#define RESET(x) _XRS(x)
#define SET(x) _XS(x)
#define TOGGLE(x) _XT(x)
#define SET_OUTPUT(x) _XSO(x)
#define SET_INPUT(x) _XSI(x)
#define IS_SET(x) _XR(x)
因此这些宏看起来与兼容,因为它们采用一个参数而不是两个参数,但是借助宏的魔力,可以创建x,y
的输出,例如]
#define GPIO1_PIN4 1,4 #define POWER_LED GPIO0,PIN2
将使
SET(POWER_LED);
成为法律转让。
#
和##
宏
#define _port2(x) PORT ## x
用于连接宏的输出以创建新结构read more here
因此使用所有宏,_XT(2,15);
将展开为
PORT2 = PORT2 ^ (1<<15)
我个人不喜欢这种宏,因为它通过将宏隐藏在宏中来破坏普通香草C的工作方式,例如,这种样式无法通过一次写入在同一端口上设置多个位。但是,它是合法的C语言,在某些嵌入式系统开发环境中很常见。
可能会更容易忽略上述宏,而只是将配置和数据逐字直接写入寄存器。