前面已经总结过STM32Fxx的特点和传输过程,下面以nRF24L01+ 2.4GHz无线收发器为例,来说明如何使用SPI。
一、nRF24L01+ 2.4GHz无线收发器的介绍
1. 主要特性
- 全球2.4GHz ISM频段操作
- 250Kbps, 1Mbps, 2Mbps三种空中传输速率
- 超低功耗
- 输出功率为 0dBm时发射功耗为11.3mA
- 空中传输速率为2Mbps时接收功耗为13.5mA
- Power down模式功耗低至900nA, Standby-I模式功耗低至26uA
- 1.9~3.6V的电压工作范围
- 支持6个接收通道(地址)
- IO口能承受5V电压
- ±60ppm 16MHz晶体振荡器
- 4×4mm QFN封装
2. SPI操作时序
2.1 读操作时序图
图1. nRF24L01+ 读操作时序
①:发送指令+寄存器地址,都是从CSN(片选线,下同)的下降沿开始
②:主机(即STM32F4xx,下同)发送8位指令代码(C7~C0,下同)
③:不管主机发送何指令,从机(即nRF24L01+,下同)第一字节都会返回状态寄存器的值(寄存器0x07)
④:从机数据在每一个SCK的上升沿输出,首先输出的是第一字节(最低字节)的最高位,...,最后输出的是最高字节的最低位
⑤:读取操作都是以CSN的上升沿结束
2.2 写操作时序
图2. nRF24L01+ 写操作时序
①:同读操作
②:同读操作
③:同读操作
④:主机数据在每一个SCK的上升沿写入从机,首先写入的是第1个字节的最高位,...,最后写入的是最后一个字节的最低位
⑤:同读操作
2.3 状态机
图3. nRF24L01+ 状态图
在该模式下,nRF24L01+的功耗最小,不能进行发送或者接收。但是所有寄存器的值保持不变,SPI处于有效状态,允许对寄存器,TX/RX FIFO进行操作,PWR_UP(此位在CONFIG寄存器中)清0即进入该状态。
将PWR_UP置1,即进入Standby-I模式,该模式既降低了nRF24L01+的平均功耗,同时又保持尽可能短的启动时间,将CE置1然后后清0,就可以进入TX/RX模式,然后又返回到Standby-I模式。
当nRF24L01+设置为接收机(PTX),并且CE=1,TX FIFO为空时即进入该模式。相比Standby-I模式,这种模式相对耗电,一旦发送FIFO有新数据,就会立即将数据打包发送出去。
进入该模式需要满足以下条件:
- PWR_UP=1
- PRIM_RX=0
- TX FIFO不为空
- CE=1脉冲宽度超过10us
- RX 模式
进入该模式需要满足以下条件
二、程序实现
根据上面nRF24L01+的时序,结合前面介绍的STM32F4xx SPI的操作小结,SPI设置成全双工收发模式,NSS(片选引脚)单独用一个IO口来控制,对nRF24L01+读写操作程序如下:
1. SPI发送/接收子函数
1 /* SPI 发送*/
2 void _SPIDataSet(SPI_TypeDef * SPIx, unsigned char *Buf, unsigned char Cnt)
3 {
4 for(; Cnt; Cnt--)
5 {
6 while((SPIx -》 SR & SPI_SR_TXE) != SPI_SR_TXE);
7 SPIx -》 DR = *Buf++;
8 }
9 while(SPIx -》 SR & SPI_SR_BSY);
10 Cnt = SPIx -》 DR;
11 }
12
13 /* SPI 接收*/
14 void _SPIDataGet(SPI_TypeDef * SPIx, unsigned char *Buf, unsigned char Cnt)
15 {
16 for(; Cnt; Cnt--)
17 {
18 while((SPIx -》 SR & SPI_SR_TXE) != SPI_SR_TXE);
19 SPIx -》 DR = 0xFF;
20 while((SPIx -》 SR & SPI_SR_RXNE) != SPI_SR_RXNE);
21 *Buf++ = SPIx -》 DR;
22 }
23 24 }
L6:写入数据前必须保证TX缓存器为空
L9:确保最后一位数据发送完毕
L10:使RXNE位清0(对DR进行读操作,将使RXNE清0),若RXNE若置1,SPI不会接受新数据。
L19:由于SPI工作与全双工模式,即发送1位数据才会接收1位数据,此语句本质是让SPI输出SCK,使nRF24L01+输出数据
L20: 确保接收到完整的数据
2. 对nRF24L01+寄存器的读/写操作
1 /* 写nRF24L01+ 寄存器 */
2 void DataSet(unsigned char CMD, /* 寄存器地址 */
3 unsigned char *Val, /* 发送数据指针 */
4 unsigned char Cnt /* 数据数量 */)
5 {
6 nRF24L01_CSN = 0;
7 _SPIDataSet(SPI1, &CMD, 1);
8 _SPIDataSet(SPI1, Val, Cnt);
9 nRF24L01_CSN = 1;
10 }
11
12
13 /* 读nRF24L01+ 寄存器 */
14 void DataGet(unsigned char CMD, /* 寄存器地址 */
15 unsigned char *Buf, /* 接收数据指针 */
16 unsigned char Cnt /* 数据大小 */)
17 {
18 nRF24L01_CSN = 0;
19 _SPIDataSet(SPI1, &CMD, 1);
20 _SPIDataGet(SPI1, Buf, Cnt);
21 nRF24L01_CSN = 1;
22 }
L6, L18: CSN的下降沿开始读/写操作
L9, L21: CSN的上升沿结束读/写操作
下图所示为通过逻辑分析仪抓取的设置nRF24L01+ pipe0接收地址(寄存器0xA)的波形:
图4. 设置Pipe0(寄存器0xA)接收地址波形
下图所示为通过逻辑分析仪抓取的读取nRF24L01+ pipe0接收地址(寄存器0xA)的波形:
图5. 读取Pipe0(寄存器0xA)接收地址波形
More~
1. 假如使用 Auto Acknowledgment 功能,发送端(PTX)Pipe0接收地址必须和发送地址 相同,这是用于接收接收端(PRX)的相应
2. 接收数据数量(最大32字节)必须写入RX_PW_Px寄存器(x为通道编号)
3. 调试失败,排查以下几点:
- 硬件连接是否正确
- 寄存器读写操作是否正确
- 确保Standby-I/II 模式变换到TX 模式时,CE高电平时间足够(大于130us)
- 发送端(PTX)和接收端(PRX)数据的大小要一致,比如接收端(PRX)接收数据大小设置为8字节,那么主机就要给发送端(PTX)的TX FIFO传输8个字节
/×××××××××××××××××××××××××××××××××××××××× THE END××××××××××××××××××××××××××××××××××××××××××××/
前面已经总结过STM32Fxx的特点和传输过程,下面以nRF24L01+ 2.4GHz无线收发器为例,来说明如何使用SPI。
一、nRF24L01+ 2.4GHz无线收发器的介绍
1. 主要特性
- 全球2.4GHz ISM频段操作
- 250Kbps, 1Mbps, 2Mbps三种空中传输速率
- 超低功耗
- 输出功率为 0dBm时发射功耗为11.3mA
- 空中传输速率为2Mbps时接收功耗为13.5mA
- Power down模式功耗低至900nA, Standby-I模式功耗低至26uA
- 1.9~3.6V的电压工作范围
- 支持6个接收通道(地址)
- IO口能承受5V电压
- ±60ppm 16MHz晶体振荡器
- 4×4mm QFN封装
2. SPI操作时序
2.1 读操作时序图
图1. nRF24L01+ 读操作时序
①:发送指令+寄存器地址,都是从CSN(片选线,下同)的下降沿开始
②:主机(即STM32F4xx,下同)发送8位指令代码(C7~C0,下同)
③:不管主机发送何指令,从机(即nRF24L01+,下同)第一字节都会返回状态寄存器的值(寄存器0x07)
④:从机数据在每一个SCK的上升沿输出,首先输出的是第一字节(最低字节)的最高位,...,最后输出的是最高字节的最低位
⑤:读取操作都是以CSN的上升沿结束
2.2 写操作时序
图2. nRF24L01+ 写操作时序
①:同读操作
②:同读操作
③:同读操作
④:主机数据在每一个SCK的上升沿写入从机,首先写入的是第1个字节的最高位,...,最后写入的是最后一个字节的最低位
⑤:同读操作
2.3 状态机
图3. nRF24L01+ 状态图
在该模式下,nRF24L01+的功耗最小,不能进行发送或者接收。但是所有寄存器的值保持不变,SPI处于有效状态,允许对寄存器,TX/RX FIFO进行操作,PWR_UP(此位在CONFIG寄存器中)清0即进入该状态。
将PWR_UP置1,即进入Standby-I模式,该模式既降低了nRF24L01+的平均功耗,同时又保持尽可能短的启动时间,将CE置1然后后清0,就可以进入TX/RX模式,然后又返回到Standby-I模式。
当nRF24L01+设置为接收机(PTX),并且CE=1,TX FIFO为空时即进入该模式。相比Standby-I模式,这种模式相对耗电,一旦发送FIFO有新数据,就会立即将数据打包发送出去。
进入该模式需要满足以下条件:
- PWR_UP=1
- PRIM_RX=0
- TX FIFO不为空
- CE=1脉冲宽度超过10us
- RX 模式
进入该模式需要满足以下条件
二、程序实现
根据上面nRF24L01+的时序,结合前面介绍的STM32F4xx SPI的操作小结,SPI设置成全双工收发模式,NSS(片选引脚)单独用一个IO口来控制,对nRF24L01+读写操作程序如下:
1. SPI发送/接收子函数
1 /* SPI 发送*/
2 void _SPIDataSet(SPI_TypeDef * SPIx, unsigned char *Buf, unsigned char Cnt)
3 {
4 for(; Cnt; Cnt--)
5 {
6 while((SPIx -》 SR & SPI_SR_TXE) != SPI_SR_TXE);
7 SPIx -》 DR = *Buf++;
8 }
9 while(SPIx -》 SR & SPI_SR_BSY);
10 Cnt = SPIx -》 DR;
11 }
12
13 /* SPI 接收*/
14 void _SPIDataGet(SPI_TypeDef * SPIx, unsigned char *Buf, unsigned char Cnt)
15 {
16 for(; Cnt; Cnt--)
17 {
18 while((SPIx -》 SR & SPI_SR_TXE) != SPI_SR_TXE);
19 SPIx -》 DR = 0xFF;
20 while((SPIx -》 SR & SPI_SR_RXNE) != SPI_SR_RXNE);
21 *Buf++ = SPIx -》 DR;
22 }
23 24 }
L6:写入数据前必须保证TX缓存器为空
L9:确保最后一位数据发送完毕
L10:使RXNE位清0(对DR进行读操作,将使RXNE清0),若RXNE若置1,SPI不会接受新数据。
L19:由于SPI工作与全双工模式,即发送1位数据才会接收1位数据,此语句本质是让SPI输出SCK,使nRF24L01+输出数据
L20: 确保接收到完整的数据
2. 对nRF24L01+寄存器的读/写操作
1 /* 写nRF24L01+ 寄存器 */
2 void DataSet(unsigned char CMD, /* 寄存器地址 */
3 unsigned char *Val, /* 发送数据指针 */
4 unsigned char Cnt /* 数据数量 */)
5 {
6 nRF24L01_CSN = 0;
7 _SPIDataSet(SPI1, &CMD, 1);
8 _SPIDataSet(SPI1, Val, Cnt);
9 nRF24L01_CSN = 1;
10 }
11
12
13 /* 读nRF24L01+ 寄存器 */
14 void DataGet(unsigned char CMD, /* 寄存器地址 */
15 unsigned char *Buf, /* 接收数据指针 */
16 unsigned char Cnt /* 数据大小 */)
17 {
18 nRF24L01_CSN = 0;
19 _SPIDataSet(SPI1, &CMD, 1);
20 _SPIDataGet(SPI1, Buf, Cnt);
21 nRF24L01_CSN = 1;
22 }
L6, L18: CSN的下降沿开始读/写操作
L9, L21: CSN的上升沿结束读/写操作
下图所示为通过逻辑分析仪抓取的设置nRF24L01+ pipe0接收地址(寄存器0xA)的波形:
图4. 设置Pipe0(寄存器0xA)接收地址波形
下图所示为通过逻辑分析仪抓取的读取nRF24L01+ pipe0接收地址(寄存器0xA)的波形:
图5. 读取Pipe0(寄存器0xA)接收地址波形
More~
1. 假如使用 Auto Acknowledgment 功能,发送端(PTX)Pipe0接收地址必须和发送地址 相同,这是用于接收接收端(PRX)的相应
2. 接收数据数量(最大32字节)必须写入RX_PW_Px寄存器(x为通道编号)
3. 调试失败,排查以下几点:
- 硬件连接是否正确
- 寄存器读写操作是否正确
- 确保Standby-I/II 模式变换到TX 模式时,CE高电平时间足够(大于130us)
- 发送端(PTX)和接收端(PRX)数据的大小要一致,比如接收端(PRX)接收数据大小设置为8字节,那么主机就要给发送端(PTX)的TX FIFO传输8个字节
/×××××××××××××××××××××××××××××××××××××××× THE END××××××××××××××××××××××××××××××××××××××××××××/
举报