网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
12月28日漏签0天
单片机吧 关注:212,955贴子:1,050,331
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 0回复贴,共1页
<<返回单片机吧
>0< 加载中...

求助一个有关NRF24L01的问题

  • 只看楼主
  • 收藏

  • 回复
  • Endman
  • 中校
    11
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
我的目的是a方(12c5a60s2)按下按键就发送某标识符,然后b方(89c52rc)接收到以后不能就亮灯;
同时b方也也有按键检测发送标识符,a方同时也接收。现在就是stc12能给stc89发送并接收亮灯,可是反过来不行,也不知道发没发出去,不过两个模块交换以后也是这样所以排除硬件问题。程序有点长,两个程序只有延时不一样其他完全一样。
#include "mcu.h"
#include "NRF24L01.H"
sbit led=P3^6;
#defineLED_ONled=0
#defineLED_OFFled=1
#define KEY_STAUS(P2&(1<<0))//P20为按键 ==0为按下,!=0 为弹起
//===============
//延时函数
//===============
void delayms(uint ms)//延时?个 ms
{
uint a,b;
for(a=ms;a>0;a--)
for(b=120;b>0;b--);
}
//======================
//主函数
//======================
void main(void)
{
uint while_times = 0;
init_NRF24L01();
delayms(300);
while(1)
{
//===== 发送模式 =====
nrf_TxMod();
if(KEY_STAUS == 0)//按键按下,
{
TxBuf[0] = 1;//把1存入TxBuf[0]中,然后发送出去;接收程序判断RxBuf[0]的值,等于1的话点亮LED
//【注:RxBuf数组和TxBuf数组中的元素是对应的】
}
else
{
TxBuf[0] = 0;
}
nrf_trans(TxBuf);//将待发送的数据写入NRF24L01
while_times = 50;//检测是否发送成功 循环检测?次 【可更改,让接收循环次数大于发送循环次数效果较好】
while(while_times-- ) //发送超时,或者发送成功,跳出循环 进入接收模式
{
get_nrf_sta();//获取状态标志
if(TX_DS == 1)//发送成功,跳出循环
break;
}
//===== 接收模式 =====
nrf_RxMod();
while_times = 150;//检测是否接收成功 循环检测?次 【可更改,让接收循环次数大于发送循环次数效果较好】
while(while_times--) //接收超时或者接收成功,跳出循环 进入发送模式
{
get_nrf_sta();//获取状态标志
if(RX_DR == 1)//接收成功
{
nrf_read(RxBuf);//接收成功后,将NRF24L01接收到的数据读到单片机的RxBuf数组中。
break;//跳出循环
}
}
if(RX_DR == 1)//是因为接收到数据,而不是因为超时才跳出循环
{
if(RxBuf[0] == 1)
LED_ON;
else if(RxBuf[0] == 0)
LED_OFF;
}
}
}
//*********************下面是无线模块的程序,宏定义太长了不在这里放出来了。
#include "NRF24L01.H"
uchar idata nrf_sta;
uchar idata RxBuf[32] = "0";//接收缓存 存入idata区
uchar idata TxBuf[32] = "0";//发送缓存
uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//本地地址
uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};//接收地址
//===== 粗略的延时 =====
void delayus(uint us)
{
while(us--);
}
//================== NRF24L01初始化 ==================
void init_NRF24L01(void)
{
delayus(100);
CE = 0; // 片选使能
CSN = 1; // SPI使能
SCK = 0; // SPI时钟拉低
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_Write_Reg(WRITE_REG + EN_AA, 0x01); //通道0自动应答
SPI_Write_Reg(WRITE_REG + EN_RXADDR, 0x01); //允许接收地址频道0
SPI_Write_Reg(WRITE_REG + RF_CH, 0x32); //设置信道工作频率,收发必须一致
SPI_Write_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度
SPI_Write_Reg(WRITE_REG + RF_SETUP, 0x0f); //设置发射速率为2MHZ,发射功率为最大值0dB
SPI_Write_Reg(WRITE_REG + NRF_CONFIG, 0x7c); //IRQ引脚不显示中断 掉电模式 1~16CRC校验
}
//==================
//读取状态标志
//==================
void get_nrf_sta(void)
{
nrf_sta = SPI_Read_Reg(STATUS);
SPI_Write_Reg(WRITE_REG+STATUS,nrf_sta);
}
//==================
//设置为接收模式
//==================
void nrf_RxMod(void)
{
CE = 0;
SPI_Write_Reg(WRITE_REG+STATUS,0xff);//清除中断标志
SPI_Write_Reg(FLUSH_RX,0x00); //清除RX_FIFO寄存器
SPI_Write_Reg(WRITE_REG + NRF_CONFIG, 0x7f);//IRQ引脚不显示中断 上电 接收模式 1~16CRC校验
CE = 1;
delayus(100);
}
//==================
//把接收到的数据存入数组
//==================
void nrf_read(uchar *rx_buf)
{
if(RX_DR == 1) //收到数据
{
CE = 0;
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);//读取数据 存入数组
SPI_Write_Reg(FLUSH_RX,0x00);//清除rx fifo寄存器
CE = 1;
delayus(100);
}
}
//==================
//设置为发送模式
//==================
void nrf_TxMod(void)
{
CE = 0;
SPI_Write_Reg(WRITE_REG+STATUS,0xff); //清除中断标志
SPI_Write_Reg(FLUSH_TX,0x00);//清除TX_FIFO寄存器
SPI_Write_Reg(WRITE_REG + NRF_CONFIG,0x7e);//IRQ引脚不显示中断 上电 发射模式 1~16CRC校验
CE = 1;
delayus(100);
}
//==================
//发送 不做任何判断只管发送
//==================
void nrf_trans(uchar *tx_buf)
{
CE = 0;//StandBy I模式
SPI_Write_Reg(WRITE_REG+STATUS,0xFF);//清除所有中断
SPI_Write_Reg(FLUSH_TX,0x00); //清除tx fifo寄存器//===== 重要 =====
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH); // 装载数据
CE = 1; //置高CE激发数据发送
delayus(100);//此延时必须有 因为从待机模式到收发模式需要时间,最大需要130us
}
//=========================
//将float数编码装载 保留4位小数
//占用5个字节 数据范围+- 65535.9999
//=========================
void nrf_load_float(uchar a,float num)
{
if(num > 0)
{
TxBuf[a] = '+';
TxBuf[a+1] = (uint)num/256;
TxBuf[a+2] = (uint)num%256;
TxBuf[a+3] = (uint)((num - (int)num)*10000)/256;
TxBuf[a+4] = (uint)((num - (int)num)*10000)%256;
}
else if(num < 0)
{
num = -num;
TxBuf[a] = '-';
TxBuf[a+1] = (uint)num/256;
TxBuf[a+2] = (uint)num%256;
TxBuf[a+3] = (uint)((num - (int)num)*10000)/256;
TxBuf[a+4] = (uint)((num - (int)num)*10000)%256;
}
else
{
TxBuf[a] = '0';
TxBuf[a+1] = 0;
TxBuf[a+2] = 0;
TxBuf[a+3] = 0;
TxBuf[a+4] = 0;
}
}
//=======================
//将接收到的float数组解码
//占用5个字节 数据范围+- 65535.9999
//=======================
float nrf_unload_float(uchar a)
{
float num;
if(RxBuf[a] == '+'){
num = RxBuf[a+1]*256 + RxBuf[a+2]+ (float)((int)RxBuf[a+3]*256 + RxBuf[a+4])/10000.0;
}
else if(RxBuf[a] == '-'){
num = RxBuf[a+1]*256 + RxBuf[a+2]+ (float)((int)RxBuf[a+3]*256 + RxBuf[a+4])/10000.0;
num = -num;
}
else if(RxBuf[a] == '0')
num = 0;
return (num);
}
//=======================
//将float数编码装载 保留2位小数
//占用3个字节 数据范围+- 255.99
//=======================
void nrf_load_sfloat(uchar a,float num)
{
if(num > 0){
TxBuf[a] = '+';
TxBuf[a+1] = (uchar)num;//转换成uchar类型,自动将保留低8位,去除高位。
TxBuf[a+2] = (uint)((num - (int)num)*100);
}
else if(num < 0){
num = -num;
TxBuf[a] = '-';
TxBuf[a+1] = (uchar)num;
TxBuf[a+2] = (uint)((num - (int)num)*100);
}
else{
TxBuf[a] = '0';
TxBuf[a+1] = 0;
TxBuf[a+2] = 0;
}
}
//=======================
//将float数解码 保留2位小数
//占用3个字节 数据范围+- 255.99
//======================
float nrf_unload_sfloat(uchar a)//a是数据包在数组内的起始位置
{
float num;
if(RxBuf[a] == '+'){
num = RxBuf[a+1]+ (float)RxBuf[a+2]/100;
}
else if(RxBuf[a] == '-'){
num = RxBuf[a+1]+ (float)RxBuf[a+2]/100;
num = -num;
}
else if(RxBuf[a] == '0')
num = 0;
return (num);
}
//spi
#include "SPI.H"
//=============================================
//SPI读写函数,往MOSI引脚写入一个字节,同时从MISO引脚读取一个字节
//=============================================
uchar SPI_RW(uchar num)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++)
{
MOSI = (num & 0x80);
num = (num << 1);
SCK = 1;
num |= MISO;
SCK = 0;
}
return(num);
}
//=============================================
//SPI读寄存器函数。只有一个功能:读取reg的值并返回
//先写入寄存器地址,使SPI器件定位到该地址,
//下一次读取取出该寄存器的值,并返回该值。
//=============================================
uchar SPI_Read_Reg(uchar reg)
{
uchar reg_val;
CSN = 0;
SPI_RW(reg);
reg_val = SPI_RW(0);//此处的0没有什么意义,可以是1,2,3,……
CSN = 1;
return (reg_val);
}
//=============================================
//SPI写寄存器函数。主要功能:往reg中写入value
//附加功能:返回寄存器的状态字
//=============================================
uchar SPI_Write_Reg(uchar reg, uchar value)
{
uchar status;
CSN = 0;
status = SPI_RW(reg);
SPI_RW(value);
CSN = 1;
return(status);
}
//====================================
//将SPI设备缓冲区的数据读入单片机,并保存到数组中
//连续读取nBytes个字节
//====================================
uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar nBytes)
{
uchar status;
uchar i;
CSN = 0;
status = SPI_RW(reg);
for(i = 0;i < nBytes;i++)
pBuf[i] = SPI_RW(0);
CSN = 1;
return(status);
}
//====================================
//将单片机有nBytes个成员的数组写入SPI设备的reg寄存器
//====================================
uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar nBytes)
{
uchar status;
uchar i;
CSN = 0;
status = SPI_RW(reg);
for(i = 0; i < nBytes;i++)
SPI_RW(pBuf[i]);
CSN = 1;
return(status);
}


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 0回复贴,共1页
<<返回单片机吧
分享到:
©2025 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示