完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前面已经总结过STM32Fxx的特点和传输过程,下面以nRF24L01+ 2.4GHz无线收发器为例,来说明如何使用SPI。
一、nRF24L01+ 2.4GHz无线收发器的介绍 1. 主要特性
2.1 读操作时序图 图1. nRF24L01+ 读操作时序 ①:发送指令+寄存器地址,都是从CSN(片选线,下同)的下降沿开始 ②:主机(即STM32F4xx,下同)发送8位指令代码(C7~C0,下同) ③:不管主机发送何指令,从机(即nRF24L01+,下同)第一字节都会返回状态寄存器的值(寄存器0x07) ④:从机数据在每一个SCK的上升沿输出,首先输出的是第一字节(最低字节)的最高位,...,最后输出的是最高字节的最低位 ⑤:读取操作都是以CSN的上升沿结束 2.2 写操作时序 图2. nRF24L01+ 写操作时序 ①:同读操作 ②:同读操作 ③:同读操作 ④:主机数据在每一个SCK的上升沿写入从机,首先写入的是第1个字节的最高位,...,最后写入的是最后一个字节的最低位 ⑤:同读操作 2.3 状态机 图3. nRF24L01+ 状态图
二、程序实现 根据上面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. 调试失败,排查以下几点:
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1754 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1613 浏览 1 评论
1053 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1667 浏览 2 评论
1931浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
716浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
562浏览 3评论
587浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
546浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 11:30 , Processed in 2.671789 second(s), Total 46, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号