课题Nrf24L01程序.docx
《课题Nrf24L01程序.docx》由会员分享,可在线阅读,更多相关《课题Nrf24L01程序.docx(23页珍藏版)》请在冰豆网上搜索。
课题Nrf24L01程序
Nrf24L01程序
本模块是NRF24L01无线传输模块,用于无线传输数据,距离不远,一般只是能够满足小距离的传输,目测是4-5m,价格一般是4元左右,可以方便的买到。
51最小系统学习板就可以,当时是用了两块学习板,一块用于发送,一块用于接收。
小车也是比较容易购到的,四个端口控制两个电机,两个控制一个电机,当两个端口高低电平不同时电机就会转动,即为赋值1和0是电机转动,赋值可以用单片机作用,当然这是小车启动部分,前进后退左转右转就是你赋值0和1的顺序问题了。
整体思路是用发射端的按键控制小车,即为按键按下就前进,再按其他按键实现其他功能,本次程序是在用NRF24L01发射数据在接收端用1602显示的基础上改变。
下面是程序源码(有好几个文件,分别创建)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include"1602.h"
#include"delay.h"
#include"nrf24l01.h"
#defineuintunsignedint
#defineucharunsignedchar
uintWeight_Shiwu=1234;
unsignedcharKeyScan(void);//键盘扫描
//unsignedcharKeyScan(void);//键盘扫描
//#defineKeyPortP0
sbitKEY1=P0^0;
sbitKEY2=P0^1;
sbitKEY3=P0^2;
sbitKEY4=P0^3;
sbitKEY5=P0^4;
voidmain()
{
//charTxDate[4];
//LCD_Init();//初始化液晶屏
//LCD_Clear();//清屏
//NRF24L01Int();//初始化LCD1602
//LCD_Write_String(4,0,"welcome");
while
(1)
{
KeyScan();
}
}
unsignedcharKeyScan(void)
{
/********************************************************/
charTxDate[4];
{
if(!
KEY1)//如果检测到低电平,说明按键按下
{
DelayMs(10);//延时去抖,一般10-20ms
if(!
KEY1)//再次确认按键是否按下,没有按下则退出
{
while(!
KEY1);//如果确认按下按键等待按键释放,没有则退出
{
TxDate[0]=1;//向左转
TxDate[1]=0;
TxDate[2]=1;
TxDate[3]=1;
NRFSetTxMode(TxDate);//发送数据·
while(CheckACK());//检测是否发送完毕
}
}
}
/********************************************************/
elseif(!
KEY2)//如果检测到低电平,说明按键按下
{
DelayMs(10);//延时去抖,一般10-20ms
if(!
KEY2)//再次确认按键是否按下,没有按下则退出
{
while(!
KEY2);//如果确认按下按键等待按键释放,没有则退出
{
TxDate[0]=1;//向右转
TxDate[1]=1;
TxDate[2]=1;
TxDate[3]=0;
NRFSetTxMode(TxDate);//发送数据
while(CheckACK());//检测是否发送完毕
}
}
}
/********************************************************/
elseif(!
KEY3)//如果检测到低电平,说明按键按下
{
DelayMs(10);//延时去抖,一般10-20ms
if(!
KEY3)//再次确认按键是否按下,没有按下则退出
{
while(!
KEY3);//如果确认按下按键等待按键释放,没有则退出
{
TxDate[0]=1;//前进
TxDate[1]=0;
TxDate[2]=1;
TxDate[3]=0;
NRFSetTxMode(TxDate);//发送数据
while(CheckACK());//检测是否发送完毕
}
}
}
/********************************************************/
elseif(!
KEY4)//如果检测到低电平,说明按键按下
{
DelayMs(10);//延时去抖,一般10-20ms
if(!
KEY4)//再次确认按键是否按下,没有按下则退出
{
while(!
KEY4);//如果确认按下按键等待按键释放,没有则退出
{
TxDate[0]=0;//后退
TxDate[1]=1;
TxDate[2]=0;
TxDate[3]=1;
NRFSetTxMode(TxDate);//发送数据
while(CheckACK());//检测是否发送完毕
}
}
}
elseif(!
KEY5)
{
DelayMs(10);
if(!
KEY5)
{
while(!
KEY5)
{
TxDate[0]=1;
TxDate[1]=1;
TxDate[2]=1;
TxDate[3]=1;
NRFSetTxMode(TxDate);
while(CheckACK());
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include
#include"1602.h"
#include"delay.h"
#include"nrf24l01.h"
#defineuintunsignedint
#defineucharunsignedchar
uintWeight;
sbita=P2^0;
sbitb=P2^1;
sbitc=P2^2;
sbitd=P2^3;
voidmain()
{
LCD_Init();//初始化液晶屏
LCD_Clear();//清屏
*(RevTempDate+4)=*\0*;
NRF24L01Int();
while
(1)
{
NRFSetRXMode();//设置为接收模式
GetDate();//开始接受数;
//Weight=RevTempDate[0]*1000+RevTempDate[1]*100+RevTempDate[2]*10+RevTempDate[3];
LCD_Write_Char(7,0,RevTempDate[0]+0x30);
LCD_Write_Char(8,0,RevTempDate[1]+0x30);
LCD_Write_Char(9,0,RevTempDate[2]+0x30);
LCD_Write_Char(10,0,RevTempDate[3]+0x30);
a=RevTempDate[0];//根据接受数据来设置高低电平(目测仅限传输1.0两种数值)
b=RevTempDate[1];
c=RevTempDate[2];
d=RevTempDate[3];
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include
#include"nrf24l01.h"
#defineucharunsignedchar
#defineuintunsignedint
sbitIRQ=P1^2;//输入
sbitMISO=P1^3;//输入
sbitMOSI=P1^1;//输出
sbitSCLK=P1^4;//输出
sbitCE=P1^5;//输出
sbitCSN=P1^0;//输出
ucharcodeTxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址
/*****************状态标志*****************************************/
ucharbdatasta;//状态标志
sbitRX_DR=sta^6;
sbitTX_DS=sta^5;
sbitMAX_RT=sta^4;
/*****************SPI时序函数******************************************/
ucharNRFSPI(uchardate)
{
uchari;
for(i=0;i<8;i++)//循环8次
{
if(date&0x80)
MOSI=1;
else
MOSI=0;//byte最高位输出到MOSI
date<<=1;//低一位移位到最高位
SCLK=1;
if(MISO)//拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
date|=0x01;//读MISO到byte最低位
SCLK=0;//SCK置低
}
return(date);//返回读出的一字节
}
/**********************NRF24L01初始化函数*******************************/
voidNRF24L01Int()
{
DDelay
(2);//让系统什么都不干
CE=0;//待机模式1
CSN=1;
SCLK=0;
IRQ=1;
}
/*****************SPI读寄存器一字节函数*********************************/
ucharNRFReadReg(ucharRegAddr)
{
ucharBackDate;
CSN=0;//启动时序
NRFSPI(RegAddr);//写寄存器地址
BackDate=NRFSPI(0x00);//写入读寄存器指令
CSN=1;
return(BackDate);//返回状态
}
/*****************SPI写寄存器一字节函数*********************************/
ucharNRFWriteReg(ucharRegAddr,uchardate)
{
ucharBackDate;
CSN=0;//启动时序
BackDate=NRFSPI(RegAddr);//写入地址
NRFSPI(date);//写入值
CSN=1;
return(BackDate);
}
/*****************SPI读取RXFIFO寄存器的值********************************/
ucharNRFReadRxDate(ucharRegAddr,uchar*RxDate,ucharDateLen)
{//寄存器地址//读取数据存放变量//读取数据长度//用于接收
ucharBackDate,i;
CSN=0;//启动时序
BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址
for(i=0;i{
RxDate[i]=NRFSPI(0);
}
CSN=1;
return(BackDate);
}
/*****************SPI写入TXFIFO寄存器的值**********************************/
ucharNRFWriteTxDate(ucharRegAddr,uchar*TxDate,ucharDateLen)
{//寄存器地址//写入数据存放变量//读取数据长度//用于发送
ucharBackDate,i;
CSN=0;
BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址
for(i=0;i{
NRFSPI(*TxDate++);
}
CSN=1;
return(BackDate);
}
/*****************NRF设置为发送模式并发送数据******************************/
voidNRFSetTxMode(uchar*TxDate)
{//发送模式
CE=0;
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,0x01);//使能接收通道0自动应答
NRFWriteReg(W_REGISTER+EN_RXADDR,0x01);//使能接收通道0
NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a);//自动重发延时等待250us+86us,自动重发10次
NRFWriteReg(W_REGISTER+RF_CH,0x40);//选择射频通道0x40
NRFWriteReg(W_REGISTER+RF_SETUP,0x07);//数据传输率1Mbps,发射功率0dBm,低噪声放大器增益
NRFWriteReg(W_REGISTER+CONFIG,0x0e);//CRC使能,16位CRC校验,上电
CE=1;
DDelay(5);//保持10us秒以上
}
/*****************NRF设置为接收模式并接收数据******************************/
//主要接收模式
voidNRFSetRXMode()
{
CE=0;
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);//选择射频通道0x40
NRFWriteReg(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校验,上电,接收模式
CE=1;
DDelay(5);//保持10us秒以上
}
/****************************检测应答信号******************************/
ucharCheckACK()
{//用于发射
sta=NRFReadReg(R_REGISTER+STATUS);//返回状态寄存器
if(TX_DS||MAX_RT)//发送完毕中断
{
NRFWriteReg(W_REGISTER+STATUS,0xff);//清除TX_DS或MAX_RT中断标志
CSN=0;
NRFSPI(FLUSH_TX);//用于清空FIFO!
!
关键!
!
不然会出现意想不到的后果!
!
!
大家记住!
!
CSN=1;
return(0);
}
else
return
(1);
}
/******************判断是否接收收到数据,接到就从RX取出*********************/
//用于接收模式
ucharNRFRevDate(uchar*RevDate)
{
ucharRevFlags=0;
sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器
if(RX_DR)//判断是否接收到数据
{
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);
}
voidDDelay(uintt)
{
uintx,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
#include"delay.h"
/*------------------------------------------------
uS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5uS
------------------------------------------------*/
voidDelayUs2x(unsignedchart)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数unsignedchart,无返回值
unsignedchar是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
voidDelayMs(unsignedchart)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
下面是接收的NRF24L01的程序。
#include
#include"nrf24l01.h"
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitIRQ=P1^2;//输入
sbitMISO=P1^3;//输入
sbitMOSI=P1^1;//输出
sbitSCLK=P1^4;//输出
sbitCE=P1^5;//输出
sbitCSN=P1^0;//输出
ucharRevTempDate[5];//最后一位用来存放结束标志
ucharcodeTxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址
/*****************状态标志*****************************************/
ucharbdatasta;//状态标志
sbitRX_DR=sta^6;
sbitTX_DS=sta^5;
sbitMAX_RT=sta^4;
/*****************SPI时序函数******************************************/
ucharNRFSPI(uchardate)
{
uchari;
for(i=0;i<8;i++)//循环8次
{
if(date&0x80)
MOSI=1;
else
MOSI=0;//byte最高位输出到MOSI
date<<=1;//低一位移位到最高位
SCLK=1;
if(MISO)//拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据
date|=0x01;//读MISO到byte最低位
SCLK=0;//SCK置低
}
return(date);//返回读出的一字节
}
/**********************NRF24L01初始化函数*******************************/
voidNRF24L01Int()
{
NRFDelay
(2);//让系统什么都不干
CE=0;
CSN=1;
SCLK=0;
IRQ=1;
}
/*****************SPI读寄存器一字节函数*********************************/
ucharNRFReadReg(ucharRegAddr)
{
ucharBackDate;
CSN=0;//启动时序
NRFSPI(RegAddr);//写寄存器地址
BackDate=NRFSPI(0x00);//写入读寄存器指令
CSN=1;
retur