我无法理解宏的逻辑及其工作方式...因此我可以创建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
答案 0 :(得分:0)
我将尝试对其进行分解,您所拥有的是一组位操作宏,它们将端口上的一位翻转/设置/清除一位,它们是通用的宏,而不是特定于SPI驱动程序。
位清除(重置)
#define _XRS(x,y) PORT(x) &= ~(1<<y)
与端口的所有位都期望端口y
上的位x
。
位设置
#define _XS(x,y) PORT(x) |= (1<<y)
仅设置了y位的OR端口。这将置位y
,而其他位不受影响。
切换
#define _XT(x,y) PORT(x) ^= (1<<y)
对1进行XOR运算将其值切换为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语言,在某些嵌入式系统开发环境中很常见。
忽略上面的宏而将配置和数据直接逐字直接写入寄存器可能会更容易。