我想知道是否有可能通过参数的值替换指令#define
中的参数,它们实际上在程序中。这是代码:
typedef struct {
uint8_t b0 : 1;
uint8_t b1 : 1;
uint8_t b2 : 1;
uint8_t b3 : 1;
uint8_t b4 : 1;
uint8_t b5 : 1;
uint8_t b6 : 1;
uint8_t b7 : 1;
} BIT_FIELD;
#define _PORTD (*( volatile BIT_FIELD*)&PORTD)
#define kupa(s) _PORTD.b##s
void SentByteTo74HC595 (uint8_t val){
for(int i = 7 ; i >=0 ; i--) {
DS = kupa(i);
SHCPpulse() ;
}
问题在于kupa让_PORTD.bi对_PORTD.b0,PORTD.b1等进行了注意。我正在尝试用#或##进行不同的方式但是我不确定它是否可能实现我想要实现的目标
答案 0 :(得分:0)
因为预编译器(扩展宏的东西)甚至在编译器之前运行。你想要的是在运行时访问struct字段的名称,这是不可能的,因为字段的名称不会被保留。 C不是动态语言,也没有反射。
但是,您可以将迭代编写为单独的定义,并将其调用8次。不过,这不是最佳解决方案 - 在您的情况下,我会使用位移而不是位字段。它更容易支持,使用和阅读。
答案 1 :(得分:0)
在处理(即编译)之前处理和应用预处理器指令。 kupa
是一个预处理器宏,因此编译器永远不会看到它。所以不,你不能这样做。
您尝试做的事情是不可移植的,比特的存储方式取决于编译器。
您可能更好地使用位操作,例如定义指定给定位的枚举
enum {
b0 = 0x001,
b1 = 0x002,
b3 = 0x004,
...
};
您可能仍需要对值进行(例如)字节序转换,具体取决于您的交换方式。
答案 2 :(得分:0)
typedef struct {
uint8_t b0 : 1;
uint8_t b1 : 1;
uint8_t b2 : 1;
uint8_t b3 : 1;
uint8_t b4 : 1;
uint8_t b5 : 1;
uint8_t b6 : 1;
uint8_t b7 : 1;
} BIT_FIELD;
union u_ToSend {
uint8_t ui8val;
BIT_FIELD BFval;
} ;
void SentByteTo74HC595 (uint8_t val){
union u_ToSend tmp;
tmp.ui8val = val;
for (int i = 7; i >=0; i--){
DS = tmp.BFval.b7 ;
tmp.ui8val <<= 1 ;
SHCPpulse() ;
}
还有其他方法可以编写它,以便程序消耗更少的RAM和闪存吗?