2014-11-17 89 views
1
uint32_t data; 

SPDR = ((uint8_t*) & data)[x]; 

我可以看到這行做 - 它可以被放在一個for循環「數據」的每個字節讀入SPDR,但我不」很明白它是如何工作的。我不懂行的代碼在SPI驅動

+1

SPI總線只有8位寬,所以要發送32位數據,你需要發送它的一部分。根據不同情況,您可以向前或向後發送。 – leppie

+1

你到底不明白什麼? 'SPI'機制或'C'代碼? – muradin

回答

0

data是4個字節,(uint8_t*) & data將它轉換爲1字節值的指針,x您沒有顯示,它正在索引到1字節值的數組中。

3

讓向上將它分成其獨立的部分:

  • &data給你一個指針data,類型是uint32_t *
  • (uint8_t*)接通該uint32_t指針變成指針uint8_t(或無符號的陣列字節)
  • 索引佔用「數組」中的一個字節

如果將其放入循環中,則從四字節uint32_t值一次只需要一個字節,並將其分配給SPDR

+0

感謝您的幫助,Joachim,但我仍然遇到這個問題。採取以下措施: –

1

作爲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個字節。

0

我仍然有這個問題。採取以下操作:

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。