关于NRF24l01的调试

合集下载

nRF24L01 无线模块 说明书

nRF24L01 无线模块 说明书

nRF24L01 无线模块用户手册目录产品概述 (3)基本特性 (3)引脚接口说明 (4)模块尺寸 (6)nRF2401工作模式 (7)Enhanced ShockBurstTM收发模式 (7)Enhanced ShockBurstTM数据发送流程 (8)空闲模式 (9)关机模式 (9)nRF24L01模块参数设置 (9)主要参数设置 (10)程序设计分析 (10)nRF24L01初始化 (10)nRF24L01SPI写操作 (11)nRF24L01 SPI读操作 (11)nRF24L01写寄存器函数 (12)nRF24L01连续读多个寄存器函数 (12)nRF24L01连续写多个寄存器函数 (12)nRF24L01接收模式设置 (13)nRF24L01接收数据流程 (13)nRF24L01发送数据流程 (13)无线应用注意事项 (14)我们的承诺 (15)产品概述nRF24L01是挪威NordicVLSI公司出品的一款新型射频收发器件,采用4 mm×4 mm QFN20封装;nRF24L01工作在ISM频段:2.4~2.524 GHz。

且内置频率合成器、功率放大器、晶体振荡器、调制器等功能,并融合增强型ShockBurst技术,其中地址、输出功率和通信频道可通过程序进行配置,适合用于多机通信。

nRF24L01功耗很低,在以-6 dBm的功率发射时,工作电流也只有9 mA;而对应接收机的工作电流只有12.3 mA,多种低功率工作模式(掉电模式和空闲模式)使节能设计更方便。

nRF24L01在业界领先的低功耗特点使其特别适合采用钮扣电池供电的2.4G应用,整个解决方案包括链路层和MultiCeiver功能提供了比现有的 nRF24XX 更多的功能和更低的电源消耗,与目前的蓝牙技术相比在提供更高速率的同时,而只需花更小的功耗基本特性(1) 2.4Ghz全球开放ISM 频段免许可证使用(2) 最高工作速率2Mbps,高效GFSK调制,抗干扰能力强(3) 125频道,满足多点通信和跳频通信需要(4) 内置硬件CRC 检错和点对多点通信地址控制(5) 低功耗1.9 - 3.6V 工作,适合电池供电应用(6) 待机模式下状态为22uA;掉电模式下为900nA(7) 模块可软件设地址,只有收到本机地址时才会输出数据(提供中断指示),可直接接各种单片机使用,软件编程非常方便(8) 内置专门稳压电路,即使开关电源也有很好的通信效果(9) 标准DIP间距接口,便于嵌入式应用(10)具有自动应答机制,和CRC校验,数据通讯稳定可靠。

nrf24L01配置

nrf24L01配置

CE 输入RX 或TX 模式选择
CSN 输入SPI 片选信号, 低电平使能,硬件不能直接接低电平
SCK 输入SPI 时钟最高8MHZ
MOSI 输入从SPI 数据输入脚
MISO 三态输出从SPI 数据输出脚
IRQ 输出中断低电平使能 TX_DS或MAX_RT或RX_DR高电平,IRQ产生中断低电平
写寄存器只有在掉电模式和待机模式下可操作。

TX模式
填充TX FIFO
PWR_UP=1,PRIM_RX=0,
CE=1(高电平持续时间最小为10us),启动发射
每一条指令的执行都必须通过一次CSN 由高到低的变化
CE一直高,TX FIFO有数据就一直发射,TX FIFO空就进入待机2模式,在这个模式,TX FIFO有数据就进入发送模式开始发送数据。

CE大于10US高脉冲,只能发一包,发完进入待机1模式。

发送数据宽度是动态的吗?
PWR_UP=1,PRIM_RX=1,CE=1启动接收
CE=0进入待机模式1
载波检测cd,跳频,
发送模块没有成功发送数据时,发送端PLOS_CNT显示数据包丢失率太高时可将其设置位接收模式检测CD值如果CD为高说明通道出现了拥挤现象需要更改通信频道
时序
SPI指令,
F340
无线传32字节,是8位一组,4组,
STM32F103
一个8位,一个32位,如何通信
两个的FLASH地址位多了,
SPI接口几位,
如何送到FIFO
测试。

nrf24l01发送接收一体程序(以调通-解决了接收端只能接收一次的问题)

nrf24l01发送接收一体程序(以调通-解决了接收端只能接收一次的问题)

