標題: SPI協(xié)議工作過程詳解文檔,內含實例代碼 [打印本頁]
作者: htxiaofeng 時間: 2018-7-7 10:12
標題: SPI協(xié)議工作過程詳解文檔,內含實例代碼
SPI:一種3線(有的沒有SS線(選擇主或從機模式))或4線的通信方式:
MOSI:主機出從機進數(shù)據(jù)線
MISO:主機進從機從數(shù)據(jù)線
SCK: 時鐘線
SS: 主從模式選擇線
工作過程的理解:設置好相應的配置后就可以發(fā)送或接收數(shù)據(jù),當放送或接收完成后就會是SPIF置位,此時如果開了中斷就會就入中斷服務程序。如果沒開中斷就可以通過查詢該標志位來做相應的事。進入中段服務程序后,或者讀(寫)SPDR寄存器都可以清零SPIF標志位。從而可以開始下一次的傳輸
相應的寄存器
1:SCPR:控制寄存器:SPI的大部分設置
2:SPSR:標志寄存器:(查看一些標志(主要是SPIF位)和設置SPI速度)
3:SPDR:數(shù)據(jù)寄存器:
SS引腳的說明:(實質就是當配置為輸入時:是主機還是從機由輸入的電平來決定)
從機模式: 當 SPI 配置為從機時,從機選擇引腳 SS 總是為輸入。SS 為低將激活 SPI 接口, MISO
成為輸出 ( 用戶必須進行相應的端口配置 ) 引腳,其他引腳成為輸入引腳。當 SS 為高時
所有的引腳成為輸入, SPI 邏輯復位,不再接收數(shù)據(jù)。
SS引腳對于數(shù)據(jù)包/字節(jié)的同步非常有用,可以使從機的位計數(shù)器與主機的時鐘發(fā)生器同
步。當SS 拉高時SPI從機立即復位接收和發(fā)送邏輯,并丟棄移位寄存器里不完整的數(shù)據(jù)。
主機模式:當 SPI 配置為主機時 (SPCR 的 MSTR置位 ),用戶可以決定 SS 引腳的方向。
若 SS 配置為輸出,則此引腳可以用作普通的 I/O 口而不影響 SPI 系統(tǒng)。典型應用是用來
驅動從機的 SS 引腳。
如果 SS 配置為輸入,必須保持為高以保證 SPI 的正常工作。若系統(tǒng)配置為主機,SS 為
輸入,但被外設拉低,則 SPI 系統(tǒng)會將此低電平解釋為有一個外部主機將自己選擇為從
機。為了防止總線沖突, SPI 系統(tǒng)將實現(xiàn)如下動作:
1. 清零 SPCR 的 MSTR 位,使 SPI 成為從機,從而 MOSI 和 SCK變?yōu)檩斎搿?/font>
2. SPSR 的 SPIF 置位。若 SPI 中斷和全局中斷開放,則中斷服務程序將得到執(zhí)行。
因此,使用中斷方式處理 SPI 主機的數(shù)據(jù)傳輸,并且存在 SS 被拉低的可能性時,中斷服
務程序應該檢查 MSTR 是否為 "1”。若被清零,用戶必須將其置位,以重新使能 SPI 主機
模式。
管腳配置
一:SCPR:控制寄存器:(SPI的大部分設置都在該寄存器)
二SPSR:標志寄存器:(查看一些標志和設置SPI速度,主要是用到SPIF這個標志位,接收完成和發(fā)送完成都會置位這個標志,進入中斷服務程序或訪問SPDR寄存 器都可以清零這個標志)
三SPDR:數(shù)據(jù)寄存器:
應用步驟:
1先根據(jù)是主還是從設置端口的模式(輸入還是輸出)
主機:SS MOSI SCK 為出 MISO為入
從機:SS MOSI SCK 為入 MISO 為出
2配置相應的寄存器(就三個寄存器,注意用到中斷時要先開總中斷)
3用中斷或查詢法發(fā)送或接收數(shù)據(jù)
注意:主機或者從機都可以發(fā)送或接收。發(fā)送完之后就可以馬上發(fā)下一個數(shù)據(jù)了。接收也是只要接收完了也可以馬上接收下一個數(shù)據(jù)了
一:發(fā)送:(一般用查詢方式發(fā)送比較好:此時只要查詢發(fā)送完畢的標志位SPIF是否置位)
常用:while(!(SPSR & (1<<SPIF))); //等待發(fā)送完畢或接收完畢
查詢法:實質就是查詢SPSR的SPIF位是否置位,接收完和發(fā)送完都可以置位,(如果開了中斷的話就會進入相應的中斷)
例子:
- 主機發(fā)送(查詢方式)(只要發(fā)送完畢了就可以繼續(xù)發(fā)送了)
//主機模式下發(fā)送1-255
- #include <avr/io.h>
- #define uint unsigned int
- #define uchar unsigned char
- void spi_init(void)
- {
- PORTB |= (1<<PB4) | (1<<PB5) | (1<<PB6) | (1<<PB7); //
- DDRB |= (1<<DDB5) | (1<<DDB7) | (1<<DDB4); //Set MOSI, SCK AND SS as outputs
- SPCR = 0x73; //SPI使能,低位首發(fā),主機模式,時鐘模式00,上升沿采樣;時鐘速率Fosc/128
- SPSR = 0x00; //SPI2x=0
- }
- void SPI_send_data(char cData)
- {
- PORTB &=~ (1<<PB4); //強制接收方進入從模式(在接收方的NSS引腳沒有接地時)
- // SPCR |= (1<<MSTR); // MSTR有時會被清零,這里強制進入主機模式
- SPDR =cData;
- while(!(SPSR & (1<<SPIF))); //等待發(fā)送完畢
- // PORTB |= (1<<PB4); //相當于釋放總線(這樣可以讓別的主機控制從機)
-
- }
-
- void Delay(uint z) //
- {
- unsigned int i,j;
- for(i=z;i>0;i--)
- for(j=2000;j>0;j--);
-
- }
-
- int main(void)
- {
- unsigned int i=0;
- spi_init();
- while(1)
- {
- for(i=255;i>0;i--)
- {
- SPI_send_data(i);
- Delay(100);
- }
- }
- }
復制代碼
2從機接收(查詢方式)
- #include <avr/io.h>
- #include <avr/delay.h>
- #define uchar unsigned char
- #define uint unsigned int
- void port_init(void)
- {
- PORTA = 0x00;
- DDRA = 0xFF;
- PORTB = 0xFF;
- }
-
- void spi_init(void)
- {
- DDRB = (1<<5) |(1<<7);
- DDRB&=~(1<<4)|(1<<6);
- SPCR = 0x63; // SPI允許。從機方式
- SPSR = 0x00; // SPI倍速.頻率為系統(tǒng)時鐘
- }
-
- void init_devices(void)
- {
- port_init();
- spi_init();
- }
- //主函數(shù)
- int main(void)
- {
- init_devices();
- while(1)
- {
- while(!(SPSR & (1<<SPIF)));//等待數(shù)據(jù)接收完成
- PORTA=SPDR;//把接收到的數(shù)據(jù)賦給A口
- _delay_loop_2(900);
-
- }
- }
復制代碼
3從機中斷方式接收數(shù)據(jù)(注意:當進入中斷服務程序后SPIF會自動清零)
- /*中斷方式接收數(shù)據(jù)*/
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #define uchar unsigned char
- #define uint unsigned int
-
- //端口初始化
- void port_init(void)
- {
- PORTA = 0xFF;
- DDRA = 0xFF;
- }
-
- void spi_init(void)
- {
- PORTB |= (1<<4) | (1<<5) | (1<<6) | (1<<7); //
- DDRB |= (1<<5) | (1<<7) | (1<<4); //Set MOSI, SCK AND SS as outputs
- SPCR = 0xE3; //SPI中斷使能,SPI使能,低位首發(fā),從機模式,時鐘模式00,上升沿采樣;時鐘速率Fosc/128
- SPSR = 0x00; //SPI2x=0
- }
-
- void init_devices(void)
- {
- port_init();
- spi_init();
- sei();//開全局中斷
- }
-
- //主函;
- int main(void)
- {
- init_devices();
- while(1);
- }
- //SPI中斷函數(shù)
- SIGNAL(SIG_SPI)
- {
-
- PORTA=SPDR;
-
- }
復制代碼
完整的Word格式文檔51黑下載地址:
SPI.doc
(663.5 KB, 下載次數(shù): 42)
2018-7-7 10:12 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者: huaishang 時間: 2018-9-16 22:32
感謝分享!! 共同學習共同進步
作者: meqqme 時間: 2019-11-2 10:43
謝謝分享 
作者: zz爛尾 時間: 2019-11-15 07:13
感謝分享
| 歡迎光臨 (http://m.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |