?? spi.c
字號:
#include "SPI.h"
/*-----------------------------------------------------------------------
SPI_Init : SPI接口初始化
輸入參數: 無
返回值: 無
-----------------------------------------------------------------------*/
void SPI_Init(void)
{
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
// 使能SPI接口,主機模式,模式0,16分頻,SPI時鐘約460KHz
}
/*-----------------------------------------------------------------------
SPI_Byte : 使用SPI發送一個字節數據,并接收一個字節數據
輸入參數: data: 寫入的數據
返回值: 接收的數據
-----------------------------------------------------------------------*/
unsigned char SPI_Byte(unsigned char data)
{
unsigned char rdata;
Device_EN();
_delay_us(50);
SPDR = data;
loop_until_bit_is_set(SPSR,SPIF); // 等待數據傳送完
rdata=SPDR;
Device_DIS();
_delay_us(50);
return rdata;
}
/*
串行外設接口-SPI
SPI接口可以令ATmega128 和外設或其他AVR器件進行高速的同步數據傳輸
ATmega128的SPI接口同時還用來實現程序和EEPROM的下載和上載。請參見[SPI串行編程和校驗]。
SPI系統包括兩個移位寄存器和一個主機時鐘發生器。
主機和從機將需要發送的數據放入相應的移位寄存器。
主機在SCK 引腳上產生時鐘脈沖以交換數據。
主機的數據從主機的MOSI 移出,從從機的MOSI 移入;從機的數據從從機的MISO 移出,從主機的MISO 移入
(其實就是由主機和從機構成一個16位的循環移位寄存器,所以收發數據是同時的,收發函數可以寫成一條函數)
SPI系統的發送方向只有一個緩沖器,而在接收方向有兩個緩沖器。
也就是說,在發送時一定要等到移位過程全部結束后才能對SPI 數據寄存器執行寫操作。
而在接收數據時,需要在下一個字符移位過程結束之前通過訪問SPI 數據寄存器讀取當前接收到的字符。
否則第一個字節將丟失。
SS引腳的功能
1從機模式
從機模式當SPI配置為從機時,從機選擇引腳SS總是為輸入。
SS 為低將激活SPI 接口, MISO成為輸出( 用戶必須進行相應的端口配置) 引腳,其他引腳成為輸入引腳。
當SS 為高時所有的引腳成為輸入, SPI 邏輯復位,不再接收數據。
SS引腳對于數據包/字節的同步非常有用,可以使從機的位計數器與主機的時鐘發生器同步。
當SS 拉高時SPI從機立即復位接收和發送邏輯,并丟棄移位寄存器里不完整的數據。
2主機模式
當SPI 配置為主機時(MSTR 的SPCR 置位),用戶可以決定SS 引腳的方向。
若SS 配置為輸出,則此引腳可以用作普通的I/O 口而不影響SPI 系統。典型應用是用來驅動從機的SS 引腳。
(單主機系統,SS引腳最好設成輸出)
如果SS 配置為輸入,必須保持為高以保證SPI 的正常工作。
若系統配置為主機, SS 為輸入,但被外設拉低,則SPI 系統會將此低電平解釋為有一個外部主機將自己選擇為從機。
為了防止總線沖突, SPI 系統將實現如下動作:
1. 清零SPCR 的MSTR 位,使SPI 成為從機,從而MOSI 和SCK 變為輸入。
2. SPSR 的SPIF 置位。若SPI 中斷和全局中斷開放,則中斷服務程序將得到執行。
因此,使用中斷方式處理SPI 主機的數據傳輸,并且存在SS 被拉低的可能性時,中斷服務程序應該檢查MSTR 是否為"1”。
若被清零,用戶必須將其置位,以重新使能SPI 主機模式。
數據模式(中文手冊有點混亂,請參考英文原版)
相對于串行數據, SCK的相位和極性有4種組合,由CPHA和CPOL控制組合的方式。
SPI模式 CPOL CPHA 起始沿 結束沿
0 0 0 采樣(上升沿) 設置(下降沿)
1 0 1 設置(上升沿) 采樣(下降沿)
2 1 0 采樣(下降沿) 設置(上升沿)
3 1 1 設置(下降沿) 采樣(上升沿)
SPI控制寄存器-SPCR
Bit 7 – SPIE: 使能SPI 中斷
置位后,只要SPSR 寄存器的SPIF 和SREG 寄存器的全局中斷使能位置位,就會引發SPI 中斷。
Bit 6 – SPE: 使能SPI
SPE 置位將使能SPI。進行任何SPI 操作之前必須置位SPE。
Bit 5 – DORD: 數據次序
DORD 置位時數據的LSB 首先發送;否則數據的MSB 首先發送。
Bit 4 – MSTR: 主/ 從選擇
MSTR置位時選擇主機模式,否則為從機。
如果MSTR為"1”,SS配置為輸入,但被拉低,則MSTR 被清零,寄存器SPSR 的SPIF 置位。
用戶必須重新設置MSTR 進入主機模式
Bit 3 – CPOL: 時鐘極性
CPOL 置位表示空閑時SCK 為高電平;否則空閑時SCK 為低電平。
Bit 2 – CPHA: 時鐘相位
CPHA 決定數據是在SCK 的起始沿采樣還是在SCK 的結束沿采樣。
Bits 1, 0 – SPR1, SPR0: SPI 時鐘速率選擇1 與0
確定主機的SCK 速率。
SPR1 和SPR0 對從機沒有影響。
SCK 和振蕩器的時鐘頻率fosc關系如下表所示:
SPI2X SPR1 SPR0 SCK 頻率
0 0 0 fosc/4
0 0 1 fosc/16
0 1 0 fosc/64
0 1 1 fosc/128
1 0 0 fosc/2
1 0 1 fosc/8
1 1 0 fosc/32
1 1 1 fosc/64
SPI狀態寄存器-SPSR
Bit 7 – SPIF: SPI 中斷標志
串行發送結束后,SPIF 置位。
若此時寄存器SPCR 的SPIE 和全局中斷使能位置位,SPI中斷即產生。
如果SPI 為主機, SS 配置為輸入,且被拉低, SPIF 也將置位。
進入中斷服務程序后SPIF自動清零。
或者可以通過先讀SPSR,緊接著訪問SPDR來對SPIF清零。
Bit 6 – WCOL: 寫碰撞標志
在發送當中對SPI 數據寄存器SPDR寫數據將置位WCOL。
WCOL可以通過先讀SPSR,緊接著訪問SPDR 來清零。
Bit 0 – SPI2X: SPI 倍速
置位后SPI 的速度加倍。
若為主機,則SCK 頻率可達CPU 頻率的一半。
若為從機,只能保證fosc /4。
SPI數據寄存器-SPDR
SPI數據寄存器為讀/寫寄存器,用來在寄存器文件和SPI移位寄存器之間傳輸數據。
寫寄存器將啟動數據傳輸,
讀寄存器將讀取寄存器的接收緩沖器。
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -