Những gì bạn đang cố gắng làm không có ý nghĩa.
#define GLUER(x,y,z) x##y##z
#define PxDIR(x) GLUER(P,x,DIR)
int main() {
int port;
port = 2;
PxDIR(port) |= 0x01;
}
Bộ tiền xử lý được chạy lúc (trước) thời gian biên dịch. Vì vậy, nó không thể biết bất cứ điều gì về nội dung của biến số port
. Bộ tiền xử lý yêu cầu bất kỳ giá trị nào được truyền dưới dạng đối số cho macro là các hằng số. Ví dụ, bạn có thể làm như sau:
#define GLUER(x,y,z) x##y##z
#define PxDIR(x) GLUER(P,x,DIR)
int main() {
PxDIR(2) |= 0x01; //setup port 2
}
Ngược lại, nếu bạn muốn để có thể vượt qua một biến để macro này thực sự là cách duy nhất là để đảm bảo mã để làm như vậy được tạo ra một cách rõ ràng:
#define GLUER(x,y,z) x##y##z
#define PxDIR(x) GLUER(P,x,DIR)
uint16_t* get_port_pointer(uint8_t port_id) {
if (port == 0) {
return &PxDIR(0);
} else if (port == 1) {
return &PxDIR(1);
} else if (port == 2) {
return &PxDIR(2);
} else if (port == 3) {
return &PxDIR(3);
} else {
return &0;
}
}
int main() {
int port;
port = 2;
*(get_port_pointer(port)) |= 0x01;
}
Bằng cách này, chúng tôi đảm bảo có mã cho bất kỳ cổng nào từ 0 đến 3 được truy cập. Ngoài ra, bây giờ chúng ta phải xem ra các con trỏ null được trả về từ hàm get_port_pointer.
Bạn có ý định thực hiện '#define port 2' không? – Gabe