成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

聯合體在單片機編程中的應用

開發 前端
結構體是一種構造類型或復雜類型,它可以包含多個類型不同的成員。在C語言中,還有另外一種和結構體非常類似的語法,叫做聯合體(Union)(有些地方也叫做共用體)。

01聯合體

之前的文章《枚舉和結構體的結合》文中提到,結構體就像是打包封裝,把一些有共同特征的變量封裝在內部。結構體是一種構造類型或復雜類型,它可以包含多個類型不同的成員。在C語言中,還有另外一種和結構體非常類似的語法,叫做聯合體(Union)(有些地方也叫做共用體)。

聯合體舉例如下

union data{
char n;
char ch;
char f;
};
union data a, b, c;

結構體和聯合體的區別在于:結構體的各個成員會占用不同的內存,互相之間沒有影響;而聯合體的所有成員占用同一段內存,修改一個成員會影響其余所有成員。

結構體占用的內存大于等于所有成員占用的內存的總和(存在字節對齊問題,這里不深入討論)。

聯合體占用的內存等于最長的成員占用的內存。聯合體中如果對新的成員賦值,就會把原來成員的值覆蓋掉。

//上文的聯合體定義
char data;
a.n = 0x0A;//雖然只修改了成員變量n,但是ch和f變量都會被改變
data = a.f;//那么data的值就會被修改為0x0A

02聯合體的應用

聯合體在一般中的編程應用中還是很少的,在單片機編程中較多,在之前的文章《枚舉和結構體的結合》將枚舉和結構體的結合,下面的例子簡單說明下聯合體在結構體中的應用(我的日常開發中聯合體一般都是和結構體一起使用的)。

在做顯示屏應用時牽扯到一個概念,顯示屏(全彩)上一個像素點是由于Red,Green,Blue三種顏色組成,在888模式下,每個像素點都是由8個bit組成的,這個時候為了便是一個像素點就需要用到結構體,這也對應前面的文章,結構體就像是打包封裝,把一些有共同特征的變量封裝在內部。

typedef struct{
uint8_t Red;
uint8_t Green;
uint8_t Blue;
uint32_t Pix_Value;
}LCD_Pixvalue_S;

上面這樣的寫法是十分清晰的,訪問很方便,可以單獨訪整個像素,也可以訪問像素的某個顏色,有個問題那就是我操作紅色像素,需要重新給Pix_Value成員賦值,如下

LCD_Pixvalue_S LCD_Pixvalue;
LCD_Pixvalue.Red = 0x12;
LCD_Pixvalue.Pix_Value = LCD_Pixvalue.Red<<16 | LCD_Pixvalue.Red<<8 |LCD_Pixvalue.Blue;

需要多一句代碼,并且內存占用也大。當然,直接用下面寫法,不會多占用內存,但是訪問不方便。

typedef struct{
uint32_t Pix_Value;
}LCD_Pixvalue_S;

那么這個時候,使用聯合體和結構體組合起來,就可以既不會多占內存,訪問也很方便。

typedef union{
struct{
uint8_t Red;
uint8_t Green;
uint8_t Blue;
}Pix;
uint32_t Pix_Value;
}LCD_Pixvalue_S;

那么就可以如下操作

LCD_Pixvalue_S LCD_Pixvalue;
uint32_t data;
LCD_Pixvalue.Pix_Value = 0x0012FF00;
LCD_Pixvalue.Pix.Red = 0x25;//單獨修改紅色
data = LCD_Pixvalue.Pix_Value;//data的值就為0x0025FF00

當然,結構體的定義你也可以寫到外面,其他地方可以使用,如下

typedef struct{
uint8_t Red;
uint8_t Green;
uint8_t Blue;
}Pix_s;
typedef union{
Pix_s Pix;
uint32_t Pix_Value;
}LCD_Pixvalue_S;

那么關于內存占用的問題,上面的定義方法,定義一個LCD_Pixvalue_S類型的變量占用4個字節。示例圖如下

03聯合體在串口開發中的應用

上面舉例LCD應用中聯合體的應用,這個是由于LCD一個像素由紅綠藍3色組成,所以用聯合體很方便。在單片機項目開發中,串口協議解析也可以利用到聯合體,十分方便。

在私有自定義協議中,合理定義協議,利用聯合體代碼十分方便。下面的例子不講幀頭,幀尾部分,舉例聯合體在協議解析中的應用,靈活應用。

串口協議舉例如下



功能


字節長度


命令長度


4


命令字


1


命令內容


7


crc16


2

那么代碼可以如下編寫

