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
    不錯
    回復
主站蜘蛛池模板: 亚洲国产亚洲 | 日韩精品中文有码 | 国产精品白丝袜 | 中文字幕在线视频精品 | 成人精品综合 | xxxxx黄色片 国产一二三在线观看 | 小黄文纯肉污到你湿 | 欧美一区二区三区国产精品 | 日本激情视频一区 | 精品人妻无码一区二区三区丝袜 | 亚洲国产精品乱码一区二区三区 | 欧美成人hd | 久久天天躁狠狠躁夜夜96流白浆 | 91伊人| 99re6国产露脸精品视频网站 | 麻豆入口 | 5xs社区免费视频5xsq | 日韩h网站 | 色图久久| 开心婷婷中文字幕 | 飘雪影院免费版在线观看视频 | 亚洲国产精品一区二区久 | 女人爽到高潮免费视频大全 | 熟妇的奶头又大又粗视频 | 国产亚洲三区 | 在线A亚洲老鸭窝天堂AV高清 | 一区二区三区精品视频免费看 | 亚洲激情校园 | 国产成人啪精品视频免费网站 | 国产成人无遮挡在线视频 | 日韩视频一二三 | 皇色在线视频 | 亚洲区精品3d国漫同人 | 日本一二三区在线观看 | 在线高清理伦片a | 在线免费av网站 | 亚洲精品三级在线观看 | 国产在线不卡精品网站 | 农民工嫖妓50岁老熟女 | 亚洲欧美国产日韩精品 | 夜色亚洲|