网购了两个nRF24l01模块,想做无线收发功能,控制器分别为89C52和STC12c5A60s2,无线模块接口接在P0口,IRQ接到单片机P3^2,求助,接收端收不到信息,附程序,求大神解释一下~~~~~好几天还没解决;
接收端程序:
#include
#include
#define uint unsigned int
#define uchar unsigned char
#define LED P1
***it key=P3^7;
/***************************************************/
#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[TX_PLOAD_WIDTH];
uchar TX_BUF[TX_PLOAD_WIDTH];
uchar flag;
uchar DATA = 0x01;
uchar bdata sta;
***it RX_DR = sta^6;
***it TX_DS = sta^5;
***it MAX_RT = sta^4;
/**************************************************
函数: init_io()
描述:
初始化IO
/**************************************************/
void init_io(void)
{
CE = 0; // 待机
CSN = 1; // SPI禁止
SCK = 0; // SPI时钟置低
IRQ = 1; // 中断复位
// LED = 0xff; // 关闭指示灯
}
/**************************************************
函数:delay()
描述:延时函数
**************************************************/
void delay(uint z)
{
uint x;
while(z--)
for(x=110;x>0;x--);
}
/**************************************************
函数:SPI_RW()
描述:
根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01
读出一字节
/**************************************************/
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
MOSI=(byte&0x80);
byte<<=1;
SCK=1;
byte|=MISO;
SCK=0;
}
return (byte);
}
/**************************************************
函数:SPI_RW_Reg()
描述:
写数据value到reg寄存器
/**************************************************/
uchar SPI_RW_REG(uchar reg,uchar value)
{
uchar status;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return(status);
}
/**************************************************
函数:SPI_Read()
描述:
从reg寄存器读一字节
/**************************************************/
uchar SPI_READ(uchar reg)
{
uchar status,reg_val;
CSN=0;
SPI_RW(reg);
reg_val=SPI_RW(0);
CSN=1;
return(status);
}
/**************************************************
函数:SPI_Read_Buf()
描述:
从reg寄存器读出bytes个字节,通常用来读取接收通道
数据或接收/发送地址
/**************************************************/
uchar SPI_READ_BUF(uchar reg,uchar *pBUF,uchar byte)
{
uchar status,i;
CSN=0;
status=SPI_RW(reg);
for(i=0;i
{
pBUF=SPI_RW(0);
}
CSN=1;
return(status);
}
/**************************************************
函数:SPI_Write_Buf()
描述:
把pBuf缓存中的数据写入到nRF24L01,通常用来写入发
射通道数据或接收/发送地址
/**************************************************/
uchar SPI_WRITE_BUF(uchar reg,uchar *pBUF,uchar byte)
{
uchar status,i;
CSN=0;
status=SPI_RW(reg);
for(i=0;i
SPI_RW(*pBUF++);
CSN=1;
return(status);
}
/**************************************************
函数:RX_Mode()
描述:
这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包
/**************************************************/
void RX_MODE()
{
CE=0;
SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
SPI_RW_REG(WRITE_REG+EN_AA,0X01);
SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
SPI_RW_REG(WRITE_REG+RF_CH,40);
SPI_RW_REG(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH);
SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
SPI_RW_REG(WRITE_REG+CONFIG,0x0f);
CE=1;
}
/**************************************************
函数:TX_Mode()
描述:
这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),
130us后启动发射,数据发送结束后,发送模块自动转入接收
模式等待应答信号。
/**************************************************/
void TX_MODE(uchar *BUF)
{
CE=0;
SPI_WRITE_BUF(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
SPI_WRITE_BUF(WR_TX_PLOAD,BUF,TX_PLOAD_WIDTH);
SPI_RW_REG(WRITE_REG+EN_AA,0X01);
SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
SPI_RW_REG(WRITE_REG+SETUP_RETR,0X1A);
SPI_RW_REG(WRITE_REG+RF_CH,40);
SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
SPI_RW_REG(WRITE_REG+CONFIG,0x0E);
CE=1;
}
/**************************************************
函数:Check_ACK()
描述:
检查接收设备有无接收到数据包,设定没有收到应答信
号是否重发
/**************************************************/
uchar Check_ACK(bit clear)
{
while(IRQ);
sta = SPI_RW(NOP); // 返回状态寄存器
if(MAX_RT)
if(clear) // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
SPI_RW(FLUSH_TX);
SPI_RW_REG(WRITE_REG + STATUS, sta); // 清除TX_DS或MAX_RT中断标志
IRQ = 1;
if(TX_DS)
return(0x00);
else
return(0xff);
}
/**************************************************
函数:keyscan()
描述:检测是否有按键按下,按下则发送一字节数据
**************************************************
void keyscan()
{
if(key==0)
{
delay(5);
if(key==0)
{
TX_BUF[0]=~DATA;
TX_MODE(TX_BUF);
LED=~DATA;
Check_ACK(1);
delay(500);
LED=0XFF;
while(!key);
DATA<<=1;
if(!DATA)
DATA=0x01;
}
}
}
************************************************/
void main()
{
init_io();
RX_MODE();
while(1)
{
sta=SPI_READ(STATUS);
if(RX_DR)
{
SPI_READ_BUF(RD_RX_PLOAD,RX_BUF,TX_PLOAD_WIDTH);
flag=1;
}
SPI_RW_REG(WRITE_REG+STATUS,sta);
if(flag)
{
flag=0;
LED=RX_BUF[0];
}
}
}
发送端程序
#include
#include
#define uint unsigned int
#define uchar unsigned char
#define LED P1
***it key=P3^7;
//***it beep=P2^5;
//***it wela=P2^6;
//***it dula=P2^7;
/***************************************************/
#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[TX_PLOAD_WIDTH];
uchar TX_BUF[TX_PLOAD_WIDTH];
uchar flag;
uchar DATA = 0x01;
uchar bdata sta;
***it RX_DR = sta^6;
***it TX_DS = sta^5;
***it MAX_RT = sta^4;
/**************************************************
函数: init_io()
描述:
初始化IO
/**************************************************/
void init_io(void)
{
// dula=0;
// wela=0;
CE = 0; // 待机
CSN = 1; // SPI禁止
SCK = 0; // SPI时钟置低
IRQ = 1; // 中断复位
// LED = 0xff; // 关闭指示灯
}
/**************************************************
函数:delay()
描述:延时函数
**************************************************/
void delay(uint z)
{
uint x;
while(z--)
for(x=110;x>0;x--);
}
/**************************************************
函数:SPI_RW()
描述:
根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01
读出一字节
/**************************************************/
uchar SPI_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
MOSI=(byte&0x80);
byte<<=1;
SCK=1;
byte|=MISO;
SCK=0;
}
return (byte);
}
/**************************************************
函数:SPI_RW_Reg()
描述:
写数据value到reg寄存器
/**************************************************/
uchar SPI_RW_REG(uchar reg,uchar value)
{
uchar status;
CSN=0;
status=SPI_RW(reg);
SPI_RW(value);
CSN=1;
return(status);
}
/**************************************************
函数:SPI_Read()
描述:
从reg寄存器读一字节
/**************************************************/
uchar SPI_READ(uchar reg)
{
uchar status,reg_val;
CSN=0;
SPI_RW(reg);
reg_val=SPI_RW(0);
CSN=1;
return(status);
}
/**************************************************
函数:SPI_Read_Buf()
描述:
从reg寄存器读出bytes个字节,通常用来读取接收通道
数据或接收/发送地址
/**************************************************/
uchar SPI_READ_BUF(uchar reg,uchar *pBUF,uchar byte)
{
uchar status,i;
CSN=0;
status=SPI_RW(reg);
for(i=0;i
{
pBUF=SPI_RW(0);
}
CSN=1;
return(status);
}
/**************************************************
函数:SPI_Write_Buf()
描述:
把pBuf缓存中的数据写入到nRF24L01,通常用来写入发
射通道数据或接收/发送地址
/**************************************************/
uchar SPI_WRITE_BUF(uchar reg,uchar *pBUF,uchar byte)
{
uchar status,i;
CSN=0;
status=SPI_RW(reg);
for(i=0;i
SPI_RW(pBUF);
CSN=1;
return(status);
}
/**************************************************
函数:RX_Mode()
描述:
这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包
/**************************************************/
void RX_MODE()
{
CE=0;
SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
SPI_RW_REG(WRITE_REG+EN_AA,0X01);
SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
SPI_RW_REG(WRITE_REG+RF_CH,40);
SPI_RW_REG(WRITE_REG+RX_PW_P0,TX_PLOAD_WIDTH);
SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
SPI_RW_REG(WRITE_REG+CONFIG,0x0f);
CE=1;
}
/**************************************************
函数:TX_Mode()
描述:
这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),
130us后启动发射,数据发送结束后,发送模块自动转入接收
模式等待应答信号。
/**************************************************/
void TX_MODE(uchar *BUF)
{
CE=0;
SPI_WRITE_BUF(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);
SPI_WRITE_BUF(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH);
SPI_WRITE_BUF(WR_TX_PLOAD,BUF,TX_PLOAD_WIDTH);
SPI_RW_REG(WRITE_REG+EN_AA,0X01);
SPI_RW_REG(WRITE_REG+EN_RXADDR,0X01);
SPI_RW_REG(WRITE_REG+SETUP_RETR,0X0A);
SPI_RW_REG(WRITE_REG+RF_CH,40);
SPI_RW_REG(WRITE_REG+RF_SETUP,0X07);
SPI_RW_REG(WRITE_REG+CONFIG,0x0e);
CE=1;
}
/**************************************************
函数:Check_ACK()
描述:
检查接收设备有无接收到数据包,设定没有收到应答信
号是否重发
/**************************************************/
uchar Check_ACK(bit clear)
{
while(IRQ);
sta = SPI_RW(NOP); // 返回状态寄存器
if(MAX_RT)
if(clear) // 是否清除TX FIFO,没有清除在复位MAX_RT中断标志后重发
SPI_RW(FLUSH_TX);
SPI_RW_REG(WRITE_REG + STATUS, sta); // 清除TX_DS或MAX_RT中断标志
IRQ = 1;
if(TX_DS)
return(0x00);
else
return(0xff);
}
/**************************************************
函数:keyscan()
描述:检测是否有按键按下,按下则发送一字节数据
**************************************************/
void keyscan()
{
if(key==0)
{
delay(5);
if(key==0)
{
TX_BUF[0]=~DATA;
TX_MODE(TX_BUF);
LED=~DATA;
Check_ACK(1);
delay(500);
LED=0XFF;
while(!key);
DATA<<=1;
if(!DATA)
DATA=0x01;
}
}
}
void main()
{
init_io();
// TX_MODE();
while(1)
{
keyscan();
}
}
nRF24l01头文件
#ifndef _API_DEF_
#define _API_DEF_
// Define interface to nRF24L01
// Define SPI pins
***it CE = P1^0; // Chip Enable pin signal (output)
***it CSN = P1^1; // Slave Select pin, (output to CSN, nRF24L01)
***it IRQ = P1^3; // Interrupt signal, from nRF24L01 (input)
***it MISO = P1^4; // Master In, Slave Out pin (input)
***it MOSI = P1^5; // Serial Clock pin, (output)
***it SCK = P1^7; // Master Out, Slave In pin (output)
// SPI(nRF24L01) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read status register
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
#endif /* _API_DEF_ */
|