C語言語法在不同編譯器下的問題,簡單談談地址,試用初學者

ReceiveData = *(u32 *)&SPI2_RxBUF[1];   
ReceiveData = *((u32 *)&SPI2_RxBUF[1]);
對於C語言來說語法上沒什麼區別,*與& 都是同等優先級,結合方式從右到左。
這兩句都是取SPI2_RxBUF[1]的地址,強制轉換爲32位地址指針,取指針即可得到32位數據,然後賦值給ReceiveData。

先看一段代碼

可以看到程序運行之後:ReceiveData = 0x00010000 這是Windows下QT的編譯環境

 

那麼再看一段Keil中STM32仿真時的代碼

程序運行到了265行,但是處於262行的等式,可以發現他們並不相等。keil編譯環境,
ReceiveData = *(u32 *)&SPI2_RxBUF[1];   該等式ReceiveData值爲0x00000000,高位直接被編譯器捨棄了。
ReceiveData = *((u32 *)&SPI2_RxBUF[1]); 該等式ReceiveData纔是0x00010000,需要加上括號纔可以,才成功被賦值。

所以C語言的語法,對於初學者可以大致熟悉即可,不用像教科書那樣去摳字眼,考試那樣去做題,具體優先級直接加括號實際些。

這個問題我還找了好久才發現,一開始一直以爲是SPI數據傳輸是不是出現了問題,一步步檢查還花費了不少時間。
有朋友可能注意到:賦值的時候有兩種寫法
ReceiveData = *((u32 *)&SPI2_RxBUF[1]);
ReceiveData = (u32)SPI2_RxBUF[2]<<16 | SPI2_RxBUF[1];

基於當前的平臺我們可以知道它是小端序。
unsigned short int SPI2_RxBUF[4] = {0x0000,0x0000,0x0001,0xffff};
地址//0x20004000     0x20004002   0x20004004   0x20004006
數據//0x0000,            0x0000,          0x0001,          0xffff

第一種寫法
//mov 直接取地址,(u32 *)0x20004002 去取32位數據 1個機器週期
//mov 賦值

第二種寫法
//棧,R0 R1 R2 ... R7 CPU內部的寄存器, N個機器週期,耗時間
//mov R1 0x0001                           
//左移的彙編指令,移16位,
//mov R2 0x0000
//或 R1 R2
//mov 賦值

哈哈,我的彙編不好,只知道大概的意思,簡單來書如果是連續內存存儲的,直接用取地址的方式快一些,簡單而且方便。

如有不對之處望海涵及留言告知。一起學習共同進步
郵箱:[email protected]

——十五

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章