很多初学者可能会不明白为什么发送函数(如下面的代码片段所示)里发送数据后通过接收数据的方式来判断发送的数据是否已发送完毕,也不解为什么接收数据前要发送一个任意数据到从机,那是因为在全双工模式下,发送和接收数据是同步进行的,即你发送数据给从机的同时,从机也会发送数据给你,而这个接收到的数据有效还是无效,完全是看相应芯片所制定的协议,但一定会发送,所以可以通过接收从机数据的方式来判断数据是否已发送完毕;而接收数据因为从机没有时钟信号,需要主机提供,所以通过给从机发送数据(任意数)的方式提供时钟信号,正如前面所述,发送一个数据意味着接收到一个数据,将接收到的数据保存即可。
1 #define Dummy_Byte 0xFF
2 /**
3 * @brief 使用SPI 发送一个字节的数据
4 * @param byte:要发送的数据
5 * @retval 返回接收到的数据
6 */
7 u8 SPI_FLASH_SendByte(u8 byte)
8 {
9 SPITimeout = SPIT_FLAG_TIMEOUT;
10
11 /* 等待发送缓冲区为空,TXE 事件 */
12 while (SPI_I2S_GetFlagStatus(FLASH_SPIx, SPI_I2S_FLAG_TXE) == RESET)
13 {
14 if ((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);
15 }
16
17 /* 写入数据寄存器,把要写入的数据写入发送缓冲区 */
18 SPI_I2S_SendData(FLASH_SPIx, byte);
19
20 SPITimeout = SPIT_FLAG_TIMEOUT;
21
22 /* 等待接收缓冲区非空,RXNE 事件 */
23 while (SPI_I2S_GetFlagStatus(FLASH_SPIx, SPI_I2S_FLAG_RXNE) == RESET)
24 {
25 if ((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(1);
26 }
27
28 /* 读取数据寄存器,获取接收缓冲区数据 */
29 return SPI_I2S_ReceiveData(FLASH_SPIx);
30 }
31
32 /**
33 * @brief 使用SPI 读取一个字节的数据
34 * @param 无
35 * @retval 返回接收到的数据
36 */
37 u8 SPI_FLASH_ReadByte(void)
38 {
39 return (SPI_FLASH_SendByte(Dummy_Byte));
40 }
参考文章:
这篇文章介绍的非常清楚