#include "24l01.h" #include "string.h" #include "stdlib.h" #include "stdio.h" #ifndef BOOTLOADER #include "rthw.h" #define IRQ_DISABLE() rt_enter_critical() #define IRQ_ENABLE() rt_exit_critical() #else #define IRQ_DISABLE() { } #define IRQ_ENABLE() { } #endif /* +--------------------------+ |GND |3V3 | | |-----------| | |CE |CS | | |-----------| | |SCK |MOSI | | |-----------| | |MISO |INT | | +--------------------------+ +--------------------------+ |GND |3V3 | | |-----------| | |PE3 |PE4 | | |-----------| | |PE2 |PE6 | | |-----------| | |PE5 |PB6 | | +--------------------------+ */ // 接口函数 static void nrf24l01_dalay_us(int us) { #ifndef BOOTLOADER rt_hw_us_delay(us); #else for(int i=0;i<30;i++); #endif } static u32 nrf24l01_det_random(void) { static int d=0; d++; return d; } // 24L01片选信号 PE3 #define NRF24L01_CE(s) GPIO_WriteBit(GPIOE,GPIO_Pin_3,(BitAction)s) // SPI片选信号 PE4 #define NRF24L01_CSN(s) GPIO_WriteBit(GPIOE,GPIO_Pin_4,(BitAction)s) // IRQ主机数据输入 PB6 #define NRF24L01_IRQ() GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6) typedef struct { // 总中断服务函数 void (*irq)(void); // 发送完成回调 void (*send_end_cb)(void *); void *send_end_cb_par; // 接收到数据回调 void (*recved_cb)(void *); void *recved_cb_par; }nrf_struct; static nrf_struct g_nrf={0}; static const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址 static const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址 void nrf24l01_spi_init(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI4,ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE); GPIO_PinAFConfig(GPIOE, GPIO_PinSource2, GPIO_AF_SPI4); GPIO_PinAFConfig(GPIOE, GPIO_PinSource5, GPIO_AF_SPI4); GPIO_PinAFConfig(GPIOE, GPIO_PinSource6, GPIO_AF_SPI4); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; /*!< SPI SCK pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOE, &GPIO_InitStructure); /*!< SPI MOSI pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_Init(GPIOE, &GPIO_InitStructure); /*!< SPI MISO pin configuration */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_Init(GPIOE, &GPIO_InitStructure); /*!< Configure sFLASH Card CS pin in output pushpull mode ********************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOE, &GPIO_InitStructure); //失能SPI外设 SPI_Cmd(SPI4, DISABLE); //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //串行同步时钟的空闲状态为低电平 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //串行同步时钟的第1个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //CRC值计算的多项式 SPI_InitStructure.SPI_CRCPolynomial = 7; //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Init(SPI4, &SPI_InitStructure); //使能SPI外设 SPI_Cmd(SPI4, ENABLE); } // 软件初始化,默认进入接收模式 void nrf24l01_sort_init(void); //初始化24L01的IO口 void nrf24l01_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOB,G时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_EXTIT,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟 // GE3 片选推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOE, &GPIO_InitStructure); // GB6 中断输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOB, &GPIO_InitStructure); EXTI_InitTypeDef EXTI_InitStruct={0}; SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource6); EXTI_InitStruct.EXTI_Line= EXTI_Line6; EXTI_InitStruct.EXTI_Mode= EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling; EXTI_InitStruct.EXTI_LineCmd= ENABLE; EXTI_Init(&EXTI_InitStruct); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // 针对NRF的特点初始化SPI的设置 nrf24l01_spi_init(); NRF24L01_CE(0); //使能24L01 NRF24L01_CSN(1); //SPI片选取消 nrf24l01_sort_init(); } // 去初始化 void nrf24l01_deinit(void) { EXTI_InitTypeDef EXTI_InitStruct={0}; EXTI_InitStruct.EXTI_Line= EXTI_Line6; EXTI_InitStruct.EXTI_Mode= EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling; EXTI_InitStruct.EXTI_LineCmd= DISABLE; EXTI_Init(&EXTI_InitStruct); NRF24L01_CE(0); } void EXTI9_5_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line6)==SET) { EXTI_ClearITPendingBit(EXTI_Line6); if(g_nrf.irq) g_nrf.irq(); } } u8 spi_read_write_byte(u8 txdata) { // 等待发送区空 while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET){} // 通过外设SPIx发送一个byte 数据 SPI_I2S_SendData(SPI4, txdata); // 等待接收完一个byte while (SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET){} // 返回通过SPIx最近接收的数据 return SPI_I2S_ReceiveData(SPI4); } //SPI写寄存器 //reg:指定寄存器地址 //value:写入的值 u8 nrf24l01_write_reg(u8 reg,u8 value) { u8 status; NRF24L01_CSN(0); //使能SPI传输 status =spi_read_write_byte(reg);//发送寄存器号 spi_read_write_byte(value); //写入寄存器的值 NRF24L01_CSN(1); //禁止SPI传输 return(status); //返回状态值 } //读取SPI寄存器值 //reg:要读的寄存器 u8 nrf24l01_read_reg(u8 reg) { u8 reg_val; NRF24L01_CSN(0); //使能SPI传输 spi_read_write_byte(reg); //发送寄存器号 reg_val=spi_read_write_byte(0XFF);//读取寄存器内容 NRF24L01_CSN(1); //禁止SPI传输 return(reg_val); //返回状态值 } //在指定位置读出指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 u8 nrf24l01_read_buf(u8 reg,u8 *pBuf,u8 len) { u8 status,u8_ctr; NRF24L01_CSN(0); //使能SPI传输 status=spi_read_write_byte(reg);//发送寄存器值(位置),并读取状态值 for(u8_ctr=0;u8_ctr