nrf24l01发送接收一体程序(以调通-解决了接收端只能接收一次的问题)基于单片机无线报警系统主机(机载设别)系统程序/**************************************************/#include#include#define uchar unsigned char/***************************************************/#define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址#define TX_PLOAD_WIDTH 4 // 数据通道有效数据宽度uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址uchar RX_BUF[4]={0,0,0,0};uchar TX_BUF[4]={0x20,0x20,0x20,0x20};uchar flag; //无线模块接受数据标志uchar DATA = 0x01;uchar bdata sta;unsigned int a,k; //定时器延时参数uchar mark; //传感器响应标志位uchar mark1; // 延时标志位sbit RX_DR = sta^6; //接受数据成功标志位sbit TX_DS = sta^5; // 发送成功标志位sbit MAX_RT = sta^4; //最大重发上限标志位sbit HW=P2^0; //红外感应模块输入端sbit ZD=P1^7; //震动传感器输入端sbit LED=P2^1; //LED报警器输出端sbit SDA=P2^4; //语音模块数据控制端sbit ONN=P2^3; //语音芯片电源控制端口sbit FM =P2^5; //蜂鸣器/**************************************************函数:delayus()描述:延迟x微秒/**************************************************/void delayus(unsigned int t){while(t--);}函数:delayms()描述:延迟x毫秒/**************************************************/void delayms(unsigned int h){unsigned int j;while(h--)for(j=85;j>0;j--);}/************************************************** 函数:delays()描述:延迟x.xx秒/**************************************************/void delays( float h){unsigned int i,j;h*=100;while(h--){for(i=0;i<235;i++)for(j=0;j<3;j++);}}/************************************************** 函数:sendadd()描述:语音模块发送地址信号/**************************************************/ void sendadd(unsigned char addr){uchar i;SDA=0;delayms(5); /* 数据信号置于低电平5ms */for(i=0;i<8;i++){ SDA=1;if(addr & 1){delayus(60); /* 高电平比低电平为600us:200us,表示发送数据1 */SDA=0;delayus(20);}else{delayus(20);SDA=0; /* 高电平比低电平为200us:600us,表示发送数据0 */ delayus(60);}addr>>=1;}SDA=1;}/**************************************************函数:SPI_RW()描述:根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01 读出一字节/**************************************************/uchar SPI_RW(uchar byte){uchar i;for(i=0; i<8; i++) // 循环8次{MOSI = (byte & 0x80); // byte最高位输出到MOSIbyte <<= 1; // 低一位移位到最高位SCK = 1; // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据byte |= MISO; // 读MISO到byte最低位SCK = 0; // SCK置低}return(byte); // 返回读出的一字节}/**************************************************//**************************************************函数:SPI_RW_Reg()描述:写数据value到reg寄存器/**************************************************/ uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN置低,开始传输数据status = SPI_RW(reg); // 选择寄存器,同时返回状态字SPI_RW(value); // 然后写数据到该寄存器CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/**************************************************函数:clear()描述:清TX_FIFO寄存器/**************************************************/void clear(){CSN=0;SPI_RW(FLUSH_TX);CSN=1;}/**************************************************函数:SPI_Read()描述:从reg寄存器读一字节/**************************************************/ uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器reg_val = SPI_RW(0); // 然后从该寄存器读数据CSN = 1; // CSN拉高,结束数据传输return(reg_val); // 返回寄存器数据}/**************************************************//**************************************************函数:SPI_Read_Buf()描述:从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址/**************************************************/ uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes){uchar status, i;CSN = 0; // CSN置低,开始传输数据status = SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; i<="" p="">pBuf[i] = SPI_RW(0); // 逐个字节从nRF24L01读出CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/**************************************************//**************************************************函数:SPI_Write_Buf()描述:把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址/**************************************************/ uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes){uchar status, i;CSN = 0; // CSN置低,开始传输数据status = SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; i<="" p="">SPI_RW(pBuf[i]); // 逐个字节写入nRF24L01CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/**************************************************函数:RX_Mode()描述:这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包/**************************************************/void RX_Mode(void){CE = 0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F); // CRC使能,16位CRC校验,上电,接收模式CE = 1;delayus(200); // 拉高CE启动接收设备}/**************************************************函数:TX_Mode()描述:这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),130us后启动发射,数据发送结束后,发送模块自动转入接收模式等待应答信号。

一位从厌倦调试NRF24L01无线模块到成功的收发经验分享

一位从厌倦调试NRF24L01无线模块到成功的收发经验分享

一位从厌倦调试NRF24L01无线模块到成功的收发经验分享拿到这对小家伙的时候,距离现在已经有好几个月了吧。

直到大概一个月前,才将它们从抽屉里拿出来。

之所以一直搁置着,是因为想要靠自己来驱动它们。

厌倦了那种拿到模块到处找例程的感觉。

不过,这也让人吃尽了苦头。

熬了多少个夜晚,看了多少遍datasheet,甚至因为实在太困难了,所以索性再次搁在一边,拿了个较为简单的1302寻寻feel。