typedef union{
struct{
uint32_t cmdlen;
uint8_t cmd;
uint8_t cmdbuf[7];
uint16_t crc16;
}unit;
uint8_t buffer[14];
}uart_buffer_s;
uart_buffer_s uart_buffer;
int main(void)
{
uint8_t len;
len = 0;
uart_buffer.buffer[len++] = 0x12;
uart_buffer.buffer[len++] = 0x34;
uart_buffer.buffer[len++] = 0x56;
uart_buffer.buffer[len++] = 0x78;
uart_buffer.buffer[len++] = 0xAA;
for(int i=0;i<7;i++)
{
uart_buffer.buffer[len++] = i;
}
uart_buffer.buffer[len++] = 0x11;
uart_buffer.buffer[len++] = 0x22;
while (1);
}

運行的結果如下

可以看到,我們只是往uart_buffer.buffer填充數據,模擬串口接收數據,接收完畢后,就自動解析出來我們自定義的cmdlen,cmd,cmdbuf和crc16。這里需要注意的是16位和32位的數據類型是小端模式,關于小端模式請看之前的文章《C語言在STM32中的內存分配》,這個還是很方便的。

!!!但是!!!需要注意字節對齊的問題,比如把上述cmdbuf修改為8個字節,就會出問題,如下

crc16就會出問題,這個就是字節對齊的問題,不懂的同學自行百度一下,這里不再重點講解。

除了上述自定義協議解析時會用到聯合體,還可以解決浮點型float的讀取問題,float是占用4個字節的,如果將從串口接收的4個字節轉換成float呢?聯合體就可以可以解決這個問題

下面示例代碼,我們知道浮點數231.5的16進制表示為0x43678000。

typedef union{
float data;
uint8_t buffer[4];
}uart_buffer_s;
uart_buffer_s uart_buffer;
int main(void)
{
uint8_t len;
len = 0;
uart_buffer.buffer[len++] = 0x00;
uart_buffer.buffer[len++] = 0x80;
uart_buffer.buffer[len++] = 0x67;
uart_buffer.buffer[len++] = 0x43;
while (1);
}

結果如下

可以看到我們模擬從串口收到4個字節,使用聯合體,不用我們額外寫代碼,就可以自動轉化為float型。當然這個轉換也是小端模式的,小端模式詳解請看文章《C語言在STM32中的內存分配》。

責任編輯:武曉燕 來源: 知曉編程
相關推薦

2021-07-08 09:15:20

單片機編程狀態機編程語言

2024-04-24 12:05:40

聯合體C++內存

2010-07-01 15:38:41

TCP IP協議棧單片機

2022-03-01 08:31:37

volatile變量編譯器

2020-07-21 15:20:20

語言結構體共用體

2010-09-08 15:18:54

單片機TCP IP協議棧

2021-06-22 10:02:07

單片機語言代碼

2011-08-01 12:54:28

北電蘋果LTE

2021-10-14 15:48:28

鴻蒙HarmonyOS應用

2018-12-25 08:37:44

C語言數據存儲

2009-04-11 15:12:24

2010-06-19 13:32:36

TCP IP協議棧

2010-06-19 14:10:35

TCP IP協議棧

2011-05-24 17:47:40

2022-03-18 15:01:36

元宇宙小冰AI

2022-11-09 17:13:17

算力天成

2009-04-22 17:18:29

PCB技術單片機
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费看黄视频网站 | 亚洲三区在线观看 | 久久精品亚洲精品国产欧美 | 日韩欧美不卡 | 在线只有精品 | 99久久精品免费视频 | 国产精品一区在线观看 | 久久成 | av日韩高清 | 日日干天天操 | 香蕉婷婷 | 91大神xh98xh系列全部 | 国产 日韩 欧美 在线 | 天天草天天干 | 毛片免费观看视频 | 亚洲最色视频 | 天天操天天玩 | 欧美在线a | 日韩精品一区二区三区在线 | 久久最新| 日韩在线 | 这里只有精品999 | 91在线精品视频 | 蜜桃精品视频在线 | 一本岛道一二三不卡区 | 91精品国产91久久久久久最新 | 亚洲狠狠爱| 国产三级电影网站 | 手机看片在线播放 | 成年人免费在线视频 | 欧美8一10sex性hd | 成人在线中文字幕 | 久久国产欧美日韩精品 | 亚洲视频区| 成人av网站在线观看 | 91亚洲精品在线 | 日韩aⅴ片| 久久999| 亚洲精品一区二区 | 91久久国产精品 | 99re国产精品|