99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

liuxiaofei126
認證:VIP會員
所在專題目錄 查看專題
單片機之USB 硬件和數據的四種傳輸方式
實例講解(二)SPI通訊顯示電子星球
實例講解(三)之USB模擬串口
實例分析之可編程數控電源
軟件和硬件SPI通信模組的實例分析
紅外遙控系統的stm32實戰分析
作者動態 更多
stm32知識點總結
2021-11-24 23:12
工程師單片機LED項目
2021-11-11 07:46
電容型負載對跟隨器的影響
2021-10-28 23:33
圖騰柱和互補推挽兩個“小冤家”
2021-10-22 23:15
學習單片機的捷徑
2021-10-17 23:07

軟件和硬件SPI通信模組的實例分析

開工了,開工了,新年新氣象,軟件和硬件SPI方式都有,可以參考

一、SPI的通信原理

SPI的通信原理很簡單,它以主從方式工作,這種模式通常有一個主設備和一個或多個從設備,需要至少4根線,事實上3根也可以(單向傳輸時)。也是所有基于SPI的設備共有的,它們是SDI(數據輸入),SDO(數據輸出),SCK(時鐘),CS(片選)。

  • SDO     – 主設備數據輸出,從設備數據輸入 對應MOSI master output slave input
  • SDI      – 主設備數據輸入,從設備數據輸出  對應MISO master input slave output
  • SCLK   – 時鐘信號,由主設備產生
  • CS        – 從設備使能信號,由主設備控制

CS: 其中CS是控制芯片是否被選中的,也就是說只有片選信號為預先規定的使能信號時(高電位或低電位),對此芯片的操作才有效,這就允許在同一總線上連接多個SPI設備成為可能。

SDI/SDO/SCLK: 通訊是通過數據交換完成的,這里先要知道SPI是串行通訊協議,也就是說數據是一位一位的傳輸的。這就是SCK時鐘線存在的原因,由SCK提供時鐘脈沖,SDI,SDO則基于此脈沖完成數據傳輸。數據輸出通過 SDO線,數據在時鐘上升沿或下降沿時改變,在緊接著的下降沿或上升沿被讀取。完成一位數據傳輸,輸入也使用同樣原理。這樣,在至少8次時鐘信號的改變(上沿和下沿為一次),就可以完成8位數據的傳輸。

  要注意的是,SCK信號線只由主設備控制,從設備不能控制信號線。同樣,在一個基于SPI的設備中,至少有一個主控設備。

這樣傳輸的特點:這樣的傳輸方式有一個優點,與普通的串行通訊不同,普通的串行通訊一次連續傳送至少8位數據,而SPI允許數據一位一位的傳送,甚至允許暫停,因為SCK時鐘線由主控設備控制,當沒有時鐘跳變時,從設備不采集或傳送數據,也就是說,主設備通過對SCK時鐘線的控制可以完成對通訊的控制。SPI還是一個數據交換協議:因為SPI的數據輸入和輸出線獨立,所以允許同時完成數據的輸入和輸出。不同的SPI設備的實現方式不盡相同,主要是數據改變和采集的時間不同,在時鐘信號上沿或下沿采集有不同定義,具體請參考相關器件的文檔。

在點對點的通信中,SPI接口不需要進行尋址操作,且為全雙工通信,顯得簡單高效。在多個從設備的系統中,每個從設備需要獨立的使能信號,硬件上比I2C系統要稍微復雜一些。

最后,SPI接口的一個缺點:沒有指定的流控制,沒有應答機制確認是否接收到數據

再看看 SPI 通訊的通訊時序,見圖 SPI 通訊時序。

二、SPI的通信模式

經常忘記SPI4種工作模式,學了忘了,現在記下方便以后查閱。在芯片資料上極性和相位一般表示為CPOL(Clock POLarity)和CPHA(Clock PHAse), 極性和相位組合成4種工作模式。

CPOL CPHA

MODE0 0 0

MODE1 0 1

MODE2 1 0

MODE3 1 1

CPOL: SPI空閑時的時鐘信號電平(1:高電平, 0:低電平)CPHA: SPI在時鐘第幾個邊沿采樣(1:第二個邊沿開始, 0:第一個邊沿開始)MODE0和MODE3最常用。

我們結合實例分析SPI模塊通信,采用W25Q64,看手冊如何選擇通信模式

我們只能采用模式0和3,這是spi讀數據

/*
*********************************************************************************************************
*	函 數 名: bsp_spiRead1
*	功能說明: 從SPI總線接收8個bit數據。  SCK上升沿采集數據, SCK空閑時為高電平
*	形    參: 無
*	返 回 值: 無
*********************************************************************************************************
*/
uint8_t bsp_spiRead1(void)
{
#ifdef SOFT_SPI		/* 軟件SPI */
	uint8_t i;
	uint8_t read = 0;

	for (i = 0; i < 8; i++)
	{
		SCK_0();
		bsp_spiDelay();
		read = read << 1;
		if (MISO_IS_HIGH())
		{
			read++;
		}
		SCK_1();
		bsp_spiDelay();
	}
	return read;
#endif

#ifdef HARD_SPI		/* 硬件SPI */
	uint8_t read;

	/* 等待發送緩沖區空 */
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

	/* 發送一個字節 */
	SPI_I2S_SendData(SPI1, 0);

	/* 等待數據接收完畢 */
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

	/* 讀取接收到的數據 */
	read = SPI_I2S_ReceiveData(SPI1);

	/* 返回讀到的數據 */
	return read;
#endif
}

