一直想整理下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