功能设计
温度传感器读取环境数据,通过无线发送模块发给MCU,上位机显示温度数据。设计要求:发送平台由两块LR44纽扣电池供电,每块电池电量160mAH;每隔24个小时(测试时间是15s)检测一次温度数据并发送给上位机,要求发送平台在不发送时进入低功耗模式,实现低功耗设计。
器件选择
STM32L151C8T6 + LM75BD + NRF24L01
电路图
1. 发送模块电路原理图
2. 发送模块电路PCB图
3D:
3. 接收模块电路原理图
4.发送模块电路PCB图
3D:
STM32CUBEMX相关配置
1. 引脚设置
2. 时钟配置
3. RTC配置
4. I2C配置
5.SPI配置
6. UART配置
7. GPIO配置
8. NVIC配置
程序设计
温度模块
寄存器配置及配置字:
/******************************************************************************************************/ // LM75BD控制字及寄存器 /******************************************************************************************************/ //char str[20]; //读出的温度数据 uint8_t buffer_receive[2] = {0x00,0x00}; //温度寄存器地址 uint8_t temp_regist=0x00; //配置寄存器地址 uint8_t control_regist=0x01; //温度下限寄存器地址 uint8_t thyst_regist=0x02; //温度上限寄存器地址 uint8_t tos_regist=0x03; //配置字 uint8_t config_byte=0x06; //温度下限初始值 uint8_t test=0; //温度超上下限中断信号 uint8_t over_tem; //温度下限 uint8_t tem_thyst; //温度上限 //uint8_t tem_tos; char tem_status[10]; //当前温度没超过上下限 char safe[]="Safe"; //当前温度超过上下 限 char danger[]="Danger"; //结果 //高位 signed int MS; //低位 signed int ML; //读到的数据 signed int result; //根据当前结果设置的下限 signed int result_thyst; //根据当前结果设置的上限 signed int result_tos;
读取温度数据,并根据当前温度设置上下限:
/******************************************************************************************************/ // 配置寄存器 /******************************************************************************************************/ //地址0x01+配置寄存器0x026:OS高有效,中断模式 HAL_I2C_Mem_Write(&hi2c1, 0x90, control_regist, 1, (uint8_t*)&config_byte, 1, 1000); /* 设置温度下限 */ //下限,默认为70,设置为0 uint8_t thyst_ini[2]={0x00,0x00}; HAL_I2C_Mem_Write(&hi2c1, 0x90, thyst_regist, 1, (uint8_t*)thyst_ini, 2, 1000); /******************************************************************************************************/ // 读温度数据 /******************************************************************************************************/ //温度寄存器地址0x00 //主机接收数据,设备地址0x90,先输出高字节 HAL_I2C_Mem_Read(&hi2c1, 0x90, temp_regist, 1, buffer_receive, 2, 1000); /******************************************************************************************************/ // 根据当前温度设置温度上下限 /******************************************************************************************************/ //拼接成16位数据 MS=buffer_receive[0]; ML=buffer_receive[1]; result=0; result=result | MS; result=result<<8; result=result | ML; //处理后结果 //HAL_UART_Transmit(&huart1,(uint8_t*)&result,2,1000); //上限值=当前温度+3℃ result_tos=result+0x0300; //下限值=当前温度-3℃ result_thyst=result-0x0300; uint8_t MS_tos=result_tos>>8; uint8_t ML_tos=(result_tos<<8)>>8; uint8_t MS_thy=result_thyst>>8; uint8_t ML_thy=(result_thyst<<8)>>8; //设置温度上限 //上限寄存器地址0x03 uint8_t tem_tos[2]={MS_tos,ML_tos}; HAL_I2C_Mem_Write(&hi2c1, 0x90, tos_regist, 1, tem_tos, 2, 1000); //设置温度下限 //下限寄存器地址:0x02 uint8_t tem_thy[2]={MS_thy,ML_thy}; HAL_I2C_Mem_Write(&hi2c1, 0x90, thyst_regist, 1, tem_thy, 2, 1000); /******************************************************************************************************/
测试LM75BD过温中断功能
/******************************************************************************************************/ // 温度超过上下限 /******************************************************************************************************/ over_tem=HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0); if(!over_tem){ sprintf(tem_status, "%s\n", safe); uint8_t haha=0xff; HAL_UART_Transmit(&huart1,(uint8_t*) &haha,1,0xffff); } else { sprintf(tem_status, "%s\n", danger); HAL_UART_Transmit(&huart1,(uint8_t*) tem_status,10,0xffff); //读温度数据,拉高OS(硬件内部) //温度寄存器地址0x00 //while(HAL_I2C_Master_Transmit(&hi2c1, 0x90, &temp_regist, 1, 1000)!=HAL_OK); //主机接收数据,设备地址0x90,先输出高字节 //while(HAL_I2C_Master_Receive(&hi2c1, 0x90, (uint8_t*)buffer_receive, 2, 100)!=HAL_OK); HAL_I2C_Mem_Read(&hi2c1, 0x90, temp_regist, 1, buffer_receive, 2, 1000); HAL_UART_Transmit(&huart1,(uint8_t*)buffer_receive,2,1000); } /******************************************************************************************************/
阅读datasheet:
上电后,当温度第一次超过上限时,才会发出中断,之后低于下限时发出中断。
无线模块发送数据
指令字与寄存器地址
/******************************************************************************************************/ //NRF24L01指令字 /******************************************************************************************************/ //读寄存器指令 uint8_t READ_REG=0x00; //写寄存器指令 uint8_t WRITE_REG=0x20; //读取接收数据指令 uint8_t RD_RX_PLOAD=0x61; //发送数据命令字 uint8_t W_TX_PAYLOAD=0xA0; //清空TX FIFO指令 uint8_t FLUSH_TX=0xE1; //清空RX FIFO指令 uint8_t FLUSH_RX=0xE2; //复用上次发送载荷 uint8_t REUSE_TX_PL=0xE3; //无操作,用于读取状态寄存器 uint8_t NOP=0xFF; /******************************************************************************************************/ //NRF24L01寄存器地址 /******************************************************************************************************/ //配置字寄存器地址 uint8_t nRF_CONFIG=0x00; //自动应答功能设置:01 uint8_t EN_AA=0x01; //可用信道设置:02 uint8_t EN_ADDR=0x02; //自动重发功能设置:04 uint8_t SETUP_RETR=0x04; //RF_CH uint8_t RF_CH=0x05; //射频配置 uint8_t RF_SETUP=0x06; //状态寄存器地址 uint8_t status_addr=0x07; //发送检测 uint8_t tran_dec=0x08; //接收功率检测 uint8_t receive_pwr=0x09; //频道0接收数据地址 uint8_t regist_addr=0x0A; //发送地址寄存器 uint8_t TX_ADDR=0x10; //接收数据大小配置寄存器 uint8_t receive_byte_reg=0x11;
对寄存器写操作:写指令字+寄存器地址,同样读操作:读指令字+寄存器地址
//写寄存器指令+RF_CH寄存器地址=0x20+0x08 uint8_t Wr_trandec=WRITE_REG+tran_dec; //写寄存器指令+RF_CH寄存器地址=0x20+0x05 uint8_t Re_pwr=WRITE_REG+receive_pwr; //写寄存器指令+RF_CH寄存器地址=0x20+0x05 uint8_t Wr_RFCH=WRITE_REG+RF_CH; //写寄存器指令+RF_SETUP寄存器地址=0x20+0x06 uint8_t Wr_RFsetup=WRITE_REG+RF_SETUP; //写寄存器指令+ENAA寄存器地址=0x20+0x01 uint8_t Wr_ENAA=WRITE_REG+EN_AA; //写寄存器指令+ENAA寄存器地址=0x20+0x02 uint8_t Wr_ENADDR=WRITE_REG+EN_ADDR; //写寄存器指令+配置寄存器地址=0x20+0x00 uint8_t COM_CONFIG=WRITE_REG+nRF_CONFIG; //写寄存器指令+自动重发功能设置寄存器地址=0x20+0x04 uint8_t COM_SETUP=WRITE_REG+SETUP_RETR; //写寄存器指令+发送地址寄存器=0x20+0x10 uint8_t ADDR_CONFIG=WRITE_REG+TX_ADDR; //写寄存器指令+接收端地址=0x20+0x0A uint8_t RX_ADDR=WRITE_REG+regist_addr; //读状态寄存器指令+状态寄存器地址=0x00+0x07 uint8_t Read_Status=READ_REG+status_addr; //写状态寄存器指令+状态寄存器地址=0x20+0x07 uint8_t Wr_Status=WRITE_REG+status_addr; //写寄存器指令+状态寄存器地址=0x20+0x07 uint8_t Wr_Stuts=WRITE_REG+status_addr; //写寄存器指令+配置接收数据数量=0x20+0x11 uint8_t Wr_receivebyte=WRITE_REG+receive_byte_reg; //写寄存器指令+配置接收数据数量=0x20+0x11 uint8_t Rd_receivebyte=READ_REG+receive_byte_reg;
相关数据定义
//重传次数寄存器配置 uint8_t SETUP_NUM=0xFF; //RF_CH uint8_t RFCH_COM=0x00; //RF_SETUP设置 uint8_t RF_COM=0x07; //本地地址:发送端本机地址即接收端接受地址 uint8_t TX_ADDRESS0[5]={0x01,0x01,0x01,0x01,0x01}; //接收地址:发送端接收地址即接收端的本机地址 uint8_t RX_ADDRESS0[5]={0x10,0x10,0x10,0x10,0x10}; //发送模式配置字 uint8_t TX_CONFIG =0x0E; //接收模式配置字 uint8_t RX_CONFIG=0x0F; //状态寄存器数据 uint8_t status; //清除状态寄存器数据 uint8_t status_clear=0x7E; //接收端接收数据大小 uint8_t receive_byte=0x02; //发送端接收数据大小 uint8_t tran_byte=0x02; //ENAA值 uint8_t EN_A=0x01; //EN_ADDR uint8_t EN_ADD=0x01;
发送代码
/******************************************************************************************************/ /* SPI发送数据 */ /******************************************************************************************************/ //拉低CE脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); //本地地址配置 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+发送地址寄存器=0x20+0x10 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&ADDR_CONFIG, 1, 1000)!=HAL_OK); //地址写入:0x01,0x01,0x01,0x01,0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&TX_ADDRESS0, 5, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //接收端地址 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+发送地址寄存器=0x20+0x0A while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RX_ADDR, 1, 1000)!=HAL_OK); //地址写入:0x10,0x10,0x10,0x10,0x10 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RX_ADDRESS0, 5, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //EN_AA //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+EN_AA寄存器=0x20+0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_ENAA, 1, 1000)!=HAL_OK); //指令:0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&EN_A, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //EN_RXADDR //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+EN_ADDR寄存器=0x20+0x02 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_ENADDR, 1, 1000)!=HAL_OK); //指令:0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&EN_ADD, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //重传次数 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+重传次数=0x20+0x04 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&COM_SETUP, 1, 1000)!=HAL_OK); //次数写入 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&SETUP_NUM, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //通信频率 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+重传次数=0x20+0x04 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_RFCH, 1, 1000)!=HAL_OK); //次数写入 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RFCH_COM, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //发射参数 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+重传次数=0x20+0x04 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_RFsetup, 1, 1000)!=HAL_OK); //次数写入 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RF_COM, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //通道0有效数据长度 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+配置接收数据数量=0x20+0x11 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_receivebyte, 1, 1000)!=HAL_OK); //指令:0000_0010 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&tran_byte, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //发送数据写入 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //数据写入命令字:0xA0 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&W_TX_PAYLOAD, 1, 1000)!=HAL_OK); //数据 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)buffer_receive, 2, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //CONFIG寄存器配置 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+配置寄存器地址=0x20+0x00 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&COM_CONFIG, 3, 1000)!=HAL_OK); //配置字:00001110 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&TX_CONFIG, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //激活模式:发送 //拉高CE HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); //发送数据时脉冲 HAL_Delay(100); //拉低CE HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); /******************************************************************************************************/ //IRQ低有效 receive=HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2); while(receive){ receive=HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2); }; //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); /******************************************************************************************************/ //清除TX_DS位 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+状态寄存器地址=0x20+0x07 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_Stuts, 1, 1000)!=HAL_OK); while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&status_clear, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //重洗FIFO指令:0xE1 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //重洗FIFO指令 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&FLUSH_TX, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/
进入StandBy模式,降低整个平台功耗
RTC配置
/* RTC init function */ void MX_RTC_Init(void) { RTC_TimeTypeDef sTime; RTC_DateTypeDef sDate; /**Initialize RTC and set the Time and Date */ hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 127; hrtc.Init.SynchPrediv = 255; hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; HAL_RTC_Init(&hrtc); sTime.Hours = 0x17; sTime.Minutes = 0x13; sTime.Seconds = 0x00; sTime.TimeFormat = RTC_HOURFORMAT12_AM; sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sTime.StoreOperation = RTC_STOREOPERATION_RESET; HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BCD); sDate.WeekDay = RTC_WEEKDAY_FRIDAY; sDate.Month = RTC_MONTH_JANUARY; sDate.Date = 0x11; sDate.Year = 0x19; HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BCD); /**Enable the WakeUp */ //HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x01, RTC_WAKEUPCLOCK_RTCCLK_DIV16); }
进入低功耗函数
void enter_stop_rtc(){ /* Enable Ultra low power mode */ HAL_PWREx_EnableUltraLowPower(); /* Enable Fast WakeUP */ HAL_PWREx_EnableFastWakeUp(); /* Disable Wakeup Counter */ HAL_RTCEx_DeactivateWakeUpTimer(&hrtc); /*To configure the wake up timer to 4s the WakeUpCounter is set to 0x242B: RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16 Wakeup Time Base = 16 /(37KHz) = ~0.432 ms Wakeup Time = ~5s = 0.432ms * WakeUpCounter ==> WakeUpCounter = ~5s/0.432ms = 11562 */ //数值=时间*2312 HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 34680, RTC_WAKEUPCLOCK_RTCCLK_DIV16); //system_power_config(); //MX_RTC_Init(); //待机模式 HAL_PWR_EnterSTANDBYMode(); //HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); /* Clear all related wakeup flags */ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); //清除标志,否则第二次以后无法进入休眠 SystemClock_Config(); }
主函数内
//关闭外设 //关闭LM75BD config_byte=0x01; HAL_I2C_Mem_Write(&hi2c1, 0x90, control_regist, 1, (uint8_t*)&config_byte, 1, 1000); //关闭NRF24L01 //CONFIG寄存器配置 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+配置寄存器地址=0x20+0x00 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&COM_CONFIG, 3, 1000)!=HAL_OK); //配置字:00001000 uint8_t standby_config=0x08; while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&standby_config, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /* Clear all related wakeup flags */ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); //清除标志,否则第二次以后无法进入休眠 enter_stop_rtc();
无线接收代码
/******************************************************************************************************/ /* 接收数据 */ /******************************************************************************************************/ while(1){ //拉低CE脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); //本地地址配置 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+发送地址寄存器=0x20+0x10 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&ADDR_CONFIG, 1, 1000)!=HAL_OK); //地址写入:0x10,0x10,0x10,0x10,0x10,与发送端相反 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RX_ADDRESS0, 5, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //接收地址配置 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+发送地址寄存器=0x20+0x0A while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RX_ADDR, 1, 1000)!=HAL_OK); //地址写入:0x01,0x01,0x01,0x01,0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&TX_ADDRESS0, 5, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //EN_AA //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+EN_AA寄存器=0x20+0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_ENAA, 1, 1000)!=HAL_OK); //指令:0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&EN_A, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //EN_RXADDR //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_ENADDR, 1, 1000)!=HAL_OK); //指令:0x01 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&EN_ADD, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //通信频率 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_RFCH, 1, 1000)!=HAL_OK); //次数写入 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RFCH_COM, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //发射参数 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+重传次数=0x20+0x06 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_RFsetup, 1, 1000)!=HAL_OK); //次数写入 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RF_COM, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //接收有效宽度 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+配置接收数据数量=0x20+0x11 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_receivebyte, 1, 1000)!=HAL_OK); //指令:0000_0010 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&receive_byte, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //清除RX_DR位 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写指令+状态寄存器地址:0x20+0x07 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_Status, 1, 1000)!=HAL_OK); //数据 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&status_clear, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //清RX FIFO //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //重洗FIFO指令 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&FLUSH_RX, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //CONFIG寄存器配置 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写寄存器指令+配置寄存器地址=0x20+0x00 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&COM_CONFIG, 1, 1000)!=HAL_OK); //指令:00001111 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RX_CONFIG, 1, 1000)!=HAL_OK); //写完拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //接收 //拉高CE脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); HAL_Delay(10); //拉低CE脚 /*HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);*/ /******************************************************************************************************/ //IRQ低有效 while((receive=HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2))){ } //拉低CE脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); /******************************************************************************************************/ //清除RX_DR位 //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //写指令+状态寄存器地址:0x20+0x07 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&Wr_Status, 1, 1000)!=HAL_OK); //数据 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&status_clear, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //读取接收数据命令字 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&RD_RX_PLOAD, 1, 1000)!=HAL_OK); //接收数据 while(HAL_SPI_Receive(&hspi1, (uint8_t*)data_receive, 2, 1000) != HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ //清RX FIFO //拉低CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); //重洗FIFO指令 while(HAL_SPI_Transmit(&hspi1, (uint8_t*)&FLUSH_RX, 1, 1000)!=HAL_OK); //拉高CSN引脚 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); /******************************************************************************************************/ /******************************************************************************************************/ // 上位机处理数据 /******************************************************************************************************/ //未处理数据 HAL_UART_Transmit(&huart1,(uint8_t*)data_receive,2,0xffff); }
上位机处理数据
JAVA代码来自:
https://www.cnblogs.com/Dreamer-1/p/5523046.html
数据处理部分:对检测串口的数据进行处理
int byte_int = ((data[0] & 0xFF) << 8)| (data[1] & 0xFF); int after_tran = byte_int>>5; double result=after_tran*0.125;
联合调试结果
遇到的问题
1. 发送端状态寄存器值为:0x1E,接收到仍然能接收到数据
2. 每次从StandBy模式唤醒时,接收端接收到两个数据(16位),而不是一个16位数据
原文地址:https://www.cnblogs.com/learning-zjx/p/10266068.html
时间: 2024-10-01 11:55:25