温度检测系统

功能设计

温度传感器读取环境数据,通过无线发送模块发给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位数据

猜你喜欢

转载自www.cnblogs.com/learning-zjx/p/10266068.html