从开始接触,到驱动编写调试完成,前前后后花费10多天,网上浏览了一下,目前还没有找到硬件SPI控制NRF24L01的驱动程序,绝大多数都是软件SPI,但是软件SPI不好,不稳定,既然都写驱动程序了,肯定要用硬件SPI啦,这样才能学到东西。学习的过程中,通过看韦东山的SPI视频,和参考他写的两个驱动程序。然后花费了四五天,终于将驱动写好了。 这个驱动可以通过ioctl切换接收和发送模式,通过read,write选择接收数据还是发送数据,废话少说,上代码
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "nrf.h"/* 构造注册 spi_driver */#define RX_MODE 0xf1#define TX_MODE 0xf2static int major;static struct class *class;static int spi_NRF24L01_ce_pin;static unsigned char *ker_buf;static struct spi_device *spi_NRF24L01_dev;static unsigned char opencount = 0;static volatile int int_flag = 0;static DECLARE_WAIT_QUEUE_HEAD(nrf24l01_waitq); /*生成一个等待队列头wait_queue_head_t,名字为nrf24l01_waitq*/static unsigned char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x10}; //本地地址static unsigned char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x10}; //接收地址struct pin_desc{ unsigned int pin; unsigned int key_val; };/*引脚描述结构体*/struct pin_desc pins_desc[2]={ /*按下时 :0x01 0x02 ... 松开始0x81 0x 82 ...*/ {S3C2410_GPG(0),0x01}, }; static uint8 TxBuf[TxBufSize]={ 0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08, 0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16, 0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24, 0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32, };static uint8 RxBuf[RxBufSize]={0};static void NRF24L01_Set_CE(char val) { s3c2410_gpio_setpin(spi_NRF24L01_ce_pin, val); }/*寄存器访问函数:用来设置 24L01 的寄存器的值。基本思路就是通过 WRITE_REG 命令(也 就是 0x20+寄存器地址)把要设定的值写到相应的寄存器地址里面去,并读取返回值。对于 函数来说也就是把 value 值写到 reg 寄存器中*/static unsigned char SPI_RW_Reg(unsigned char reg,unsigned char value) { unsigned char status; unsigned char tx_buf[2]; unsigned char rx_buf[2]; tx_buf[0] = reg; tx_buf[1] = value; spi_write(spi_NRF24L01_dev, tx_buf, 2); status = rx_buf[0]; return (status); }/*读取寄存器值的函数:基本思路就是通过 READ_REG 命令(也就是 0x00+寄存器地址),把 寄存器中的值读出来。对于函数来说也就是把 reg 寄存器的值读到 reg_val 中去*/static void SPI_Read(int *pMID, int *pDID,unsigned char reg) { unsigned char tx_buf[2]; unsigned char rx_buf[2]; tx_buf[0] = reg; tx_buf[1] = 0x00; spi_write_then_read(spi_NRF24L01_dev, tx_buf, 2, rx_buf, 2); *pMID = rx_buf[0]; *pDID = rx_buf[1]; } /*接收缓冲区访问函数:主要用来在接收时读取 FIFO 缓冲区中的值。基本思路就是通过 READ_REG 命令把数据从接收 FIFO(RD_RX_PLOAD)中读出并存到数组里面去*///static unsigned char SPI_Read_Buf(unsigned char reg,unsigned char * ker_buf,unsigned char bytes)static void SPI_Read_Buf(unsigned char reg, unsigned char * buf, int len) { /* spi_write_then_read规定了tx_cnt+rx_cnt < 32 * 所以对于大量数据的读取,不能使用该函数 */ unsigned char i=0; unsigned char tx_buf[1]; unsigned char tx_buf1[len]; struct spi_transfer t[] = { { .tx_buf = tx_buf, .len = 1, }, { .tx_buf = tx_buf1, .rx_buf = buf, .len = len, }, }; struct spi_message m; for(i=0;i 这个是头文件 nrf.h
//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//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栈入栈出状态寄存器设置#define MAX_TX 0x10 //达到最大发送次数中断#define TX_OK 0x20 //TX发送完成中断#define RX_OK 0x40 //接收到数据中断#define TxBufSize 32#define RxBufSize 32typedef unsigned int uint16 ; typedef unsigned char uint8 ;
上一篇:STM32 软件模拟SPI时序驱动NRF24L01
下一篇:STM32值SPI的使用及SPI初始化注意事项
推荐阅读最新更新时间:2024-03-16 15:38