℉Endman hgdjgf
关注数: 5 粉丝数: 680 发帖数: 3,267 关注贴吧数: 68
求助一个有关NRF24L01的问题 我的目的是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); }
【参赛】“Star Voyager”星际旅行者号生存飞船[no mods] 重量 :1575t 最大逃逸载重:2492t 动力设备:陀螺仪:4个 推进器类型:离子+大气 推进器数量(数了半天没数清楚大概就这样) 离子:40个 大气:38个 大型反应堆:1个 电池:10个 跃迁引擎:1个(1575km±) 生产设备:全套无升级(精炼厂*1装配机*1氧气制造机*1氧气罐*1) 武器 :自动机枪:2个 自动火箭:1个 手动火箭 前:7个 下:3个 维生设备:医疗仓:1个 其他 :长:62.5m 宽:47.5m 高:32.5m 乘船须知:入口只有一个,是在船尾部的一个转子门,会自动感应接近的玩家和小船。注意!!!不要再门口逗留太久,没有自动锁定的转子会使得船慢慢翘头,我设计了关门自动锁定,所以不用大家操心!上面和侧面下面和侧边后面和船舱船舱内部(右边是生产设备)主电池部分跃迁引擎和反应堆主驾驶舱(反应堆仓还有一个隐藏的控制站)本船是生存向的全功能飞船,细节部分较少,内饰也是单调的白色。但是实用性很强,能不借助氢推直接逃逸地球(中途无减速),也能登陆所有星球(大概吧),有一点就是超级容易鬼畜,有的时候起落架一松就弹起来旋转跳跃了。没了 看我傻的 创意工坊还没发呢:http://tieba.baidu.com/mo/q/checkurl?url=http%3A%2F%2Fsteamc&urlrefer=c4b23957732d8252bbc8fbb3e803f44community.com/sharedfiles/filedetails/?id=892354499&searchtext=
1 下一页