[英]C, Is it possible to ASSIGN a macro to a structure variable?
我是嵌入式編程的新手。 我有一個帶有2個頭文件的PIC微控制器: pic.h
和Timer_peripheral.h
。
在pic.h
,計時器配置寄存器已定義為:
__extension__ typedef struct tagT1CONBITS {
union {
struct {
unsigned :1;
unsigned TCS:1;
unsigned TSYNC:1;
unsigned :1;
unsigned TCKPS:2;
unsigned TGATE:1;
unsigned :6;
unsigned TSIDL:1;
unsigned :1;
unsigned TON:1;
};
struct {
unsigned :4;
unsigned TCKPS0:1;
unsigned TCKPS1:1;
};
};
} T1CONBITS;
在timer.h
,一些宏定義為:
/* Timer1 Control Register (T1CON) Bit Defines */
#define T1_ON 0xffff /* Timer1 ON */
#define T1_OFF 0x7fff /* Timer1 OFF */
與單片機數據表相對應。 unsigned
類型是16位。 我試圖通過這種方式將T1_ON分配給結構變量T1CONBITS
:
T1CONBITS=T1_ON // which is wrong.
我知道我可以初始化一個結構,但是我想在我的主要功能中做一個賦值,並且我不想使用這樣的結構成員來做它:
T1CONBITS.TCS=1;
T1CONBITS.TSYNC=1;
有什么辦法嗎? 如果沒有,為什么您認為在timer.h
中定義了這些宏?
感謝您的見解
這是行不通的,因為您正在嘗試為某個完全不相關的類型的變量分配數字。 數字與結構的基礎位模式匹配這一事實是編譯器不太關心的事情。
嘗試這個:
union BitsInt {
struct tagT1CONBITS con;
int bits;
};
T1CONBITS = ((union BitsInt){ .bits = T1_ON }).con;
您將一種類型的數據放入,而得到無關類型的相同數據。
(使用聯合來轉換位模式對於最新的C標准是有效的。)
經過預處理
T1CONBITS=T1_ON;
會是這樣的:
T1CONBITS=0xffff;
要成為struct
變量,只能分配相同類型的變量 。
您可以這樣輕松地將T1CONBITS
設置為全1
:
memset(&T1CONBITS, 0xff, sizeof(T1CONBITS));
T1CONBITS結構的名稱表明它旨在訪問T1CON的位 。 是否還定義了一個寄存器T1CON,您可以編寫以下內容?
T1CON = T1_ON ;
更好的是,您可以按預期方式簡單地使用T1CONBITS,並且完全需要同時達到T1_ON和T1_OFF:
T1CONBITS.TON = 0 ; // Off
T1CONBITS.TON = 1 ; // On
通過直接分配T1CON,可以將所有其他位設置為1,這在任何情況下都可能不是您想要的。 而是您將進行“讀取-修改-寫入”操作,這實際上是位訪問所產生的錯誤少得多且更清晰的方式。
以我的經驗,編譯器為某個微控制器提供的預制寄存器映射充其量是繁瑣,不可讀和不可移植的。 沒有人能說出您的特定代碼是否有意義,因為在每個編譯器上位字段的實現方式都是不同的。
如果您可以選擇自己編寫寄存器定義,請這樣做。 例如:
#define T1CON (*(uint16_t*)0x1234u) // some address
#define T1CON_TCS 0x4000u
#define T1CON_TSYNC 0x2000u
...
#define T1CON_TCKPS 0x0C00u
然后使用標准C編程位設置慣用法設置位:
T1CON |= T1CON_TCS; // set this bit
T1CON &= ~T1CON_TCS; // clear this bit
設置屬於同一組的幾個位:
#define T1_ON 0x0C00u
#define T1_OFF 0x0400u
T1CON |= (T1CON_TCKPS & T1_ON);
等等。
(盡管請注意,這可能是讀-修改-寫,可能不是您想要的。如果必須使用普通位集(在特殊情況下,用於清除標志寄存器等),則通常省略按位邏輯和只需編寫T1CON = T1CON_TCS | TSYNC;
並設置所有所需的位即可,但請注意,沒有保證,特定的C代碼提供讀-修改-寫還是位設置取決於CPU和編譯器。請反匯編以確保代碼確實您所期望的。)
這對於世界上的每個C編譯器都是100%可移植的,並且對於使用嵌入式系統工作的每個C程序員而言都是100%可讀的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.