这一搁置,又过了一个多星期。

大学时间真的太紧张了,各种各样无聊的课占据了平日的大部分时间。

周末,才感觉是为自己活着的日子。

第三次&mdash;&mdash;真正的战役,持续时间并不算长,相对于前两次的铺垫来说。

熬了一个星期的夜,时间总是在不知不觉之间溜走,往往回过神来才发觉,大家都睡下了,已经三四点了。

不过喜欢这宁静的夜,也再一次深深的体会到,走这条路的人是没有夜晚的,因为深夜才是最高效的时间。

不过,这次的收尾工作却是在今天早上进行的。

前天晚上进行最终的测试,两台机都装的自己程序,结果接收机反馈回来乱码,经过昨天一整天的排查才知道是连续读数据函数不能表达。

修修改改忙了一整晚,到昨晚三四点还是没有突破,索性睡个觉。

今早九点,熟睡中一个激灵醒过来,打开电脑再看看,还是不行。

失望中倒头呼呼大睡,十一点再次醒来,牙都还没刷,问题就解决了。

虽然如此,但是心里还是带着小小的疑问,不明白究竟为什么。

这里实现的功能比较简单:通过PC串口给发送端写入要传送的数据(定长32字节),接收端将收到的数据反馈给PC。

由于只有一台电脑,所以只能够同时开两个串口调试窗来观察。

不过这里面的收获也挺多的,例如对C的指针有了较为直观、深刻的感受,再如数据交换函数的写法,还有就是包含串口通信在内所有程序都是参考数据手册写的。

NRF24L01 MSP430调试文档.

NRF24L01 MSP430调试文档.

/****************nrf24l01 fuctions ******************/
void NRF24L01IO_initial(); uchar SPI_RW(uchar byte); uchar SPI_RW_Reg(uchar reg, uchar value); uchar SPI_Read(uchar reg); uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes); uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes); void RX_Mode(void);
#define BIT(x) (1 << (x))
#defefine CSN
5
#define CLK
3
#define MOSI
1
#define MISO
2
#define IRQ
4
/************address width and Pload width******************/
0x00 // Define read command to register 0x20 // Define write command to register 0x61 // Define RX payload register address
// 5 bytes // 1 bytes
#define WR_TX_PLOAD #define FLUSH_TX #define FLUSH_RX #define REUSE_TX_PL #define NOP
2010-7-11 21:33

NRF24L01t调试程序 含发送和接收 可直接用

NRF24L01t调试程序   含发送和接收 可直接用

//***SPI(nRF24L01) 寄存器地址**************************************************** #define CONFIG #define EN_AA 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式 0x01 // 自动应答功能设置
说实话,对于一个初次调试这个模块的同学,想要找一个直接可用的程序不好找,同时是找到的片 段程序很多又是木有注释的,我们(菜鸟)没有很好的理解芯片资料的能力,看着都是一头雾水。 在这儿,我贴出发送和接收两部分,希望可以让学习者轻松一点理解和掌握其操作流程。同时声明 一下,下面的程序不是我写的,但是99%的注释是我写的,对于掌握的人来说,不需要这样多的注 释,我是面对需要学习的人而写的。这样也算是我对电子技术给我的乐趣的回馈。在没有和程序作 所 帮助! 注释的位置需要调整一下哦 以下是发送端程序: #include <reg52.h> #include <intrins.h> #define MODE 0 //MODE=1时为发送代码 typedef unsigned char uchar; //************************************************IO 端口定义***************** sbit MISO = P2^3; sbit MOSI = P2^2; sbit SCK = P2^1; sbit CE = P2^5; sbit CSN = P2^0; sbit IRQ = P3^2; sbit led = P1^2; //***************************************************************************** uchar bdata sta; //状态标志 sbit RX_DR = sta^6; sbit TX_DS = sta^5; sbit MAX_RT = sta^4; MODE=0时为接收代码

nrf24l01使用与调试经验总结(包括一收多发)

nrf24l01使用与调试经验总结(包括一收多发)

nrf24l01使用与调试经验总结(包括一收多发--1主机最多6从机)----------------------------------------------------------------------------------------------------------------------------主要特性工作在2.4GHz ISM 频段调制方式:GFSK/FSK数据速率:2Mbps/1Mbps/250Kbps超低关断功耗:<0.7uA超低待机功耗:<15uA快速启动时间:<130uS内部集成高PSRR LDO宽电源电压范围:1.9-3.6V数字IO 电压: 3.3V/5V低成本晶振:16MHz±60ppm接收灵敏度:<-83dBm @2MHz最高发射功率:7dBm接收电流(2Mbps):<15mA发射电流(2Mbps):<12mA(0dBm)10MHz 四线SPI 模块内部集成智能ARQ 基带协议引擎收发数据硬件中断输出支持1bit RSSI 输出极少外围器件,降低系统应用成本QFN20 封装或COB 封装注意:C代表了命令,S表示寄存器值,D表示数据写数据:SPI写命令+寄存器地址----->SPI写入数据读数据:SPI写寄存器地址(可以使用读命令+寄存器地址)----->SPI读取数据不论是读取或者写入数据,甚至是读/写len长度的数据都要先写寄存器地址;总的来说时候就三个模式:1.待机模式(待机模式+掉电省电模式)2.发送模式3.接受模式具体各个模式介绍参考数据手册。

