SPI,是英語Serial Peripheral interface的縮寫,顧名思義就是串行外圍設備接口。SPI,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節約了芯片的管腳,同時為PCB的布局上節省空間,提供方便,正是出于這種簡單易用的特性,現在越來越多的芯片集成了這種通信協議。 其工作模式有兩種:主模式和從模式,無論那種模式,都支持3Mbit/s的速率,并且還具有傳輸完成標志和寫沖突保護標志。
跟SPI密切相關的兩個概念是時鐘極性和時鐘相位。
時鐘極性:表示時鐘信號在空閑時是高電平還是低電平。 時鐘相位:決定數據是在SCK的上升沿采樣還是在SCK的結束沿采樣。 下面以矩力的7022B芯片為例子,分析SPI工作模式的設置。
在7022B的數據手冊中,指出:在SCK的上升沿放數據,在下降沿取數據。在SCK的下降沿將DIN的數據采樣到7022B中,在SCK的上升沿將7022B的數據放置在DOUT上面輸出。
下面是模擬SPI總線對7022B進行讀取的例子,這個例子生動表示了何時放數據,何時采樣數據。
unsigned long Read_reg3(unsigned char cmd) { int i; unsigned long data; set_bit(SPI_PORT,SPI_SS); clr_bit(SPI_PORT,SPI_SCK); clr_bit(SPI_PORT,SPI_SS); for(i=0;i<8;i++) { set_bit(SPI_PORT,SPI_SCK); if(cmd&0x80) { set_bit(SPI_PORT,SPI_MOSI); } else { clr_bit(SPI_PORT,SPI_MOSI); } cmd=cmd<<1; nop; nop; clr_bit(SPI_PORT,SPI_SCK);nop; } clr_bit(SPI_PORT,SPI_SCK); _delay_us(3); data=0; for(i=0;i<24;i++) { set_bit(SPI_PORT,SPI_SCK); nop; nop; nop; if(PINB&(1 { data+=1; }else { data+=0; } data=data<<1; nop; clr_bit(SPI_PORT,SPI_SCK); } set_bit(SPI_PORT,SPI_SS); return data; }
如果采用硬件SPI,則需要對單片機(ATMEGA16)SPI寄存器進行設置,本例子中,需要設置SPCR=0x57;//MSB在先01010011
時鐘極性為0,因為空閑時CLK電平為低。
時鐘相位設置為1,因為是下降沿采樣數據,上升沿放數據。
我對SPI的理解錯在采樣的概念上。比如,下降沿采樣,當主機接收時,我覺得應該是先有下降沿,再有采樣。其實,正確的理解是:采樣是對主機從機都一致的概念,采樣之前必須把數據準備好。當主機接收數據時,主機也是下降沿采樣,但是在下降沿發生之前,必須準備好數據,換句話說,從機在上升沿發生后,就要把數據放出來,為下降沿采樣做好準備。 參考鏈接:http://www.picavr.com/news/2009-08/203.htm |