




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、经过两日的调试nRF24L01终于调试成功。耐心,细心。有想法。资料。数据手册。总就会成功。 下面是调试的基本方法: 24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根本不知道是发的问题还是收的问题,不好意思的说,我当时也是没理清调试思路才浪费了一天时间看着模块干瞪眼。并且烧坏了两个模块。(还好这个模块可以。)。所以正确的调试方法应该是先调试发送方,能保证发送正确,再去调接收,这样就可以有针对性的解决问题。至于怎么去调发送方,先说下发送方的工作流程:?配置寄存器使芯片工作于发送模式后拉高CE端至少10us?读状态寄存器STATUS?判断是否
2、是发送完成标志位置位?清标志?清数据缓冲网上的程序我也看过,大多都是成品,发送方发送-等应答-(自动重发)-触发中断。可是这样的流程就已经把接收方给牵涉进来了,就是说一定要接收方正确收到数据并且回送应答信号之后发送方才能触发中断,结束一次完整的发送。可是这跟我们的初衷不相符,我们想单独调试发送,完全抛开接收,这样就要去配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); / 失能通道0自动应答SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); / 失能接收通道0SPI
3、_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); / 失能自动重发 1有了以上这三个配置,发送方的流程就变成了发送-触发中断。这样就抛开了接收方,可以专心去调试发送,可是怎么样才知道发送是否成功呢,要用到另外两个寄存器,STATUS和FIFO_STATUS。这样就很清晰了,我们可以通过读取STATUS的值来判断是哪个事件触发了中断,寄存器4、5、6位分别对应自动重发完成中断,数据发送完成中断,数据接收完成中断。也就是说,在之前的配置下,如果数据成功发送,那么STATUS的值应该为0x2e。这样就可以作为一个检测标准,另外一个标准可以看FIFO_STATUS寄存器,第
4、5位的描述:发送缓冲器满标志,1为满,0为有可用空间;第4位的描述:发送缓冲器空标志,1为空,0为有数据;同样可以看到接收缓冲器的对应标志。这样在数据发送成功后,发送寄存器当然应该是空的,接收缓冲因为在之前已经失能,所以也应该是空,也就是说成功发送之后的FIFO_STATUS寄存器值应该是0x11。有了这两个检测标准,我们即使不用接收方也可以确定发送方是否成功发送。当发送方调试成功之后,在程序里让它一直发送,然后我们就可以去调试接收方,思路是一样的,同样说下接收方工作流程先。?配置寄存器使芯片工作于接收模式后拉高CE端至少130us?读状态寄存器STATUS?判断是否是接收完成标志位置位?清标
5、志?读取数据缓冲区的数据?清数据缓冲然后在初始化配置寄存器的时候要和发送方保持一致,比较重要的是要失能自动应答,使能通道0接收:SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); / 失能通道0自动应答SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); / 接收要使能接收通道0这样就可以了,接收方就可以进入接收模式去接收数据了,这次的调试就会灵活一些,因为是接收数据,可以在接收方添加一个显示设备把数据直观的显示出来,去对照看是否正确,当然还可以使用和发送方一样的方法:观察STATUS和FIFO_STATUS的值,对照寄存器描述,接收正确时ST
6、ATUS的值应该是0x40,对于FIFO_STATUS的情况就多了些,因为数据宽度的不同也会造成寄存器的值不一样,24L01最大支持32字节宽度,就是说一次通讯最多可以传输32个字节的数据,在这种情况下,接收成功读数据之前寄存器值应该为0x12,读数据之后就会变成0x11;如果数据宽度定义的小于32字节,那么接收成功读数据之前寄存器值应该为0x10,读数据之后就会变成0x11。这个看起来挺复杂,其实很清晰,大家可以试着分析下,对照数据手册分析每个位的状态就可以得到结果。好了,到这里对nRF24L01的调试基本上就算通了,但是要明白这些只是调试方法,最终的产品如果不加上应答和重发的话那么数据的稳
7、定性是很难保证的,所以在基本的通讯建立之后就要把发送的配置改为:SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); /使能接收通道0自动应答SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); / 使能接收通道0SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); / 自动重发10次,间隔500us接收方的配置也要更改:SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); / 失能通道0自动应答SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); / 接收要使能接收通
8、道0这样发送和接收就进入了一个标准状态,发送-等应答-(自动重发)-触发中断;接收-应答-触发中断,一切按部就班,程序里加上自己的应用部分就能实现很多功能了。其实自己摸索单片机已经有一年了,但没在网上写过笔记,终于觉得既然整天都在各种网站找资料,也看人家的博客,自己也写写笔记,一方面给自己看,一方面作为分享和供批评。STM32这块片子接触也有半年了,还没真正做自己的作品,这阵子和一个朋友想做一下一个基于STM32的小作品,要用到无线控制,决定用NRF24L01+这片芯片,主要也是这片常用,简单,也便宜。 一个小插曲是在淘宝上淘模块的时候发现,相当多的店子都写明了是Si24R91(其实是应该是S
9、i24R1,那个好像是不存在的)这一代替芯片,其实看了手册,单单从功能上,Si24R1是提升了一些,属于向下兼容NRF24L01,但是不解的是淘宝发回来的芯片上印的却是NRF24L01,通过比对调试寄存器的内容确实是NRF24L01(这才让我不解,商家搞什么名堂)。 STM32F103VET6有俩SPI接口,选择用SPI1来驱动NRF24L01. 1.配置STM32的SPI1接口: 1)开启GPIOA,AFIO时钟 2)配置GPIOA对应Pin为SPI1的MISO,MOSI,CLK,NSS(SPI1的NSS已经为他用,故用PA1软件控制NRF24L01的CSN),CE(NRF24L01使能端口
10、),IRQ-NRF24L01的中断信号 3)配置SPI模式 2.仔细读手册(重点是时序和寄存器) 3.编写用SPI1控制NRF的函数数个 4.用以上的函数编写功能函数 OK!但这是说的。真正做起来的时候饱受打击。串口转USB线坏了,无奈只能LCD屏来显示调试信息,增大了代码负担。后来J-Link有坏了,差点放弃,好在重写了固件还能复活。 1)2)步的代码:void SPI1_Config(void) RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); /使能SP
11、I1时钟 / PA5-CLK PA7-MOSI 复用推挽输入 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /PA6-MISO 输入浮空 GPIO_InitStructure.GPIO_P
12、in =GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed =GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructu
13、re); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure);SPI1_CE_LOW(); SPI1_NRF_CSN_HIGH();/拉高CSN失能片选 SPI_InitTypeDefSPI_InitStructure; /声明用来初始化的结构体 SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex;/全双工 SPI
14、_InitStructure.SPI_Mode =SPI_Mode_Master; /主模式 SPI_InitStructure.SPI_DataSize =SPI_DataSize_8b; /一次传输8位 SPI_InitStructure.SPI_CPOL =SPI_CPOL_Low; /空闲电平低电平 SPI_InitStructure.SPI_CPHA =SPI_CPHA_1Edge; /第一个上升沿采样 SPI_InitStructure.SPI_NSS =SPI_NSS_Soft; /NSS管理为软件件模式 SPI_InitStructure.SPI_BaudRatePrescal
15、er =SPI_BaudRatePrescaler_8;/波特率预分频8 9MHz SPI_InitStructure.SPI_FirstBit =SPI_FirstBit_MSB; /数据传输低位在前 SPI_InitStructure.SPI_CRCPolynomial =7; /CRC校验方式 SPI_Init(SPI1,&SPI_InitStructure); /初始化 /SPI_NSSInternalSoftwareConfig(SPI1,SPI_NSSInternalSoft_Set); SPI_Cmd(SPI1, ENABLE); /使能SPI1/SPI1_Config(
16、) *操作NRF24L01寄存器的时候要在待机模式,CE=0的情况下,没发一个命令或数据,都会返回SPI一个字节,此字节是STAUS状态寄存器的内容,所以写命令的函数要发后,读回一字节,不然,发完命令,读数据的时候会出错。下面就是SPI写1 BYTE的函数。u8 SPI_RW_Byte(SPI_TypeDef* SPIx,unsigned char Byte) while( SPI_I2S_GetFlagStatus(SPIx,SPI_I2S_FLAG_TXE) = RESET); /查发送缓冲器是否为空,空即可以发送 SPI_I2S_SendData(SPIx,Byte); /库函数:发送一
17、个字节 /当SPI接收缓冲器为空时等待 while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_RXNE) =RESET); returnSPI_I2S_ReceiveData(SPIx);/SPI_RW_Byte() *下面一个是发写命令+指定字节数的数据的函数u8 SPI_NRF_Write(SPI_TypeDef* SPIx,char CMD,unsigned char*WBuff,unsigned char ByteNUM)unsigned chari,status; SPI1_CE_LOW();SPI1_NRF_CSN_LOW();/使能片选st
18、atus=SPI_RW_Byte( SPIx , CMD);for(i=0;i SPI_RW_Byte( SPIx,*WBuff+); /printf("写入第%d个数据rn",ByteNUM); SPI1_NRF_CSN_HIGH();/return status;/SPI_NRF_Write() *发读命令+指定字节数的数据的函数u8 SPI_NRF_Read(SPI_TypeDef* SPIx,char CMD,unsigned char*RBuff,unsigned char ByteNUM)unsigned char i,status ; SPI1_CE_LOW(
19、);SPI1_NRF_CSN_LOW(); status=SPI_RW_Byte( SPIx , CMD);for(i=0;i< ByteNUM ;i+) RBuff=SPI_RW_Byte(SPIx,NOP); / 取接收缓冲器,一个字节 /printf("读出第%d个数据rn",ByteNUM); LCD_Num_6x12_O(100,20*(i+1),RBuff,WHITE); SPI1_NRF_CSN_HIGH(); return status; /SPI_NRF_Read()下面是NRF24L01两种模式TX RX的配置void SPI_NRF_MOD_TX
20、(void) u8TX_Array5;u8_TX_RX_ADDR_5=0xB3,0xB4,0xB5,0xB6,0x05; SPI1_CE_LOW();/CE=0待机模式 TX_Array0=0x03;/设置地址宽度11-5字节 10-4字节 01-3字节 00-不合法SPI_NRF_Write(SPI1,W_REGISTER+SETUP_AW,TX_Array,1); TX_Array0=0xf3;/建立自动重发间隔1111-等待4000+86us 15次SPI_NRF_Write(SPI1,W_REGISTER+SETUP_RETR,TX_Array,1); TX_Array0=0x02;/
21、射频通道 X0000010SPI_NRF_Write(SPI1,W_REGISTER+RF_CH,TX_Array,1); TX_Array0=0x0f;/射频参数寄存器 00001111 2Mbps 发射功率 00-18dBm 01-12dBm 10-6dBm 11-0dBm 1-低噪声放大器增益SPI_NRF_Write(SPI1,W_REGISTER+RF_SETUP,TX_Array,1); TX_Array0=0x3f;/xx11 11110-5接收通道允许 SPI_NRF_Write(SPI1,W_REGISTER+EN_RXADDR,TX_Array,1); TX_Array0=
22、0x3f;/xx11 11110-5通道允许自动应答SPI_NRF_Write(SPI1,W_REGISTER+EN_AA,TX_Array,1); SPI_NRF_Write(SPI1,W_REGISTER+TX_ADDR,_TX_RX_ADDR_,5);/写入接收发送数据的地址,这个地址是接收端收件的凭证SPI_NRF_Write(SPI1,W_REGISTER+RX_ADDR_P0,_TX_RX_ADDR_,5);/写入接收发送数据的地址,这个地址是接收端收件的凭证TX_Array0=0x0e;/中断全开 发送模式 PRIM_RX=0PWR_UP=1 SPI_NRF_Write(SPI1
23、,W_REGISTER+CONFIG,TX_Array,1);TX_Array0=0xfe;/1111 xxxx STATUS寄存器写1清除所有标志SPI_NRF_Write(SPI1,W_REGISTER+STATUS,TX_Array,1);SPI1_CE_HIGH();/CE=1使能发射模式 Delay_us(100);/CE拉高需要一定的延时才能进行发送 延时之后即可通过SPI接口发送TX_PLDvoid SPI_NRF_MOD_RX(void) u8TX_Array5;u8_TX_RX_ADDR_5=0xB3,0xB4,0xB5,0xB6,0x05;SPI1_CE_LOW();/CE
24、=0待机模式 TX_Array0=0x03;/允许接收通道00000011SPI_NRF_Write(SPI1,W_REGISTER+EN_RXADDR,TX_Array,1); TX_Array0=0x03;/设置地址宽度11-5字节 10-4字节 01-3字节 00-不合法SPI_NRF_Write(SPI1,W_REGISTER+SETUP_AW,TX_Array,1); TX_Array0=0x20;/射频通道 X0000010SPI_NRF_Write(SPI1,W_REGISTER+RF_CH,TX_Array,1); TX_Array0=0x0f;/射频参数寄存器 0000111
25、1 2Mbps 发射功率 00-18dBm 01-12dBm 10-6dBm 11-0dBm 1-低噪声放大器增益SPI_NRF_Write(SPI1,W_REGISTER+RF_SETUP,TX_Array,1); TX_Array0=0x3f;/xx11 11110-5通道允许自动应答SPI_NRF_Write(SPI1,W_REGISTER+EN_AA,TX_Array,1); TX_Array0=0x04;/xx11 1111数据通道0 有效数据宽度 (1-32)字节SPI_NRF_Write(SPI1,W_REGISTER+RX_PW_P0,TX_Array,1); TX_Array
26、0=0xfe;/1111 xxxxSTATUS寄存器 写1清除所有标志SPI_NRF_Write(SPI1,W_REGISTER+STATUS,TX_Array,1);SPI_NRF_Write(SPI1,W_REGISTER+TX_ADDR,_TX_RX_ADDR_,5);/写入接收发送数据的地址,这个地址是接收端收件的凭证SPI_NRF_Write(SPI1,W_REGISTER+RX_ADDR_P0,_TX_RX_ADDR_,5);/写入接收发送数据的地址,这个地址是接收端收件的凭证TX_Array0=0x0f;/接收模式 PRIM_RX=1 PWR_UP=1允许接收终端SPI_NRF_
27、Write(SPI1,W_REGISTER+CONFIG,TX_Array,1);SPI1_CE_HIGH();/CE=1使能发射模式 Delay_us(100);/CE拉高需要一定的延时才能进行发送 延时之后即可通过SPI接口发送TX_PLD/轮询中断24L01中断的到来 NRF_Read_IRQ()下面是两种模式的测试ErrorStatus SPI_NRF_TX_DATAS(u8* TBuff,u8 ByteNUM) u8 Status1;do SPI1_CE_LOW();/拉低待机 SPI_NRF_Write(SPI1,W_TX_PAYLOAD,TBuff,ByteNUM);/发送TBuff数组 SPI1_CE_HIGH();/拉低待机 while(NRF_Read_IRQ()!=0);/中断产生时,IRQ引脚低电平SPI_NRF_Write(SPI1, FLUSH_TX,TBuff,0);SPI1_CE_LOW();/拉低待机Delay_us(100);SPI_NRF_Read(SPI1,R_REGISTER+STATUS,St
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2030年中国电商零售行业市场深度调研及运营模式与投资研究报告
- 2025-2030年中国电动热打码机行业市场发展分析及发展趋势与投资研究报告
- 2025-2030年中国甜菜根糖蜜行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国琼崖海棠油行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国环氧涂料行业市场深度调研及前景趋势与投资研究报告
- 2025-2030年中国牛仔裤行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国烤肉店行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国湿刮行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国清香型白酒行业市场现状供需分析及投资评估规划分析研究报告
- 2025-2030年中国淀粉行业市场发展现状及投资与发展前景研究报告
- 智能海洋牧场装备行业跨境出海战略研究报告
- 麻醉镇静药与阿片类
- 调兵山市招聘社区工作者真题2024
- 2025-2030中国腊味行业发展趋势及发展前景研究报告
- 2025-2030中国手机外壳行业市场发展现状及竞争格局与投资前景研究报告
- 《中型餐饮企业组织结构》课件
- 2025年浙江绍兴诸暨新城投资开发集团有限公司招聘笔试参考题库含答案解析
- 病理学课件-炎症的机制
- 安徽卓越县中联盟2024-2025学年高三下学期5月份检测政治试卷+答案
- 广东省珠海市2024-2025学年下学期期中八年级数学质量监测试卷(含答案)
- 初中美育考试试题及答案
评论
0/150
提交评论