求助 nRF24L01 + 51单片机 测试程序 附源代码
麻烦各位专家赐教,NRF24L01的实验程序调了一周了,还是不能通信,两天后就要,时间很紧,万请帮忙
用单片机是STC89LE58RD 3.3V的单片机
一端发送,一端接收
现在知道硬件肯定没问题
发送端和接收端的NRF24L01的寄存器已经正常读写,
发送端FIFO_STATUS在启动发送前后由不空变空,证明已经发送出去
但是接收端检测不到载波信号
附上源代码 /***以下为接收***/
#include <REGX52.H>
#include <INTRINS.H> //for funtion _NOP_
#include <STDIO.H>
/***自定义数据类型声明***/
typedef unsigned char uchar;
typedef unsigned int uint;
/***宏定义***/
#define TRANSMIT_LED 1
#define RECEIVE_LED 0
#define LEDDATA P0
#define SCAN_CYCLE 500 //数码管动态扫描间隔
#define TIMER1 0xe6 //256-(110592/(12*32*96))
#define TIMER0H (65535-SCAN_CYCLE)/256
#define TIMER0L (65535-SCAN_CYCLE)%256 //定时3MSVR3*FOSC/12/1000
/***I/O口定义***/
sbit MISO =P1^6;
sbit MOSI =P1^5;
sbit SCK =P1^7;
sbit CE =P1^3;
sbit CSN =P1^4;
sbit IRQ =P3^2;
sbit LED0 =P2^0;
sbit LED1 =P2^1;
/***显示及接收数据数组***/
code uchar TxBuf=
{
0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};
code uchar RxBuf={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
uchar CheckBuf=
{
0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
};
uchar dis_buf={0x00,0x00}; //显示数组
code uchar LED7Code[]={
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90, // 9
0x88, // A
0x83, // B
0xC6, // C
0xA1, // D
0x86, // E
0x8E, // F
0xFF, //熄灭
};
/***NRF24L01***/
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH32 // 32 uints TX payload
#define RX_PLOAD_WIDTH32 // 32 uints TX payload
uchar const TX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uchar const RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //接收地址
/***NRF24L01寄存器指令***/
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
/***SPI(nRF24L01)寄存器地址***/
#define CONFIG 0x00// 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01// 自动应答功能设置
#define EN_RXADDR 0x02// 可用信道设置
#define SETUP_AW 0x03// 收发地址宽度设置 11 0x03 5bytes
#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// 接收频道0接收数据长度
#define RX_PW_P1 0x12// 接收频道0接收数据长度
#define RX_PW_P2 0x13// 接收频道0接收数据长度
#define RX_PW_P3 0x14// 接收频道0接收数据长度
#define RX_PW_P4 0x15// 接收频道0接收数据长度
#define RX_PW_P5 0x16// 接收频道0接收数据长度
#define FIFO_STATUS 0x17// FIFO栈入栈出状态寄存器设置
/***NRF24L01状态标志***/
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
uchar flag;
/***函数声明***/
void Delayms(uint s);
void Delayus(uchar n);
void InitTimer(void);
void InitUART(void);
void InitNRF24L01(void);
void SetRXMode(void);
uchar SPI_RW(uchar); //NRF24L01的SPI写时序;写一个字节到24l01,同时读出一个字节
uchar SPI_Read(uchar reg); //NRF24L01的SPI读时序
uchar SPI_Read_Reg(uchar reg);//从寄存器reg读一个字节
uchar SPI_RW_Reg(uchar reg, uchar value);//向寄存器reg写一个字节,同时返回状态字节
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes); //从寄存器reg读出bytes个字节,通常用来读取接收通道数据或发送地址
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes);//把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址
uchar nRF24L01_RxPacket(uchar *rx_buf); //接收函数,返回1收到,
void nRF24L01_TxPacket(uchar *tx_buf); //发送函数
/**********************************************************************
函数:void Delay(uint s)
描述:
**********************************************************************/
void Delayms(uint s)
{
unsigned int i,j;
for(i=0; i<s; i++);
for(j=0; j<12; j++);
}
/**********************************************************************
函数:void Delayus(uchar n)
描述:短延时函数,延时9n+4 us
**********************************************************************/
void Delayus(uchar n)
{
for(;n>0;n--)
_nop_();
}
/*****************************************************************************************
函数:void InitTimer(void)
描述:定时器0初始化程序
*****************************************************************************************/
void InitTimer(void)
{
TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1
TH0 = TIMER0H; //设定T0每隔SCAN_CYCLE us中断一次
TL0 = TIMER0L;
IE=0x82; //|EA|-|ET2|ES|ET1|EX1|ET0|EX0|
//ET0 = 1; //定时器0中断允许
//EA = 1; //开全局中断
TF0 = 0; //中断标志重置
TR0 = 1; //启动定时器0
}
/*****************************************************************************************
函数:void InitUART(void)
描述:串口初始化程序
*****************************************************************************************/
void InitUART(void) //波特率9600
{
SCON = 0x50; //串口方式1,允许接收
// TI=1;
TH1 = TIMER1;
TL1 = TIMER1;
PCON = 0x00;
TR1 = 1; //启动定时器1
}
/****************************************************************************************
函数:void InitNRF24L01(void)
描述:NRF24L01初始化
****************************************************************************************/
void InitNRF24L01(void)
{
Delayus(100);
CE= 0; // 待机
CSN = 1; // SPI禁止
SCK = 0; // SPI时钟置低
IRQ = 1; // 中断复位
}
/**************************************************
函数:SetRXMode()
描述:设置nRF24L01为接收模式,等待接收发送设备的数据包
**************************************************/
void SetRXMode(void)
{
CE = 0; //Standby-1
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);// 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);// 接收设备接收通道0使用和发送设备相同的发送地址
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 使能接收通道0
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 使能接收通道0自动应答
SPI_RW_Reg(WRITE_REG + RF_CH, 0x00); // 选择射频通道0x00
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);// 接收通道0选择和发送通道相同有效数据宽度
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // CRC使能,16位CRC校验,上电,接收模式
CE = 1; // 拉高CE启动接收设备
Delayus(130); // Standby-1 to RXMode need 130us
}
/******************************************************************************************************
函数:uchar nRF24L01_RxPacket(uchar *rx_buf)
描述:数据读取后放入rx_buf接收缓冲区中
******************************************************************************************************/
uchar nRF24L01_RxPacket(uchar *rx_buf)
{
uchar revale=0;
sta=SPI_Read_Reg(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
CE = 0; //Stand by
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来清除中断标志
return revale;
}
/****************************************************************************************************
函数:uint SPI_RW(uint uchar)
描述:NRF24L01的SPI写时序
/****************************************************************************************************/
uchar SPI_RW(uchar uch)
{
uint bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI = (uch & 0x80); // output 'uchar', MSB to MOSI
uch = (uch << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
uch |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(uch); // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI读时序
/****************************************************************************************************/
uchar SPI_Read_Reg(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
/****************************************************************************************************
函数:uint SPI_RW_Reg(uchar reg, uchar value)
描述:NRF24L01读写寄存器函数
****************************************************************************************************/
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status uchar
}
/****************************************************************************************************
函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,bytes:读出数据的个数
****************************************************************************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uint status,uchar_ctr;
CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status uchar
for(uchar_ctr=0;uchar_ctr<bytes;uchar_ctr++)
pBuf = SPI_RW(0); //
CSN = 1;
return(status); // return nRF24L01 status uchar
}
/*****************************************************************************************************
函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,bytes:写入数据的个数
*****************************************************************************************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
{
uchar status,uchar_ctr;
CSN = 0; //SPI使能
status = SPI_RW(reg);
for(uchar_ctr=0; uchar_ctr<bytes; uchar_ctr++) //
SPI_RW(*pBuf++);
CSN = 1; //关闭SPI
return(status); //
}
/************************************************************************
函数:void ScanSeg7()
描述:数码管扫描显示
************************************************************************/
void ScanSeg7() //数码管扫描显示,一次扫描一位数码管
{
static uchar scanCounter=0;
LED1=1;
LED0=1;
if(scanCounter==RECEIVE_LED)
{
LEDDATA=dis_buf;
LED0=0;
scanCounter=TRANSMIT_LED;
}
else //scanCounter=TRANSMIT_LED
{
LEDDATA=dis_buf;
LED1=0;
scanCounter=RECEIVE_LED;
}
}
/************************************************************************
函数:void Timer0_OverFlow()interrupt 1
描述:Timer0溢出中断,用于数码管动态扫描定时
************************************************************************/
void Timer0_OverFlow()interrupt 1 //500us中断一次
{
ScanSeg7(); //扫描数码管
TH0=(65536-SCAN_CYCLE)/256; //设定Timer0每隔SCAN_CYCLE us中断一次
TL0=(65536-SCAN_CYCLE)%256;
TF0=0; //定时器0中断标志位清零
}
/*****************************************************
函数:bit ErrorCheck(void)
描述:错误校验程序,检查收到的数据包是否正确
*****************************************************/
uchar ErrorCheck(void)
{
uchar i;
for(i=0;i<32;i++)
{
if(RxBuf!=TxBuf)
return 1;
}
return 0;
}
/************************************************************************
函数:void R_S_Byte(uchar R_Byte)
描述:通过串口将接收到数据发送给PC端
************************************************************************/
void R_S_Byte(uchar R_Byte)
{
SBUF = R_Byte;
while( TI == 0 ); //查询法
TI = 0;
}
/************************************************************************
函数:void main(void)
描述:主函数
************************************************************************/
void main(void)
{
int i;
uchar rabuf={0};
uchar tabuf={0};
InitTimer(); //Timer初始化
InitUART(); //串口初始化
InitNRF24L01(); //24l01初始化
LED0=1;
LED1=1;
//dis_buf=LED7Code;
//dis_buf=LED7Code;
//while(1);
SetRXMode(); //进入接收模式
/* TI=1;
printf("CONFIG=0x%x\n",(int)SPI_Read_Reg(CONFIG));
printf("EN_AA=0x%x\n",(int)SPI_Read_Reg(EN_AA));
printf("EN_RXADDR=0x%x\n",(int)SPI_Read_Reg(EN_RXADDR));
printf("SETUP_AW=0x%x\n",(int)SPI_Read_Reg(SETUP_AW));
printf("SETUP_RETR=0x%x\n",(int)SPI_Read_Reg(SETUP_RETR));
printf("RF_CH=0x%x\n",(int)SPI_Read_Reg(RF_CH));
printf("RF_SETUP=0x%x\n",(int)SPI_Read_Reg(RF_SETUP));
printf("STATUS=0x%x\n",(int)SPI_Read_Reg(STATUS));
printf("OBSERVE_TX=0x%x\n",(int)SPI_Read_Reg(OBSERVE_TX));
printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
SPI_Read_Buf(TX_ADDR,tabuf,5);
for(i=0;i<5;i++)
printf("tabuf[%d]=0x%x\n",i,(int)tabuf);
SPI_Read_Buf(RX_ADDR_P0,rabuf,5);
for(i=0;i<5;i++)
printf("rabuf[%d]=0x%x\n",i,(int)rabuf);
SPI_RW(FLUSH_RX);
SPI_RW(FLUSH_TX);
Delayus(2);
*/
do
{
//if(RX_DR)
//printf("%s\n","rs");
nRF24L01_RxPacket(RxBuf);
//SPI_Read_Buf(RD_RX_PLOAD,RxBuf,TX_PLOAD_WIDTH);
// if(nRF24L01_RxPacket(RxBuf))
// printf("DataReceived\n");
// printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
for(i=0;i<32;i++)
printf("RxBuf[%d]=0x%x\n",i,(int)RxBuf);
if(ErrorCheck())
{
dis_buf=LED7Code;
dis_buf=LED7Code;
}
else
{
dis_buf=LED7Code;
dis_buf=LED7Code;
}
}
while(IRQ == 0);
//dis_buf=LED7Code;
//dis_buf=LED7Code;
// while(IRQ==0) //发送完毕,
// R_S_Byte(&RxBuf);
// while(1)
// printf("CD=0x%x",(int)SPI_Read_Reg(CD));
}
/* if(nRF24L01_RxPacket(RxBuf))
{
for(i=0;i<32;i++)
{
R_S_Byte(RxBuf);
Delayms(600);
}
}
*/
/*
while(1)
{
sta = SPI_Read(STATUS); // 读状态寄存器
if(RX_DR) // 判断是否接受到数据
{
SPI_Read_Buf(RD_RX_PLOAD, RxBuf, TX_PLOAD_WIDTH);// 从RX FIFO读出数据
flag = 1;
}
SPI_RW_Reg(WRITE_REG + STATUS, sta);// 清除RX_DS中断标志
if(flag) // 接受完成
{
flag = 0; // 清标志
LED = RxBuf; // 数据送到LED显示
Delayms(250);
Delayms(250);
LED = 0xff; // 关闭LED
}
}
*/
/* if(nRF24L01_RxPacket(RxBuf))
{
temp++;
for(i=0;i<32;i++)
{
R_S_Byte(RxBuf);
Delay(600);
}
}
*/ /***以下为发送***/
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
typedef unsigned char uchar;
typedef unsigned char uint;
//****************************************IO端口定义***************************************
#define TRANSMIT_LED 1
#define RECEIVE_LED 0
#define LEDDATA P0
#define SCAN_CYCLE 500
#define TIMER0H (65535-SCAN_CYCLE)/256
#define TIMER0L (65535-SCAN_CYCLE)%256 //定时3MSVR3*FOSC/12/1000
uchar dis_buf={0x00,0x00}; //显示数组
sbit MISO =P1^6;
sbit MOSI =P1^5;
sbit SCK =P1^7;
sbit CE =P1^3;
sbit CSN =P1^4;
sbit IRQ =P3^2;
//***********************************数码管0-F编码*******************************************
const unsigned char LED7Code[]={
0xC0, // 0
0xF9, // 1
0xA4, // 2
0xB0, // 3
0x99, // 4
0x92, // 5
0x82, // 6
0xF8, // 7
0x80, // 8
0x90, // 9
0x88, // A
0x83, // B
0xC6, // C
0xA1, // D
0x86, // E
0x8E, // F
0xFF, //熄灭
};
code uchar TxBuf=
{
0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,
0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,
0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,
}; //
//***********************************数码管位选**************************************************
sbit LED1=P2^1;
sbit LED0=P2^0;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH 5 // 5 uints TX address width
#define RX_ADR_WIDTH 5 // 5 uints RX address width
#define TX_PLOAD_WIDTH32 // 20 uints TX payload
#define RX_PLOAD_WIDTH32 // 20 uints TX payload
uint const TX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //本地地址
uint const RX_ADDRESS= {0x34,0x43,0x10,0x10,0x01}; //接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG 0x00 // 读寄存器指令
#define WRITE_REG 0x20 // 写寄存器指令
#define RD_RX_PLOAD 0x61 // 读取接收数据指令
#define WR_TX_PLOAD 0xA0 // 写待发数据指令
#define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令
#define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令
#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令
#define NOP 0xFF // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG 0x00// 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA 0x01// 自动应答功能设置
#define EN_RXADDR 0x02// 可用信道设置
#define SETUP_AW 0x03// 收发地址宽度设置
#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// 接收频道0接收数据长度
#define RX_PW_P1 0x12// 接收频道0接收数据长度
#define RX_PW_P2 0x13// 接收频道0接收数据长度
#define RX_PW_P3 0x14// 接收频道0接收数据长度
#define RX_PW_P4 0x15// 接收频道0接收数据长度
#define RX_PW_P5 0x16// 接收频道0接收数据长度
#define FIFO_STATUS 0x17// FIFO栈入栈出状态寄存器设置
//**************************************************************************************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uchar SPI_RW(uchar uch);
uchar SPI_Read_Reg(uchar reg);
void SetRX_Mode(void);
uchar SPI_RW_Reg(uchar reg, uchar value);
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
uchar nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//*****************************************长延时*****************************************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
//******************************************************************************************
uint bdata sta; //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/******************************************************************************************
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
_nop_();
}
/*****************************************************************************************
函数:void InitTimer(void)
描述:定时器0初始化程序
*****************************************************************************************/
void InitTimer(void)
{
TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1
TH0 = TIMER0H; //设定T0每隔SCAN_CYCLE us中断一次
TL0 = TIMER0L;
IE=0x82; //|EA|-|ET2|ES|ET1|EX1|ET0|EX0|
//ET0 = 1; //定时器0中断允许
//EA = 1; //开全局中断
TF0 = 0; //中断标志重置
TR0 = 1; //启动定时器0
}
/*****************************************************************************************
函数:void InitUART(void)
描述:串口初始化程序
*****************************************************************************************/
void InitUART(void) //波特率9600
{
SCON = 0x50; //串口方式1,允许接收
TI=1;
// TH1 = 0xe5; //12 The byte rate is 1200
// TL1 = 0xe5;
TH1 = 0xe8; //11.0592 The byte rate is 1200
TL1 = 0xe8;
PCON = 0x00;
TR1 = 1; //启动定时器1
}
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
inerDelay_us(100);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0; // Spi clock line init low
IRQ = 1; // 中断复位
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写读时序
/****************************************************************************************************/
uchar SPI_RW(uchar uch)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
{
MOSI = (uch & 0x80); // output 'uchar', MSB to MOSI
uch = (uch << 1); // shift next bit into MSB..
SCK = 1; // Set SCK high..
uch |= MISO; // capture current MISO bit
SCK = 0; // ..then set SCK low again
}
return(uch); // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:读NRF24L01的寄存器
/****************************************************************************************************/
uchar SPI_Read_Reg(uchar reg)
{
uchar reg_val;
CSN = 0; // CSN low, initialize SPI communication...
SPI_RW(reg); // Select register to read from..
reg_val = SPI_RW(0); // ..then read registervalue
CSN = 1; // CSN high, terminate SPI communication
return(reg_val); // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01写寄存器函数
/****************************************************************************************************/
uchar SPI_RW_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0; // CSN low, init SPI transaction
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN = 1; // CSN high again
return(status); // return nRF24L01 status uchar
}
/****************************************************************************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uchar status,uchar_ctr;
CSN = 0; // Set CSN low, init SPI tranaction
status = SPI_RW(reg); // Select register to write to and read status uchar
for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
pBuf = SPI_RW(0); //
CSN = 1;
return(status); // return nRF24L01 status uchar
}
/*********************************************************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:reg为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uchar 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 SetTxMode(void)
/*功能:数据发送配置
/****************************************************************************************************/
void SetTxMode(void)
{
CE=0;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
//SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //频道0自动 ACK应答允许
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);//允许接收地址只有频道0,如果需要多频道可以参考Page21
//SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 0x00); // 设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
SPI_RW_Reg(WRITE_REG + STATUS, 0x7e); //写状态寄存器
}
/****************************************************************************************************/
/*函数: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_Reg(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR) // 判断是否接收到数据
{
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来清楚中断标志
return revale;
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
int i;
//CE=0; //StandBy I模式
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
printf("Load data\n");
printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
SPI_Read_Buf(WR_TX_PLOAD,TxBuf,TX_PLOAD_WIDTH);
for(i=0;i<32;i++)
{
printf("TxBuf[%d]=0x%x\n",i,(int)TxBuf);
}
// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
// SPI_RW(REUSE_TX_PL);
CE=1; //置高CE,激发数据发送
inerDelay_us(10);
inerDelay_us(130);
}
//************************************************************************************************
void ScanSeg7() //数码管扫描显示,一次扫描一位数码管
{
static uchar scanCounter=0;
LED1=1;
LED0=1;
if(scanCounter==RECEIVE_LED)
{
LEDDATA=dis_buf;
LED0=0;
scanCounter=TRANSMIT_LED;
}else //scanCounter=TRANSMIT_LED
{
LEDDATA=dis_buf;
LED1=0;
scanCounter=RECEIVE_LED;
}
}
//*********************************************************************************************************
void Timer0_OverFlow()interrupt 1 //500us中断一次
{
ScanSeg7(); //扫描数码管
TH0=(65536-SCAN_CYCLE)/256; //设定Timer0每隔SCAN_CYCLE us中断一次
TL0=(65536-SCAN_CYCLE)%256;
//TF0=0; //定时器0中断标志位清零
}
/********************************
check_ACK();
********************************/
void check_ACK()
{
uchar test;
test=SPI_Read_Reg(READ_REG+STATUS); // read register STATUS's
test=test&0x20; // check if have Data sent TX FIFO interrupt (TX_DS=1)
if(test==0x20) // TX_DS =1
{
P0=0x00; // turn on all led
Delay(100); // delay 100ms
P0=0xff;
}
}
//************************************主函数************************************************************
void main(void)
{
uchar tabuf={0};
uchar rabuf={0};
int i ;
InitTimer(); //Timer初始化
InitUART(); //串口初始化
init_NRF24L01();
SetTxMode();
Delay(1000);
printf("CONFIG=0x%x\n",(int)SPI_Read_Reg(CONFIG));
printf("EN_AA=0x%x\n",(int)SPI_Read_Reg(EN_AA));
printf("EN_RXADDR=0x%x\n",(int)SPI_Read_Reg(EN_RXADDR));
printf("SETUP_AW=0x%x\n",(int)SPI_Read_Reg(SETUP_AW));
printf("SETUP_RETR=0x%x\n",(int)SPI_Read_Reg(SETUP_RETR));
printf("RF_CH=0x%x\n",(int)SPI_Read_Reg(RF_CH));
printf("RF_SETUP=0x%x\n",(int)SPI_Read_Reg(RF_SETUP));
printf("STATUS=0x%x\n",(int)SPI_Read_Reg(STATUS));
printf("OBSERVE_TX=0x%x\n",(int)SPI_Read_Reg(OBSERVE_TX));
printf("CD=0x%x\n",(int)SPI_Read_Reg(CD));
printf("TX_ADDR=0x%x\n",(int)SPI_Read_Reg(TX_ADDR));
SPI_Read_Buf(TX_ADDR,tabuf,TX_ADR_WIDTH);
for(i=0;i<5;i++){
printf("tabuf[%d]=0x%x\n",i,(int)tabuf);
}
SPI_Read_Buf(RX_ADDR_P0,rabuf,TX_ADR_WIDTH);
for(i=0;i<5;i++){
printf("rabuf[%d]=0x%x\n",i,(int)rabuf);
}
LED0=0;
LED1=0;
P0=0x00;
dis_buf=LED7Code;
dis_buf=LED7Code;
printf("SetTxMode\n");
printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
while(1)
{
printf("Enter while(1)\n");
do
{
// printf("IRQ==0\n");
nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer data
printf("transmit\n");
printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
SPI_Read_Buf(WR_TX_PLOAD,TxBuf,TX_PLOAD_WIDTH);
for(i=0;i<32;i++)
{
printf("TxBuf[%d]=0x%x\n",i,(int)TxBuf);
}
// check_ACK();
Delay(6000);
// printf("Transmit\n");
}while(IRQ==0);
while(IRQ!=0)
{
printf("IRQ!=0\n");
printf("FIFO_STATUS=0x%x\n",(int)SPI_Read_Reg(FIFO_STATUS));
};
}
} 你买的哪家的东西?
直接找他们技术支持啊 方便留个联系方式么, profcole,我也正在玩这个无线,交流,交流,我的QQ:512582511 mark 学习了 mark thanks 加我吧。看你们这么辛苦 mark 哇,真厉害啊 楼主自己写的吗 点击此处下载 ourdev_581189UYLUE2.pdf(文件大小:300K) (原文件名:Moreway-RF24L01.pdf)
点击此处下载 ourdev_581190YR3W9F.rar(文件大小:58K) (原文件名:Moreway1000_NRF24L01.rar) MARK 标记 我也在做,程序烦啊。。。。 ding qi 我也玩24L01了 需要仿真机么…… 直接用AT89S52控制的人飘过。。。 mark NRF24L01/NRF24L01+
无线不在神秘 零难度入门
买回就可以看到通信效果
第一次应用和初学者不在为无线迷茫
感性认识+理性分析-->轻松驾驭NRF24L01+
NRF24L01/NRF24L01+是挪威NordicVLSI公司出品的一款新型射频收发器件,采用4 mm×4 mmQFN20封装;NRF24L01/NRF24L01+工作在ISM频段:2.4~2.524 GHz。且内置频率合成器、功率放大器、晶体振荡器、调制器等功能,并融合增强型ShockBurst技术,其中地址、输出功率和通信频道可通过程序进行配置,适合用于多机通信。NRF24L01/NRF24L01+功耗很低,在以-6 dBm的功率发射时,工作电流也只有9 mA;而对应接收机的工作电流只有12.3 mA,多种低功率工作模式(掉电模式和空闲模式)使节能设计更方便。NRF24L01/NRF24L01+在业界领先的低功耗特点使其特别适合采用钮扣电池供电的2.4G应用,整个解决方案包括链路层和MultiCeiver功能提供了比现有的nRF24XX更多的功能和更低的电源消耗,与目前的蓝牙技术相比在提供更高速率的同时,而只需花更小的功耗.最新采用的nRF24L01+与nRF24L01兼容,并增加250kbps低速功能。
详细点连接:http://item.taobao.com/item.htm?id=10096264698
让我们想的更多,做的更到位,你的无线应用更轻松,更简单
点击此处下载 ourdev_632805VFO9Y3.pdf(文件大小:1.49M) (原文件名:JASK51-24L01模块使用手册.pdf)
点击此处下载 ourdev_632806C18V47.pdf(文件大小:1.56M) (原文件名:USB-TTL模块使用手册.pdf)
点击此处下载 ourdev_632781Z4RW87.pdf(文件大小:462K) (原文件名:nRF24L01芯片文档.pdf)
点击此处下载 ourdev_632782PCXG7E.pdf(文件大小:1.08M) (原文件名:nRF24L01+.pdf)
http://cache.amobbs.com/bbs_upload782111/files_38/ourdev_632807HEM7M6.JPG
(原文件名:DSC02404.JPG) 好东西,标记下! 2.4g这个东西时需要慢慢一点一点调试的,第一次我调试两天出来效果了,但是一个月之后,当我需要用的时候,连续调试三天都没有出来,估计是模块烧了,建议;楼主在其引脚与单片机的io口加个限流电阻试一下效果。其它的就是看看接收的有没有存储在寄存器中,再看处理的是否有问题,一点一点的调试 这个,如果是51做的话,不用加限流电阻,我说的是89s52,如果avr的话,一定加,否则,直接烧。我有个经过测试的,当时无线模块是自己买的8引脚,其实10引脚就多了两个GND,一样的,我经过运行,好使的。lz要的话,加qq向我要吧。 我的没有调试出来,烦啊!用的LM3S的芯片 mark 郁闷啊,我的芯片都坏几块了。
23楼得兄弟,模块烧了是怎么个现象。
我的是上电时IRQ输出直接是低了,要么MISO有数据输出,我怀疑是芯片坏掉了,单片机用的是PIC的,没加限流电阻,电源使用的是3.3V的 回复【楼主位】profcole
-----------------------------------------------------------------------
楼主翻翻坛子里面关于NRF24L01的帖子。。。 我可以帮你搞的QQ475485272 回复【26楼】jiabin1024
-----------------------------------------------------------------------
注意检查电路 我也为这个郁闷 mark~~~~ 楼主辛苦了,不错的源码。 很好的源代码,中断那里受教了,无线部分期待有人能为楼主解答。 MARK,学习!
页:
[1]