這是寫數據

/*
*********************************************************************************************************
*	函 數 名: bsp_spiWrite0
*	功能說明: 向SPI總線發送一個字節。SCK上升沿采集數據, SCK空閑時為低電平。
*	形    參: 無
*	返 回 值: 無
*********************************************************************************************************
*/
void bsp_spiWrite0(uint8_t _ucByte)
{
#ifdef SOFT_SPI		/* 軟件SPI */
	uint8_t i;

	for(i = 0; i < 8; i++)
	{
		if (_ucByte & 0x80)
		{
			MOSI_1();
		}
		else
		{
			MOSI_0();
		}
		bsp_spiDelay();
		SCK_1();
		_ucByte <<= 1;
		bsp_spiDelay();
		SCK_0();
	}
	bsp_spiDelay();
#endif

#ifdef HARD_SPI		/* 硬件SPI */
	/* 等待發送緩沖區空 */
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

	/* 發送一個字節 */
	SPI_I2S_SendData(SPI1, _ucByte);

	/* 等待數據接收完畢 */
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

	/* 讀取接收到的數據 */
	SPI_I2S_ReceiveData(SPI1);
#endif
}

/*
*********************************************************************************************************
*	函 數 名: bsp_spiRead0
*	功能說明: 從SPI總線接收8個bit數據。 SCK上升沿采集數據, SCK空閑時為低電平。
*	形    參: 無
*	返 回 值: 讀到的數據
*********************************************************************************************************
*/
uint8_t bsp_spiRead0(void)
{
#ifdef SOFT_SPI		/* 軟件SPI */
	uint8_t i;
	uint8_t read = 0;

	for (i = 0; i < 8; i++)
	{
		read = read<<1;

		if (MISO_IS_HIGH())
		{
			read++;
		}
		SCK_1();
		bsp_spiDelay();
		SCK_0();
		bsp_spiDelay();
	}
	return read;
#endif

#ifdef HARD_SPI		/* 硬件SPI */
	uint8_t read;

	/* 等待發送緩沖區空 */
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

	/* 發送一個字節 */
	SPI_I2S_SendData(SPI1, 0);

	/* 等待數據接收完畢 */
	while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

	/* 讀取接收到的數據 */
	read = SPI_I2S_ReceiveData(SPI1);

	/* 返回讀到的數據 */
	return read;
#endif
}

具體資料在配套資料

聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
本篇所含全部資料,點擊此處留下郵箱我會發給你
資料明細:V4-101_SPI串行Flash讀寫例程(V1.0).zip
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 9
收藏 10
關注 211
成為作者 賺取收益
全部留言
0/200
  • 星球居民-YBPLIKJ1 2021-03-24 22:42
    給力
    回復
  • 小董 2021-03-04 19:27
    期待繼續
    回復
  • dy-blNlwnWV 2021-02-21 21:18
    感謝分享
    回復
  • lihui710884923 2021-02-20 07:28
    不錯
    回復
主站蜘蛛池模板: 欧美金8天国 | 久久免费的精品国产v∧ | 欧美秋霞| 精品成人毛片一区二区 | 肥美欧美内射中出 | 久久99热狠狠色一区二区 | 91国在线高清视频 | 少妇高潮惨叫正在播放对白 | 免费视频mv在线观看 | 成人综合色站 | 真实国产乱子伦精品视频 | 日本少妇高潮叫床声 | 麻豆久久久久久久 | 自拍一级片| 一区二区三区国产免费 | WWW.亚洲最大夜色伊人 | 日本最新在线观看一区二区三区 | 国产精品三级在线观看 | 国产一级二级视频 | 在线观看国产成人av天堂 | 国产wwwxx| 国产一区二区不卡视频 | 亚洲精品久久久久高潮 | 日女av在线| 亚洲不卡在线视频 | 亚洲无限看 | 性欧美视频在线观看 | 国产福利萌白酱在线观看视频 | 色一欲一性一乱一区二区三区 | 日韩精品一区二区三区免费观看 | 国内自拍偷拍一区 | 四虎免看黄 | 亚洲3p激情在线观看 | 国产尺码和欧洲尺码表2022 | 99久久无码一区人妻A片红豆 | 天天爱天天做天天添天天欢 | 欧美肥熟妇xxxxx | 老司机精品视频一区二区 | 国产高清成人久久 | 国产成人久久精品激情91 | 婷婷久久综合九色综合88 |