uint32_t data;
SPDR = ((uint8_t*) & data)[x];
我可以看到這行做 - 它可以被放在一個for循環「數據」的每個字節讀入SPDR
,但我不」很明白它是如何工作的。我不懂行的代碼在SPI驅動
uint32_t data;
SPDR = ((uint8_t*) & data)[x];
我可以看到這行做 - 它可以被放在一個for循環「數據」的每個字節讀入SPDR
,但我不」很明白它是如何工作的。我不懂行的代碼在SPI驅動
data
是4個字節,(uint8_t*) & data
將它轉換爲1字節值的指針,x
您沒有顯示,它正在索引到1字節值的數組中。
讓向上將它分成其獨立的部分:
&data
給你一個指針data
,類型是uint32_t *
(uint8_t*)
接通該uint32_t
指針變成指針uint8_t
(或無符號的陣列字節)如果將其放入循環中,則從四字節uint32_t
值一次只需要一個字節,並將其分配給SPDR
。
感謝您的幫助,Joachim,但我仍然遇到這個問題。採取以下措施: –
作爲StackOverflow的的Tag Info說
串行外設接口(SPI)是串行的,同步的全 雙工在嵌入式系統中通常使用的總線。它通常用於微控制器和外圍硬件之間的通信,例如存儲器,移位寄存器,傳感器,顯示器等,但也可以用於MCU到MCU的通信。傳輸通常涉及一些給定字 大小的兩個移位寄存器,例如8位,一個在主設備中,另一個在從設備中;他們 連接在一個環。數據通常首先移出最高位,而將新的最低位移入同一寄存器的 。在該寄存器被移出後, 主機和從機已交換寄存器值。然後,每個設備 都取得該值並對其執行某些操作,例如將其寫入 內存。如果有更多的數據要交換,移位寄存器是 加載新數據[1],並重復該過程。傳輸可能涉及任意數量的時鐘週期。當沒有更多數據要傳輸時,主站停止切換其時鐘。通常,它然後 取消選擇從站。 傳輸通常由8位字組成。主機可以根據需要啓動多個此類傳輸。然而,其他字大小也是常見的,例如用於 觸摸屏控制器或音頻編解碼器的16位字,如來自德克薩斯州的TSC2101 儀器;或許多數字至模擬或12位字的模數轉換器。
SPDR = ((uint8_t*) & data)[x];
將導致鑄uint32_t
指針到一個指向uint8_t
- 也就是指向8位。指針運算是基於指針類型和陣列subsripting基於指針算術
C標準n1124 § 6.5.2.1/2數組下標
後綴表達式接着在正方形的表達括號[]是數組對象的元素的下標 。下標運算符[] 的定義是E1 [E2]與(*((E1)+(E2)))相同。由於 適用於二元運算符的轉換規則,如果E1是一個數組對象(等價地,指向數組對象的初始元素的指針)並且E2是一個整數,則E1 [E2]指定第E2個E1的元素(從零開始計數)。
索引數組會移動一個關於sizeof(*指針)的指針,因此會移動1個字節。這樣你可以遍歷32位的所有4個字節。
我仍然有這個問題。採取以下操作:
uint16_t EN_A_WrRd_OP16(uint8_t opcode,uint16_t write_data)
{
uint16_t read_data;
uint8_t i;
EN_A_CS_Low();
SPIC_DATA=opcode;
while (!(SPIC_STATUS&SPI_IF_bm));
for (i=0;i<2;i++)
{
SPIC_DATA=((uint8_t*)&write_data)[i];
while (!(SPIC_STATUS&SPI_IF_bm));
((uint8_t*)&read_data)[i]=SPIC_DATA;
}
EN_A_CS_High();
return read_data;
}
繞過循環兩次讀取SPIC_DATA,它讀取0x34,然後0x12。但是,在退出循環時,read_data包含0x0000! 如果我這樣做「長」的方式,並替換爲以下循環:
SPIC_DATA=write_data;
while (!(SPIC_STATUS&SPI_IF_bm));
read_data=SPIC_DATA;
SPIC_DATA=write_data>>8;
while (!(SPIC_STATUS&SPI_IF_bm));
read_data|=SPIC_DATA<<8;
它工作正常即收益的read_data與價值爲0x1234。
SPI總線只有8位寬,所以要發送32位數據,你需要發送它的一部分。根據不同情況,您可以向前或向後發送。 – leppie
你到底不明白什麼? 'SPI'機制或'C'代碼? – muradin