嵌入式linux中nRF24L01驱动(主控板tiny4412)

2019-07-13 02:07发布


一直想整理下15年的一些知识,终于,久违了的第一篇。 或许网上有博主写过nRF24L01驱动,如果认为侵权,请与我联系。 接触nRF24L01是因为毕业设计,需要利用这个无线模块来接受数据,所以在代码中只有接受的部分,发送的框架也有,里面的代码根据功能自己实现。 与网上其他资料一样,本人没有使用linux下自带的SPI子系统,用的是IO模拟的方式来控制这个无线模块。说实话,我一开始研究的时候,发现nRF24L01模块是SPI接口,而linux下又自带了SPI平台驱动,应该很好的对接上去,研究了两天,发现不管是用SPI子系统还是IO模拟,都有一个共同的地方,就是都需要封装nRF24L01的一些函数,发送接收等函数,为了省时省力(当时离答辩只有一个月时间,还有QT和CGI方面没有研究),没有再去研究那个功能强大的SPI子系统,选了简单的IO模拟来控制。我的主控板是友善之臂的TINY4412。代码如下。 /************************************************************/ //文件名:nrf24l01.c //功能:linux下的nrf24l01驱动程序 //使用说明: (1)友善之臂tiny4412 // (2)主控芯片cortex-A9 // (3)linux3.5内核 //作者:juring-江 //日期:2015-03-09 /************************************************************/ #include #include #include #include #include #include #include #include #include #include typedef unsigned char uchar; //NRF24L01引脚相关的宏定义 #define CE EXYNOS4_GPA1(1) //con15 3号管脚 #define CSN EXYNOS4_GPA1(0) //con15 4号管脚 #define SCK EXYNOS4_GPD1(1) //con15 5号管脚 #define MOSI EXYNOS4_GPD1(0) //con15 6号管脚 #define MISO EXYNOS4_GPB(0) //con15 9号管脚 #define IRQ EXYNOS4_GPB(1) //con15 10号管脚 #define DEVICE_NAME "NRF24L01" //设备名称,在可以 /proc/devices 查看 //NRF24L01 #define TX_ADR_WIDTH 5 // 5 uint8s TX address width #define RX_ADR_WIDTH 5 // 5 uint8s RX address width #define TX_PLOAD_WIDTH 32 // 20 uint8s TX payload #define RX_PLOAD_WIDTH 32 // 20 uint8s TX payload uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址 uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址 //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 // 接收频道0接收数据长度 #define RX_PW_P2 0x13 // 接收频道0接收数据长度 #define RX_PW_P3 0x14 // 接收频道0接收数据长度 #define RX_PW_P4 0x15 // 接收频道0接收数据长度 #define RX_PW_P5 0x16 // 接收频道0接收数据长度 #define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 uchar opencount = 0; uchar /*bdata*/ sta; typedef struct uchar_bits { uchar bit0:1; //位域表示方法,表示bit0只占一个位 uchar bit1:1; uchar bit2:1; uchar bit3:1; uchar bit4:1; uchar bit5:1; uchar bit6:1; uchar bit7:1; }uchar_bits, uint8_bits; #define RX_DR (((uchar_bits *)&sta)->bit6) //sbit RX_DR=sta^6; #define TX_DS (((uchar_bits *)&sta)->bit5) //sbit TX_DS=sta^5; #define MAX_RT (((uchar_bits *)&sta)->bit4) //sbit MAX_RT=sta^4; extern unsigned int s3c2410_gpio_getpin(unsigned int pin); extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to); extern void s3c2410_gpio_pullup(unsigned int pin, unsigned int to); //=========================================// /**********************************************/ //函数:uchar SPI_RW(uchar tmp) //功能:SPI时序 /*********************************************/ uchar SPI_RW(uchar tmp) { uchar bit_ctr; for(bit_ctr=0 ;bit_ctr<8 ;bit_ctr++) // output 8-bit { if(tmp & 0x80) // output 'tmp', MSB to MOSI s3c2410_gpio_setpin(MOSI, 1); //MOSI=1 else s3c2410_gpio_setpin(MOSI, 0); //MOSI=0 ndelay(60); tmp <<= 1; // shift next bit into MSB.. s3c2410_gpio_setpin(SCK, 1); // Set SCK high.. ndelay(60); tmp |= s3c2410_gpio_getpin(MISO) ; // byte |= MISO; s3c2410_gpio_setpin(SCK, 0); // ..then set SCK low again ndelay(60); } return(tmp); // return read tmp } /************************************************** //函数:uchar NRFWriteReg(uchar RegAddr,uchar date) //功能:NRF24L01写寄存器函数 **************************************************/ uchar NRF24L01_Write_Reg(uchar RegAddr,uchar date) { uchar status; s3c2410_gpio_setpin(CSN, 0); //CSN=0; // CSN low, init SPI transaction ndelay(60); status = SPI_RW(RegAddr); // select register SPI_RW(date); // ..and write value to it.. s3c2410_gpio_setpin(CSN, 1); //CSN=1 // CSN high again ndelay(60); return(status); // return nRF24L01 status byte } /************************************************** //函数:uchar NRFWriteReg(uchar RegAddr,uchar date) //功能:NRF24L01读寄存器函数 **************************************************/ uchar NRF24L01_Read_Reg(uchar RegAddr) { uchar status; s3c2410_gpio_setpin(CSN, 0); //CSN=0; // CSN low, init SPI transaction ndelay(60); SPI_RW(RegAddr); // select register status = SPI_RW(0); // ..and write value to it.. s3c2410_gpio_setpin(CSN, 1); //CSN=1 // CSN high again ndelay(60); return(status); // return nRF24L01 status byte } /*********************************************************************************************** //函数:uchar NRF24L01_Read_RxDate(uchar RegAddr,uchar *RxDate,uchar DateLen) //功能: 用于读数据,RegAddr:为寄存器地址,RxDate:为待读出数据地址,DateLen:读出数据的长度 ***********************************************************************************************/ uchar NRF24L01_Read_RxDate(uchar RegAddr,uchar *RxDate,uchar DateLen) { uchar status,i; s3c2410_gpio_setpin(CSN, 0); // Set CSN low, init SPI tranaction ndelay(60); status = SPI_RW(RegAddr); // Select register to write to and read status uint8 for(i = 0;i < DateLen;i++) { RxDate[i] = SPI_RW(0); // ndelay(20); } s3c2410_gpio_setpin(CSN, 1); //csn=1 ndelay(60); return(status); // return nRF24L01 status uint8 } /*********************************************************************************************** //函数:uchar NRF24L01_Write_TxDate(uchar RegAddr,uchar *TxDate,uchar DateLen) //功能: 用于读数据,RegAddr:为寄存器地址,TxDate:为待写入数据地址,DateLen:读出数据的长度 ***********************************************************************************************/ uchar NRF24L01_Write_TxDate(uchar RegAddr,uchar *TxDate,uchar DateLen) { uchar BackDate,i; s3c2410_gpio_setpin(CSN, 0); ndelay(60); BackDate=SPI_RW(RegAddr); for(i=0;i

代码地址    https://github.com/Juringvay/nRF24L01.git