----------------------------------------------------------------------------------------------------------------nrf发送数据是以包来发送。

nrf24l01调试方法及经验总结

nrf24l01调试方法及经验总结

NRF24L01 :在通信中的应用方法,经验总结(1)2011-07-31 13:15首先说一下:是一款新型单片射频收发器件,工作于 GHz~ GHz ISM频段。

内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块,并融合了增强型ShockBurst技术,其中输出功率和通信频道可通过程序进行配置。

nRF24L01功耗低,在以-6 dBm的功率发射时,工作电流也只有9 mA;接收时,工作电流只有 mA,多种低功率工作模式(掉电模式和空闲模式)使节能设计更方便。

是想将这个IC调通,首先要多读一下技术文档:下载技术文档以下C51驱动的源代码库()此库文件适合发送端使用,在接收端会有所不同,请看第 2 部分的分析在使用过程中,需要引用SCK = 1; uchar |=MISO; then set SCK lowagain } return(uchar); . SPI_RW(reg);reg_val = SPI_RW(0); then read registervalue CSN =1; and write value to it.. CSN =1; // CSN highagain return(status); // return nRF24L01 statusuchar } /****************************************************************************************************/ /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/*************************************************************************************** *************/ uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) { uintstatus,uchar_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW(reg); // Select register to write to and read statusuchar for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++) pBuf[uchar_ctr] =SPI_RW(0); // CSN =1; return(status);// return nRF24L01 statusuchar } /******************************************************************************* ************************** /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) /*功能: 用于写数据:reg为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/*************************************************************************************** ******************/ uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) { uint status,uchar_ctr; CSN = 0; //SPI使能status = SPI_RW(reg); for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++)// SPI_RW(*pBuf++); CSN = 1; //关闭SPI return(status); //} /************************************************************************************ ****************/ /*函数:void SetRX_Mode(void) /*功能:数据接收配置/*************************************************************************************** *************/ void SetRX_Mode(void) { CE=0; SPI_RW_Reg(WRITE_REG + CONFIG,0x0f); // IRQ收发完成中断响应,16位CRC ,主接收CE = 1;inerDelay_us(130); } /************************************************************** ****************************************/ /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) /*功能:数据读取后放如rx_buf接收缓冲区中/*************************************************************************************** ***************/ uchar nRF24L01_RxPacket(unsigned char* rx_buf) { unsigned char revale=0; sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) // 判断是否接收到数据{ Display8bit(3,0,sta); //看一下接收机状态判断一下,IC的工作状态,在正常使用过程中,这句需要去掉 CE =0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer revale =1; //读取数据完成标志} SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志returnrevale; } /***************************************************************************** ****************************** /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf) /*功能:发送 tx_buf中数据/*************************************************************************************** *******************/ void nRF24L01_TxPacket(unsigned char *tx_buf) { CE=0; //StandBy I模式SPI_Write_Buf(WRITE_REG + RX_ADDR_P0,TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址SPI_Write_Buf(WR_TX_PLOAD, tx_buf,TX_PLOAD_WIDTH); // 装载数据SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送SPI_RW_Reg(WRITE_REG+STATUS,0X7E); CE=1; //置高CE,激发数据发送inerDelay_us(100); }NRF24L01 :在通信中的应用方法,经验总结(3)2011-07-31 13:42再接着往下说调试过程:一般拿到IC后最大的困难就是无法知道自己 IC 是否已经工作了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

NRF24l01的调试过程与方法小结心得体会:最近老板给了几块nrf24l01模块我,初次上手难免走了许多的弯路,经过近一周的时间的不断调试,模块之间终于可以相互收发数据了。

这样下来终于松了一口气。

其间的各种辛苦与艰辛难于言表。

上网大致看了一下,网上基于51的调试比较多,但是我们实验室用的是DSP2812,由于nrf24l01是SPI接口,2812上刚好有SPI的接口,这样貌似给使用带来了方便,但是51之类的芯片虽然没有SPI口,但是例程也最多,关于他的讨论比较多。

