一、介紹
簡述:
1)通常 SPI 通信要求 4 根線,分別是 MOSI(主機輸出從機輸入), MISO(主機輸入從機輸出), CLK(時鐘線), CS(片選線)
2)當發送和接受數據的工作都準備好了,只要有時鐘 CLK,就發送數據,沒有時鐘就不發送,而且一個時鐘周期發送一位(bit)數據,所以發送數據的快慢由時鐘頻率來控制。
3)至于時鐘和數據的相位沒有特別嚴格的要求(而 IIC 中,數據的變化只能在 SCL 是低電平的時候發生), SPI數據的變化是一個時鐘周期一次,這樣的方法來傳輸數據就簡單多了。我們可以根據需求對時鐘的極性和相位做調整,看看是在時鐘上升沿還是下降沿來發送數據,還有停止發送時時鐘的極性,是保持高電平還是低電平。
4)另外在多機通信時, SPI 只是簡單的通過一個片選信號(拉低電平選擇)來選擇哪個設備占用總線,但是 IIC 是通過發送從設備地址來自動選擇的。(簡介來自某手冊說明)
SPI有四種時序模式:
SPI工作原理,方便自己就用了原子哥的原話:
1)硬件上為4根線。
2)主機和從機都有一個串行移位寄存器,主機通過向它的SPI串行寄存器寫入一個字節來發起一次傳輸。
3)串行移位寄存器通過MOSI信號線將字節傳送給從機,從機也將自己的串行移位寄存器中的內容通過MISO信號線返回給主機。這樣,兩個移位寄存器中的內容就被交換。
4)外設的寫操作和讀操作是同步完成的。如果只進行寫操作,主機只需忽略接收到的字節;反之,若主機要讀取從機的一個字節,就必須發送一個空字節來引發從機的傳輸。
在當第一次接觸SPI協議的時候,還是練習OLED時,當時總感覺這東西太難了,看不懂時序,不清楚原理。但是在學習過IIC之后,感覺SPI比起IIC來說很簡潔明了了,IIC模擬起來復雜,硬件配置也不是那么輕松。總之,對于現在的我來說,都不是很輕松。
二、模擬SPI
比起來IIC,SPI代碼真是簡潔了許多。模擬SPI只需要簡單初始化用到的IO再根據時序圖來實現發送接收數據即可。
/*
#define SPI_SCK pbout(13)
#define SPI_MOSI pbout(15)
#define SPI_MISO pbin(14)
*/
/*
SPI_SCK:PB13(SPI2)
SPI_MOSI:PB15,
SPI_MISO:PB14
片選腳(CS)不用初始化,因為片選腳屬于需要SPI控制的芯片自身。可以在驅動芯片時定義CS引腳
*/
void SPI_Init(void)
{
RCC->APB2ENR |= 1<<3;
GPIOB->CRH &= 0x000fffff;
GPIOB->CRH |= 0x38300000;
SPI_SCK = 1;//空閑電平為高
}
/*
讀寫一個字節,因為全雙工同時發收
txdata
配置的時序圖為模式3,即CPOL=1,CPHA=1
*/
u8 SPI_ReadWriteOneData(u8 txdata)
{
u8 rxdata=0;
u8 i=0;
for(i=0;i<8;i++)
{
SPI_SCK=0;
if(txdata&0x80)SPI_MOSI=1;//發送數據格式為高位在前,八位。當發送的某一位為1時,對MOSI賦1.
else SPI_MOSI=0;//主機采樣為第二個邊沿,為上升沿,所以主機發送數據時為下降沿
txdata<<=1;
SPI_SCK=1;
//上升沿時讀取從機發送過來的數據
rxdata<<=1;
if(SPI_MISO)rxdata |= 0x01;
}
return rxdata;
}
三、硬件SPI
硬件SPI也很好理解,唯一難理解的就是NSS(SPI_CR1)腳管理。
/*
SPI硬件時序配置初始化
Hardware:硬件
pb13:sp2_sck
pb14:miso
pb15:mosi
*/
void HWSPI_Init(void)
{
RCC->APB2ENR |= 1<<3;
GPIOB->CRH &= 0x000fffff;
GPIOB->CRH |= 0xb8b00000;
RCC->APB1ENR |= 1<<14;//開啟rcc時鐘
RCC->APB1RSTR |= 1<<14;
RCC->APB1RSTR &=~(1<<14);
SPI2->CR1 |= 0x3<<8;
//8,9位:啟動軟件NSS管理(也就是允許用程序控制片選腳)。當配置MCU為主模式(MSTR=1),SSOE=0時,NSS為低的話則會進入主模式失敗
//而進入從模式。所以必須拉高。
//一旦使能SSOE位,NSS引腳也可以作為輸出引腳,并在SPI處于主模式時將NSS拉低;此時,所有的SPI設備,如果它們的NSS引腳連接
//到主設備的NSS引腳,則會檢測到低電平,如果它們被設置為NSS硬件模式,就會自動進入從設備狀態。(中文手冊23.3.1)
SPI2->CR1 |= 1<<1;//SCK空閑電平為高
SPI2->CR1 |= 1<<0;//數據采樣從第二個邊沿開始
SPI2->CR1 |= 1<<2;//配置為主設備
SPI2->CR1 |= 1<<6;//使能SPI
HWSPI_ReadWriteOneByte(0xff);
}
/*發送和接收數據(8位)*/
u8 HWSPI_ReadWriteOneByte(u8 data)
{
u32 i=0;
while(!(SPI2->SR & 1<<1))//等待發送緩沖區空
{
i++;
if(i>0xfffe)return 0;//超時,發生錯誤
}
SPI2->DR = data;
i=0;
while(!(SPI2->SR & 1<<0))//等待接收緩沖區非空
{
i++;
if(i>0xfffe)return 0;
}
return SPI2->DR;
}
目前只學習了硬件SPI的主模式,好多強大的功能同樣沒有學習到,所有只能記錄到這了。才疏學淺,慚愧慚愧~
上一篇:STM32F10x 學習筆記之USART實現串口通訊 DMA 方式
下一篇:STM32自學之SPI的DMA操作(寄存器級)
推薦閱讀
史海拾趣
品質是超音一直以來的追求。公司注重產品質量管理,建立了完善的質量檢測體系,確保每一件產品都符合高標準的質量要求。同時,超音還加強了品牌建設,通過廣告宣傳、贊助活動等方式提升品牌知名度和美譽度。這些努力使得超音在消費者心中樹立了良好的品牌形象,為公司的長期發展奠定了堅實的基礎。
隨著市場需求的不斷變化,Easy Magnet Corp公司意識到,只有不斷創新才能保持競爭優勢。因此,公司加大了研發投入,不斷推出具有創新性的產品。其中,一款集成了微型化、高性能和高穩定性的磁性傳感器,因其獨特的優勢,在智能手機、平板電腦等電子產品中得到了廣泛應用。這一技術突破不僅提升了公司的知名度,也為公司帶來了可觀的收益。
在穩固了電子元器件和模塊市場地位后,Emmoco開始尋求多元化發展。公司利用自身的技術優勢和市場經驗,逐步拓展產品線,涉足智能家居、物聯網等領域。通過不斷的技術創新和市場拓展,Emmoco成功實現了產品線的多元化,為客戶提供更加全面和多樣化的解決方案。
隨著業務的不斷拓展,CANOPUS開始專注于鼓的制造研究。在1984年,公司推出了其標志性產品——整木掏空櫸木軍鼓。這款鼓的獨特之處在于其鼓腔是由整個樹干挖空處理而成,導角也做了特有的設計。這一創新使得CANOPUS的鼓在音質和外觀上都與眾不同,迅速在市場上獲得了認可。
隨著業務的不斷拓展,CANOPUS開始專注于鼓的制造研究。在1984年,公司推出了其標志性產品——整木掏空櫸木軍鼓。這款鼓的獨特之處在于其鼓腔是由整個樹干挖空處理而成,導角也做了特有的設計。這一創新使得CANOPUS的鼓在音質和外觀上都與眾不同,迅速在市場上獲得了認可。
在電子行業的快速發展中,Dremio公司以其獨特的數據治理技術嶄露頭角。他們開發了一種新型的數據處理引擎,能夠直接在云數據湖中查詢和分析數據,無需將數據復制到專有數據倉庫中。這一創新技術大大提高了數據處理效率,降低了成本,并為企業提供了更靈活的數據管理方式。Dremio憑借這一技術,迅速在電子行業中樹立了領先地位。
先設定應用背景: A測控16個溫度點,B控制4臺步進電機,C控制8個繼電器,D至少預留12個以上的測控端接受多種傳感器的電信號 還有一個小前提,芯片容易買到。因為我研究測控模塊只是為了提高產品的技術含量,不可能大批制造板子,更不會轉行 1、F ...… 查看全部問答∨ |
|
W_DOT: MOV A,O_YL ; Y坐標轉換計算 MOV B,#20h MUL AB MOV O_YL,A ; O_YL存地址低8位 MOV A,B XCH A,O_XH ; O_XH存地址高8位 PUSH ACC ; 存D7標志位 CLR ACC.7 ; 清D7位 MOV B,#20H ; X坐標高位轉換計算 MUL AB ADD A,O_YL MOV O_YL ...… 查看全部問答∨ |
本帖最后由 jameswangsynnex 于 2015-3-3 20:02 編輯 CMOS即互補性金屬氧化物半導體。其在微處理器、閃存和特定用途集成電路(ASIC)的半導體技術上占有絕對重要的地位。CMOS和CCD都是可用來感受光線變化的半導體。CMOS主要是利用“硅”和“鍺”這兩 ...… 查看全部問答∨ |
最近一直在尋找如何只用ddk(2600)與vc6.0來建xp下的驅動開發環境,該如何配置呢?我是試過很多方案編譯都不能通過,希望高人指點一二!… 查看全部問答∨ |
|
編譯2.6.14.1的內核出錯了,有會的看看,已經一個星期了,急,在線.......... 我用的是arm-linux-gcc3.3.2,在編譯kernel2.6.14.1時,報錯 /usr/local/arm/3.3.2/bin/arm-linux-ld:arch/arm/kernel/vmlinux.lds:711:parse error 這是什么錯誤啊,大概是什么原因引起的,如何修改呢? 大家幫幫忙,都弄了一個星期了,一點結果 ...… 查看全部問答∨ |
|
通過請教別人知道: 1 在編輯VHDL時,需要屏蔽某一句代碼時要寫-- 屏蔽一大坨代碼時我一直是每行加--(剛學哈),通過請教,現在找到兩個方法:第一:利用q2的區域注釋功能,選擇要屏蔽的代碼,右鍵選擇comment selection/uncomment selection 可 ...… 查看全部問答∨ |