#include "stdio.h"
typedef struct{
unsigned char BASE;
unsigned char PORTA;
unsigned char PORTB;
unsigned char PORTC;
unsigned char PORTD;
// unsigned char Preserve0[2]; /* 假設在 MCU 中,暫存器的位置有跳躍的話可以用這種方式越過 2 個 bytes */
// unsigned char Preserve1; /* 假設在 MCU 中,暫存器的位置有跳躍的話可以用這種方式越過 1 個 byte */
unsigned char DDRA;
unsigned char DDRB;
unsigned char DDRC;
}REG,*REGptr;
void main(){
// 宣告一個陣列,來模擬一個暫存器群(這個暫存器群可能在 MCU 裡面管理著通訊系統)
unsigned char regGroup[] = { 0x00, 0x01, 0x02, 0x03, 0x1A, 0x56, 0x77, 0xff };
printf("通訊系統0\n");
// 可以藉由"結構名稱強制轉為指標"的方式,去取出暫存器群中的某個暫存器之值
printf("((REG*)(regGroup))->DDRB : 0x%x \n", ((REG*)(regGroup))->DDRB);
// 或直接使用結構指標
printf("((REGptr)(regGroup))->DDRC : 0x%x \n", ((REGptr)(regGroup))->DDRC);
/* 假設 MCU 裡面"相同性質的暫存器群"具有多組,例如有 通訊系統0 、 通訊系統1、通訊系統2
** 雖然是"不同組"通訊系統 ,但因為裡面所"需要操作的暫存器完全相同",我們藉由定義一個結構體的方式
** 就不用大幅度的修改程式碼,達到程式碼的再利用性 */
//假設通訊系統1的暫存器群
unsigned char regGroup1[] = { 0x01, 0x08, 0x09, 0x0A, 0x55, 0x88, 0x99, 0xCC };
printf("通訊系統1\n");
printf("((REG*)(regGroup1))->DDRB : 0x%x \n", ((REG*)(regGroup1))->DDRB);
printf("((REGptr)(regGroup1))->DDRC : 0x%x", ((REGptr)(regGroup1))->DDRC);
}
甚至我可以更簡潔的配合 #define
#include "stdio.h"
typedef struct{
unsigned char BASE;
unsigned char PORTA;
unsigned char PORTB;
unsigned char PORTC;
unsigned char PORTD;
// unsigned char Preserve0[2]; /* 假設在 MCU 中,暫存器的位置有跳躍的話可以用這種方式越過 2 個 bytes */
// unsigned char Preserve1; /* 假設在 MCU 中,暫存器的位置有跳躍的話可以用這種方式越過 1 個 byte */
unsigned char DDRA;
unsigned char DDRB;
unsigned char DDRC;
}REG,*REGptr;
#define communication0 ((REGptr)(regGroup))
#define communication1 ((REGptr)(regGroup1))
void main(){
unsigned char regGroup[] = { 0x00, 0x01, 0x02, 0x03, 0x1A, 0x56, 0x77, 0xff };
unsigned char regGroup1[] = { 0x01, 0x08, 0x09, 0x0A, 0x55, 0x88, 0x99, 0xCC };
printf("通訊系統0\n");
printf("communication0->DDRB : 0x%x \n", communication0->DDRB);
printf("通訊系統1\n");
printf("communication1->DDRB : 0x%x \n", communication1->DDRC);
}
20180910 補充 :
在原文書上有提到,結構內的成員變數在建立時可能會有"洞"出現,也就是在記憶體的排序中可能會造成位址的跳躍。但這問題只存在於你定義不同的數據類型於同一個結構體中。也就是說只要你整個結構體都定義為 unsigned char 就不會有這個問題
C語言系列結束 結語 :
至此章節, C 語言有至少八成以上的知識概念都已囊括在內。
熟悉了前述的文章,基本上有關於 MCU 會使用到的 C 語言的語法不太可能會出現看不懂的(意指你不會完全不知道他在做什麼)
但,基於目前很多的 open source code 都會使用到 C++ 的部分 (又或者說是 C/C++ 混用)
所以此系列還會往 C++ 的部分繼續延伸
但因為 C++ 的部分實在太廣了,故我們只會將使用在 MCU 中常見的部分進行解說
幫助我們在看 open source code 時能夠理解他是在做什麼