最开始我的想法也比较混乱,想直接用SPI来调试,把底层函数稍微修改了一下,发现并没有结果,这个东西就像一个黑匣子一样,即看不见也摸不着,后来我慢慢改变了思路。

既然网上基于IO口模拟的SPI的例程最多,我决定另外走一条路,先用2812的IO 口模拟SPI再用自带的SPI口去调试。

这样一来我就有了两条可以走的路。

第一条:底层SPI时序用IO口模拟去写。

第二条:底层直接用2812的SPI去操作。

虽然这样一来,路好走了一点,有各类的程序可以参考,但是这样带来最大的一个问题,这也是后来我才发现的,nrf24l01的最大读写速率是有限制的,2812在150M运行时很显然是太大了一点,由于nrf24l01对时序的要求很高,端口的读写速率和时序都有严格的要求,所以我们才看到,在网上一般是15M左右的单片机来模拟IO口,没有谁用150M的DSP来模拟IO口的,当然既然确定了这样的方法后来也发现了问题,我还是继续走下去了。

很重要的一点是系统的时钟频率。

当然时序的要求也很高,这也就是为什么,网上说这个模块不好调试的原因,既然是调试,当然我们既然是调试,肯定有一个思路和方法。

那么方法是什么呢?开始的时候我是一股脑将发送和接收的程序都写进去,然后啥现象也没有,然后就傻眼了。

在网上看了看,于是有了一点思路。

方法是将发送和接收的调试分开来调试,以读取nrf24l01内部的寄存器为手段,先调试发送方,发送方调试没有问题以后,让发送方不断的发送数据,然后再来调试接收方,直到接收方也没有问题,再接着望下面去做。

秉着这样的一个想法,我开始了调试。

这里我只对一对一的调试进行说明,后续的一对多,以及调频之类虽然我有了想法,但是还没有开始实施。

在开始调试之前建议将NRF24l01说明书读个三遍。

模块的外部端口XL24LD01 是采用挪威N O R D I C 公司的n r f 2 4 L 0 1 2.4G 无线收发IC 设计的一款高性能2.4G无线收发模块,采用GFSK 调制,工作在2400‐2483M 的国际通用ISM 频段,最高调制速率可达2MBPS。

XL24L01-D01 集成了所有与RF 协议相关的高速信号处理部分,如:自动重发丢失数据包和自动产生应答信号等,模块的SPI 接口可以利用单片机的硬件SPI 口连接或用单片机的I/O 口进行模拟,内部有FIFO 可以与各种高低速微处理器接口,便于使用低成本单片机。

在连线的时候要特别注意电源线不要弄反过来了,要注意电源的最大值不能超过3.6V,这个电压直接影响了模块的端口的输出电压值,由于我们的DSP端口的高电平在3.3V,一般将电压设置在这个附近左右。

只有在硬件没有问题的基础上才能开始调试软件,否者会出现很多的问题。

还有一个,工作模式的问题,要注意在待机和掉电的模式下才能够进行寄存器的写操作。

模块内部的寄存器在调试中对寄存器的读取操作是一个非常有效的验证方法。

对芯片资料中给出的23个寄存器内容请看手册。

对应的寄存器在头文件里面。

