完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
/******************************************/ // // 该程序工作的主频是12MHz,单片机使用STC12C5A60S2 // /******************************************/ #include "STC12C5A60S2.H" #define uchar unsigned char #define uint unsigned int /********** NRF24L01寄存器操作命令 ***********/ #define READ_REG 0x00 //读配置寄存器,低5位为寄存器地址 #define WRITE_REG 0x20 //写配置寄存器,低5位为寄存器地址 #define RD_RX_PLOAD 0x61 //读RX有效数据,1~32字节 #define WR_TX_PLOAD 0xA0 //写TX有效数据,1~32字节 #define FLUSH_TX 0xE1 //清除TX FIFO寄存器.发射模式下用 #define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用 #define REUSE_TX_PL 0xE3 //重新使用上一包数据,CE为高,数据包被不断发送. #define NOP 0xFF //空操作,可以用来读状态寄存器 /********** NRF24L01寄存器地址 *************/ #define CONFIG 0x00 //配置寄存器地址 #define EN_AA 0x01 //使能自动应答功能 #define EN_RXADDR 0x02 //接收地址允许 #define SETUP_AW 0x03 //设置地址宽度(所有数据通道) #define SETUP_RETR 0x04 //建立自动重发 #define RF_CH 0x05 //RF通道 #define RF_SETUP 0x06 //RF寄存器 #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有效数据宽度(1~32字节) #define RX_PW_P1 0x12 // 接收数据通道1有效数据宽度(1~32字节) #define RX_PW_P2 0x13 // 接收数据通道2有效数据宽度(1~32字节) #define RX_PW_P3 0x14 // 接收数据通道3有效数据宽度(1~32字节) #define RX_PW_P4 0x15 // 接收数据通道4有效数据宽度(1~32字节) #define RX_PW_P5 0x16 // 接收数据通道5有效数据宽度(1~32字节) #define FIFO_STATUS 0x17 // FIFO状态寄存器 /*————————————————————————————————————————————————————————————————————*/ /****** STATUS寄存器bit位定义 *******/ #define MAX_TX 0x10 //达到最大发送次数中断 #define TX_OK 0x20 //TX发送完成中断 #define RX_OK 0x40 //接收到数据中断 /*——————————————————————————————————————————————————*/ /********* 24L01发送接收数据宽度定义 ***********/ #define TX_ADR_WIDTH 5 //5字节地址宽度 #define RX_ADR_WIDTH 5 //5字节地址宽度 #define TX_PLOAD_WIDTH 32 //32字节有效数据宽度 #define RX_PLOAD_WIDTH 32 //32字节有效数据宽度 const uchar TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; const uchar RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; ***it NRF_CE = P1^2; ***it NRF_CSN = P1^3; ***it NRF_MISO = P1^6; ***it NRF_MOSI = P1^5; ***it NRF_SCK = P1^7; ***it NRF_IRQ = P1^4; ***it LED1=P1^0; //状态指示灯 ***it LED2=P1^1; //接收时的被控对象 unsigned char send_buf[TX_PLOAD_WIDTH]="qwertyuiopasdfghjklzxcvbnm123456"; //26+6 unsigned char recv_buf[RX_PLOAD_WIDTH]; /* 延时函数 */ /***************/ void delay_ms(unsigned char ms) { unsigned int i; do { i = 1701; while(--i) ; //14T per loop } while(--ms); } /**********************/ /* 初始化硬件SPI口 */ /**********************/ void SPI_Init(void) { NRF_CE=0; NRF_CSN=1; NRF_SCK=0; NRF_IRQ=1; //SPSTAT |= 0XC0; //SPCTL = 0XD0; } /**********************/ /* SPI数据收发函数 */ /**********************/ //uchar SPI_RW(uchar tr_data) //{ // uchar i=0; // // SPSTAT |= 0Xc0; // 清高两位, // SPDAT=tr_data; // while(((SPSTAT&0X80)!=0X80)&&(i<20)) // { // i++; // delay_ms(1); // } // return SPDAT; //} // 下面是“模拟SPI” uchar SPI_RW(uchar byte) { uchar bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++) // 输出8位 { NRF_MOSI=(byte&0x80); // MSB TO MOSI byte=(byte<<1); // shift next bit to MSB NRF_SCK=1; byte|=NRF_MISO; // capture current MISO bit NRF_SCK=0; } return byte; } /*********************************************/ /* 函数功能:给24L01的寄存器写值(一个字节) */ /* 入口参数:reg 要写的寄存器地址 */ /* value 给寄存器写的值 */ /* 出口参数:status 状态值 */ /*********************************************/ uchar NRF24L01_Write_Reg(uchar reg,uchar value) { uchar status; NRF_CSN=0; //CSN=0; status = SPI_RW(reg);//发送寄存器地址,并读取状态值 SPI_RW(value); NRF_CSN=1; //CSN=1; return status; } /*************************************************/ /* 函数功能:读24L01的寄存器值 (一个字节) */ /* 入口参数:reg 要读的寄存器地址 */ /* 出口参数:value 读出寄存器的值 */ /*************************************************/ uchar NRF24L01_Read_Reg(uchar reg) { uchar value; NRF_CSN=0; //CSN=0; SPI_RW(reg);//发送寄存器值(位置),并读取状态值 value = SPI_RW(NOP); NRF_CSN=1; //CSN=1; return value; } /*********************************************/ /* 函数功能:读24L01的寄存器值(多个字节) */ /* 入口参数:reg 寄存器地址 */ /* *pBuf 读出寄存器值的存放数组 */ /* len 数组字节长度 */ /* 出口参数:status 状态值 */ /*********************************************/ uchar NRF24L01_Read_Buf(uchar reg,uchar *pBuf,uchar len) { uchar status,u8_ctr; NRF_CSN=0; //CSN=0 status=SPI_RW(reg);//发送寄存器地址,并读取状态值 for(u8_ctr=0; u8_ctr NRF_CSN=1; //CSN=1 return status; //返回读到的状态值 } /**********************************************/ /* 函数功能:给24L01的寄存器写值(多个字节) */ /* 入口参数:reg 要写的寄存器地址 */ /* *pBuf 值的存放数组 */ /* len 数组字节长度 */ /**********************************************/ uchar NRF24L01_Write_Buf(uchar reg, uchar *pBuf, uchar len) { uchar status,u8_ctr; NRF_CSN=0; status = SPI_RW(reg);//发送寄存器值(位置),并读取状态值 for(u8_ctr=0; u8_ctr NRF_CSN=1; return status; //返回读到的状态值 } /*********************************************/ /* 函数功能:24L01接收数据 */ /* 入口参数:rxbuf 接收数据数组 */ /* 返回值: 0 成功收到数据 */ /* 1 没有收到数据 */ /*********************************************/ uchar NRF24L01_RxPacket(uchar *rxbuf) { uchar state; state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志 if(state&RX_OK)//接收到数据 { NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 return 0; } return 1;//没收到任何数据 } /**********************************************/ /* 函数功能:设置24L01为发送模式 */ /* 入口参数:txbuf 发送数据数组 */ /* 返回值; 0x10 达到最大重发次数,发送失败*/ /* 0x20 成功发送完成 */ /* 0xff 发送失败 */ /**********************************************/ uchar NRF24L01_TxPacket(uchar *txbuf) { uchar state; // uchar i; NRF_CE=0;//CE拉低,使能24L01配置 NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节 NRF_CE=1;//CE置高,使能发送 while(NRF_IRQ==1);//等待发送完成 state=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志 if(state&MAX_TX)//达到最大重发次数 { NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器 return MAX_TX; } if(state&TX_OK)//发送完成 { return TX_OK; } return 0xff;//发送失败 } /********************************************/ /* 函数功能:检测24L01是否存在 */ /* 返回值; 0 存在 */ /* 1 不存在 */ /********************************************/ uchar NRF24L01_Check(void) { uchar check_in_buf[5]= {0x11,0x22,0x33,0x44,0x55}; uchar check_out_buf[5]= {0x00}; NRF_CE=0; NRF24L01_Write_Buf(WRITE_REG+TX_ADDR, check_in_buf, 5); NRF24L01_Read_Buf(READ_REG+TX_ADDR, check_out_buf, 5); if((check_out_buf[0] == 0x11)&& (check_out_buf[1] == 0x22)&& (check_out_buf[2] == 0x33)&& (check_out_buf[3] == 0x44)&& (check_out_buf[4] == 0x55))return 0; else return 1; } void NRF24L01_TX_Mode(void) { NRF_CE=0; //NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 //NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址 NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 NRF24L01_Write_Reg(WRITE_REG+RF_CH,40); //设置RF通道为125 //NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x27); //7db增益,250kbps NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 (两边的速率一定要一样!!!!) NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0E); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发送模式,开启所有中断 NRF_CE=1; //CE置高 } void NRF24L01_RX_Mode(void) { NRF_CE=0; NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址 NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址 NRF24L01_Write_Reg(WRITE_REG+RF_CH,40); //设置RF通信频率 NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 delay_ms(150); NRF_CE = 1; //CE为高,进入接收模式 } /**********************************************/ void main(void) { LED1=0; delay_ms(100); // 延时待系统稳定 SPI_Init(); // 初始化SPI口 while(NRF24L01_Check()); // 等待检测到NRF24L01,程序才会向下执行 LED1=1; LED2=1; NRF24L01_RX_Mode(); // 配置NRF24L01为发送模式 while (1) { delay_ms(500); NRF24L01_RxPacket(recv_buf); // 无线发送数据 LED1=!LED1; if(recv_buf[0]=='a') LED2=0; else LED2=1; } NRF24L01_TX_Mode(); // 配置NRF24L01为发送模式 while (1) { delay_ms(500); NRF24L01_TxPacket(send_buf); // 无线发送数据 LED1=!LED1; } } |
|
|
|
stm32部分使用的正点原子开发板例程,只对主程序进行了一部分改写。
if(mode==0)//RX模式 { LCD_ShowString(30,150,200,16,16,"NRF24L01 RX_Mode"); LCD_ShowString(30,170,200,16,16,"Received DATA:"); NRF24L01_RX_Mode(); while(1) { if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来. { tmp_buf[32]=0;//加入字符串结束符 LCD_ShowString(0,190,lcddev.width-1,32,16,tmp_buf); } else delay_us(100); t++; if(t==10000)//大约1s钟改变一次状态 { t=0; LED0=!LED0; } }; } else//TX模式 { LCD_ShowString(30,150,200,16,16,"NRF24L01 TX_Mode"); NRF24L01_TX_Mode(); while(1) { key=KEY_Scan(0); if(key==KEY0_PRES) test[0]='a'; else if(key==KEY1_PRES) test[0]='b'; if(NRF24L01_TxPacket(test)==TX_OK) { LCD_ShowString(30,170,239,32,16,"Sended DATA:"); LCD_ShowString(0,190,lcddev.width-1,32,16,test); } else { LCD_Fill(0,170,lcddev.width,170+16*3,WHITE);//清空显示 LCD_ShowString(30,170,lcddev.width-1,32,16,"Send Failed "); }; LED0=!LED0; delay_ms(500); }; } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1750 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1608 浏览 1 评论
1049 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1665 浏览 2 评论
1924浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
709浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
559浏览 3评论
583浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
544浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 10:08 , Processed in 0.966216 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号