完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 xintuxing 于 2016-2-13 23:05 编辑
本帖内容: 一、原理图回顾。 二、远程控制照明灯工作过程。 三、NRF24L01与IntoRobot ATOM核心板的引脚连接。 四、NRF24L01代码。 五、简介无线开关。 一、原理图回顾: 二、远程控制照明灯工作过程: 三、NRF24L01与IntoRobot ATOM核心板的引脚连接: NRF24L01无线模块共有8个引脚,连接情况如下: 1、GND与核心板的GND连接。 2、VCC 与核心板的3.3V连接。 3、CE引脚与核心板的D6(PB8)连接。 4、CSN引脚与核心板的D2(SPI1的SS)连接。 5、SCK引脚与核心板的D3(SPI1的SCK)连接。 6、MOSI引脚与核心板的D5(SPI1的MOSI)连接。 7、MISO引脚与核心板的D4(SPI1的MISO)连接。 8、IRQ引脚与核心板的D7(PB9)连接。 四、NRF24L01代码:1、在工程添加两个文件: 2、在NRF24L01A.h中添加如下内容: typedef unsigned char BYTE; typedef unsigned char uchar; #define TX_ADR_WIDTH 5 // 5 uints TX address width #define RX_ADR_WIDTH 5 // 5 uints RX address width #define TX_PLOAD_WIDTH 2 // 32 uints TX payload #define RX_PLOAD_WIDTH 2 // 32 uints TX payload //*********NRF24L01寄存器指令****************************************************** #define READ_REG 0x00 //读寄存器指令 #define WRITE_REG 0x20 //写寄存器指令 #define RD_RX_PLOAD 0x61 //读取接收数据指令 #define WR_TX_PLOAD 0xA0 //写待发数据指令 #define FLUSH_TX 0xE1 //冲洗发送FIFO指令 #define FLUSH_RX 0xE2 // 冲洗接收FIFO指令 #define REUSE_TX_PL 0xE3 //定义重复装载数据指令 #define NOP 0xFF //保留 //*******SPI(nRF24L01)寄存器地址**************************************************** #define CONFIG 0x00 //配置收发状态,crc校验模式以及收发状态响应方式 #define EN_AA 0x01 //自动应答功能设置 #define EN_RXADDR 0x02 //可用信道设置 #define SETUP_AW 0x03 // 收发地址宽度设置 #define SETUP_RETR 0x04 //自动重发功能设置 #define RF_CH 0x05 // 工作频率设置 #define RF_SETUP 0x06 //发射速率、功耗功能设置 #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接收数据长度 #define RX_PW_P1 0x12 //接收频道1接收数据长度 #define RX_PW_P2 0x13 //接收频道2接收数据长度 #define RX_PW_P3 0x14 //接收频道3接收数据长度 #define RX_PW_P4 0x15 //接收频道4接收数据长度 #define RX_PW_P5 0x16 //接收频道5接收数据长度 #define FIFO_STATUS 0x17 //FIFO栈入栈出状态寄存器设置 #define STA_MARK_RX 0X40 #define STA_MARK_TX 0X20 #define STA_MARK_MX 0X10 #define CE D6 #define IRQ D7 #define CSN D2 class NRF24L01 { public: NRF24L01(int i); void init_nrf24l01_io(uint8_t order,uint8_t divider,uint8_t mode); // Init HW or SW SPI uchar SPI_RW(uchar _byte); // Single SPI read/write uchar SPI_Read(BYTE reg); // Read one byte from nRF24L01 uchar SPI_RW_Reg(BYTE reg, BYTE _byte); // Write one byte to register 'reg' uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes); // Writes multiply bytes to one register uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes); // Read multiply bytes from one register void RX_Mode(void); void TX_Mode(void); unsigned char nRF24L01_RxPacket(unsigned char* rx_buf); void Transmit(unsigned char * tx_buf); uchar RX_DR = 0; uchar TX_DS = 0; uchar MAX_RT = 0; uchar TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; uchar RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; uchar Tx_Buf[TX_PLOAD_WIDTH]={0,0};//发送数据 uchar Rx_Buf[RX_PLOAD_WIDTH]={0,0};//接收数据 }; 3、在NRF24L01A.cpp文件中添加如下内容:#include NRF24L01::NRF24L01(int i) { i=i; } void NRF24L01::init_nrf24l01_io(uint8_t order,uint8_t divider,uint8_t mode) { SPI_1.begin(); SPI_1.setBitOrder(order); SPI_1.setClockDivider(divider); SPI_1.setDataMode(mode); pinMode(CE,OUTPUT); pinMode(CSN,OUTPUT); pinMode(IRQ,INPUT_PULLUP); digitalWrite(CE,LOW); digitalWrite(CSN,HIGH); } //**SPI代码**************************************** uchar NRF24L01::SPI_RW(uchar _byte) { return(SPI_1.transfer(_byte)); } uchar NRF24L01::SPI_RW_Reg (uchar reg,uchar value)//向寄存器REG写一个字节,同时返回状态字节 { uchar status; digitalWrite(CSN,LOW); status=SPI_RW(reg); SPI_RW(value); digitalWrite(CSN,HIGH); return(status); } uchar NRF24L01::SPI_Read(uchar reg) { uchar reg_val; // CSN(0); digitalWrite(CSN,LOW); SPI_RW(reg); reg_val=SPI_RW(0); // CSN(1); digitalWrite(CSN,HIGH); return(reg_val); } uchar NRF24L01::SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) { uchar status,byte_ctr; // CSN(0); // Set CSN low, init SPI tranaction digitalWrite(CSN,LOW); status = SPI_RW(reg); // Select register to write to and read status byte for(byte_ctr=0; byte_ctr // CSN(1); // Set CSN high again digitalWrite(CSN,HIGH); return(status); // return nRF24L01 status byte } //发送模式 代码 void NRF24L01::TX_Mode(void) { digitalWrite(CE,LOW); SPI_RW_Reg(FLUSH_TX,0x00); SPI_Write_Buf(WRITE_REG + TX_ADDR,(uchar*)TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0,(uchar*)RX_ADDRESS, RX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40 SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); digitalWrite(CE,HIGH); delay(100); } void NRF24L01::Transmit(unsigned char * tx_buf) { unsigned char sta = SPI_Read(STATUS); //读取状态寄存器来判断数据接收状态 // while((sta & 0x10)); if(((sta & 0x10) | (sta& 0x20))) { SPI_RW_Reg(WRITE_REG+STATUS,sta); TX_Mode(); } digitalWrite(CE,LOW); //StandBy I模式 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uchar*)TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址 SPI_RW_Reg(FLUSH_TX,0x00); SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据 SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送 digitalWrite(CE,HIGH); //置高CE,激发数据传送 delay(150); } //接收模式代码 uchar NRF24L01::SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) { uchar sta,uchar_ctr; // CSN(0); // Set CSN low, init SPI tranaction sta = SPI_RW(reg); // Select register to write to and read status uchar for(uchar_ctr=0;uchar_ctr // CSN(1); return(sta); // return nRF24L01 status uchar } /***************************************************************************************************** 函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) 功能:数据读取后放入rx_buf接收缓冲区中 *****************************************************************************************************/ unsigned char NRF24L01::nRF24L01_RxPacket(unsigned char* rx_buf) { unsigned char revale=0,sta = 0; sta = SPI_Read(STATUS); //读取状态寄存器来判断数据接收状态 // RX_DR = (); if(sta & 0x40) //判断是否接收到数据 { //CE = 0; //SPI使能 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer revale =1; //读取数据完成标志 //Delay(100); } SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置为高,通过写1来清除中断标志。 return revale; } /*****************************************************************************************************/ /*函数:void RX_Mode(void) *功能:数据接收配置 ***************************************************************************************************/ void NRF24L01::RX_Mode(void) { digitalWrite(CE,LOW); SPI_RW_Reg(FLUSH_RX,0x00); //SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, (uchar*)RX_ADDRESS, RX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 //SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...1a SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40 SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F); digitalWrite(CE,HIGH); delay(130); } 3、特别注释:下图的函数是SPI1的配置,最后要把CE和CSN拉低: transfer函数是含写与读两个功能,只需调用一次就完成一个完整的SPI时序: 五:简介无线开关: 这是STM8S103单片机与NRF24L01的连接,可控硅电路只需要一个IO引脚就可以控制,连接较为简单。 这个电路板设置的功能比较多,是为了可以多用途拓展,需要用到的时候就可以将相应的元件焊接上。 现在已经把该电路板嵌入到了正常的手动开关里,已经实现了远程无线控制照明灯,并且不影响手动开关的正常使用。 本帖到此结束,效果图待下贴上传。 |
|
相关推荐
1 个讨论
|
|
只有小组成员才能发言,加入小组>>
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-3-6 03:58 , Processed in 0.399934 second(s), Total 39, Slave 32 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191