用IO口模拟SPI的方法头文件如下:#ifndef _NRF24L01_H_#define _NRF24L01_H_#define CPU_RATE 6.667L // for a 150MHz CPU clock speed (SYSCLKOUT)// DO NOT MODIFY THIS LINE.#define DELAY_US(A) DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)//这个函数是在150M下的us级延时函数/*******************************************************/#define TX_ADDR_WITDH 5 //发送地址宽度设置为5个字节#define RX_ADDR_WITDH 5 //接收地址宽度设置为5个字节#define TX_DATA_WITDH 1//发送数据宽度1个字节#define RX_DATA_WITDH 1//接收数据宽度1个字节/*******************命令寄存器***************************/#define R_REGISTER 0x00//读取配置寄存器#define W_REGISTER 0x20//写配置寄存器#define R_RX_PAYLOAD 0x61//读取RX有效数据#define W_TX_PAYLOAD 0xa0//写TX有效数据#define FLUSH_TX 0xe1//清除TXFIFO寄存器#define FLUSH_RX 0xe2//清除RXFIFO寄存器#define REUSE_TX_PL 0xe3//重新使用上一包有效数据#define NOP 0xff//空操作/******************寄存器地址****************************/#define CONFIG 0x00//配置寄存器#define EN_AA 0x01//使能自动应答#define EN_RXADDR 0x02//接收通道使能0-5个通道#define SETUP_AW 0x03//设置数据通道地址宽度3-5#define SETUP_RETR 0x04//建立自动重发#define RF_CH 0x05//射频通道设置#define RF_SETUP 0x06//射频寄存器#define STATUS 0x07//状态寄存器#define OBSERVE_TX 0x08//发送检测寄存器#define CD 0x09//载波#define RX_ADDR_P0 0x0a//数据通道0接收地址#define RX_ADDR_P1 0x0b//数据通道1接收地址#define RX_ADDR_P2 0x0c//数据通道2接收地址#define RX_ADDR_P3 0x0d//数据通道3接收地址#define RX_ADDR_P4 0x0e//数据通道4接收地址#define RX_ADDR_P5 0x0f//数据通道5接收地址#define TX_ADDR 0x10//发送地址#define RX_PW_P0 0x11//P0通道数据宽度设置#define RX_PW_P1 0x12//P1通道数据宽度设置#define RX_PW_P2 0x13//P2通道数据宽度设置#define RX_PW_P3 0x14//P3通道数据宽度设置#define RX_PW_P4 0x15//P4通道数据宽度设置#define RX_PW_P5 0x16//P5通道数据宽度设置#define FIFO_STATUS 0x17//FIFO状态寄存器/*******************相关函数声明**************************/ unchar NRFACK();unchar NRFSPI(unchar date);unchar NRFReadReg(unchar RegAddr);unchar NRFWriteReg(unchar RegAddr,unchar date);unchar NRFReadRxDate(unchar RegAddr,unchar *RxDate,unchar DateLen); unchar NRFWriteTxDate(unchar RegAddr,unchar *TxDate,unchar DateLen); unchar NRFRevDate(unchar *RevDate);void NRFSetTxMode(unchar *TxDate);void NRF24L01Int();void NRFSetRXMode();unchar CheckACK();/**nrf24l01状态寄存器的申明**/struct STA_BITS { // bit descriptionUint16 TX_FULL:1; // 0 FIFO寄存器满标志Uint16 RX_P_NO:3; // 1:3 接收通道号Uint16 MAX_RT:1; // 4 最大重发次数Uint16 TX_DS:1; // 5 数据发送完成标志Uint16 RX_DR:1; // 6 接收数据中断Uint16 rsvd:1; // 7 reserved};union STA_REG {Uint16 all;struct STA_BITS bit;};struct LOOK_BITS { // bit descriptionUint16 bit0:1; // 0Uint16 bit1:1; // 1Uint16 bit2:1; // 2Uint16 bit3:1; // 3Uint16 bit4:1; // 4Uint16 bit5:1; // 5Uint16 bit6:1; // 6Uint16 bit7:1; // 7};union LOOK_REG {Uint16 all;struct LOOK_BITS bit;};/*********************************************************/#endif函数的底层如下:/******************************************创建:那是星期天*时间:2015.4.15*功能:NRF24L01射频模块C文件*****************************************/#include "DSP28_Device.h"#include "NRF24L01.h"//nrf24l01的射频模块的头文件unchar TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址union STA_REG sta={0};/*****************SPI时序函数******************************************/unchar NRFSPI(unchar data){unchar i;for(i=0;i<8;i++) // 循环8次{if(data&0x80)GpioDataRegs.GPADAT.bit.GPIOA3=1;//MOSIelseGpioDataRegs.GPADAT.bit.GPIOA3=0;// byte最高位输出到MISO data<<=1; // 低一位移位到最高位GpioDataRegs.GPADAT.bit.GPIOA1=1;//SCLK=1if(GpioDataRegs.GPADAT.bit.GPIOA2)//MISOdata|=0x01;GpioDataRegs.GPADAT.bit.GPIOA1=0;//SCLK=0}data=data&0x00ff;return(data);//返回读出的一个字节}/**********************NRF24L01初始化函数*******************************/void NRF24L01Int(){DELAY_US(2);//延时2us//让系统什么都不干GpioDataRegs.GPADAT.bit.GPIOA5=0; //ce=0待机模式1GpioDataRegs.GPADAT.bit.GPIOA0=1; //CSN=1;GpioDataRegs.GPADAT.bit.GPIOA1=0;// SCLK=0;GpioDataRegs.GPADAT.bit.GPIOA4=1;// IRQ=1;}/*****************SPI读寄存器一字节函数*********************************/unchar NRFReadReg(unchar RegAddr){unchar BackDate;GpioDataRegs.GPADAT.bit.GPIOA0=0; //CSN=0启动时序NRFSPI(RegAddr);//写寄存器地址BackDate=NRFSPI(0x00);//写入读寄存器指令GpioDataRegs.GPADAT.bit.GPIOA0=1;// CSN=1return(BackDate); //返回状态}/*****************SPI写寄存器一字节函数*********************************/unchar NRFWriteReg(unchar RegAddr,unchar date){unchar BackDate;GpioDataRegs.GPADAT.bit.GPIOA0=0; //CSN=0启动时序BackDate=NRFSPI(RegAddr);//写入地址NRFSPI(date);//写入值GpioDataRegs.GPADAT.bit.GPIOA0=1;// CSN=1return(BackDate);}/*****************SPI读取RXFIFO寄存器的值********************************/unchar NRFReadRxDate(unchar RegAddr,unchar *RxDate,unchar DateLen){ //寄存器地址//读取数据存放变量//读取数据长度//用于接收unchar BackDate,i;GpioDataRegs.GPADAT.bit.GPIOA0=0; //CSN=0启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i<DateLen;i++) //读取数据{RxDate[i]=NRFSPI(0);}GpioDataRegs.GPADAT.bit.GPIOA0=1;// CSN=1return(BackDate);}/*****************SPI写入TXFIFO寄存器的值**********************************/unchar NRFWriteTxDate(unchar RegAddr,unchar *TxDate,unchar DateLen){ //寄存器地址//写入数据存放变量//读取数据长度//用于发送unchar BackDate,i;GpioDataRegs.GPADAT.bit.GPIOA0=0; //CSN=0启动时序BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址for(i=0;i<DateLen;i++)//写入数据{NRFSPI(*TxDate++);}GpioDataRegs.GPADAT.bit.GPIOA0=1;// CSN=1return(BackDate);}/*****************NRF设置为发送模式并发送数据******************************/void NRFSetTxMode(unchar *TxDate){//发送模式GpioDataRegs.GPADAT.bit.GPIOA5=0; //CE=0NRFWriteReg(W_REGISTER+CONFIG,0x00);//在掉电模式中配置寄存器NRFWriteReg(W_REGISTER+FLUSH_TX,0x00);//清除TX FIFO寄存器NRFWriteReg(W_REGISTER+SETUP_AW,0x03);//设置发射地址的宽度为5位 NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WITDH);//写入数据/******下面有关寄存器配置**************/NRFWriteReg(W_REGISTER+EN_AA,0x00);//NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x00);//NRFWriteReg(W_REGISTER+EN _RXADDR,0x01); // 使能接收通道0NRFWriteReg(W_REGISTER+SETUP_RETR,0x00);//NRFWriteReg(W_REGISTER+SE TUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC校验,上电GpioDataRegs.GPADAT.bit.GPIOA5=1;//CE=1DELAY_US(10);//保持10us以上}/*****************NRF设置为接收模式并接收数据******************************///主要接收模式void NRFSetRXMode(){GpioDataRegs.GPADAT.bit.GPIOA5=0;// CE=0;NRFWriteReg(W_REGISTER+CONFIG,0x00);//在掉电模式中配置寄存器NRFWriteReg(W_REGISTER+FLUSH_RX,0x00);//清除TX FIFO寄存器NRFWriteReg(W_REGISTER+SETUP_AW,0x03);//设置发射地址的宽度为5位NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式GpioDataRegs.GPADAT.bit.GPIOA5=1;// CE = 1;DELAY_US(10);//保持10us以上}/****************************检测应答信号******************************/unchar CheckACK(){ //用于发射sta.all=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器// sta.all=NRFReadReg(R_REGISTER+0x17);if(sta.bit.TX_DS||sta.bit.MAX_RT) //发送完毕中断{NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志GpioDataRegs.GPADAT.bit.GPIOA0=0;// CSN=0;NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!不然会出现意想不到的后果!!!大家记住!!GpioDataRegs.GPADAT.bit.GPIOA0=1;// CSN=1;return(0);}elsereturn(1);}/******************判断是否接收收到数据,接到就从RX取出*********************///用于接收模式unchar NRFRevDate(unchar *RevDate){unchar RevFlags=0;sta.all=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器if(sta.bit.RX_DR) // 判断是否接收到数据{GpioDataRegs.GPADAT.bit.GPIOA5=0; // CE=0; //SPI使能NRFReadRxDate(R_RX_PAYLOAD,RevDate,RX_DATA_WITDH);// 从RXFIFO读取数据RevFlags=1; //读取数据完成标志}NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标return(RevFlags);}void InitGpio(void){EALLOW;///设置SPI口外设功能GpioMuxRegs.GPAMUX.bit.PWM1_GPIOA0=0;//CSNGpioMuxRegs.GPAMUX.bit.PWM2_GPIOA1=0;//sckGpioMuxRegs.GPAMUX.bit.PWM3_GPIOA2=0;//MISOGpioMuxRegs.GPAMUX.bit.PWM4_GPIOA3=0;//MOSIGpioMuxRegs.GPAMUX.bit.PWM5_GPIOA4=0;//IRQGpioMuxRegs.GPAMUX.bit.PWM6_GPIOA5=0;//CEGpioMuxRegs.GPADIR.bit.GPIOA0=1;GpioMuxRegs.GPADIR.bit.GPIOA1=1;GpioMuxRegs.GPADIR.bit.GPIOA2=0; //MISO为输入GpioMuxRegs.GPADIR.bit.GPIOA3=1;GpioMuxRegs.GPADIR.bit.GPIOA4=1;GpioMuxRegs.GPADIR.bit.GPIOA5=1;EDIS;}主函数中包涵了调试的内容:#include "DSP28_Device.h"#include "NRF24L01.h"void WriteLED(unchar data); //点亮LED2函数unchar TxDate[4];union LOOK_REG look0={0};union LOOK_REG look1={0};union LOOK_REG look2={0};union LOOK_REG look3={0};union LOOK_REG look4={0};union LOOK_REG look5={0};union LOOK_REG look6={0};union LOOK_REG look7={0}; union LOOK_REG look8={0}; union LOOK_REG look9={0}; union LOOK_REG look10={0}; union LOOK_REG look11={0}; union LOOK_REG look12={0}; union LOOK_REG look13={0}; union LOOK_REG look14={0}; union LOOK_REG look15={0}; union LOOK_REG look16={0}; union LOOK_REG look17={0}; union LOOK_REG look18={0}; union LOOK_REG look19={0}; union LOOK_REG look20={0}; union LOOK_REG look21={0}; union LOOK_REG look22={0}; union LOOK_REG look23={0};void main(void){/*初始化系统*/InitSysCtrl();/* 关中断*/DINT;IER = 0x0000;IFR = 0x0000;/* 初始化PIE控制寄存器*/InitPieCtrl();/* 初始化PIE参数表*/InitPieVectTable();/* 初始化外设寄存器*/InitGpio();InitSpi();/*设置CPU*/EINT; // 开全局中断ERTM; // 开实时中断NRF24L01Int();while(1){int ReadTempDate=6;TxDate[0]=ReadTempDate;// TxDate[1]=0;//TxDate[2]=0;//TxDate[3]=0;NRFSetTxMode(TxDate);//发数据while(CheckACK()); //检测是否发送完毕// GpioDataRegs.GPADAT.bit.GPIOA0=1;look0.all=NRFReadReg(R_REGISTER+0x00);look1.all=NRFReadReg(R_REGISTER+0x01);look2.all=NRFReadReg(R_REGISTER+0x02);look3.all=NRFReadReg(R_REGISTER+0x03);look4.all=NRFReadReg(R_REGISTER+0x04);look5.all=NRFReadReg(R_REGISTER+0x05);look6.all=NRFReadReg(R_REGISTER+0x06);look7.all=NRFReadReg(R_REGISTER+0x07);look8.all=NRFReadReg(R_REGISTER+0x08);look9.all=NRFReadReg(R_REGISTER+0x09);look10.all=NRFReadReg(R_REGISTER+0x0a);look11.all=NRFReadReg(R_REGISTER+0x0b);look12.all=NRFReadReg(R_REGISTER+0x0c);look13.all=NRFReadReg(R_REGISTER+0x0d);look14.all=NRFReadReg(R_REGISTER+0x0e);look15.all=NRFReadReg(R_REGISTER+0x0f);look16.all=NRFReadReg(R_REGISTER+0x10);look17.all=NRFReadReg(R_REGISTER+0x11);look18.all=NRFReadReg(R_REGISTER+0x12);look19.all=NRFReadReg(R_REGISTER+0x13);look20.all=NRFReadReg(R_REGISTER+0x14);look21.all=NRFReadReg(R_REGISTER+0x15);look22.all=NRFReadReg(R_REGISTER+0x16);look23.all=NRFReadReg(R_REGISTER+0x17);TxDate[0]=ReadTempDate;}}/******************************************************************** **********名称:WriteLED()**功能:接收到的数据点亮LED**入口参数:char data,需要发送的数据**出口参数:无********************************************************************** *******/void WriteLED(unchar data){int n,j;for(n=0;n<data;n++){GpioDataRegs.GPFDAT.bit.GPIOF8=1;for(j=0;j<10000;j++);GpioDataRegs.GPFDAT.bit.GPIOF8=0;for(j=0;j<10000;j++);}}SPI接口直接调试的方法DSP2812的SPI的调试是nrf24l01的第一步,2812的spi在读写nrf24l01过程中会出现写入数据的错误,这个也是后来我用示波器观测的时候发现的现象,一切的调试都是建立在SPI的底层函数上,SPI有问题那么对24l01的操作就会出现问题,在我的调试过程中就发现这样的问题,我不知道这种问题是不是共性,但是SPI的调试出现问题无线收发模块就有问题。

相关文档
最新文档