温度检测系统

功能设计

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

温度检测系统的相关文章

空气质量在线检测系统制作 之Smart Airbox 制作流程

已刊登在<无线电>8月刊 在帝都生活的小伙伴们,想必对空气质量一定是不能再敏感,十几米的能见度想想也是醉了.一遇到久违的蓝天,朋友圈就被各种炫蓝天的照片刷屏.既然已经无法奢望室外空气,就在室内空气上下点功夫吧,毕竟一天中的大多数时间还是在室内度过的.于是乎,小熊决定做一个智能空气盒子,实时检测家里的空气是否达标.关爱绳命,从一呼一吸开始- 项目简介 智能空气盒子(Smart AirBox)是空气质量在线检测系统的雏形.该系统可以监测周围的空气质量(VOC.PM2.5.温度.湿度等),并将参数数

搭建开源入侵检测系统Snort并实现与防火墙联动

Snort作为一款优秀的开源主机入侵检测系统,在windows和Linux平台上均可安装运行.BT5作为曾经的一款经典的渗透神器,基于 Ubuntu,里面已经预装很多的应用,比如Mysql.Apache.Snort等等.Guardian是snort的插件,通过读取snort报警日 志将入侵IP加入到Iptables中.Iptables 是与最新的 3.5 版本 Linux 内核集成的 IP 信息包过滤系统. 本文详细介绍了BT5中安装snrot NIDS并实现与iptables防火墙联动的过程.

代码抄袭检测系统的设计和实现(1)--需求分析和基础架构

前言: 其实挺意外的, 最近和大学的老师联系, 得知4年前写的代码抄袭检测系统还在运行, 又惊又喜, 还以为早就替换升级了.  千百次回眸, 可惜界面依旧不给面子的简陋, 不过"金窝, 银窝, 不如自家的草窝", 脑补之后, 越看越帅气, ^_^!!. 让我们暂时抛开"娇俏动人"的web界面, 来谈谈背后"核心"的相似检测算法. 算法未必华丽, 效果未必惊艳, 但愿与大家一起分享, 与君共勉. 场景: 让我们来玩个游戏, 假设我们是懒得"

如何开发一个异常检测系统:如何评价一个异常检测算法

利用数值来评价一个异常检测算法的重要性 使用实数评价法很重要,当你用某个算法来开发一个具体的机器学习应用时,你常常需要做出很多决定,如选择什么样的特征等等,如果你能找到如何来评价算法,直接返回一个实数来告诉你算法的好坏,那样你做决定就会更容易一些.如现在有一个特征,要不要将这个特征考虑进来?如果你带上这个特征运行你的算法,再去掉这个特征运行你的算法,得到返回的实数,这个实数直接告诉你加上这个特征算法是变好了还是变坏了,这样你就有一种更简单的算法来确定是否要加上这个特征. 为了更快地开发出一个异常

安装oracle时,检测系统要求时状态为错误的解决办法

在安装oracle时,检测系统要求时状态为错误的解决办法: 正在检查操作系统要求.... 要求的结果:5.0,5.1,5.2,6.0之一 实际结果:6.1      实际上是因为配置文件引起的      找到 refhost.xml 文件(位置:database/stage/prereq/db,打开 refhost.xml 配置文件并找到 <CERTIFIED_SYSTEMS> 节点,接着在节点后面修改6.0至6.1      <!--Microsoft Windows 7-->

Easyspy网络检测系统

Easyspy是一款网络入侵检测和流量实时监控软件.作为一个入侵检测系统,用来快速发现并定位诸如ARP攻击.DOS/DDOS.分片IP报文攻击等恶意攻击行为,帮助发现潜在的安全隐患.Easyspy又是一款Sniffer软件,用来进行故障诊断,快速排查网络故障,准确定位故障点,评估网络性能,查找网络瓶颈从而保障网络质量. 实时监控,发现问题.. 烈焰下载:http://pan.baidu.com/s/1hqrE2mo Easyspy网络检测系统

浅析论文检测系统的发展历程

近日教育部针对目前的学术不端行为出台了<关于对学位论文作假行为的暂行处理办法(征求意见稿)>.办法中规定指导教师未尽到学术道德和学术规范教育.论文指导和审查把关等职责,其负责指导的学生学位论文存在购买.他人代写或者抄袭.剽窃等作假情形的,学位授予单位视情节轻重,可暂停其招生.取消指导教师资格,并可给予处分直至解除聘任合同等处理.于是各高校采取引用论文抄袭检测系统的方法检测学生的抄袭,高校学生必须通过了论文抄袭检测系统的检测才能获得正式答辩资格,目前本科院校也引用了这一系统. 现如今,本科院校的

百科知识 学位论文学术不端行为检测系统简介

学位论文学术不端行为检测系统 研制介绍与使用方法 第一章 系统简介 1.1 系统概述 学位论文学术不端行为检测系统(简称"TMLC")以<中国学术文献网络出版总库>为全文比对数据库,实现了对抄袭与剽窃.伪造.篡改等学术不端行为的快速检测,可供用户检测学位论文,并支持用户自建比对库.其系统示意图如图1所示. 图1 检测系统示意图 1.2 系统技术路线介绍 TMLC 采用CNKI 自主研发的自适应多阶指纹(AMLFP)特征检测技术,具有检测速度快,准确率,召回率较高,抗干扰性强

php通过变通方法检测系统的文件夹路径编码

最近在通过php来写一个类似ftp的的web-ftp平台; 需要兼容linux和window的路径访问; 过程中发现window与linux使用的路径编码是不一样的,比如linux好像是utf-8,window却是gbk; php的编码是utf-8,如果路径中有中文,统一使用utf-8编码来访问路径,就会出现像file_exists这类fs方法出现无法访问情况; 因为路径不存在,原因就是utf-8按照gbk的格式来解析路径编码时,肯定是中文变成不的字符了;就出现路径不存在而出错; 这时就需要自动