stm32笔记[14]-读取STS30温度

摘要

在蓝桥杯物联网的CT127C开发板上测试STS30温度模块,通过LoRa显示到NODE_B显示屏上.读写"hello"数据到EEPROM中.

关键信息

  • Keil 5.35.00
  • HAL库版本:STM32Cube FW_L0 V1.12.0
  • STM32CubeMX:6.2.1
  • 芯片:STM32L071KBU

原理简介

STS30温度传感器简介

The STS3x-DIS is Sensirion’s new high accuracy digital temperature sensor. It relies on the industry proven CMOSens® technology, providing for increased intelligence, reliability and improved accuracy specifications compared to its predecessors. Its functionality includes enhanced signal processing, two distinctive and user selectable I2C addresses and
communication speeds of up to 1 MHz. The DFN package has a footprint of 2.5 x 2.5 mm2 while keeping a height of 0.9 mm. This allows for integration of the STS3x-DIS into a great variety of applications. Additionally, the wide supply voltage range of 2.15 V to 5.5 V guarantees compatibility with a wide range of applications. All in all, the STS3x-DIS incorporates more than 15 years of Sensirion’s digital sensor know-how.
STS3x-DIS 是 Sensirion 的新型高精度数字温度传感器。它采用业界经过验证的 CMOSens® 技术,与前辈产品相比,提供了更高的智能、可靠性和精度规格。其功能包括增强的信号处理、两个独特的、用户可选择 I2C 地址以及高达 1 MHz 的通信速度。DFN 封装具有 2.5 x 2.5 mm² 的占地面积,同时保持 0.9 mm 的高度。这使得可以将 STS3x-DIS 集成到各种应用中。此外,2.15 V 至 5.5 V 的宽供应电压范围确保了与广泛的应用兼容。总的来说,STS3x-DIS 集成了 Sensirion 超过 15 年的数字传感器专业知识。

AS312红外热释电传感器简介

The product is a type of intelligent PIR sensor which integrates digital control circuit and body sensitive element in one electromagnetic shielding. The signal inputs from sensitive element to digital circuit via a high impedance differential. The digital circuit converts the input signal to 15bit ADC digital value.
When the PIR signal above the selected threshold, there will be a REL output. The parameter of time are set by resistance to control the time delay of application continuous work.
All signals are processed digitally.
该产品是一种智能PIR传感器,将数字控制电路和人体感应元件集成在一个电磁屏蔽中。敏感元件的信号通过高阻抗差分输入到数字电路中。数字电路将输入信号转换为15位ADC数字值。
当PIR信号高于所选阈值时,将有一个REL输出。时间参数通过电阻设置,以控制应用程序连续工作的时间延迟。
所有信号都经过数字化处理。

STM32L071KBU的内置EEPROM

The STM32L071xx devices have the following features:
• 20 Kbytes of embedded SRAM accessed (read/write) at CPU clock speed with 0 wait
states. With the enhanced bus matrix, operating the RAM does not lead to any
performance penalty during accesses to the system bus (AHB and APB buses).
• The non-volatile memory is divided into three arrays:
– 64, 128 or 192 Kbytes of embedded Flash program memory
6 Kbytes of data EEPROM
– Information block containing 32 user and factory options bytes plus 8 Kbytes of
system memory
Flash program and data EEPROM are divided into two banks. This allows writing in one
bank while running code or reading data from the other bank.
The user options bytes are used to write-protect or read-out protect the memory (with
4 Kbyte granularity) and/or readout-protect the whole memory with the following options:
• Level 0: no protection
• Level 1: memory readout protected.
The Flash memory cannot be read from or written to if either debug features are
connected or boot in RAM is selected
• Level 2: chip readout protected, debug features (Cortex-M0+ serial wire) and boot in
RAM selection disabled (debugline fuse)
The firewall protects parts of code/data from access by the rest of the code that is executed
outside of the protected area. The granularity of the protected code segment or the non-
volatile data segment is 256 bytes (Flash memory or EEPROM) against 64 bytes for the
volatile data segment (RAM).
The whole non-volatile memory embeds the error correction code (ECC) feature.
Bit3 UFB:Userbankswapping
This bit is available only on category 5 devices and reserved on other categories.
It is set and cleared by software. It controls the Bank 1/2 mapping (see Table 10: NVM organization for UFB = 0 (128 Kbyte category 5 devices) and Table 12: NVM organization for UFB = 0 (64 Kbyte category 5 devices)).

  • 0: Flash Program memory Bank 1 is mapped at 0x0800 0000 (and aliased at 0x0000 0000 if MEM_MODE=00) and Data EEPROM Bank 1 at 0x0808 0000 (aliased at 0x0008 0000 if MEM_MODE=00)
  • 1: Flash Program memory Bank 2 is mapped at 0x0800 0000 (and aliased at 0x0000 0000 if MEM_MODE=00) and Data EEPROM Bank 2 at 0x0808 0000 (and aliased at 0x0008 0000 if MEM_MODE=00)
  • 0:闪存程序存储器 Bank 1 映射在 0x0800 0000(如果 MEM_MODE=00,则别名为 0x0000 0000),数据 EEPROM Bank 1 映射在 0x0808 0000(如果 MEM_MODE=00,则别名为 0x0008 0000)。
  • 1:闪存程序存储器 Bank 2 映射在 0x0800 0000(如果 MEM_MODE=00,则别名为 0x0000 0000),数据 EEPROM Bank 2 映射在 0x0808 0000(如果 MEM_MODE=00,则别名为 0x0008 0000)。

实现

NODE_A

  • 读取STS30数据,读写EEPROM,通过LoRa发送温度数据
    main.c
#include "main.h"
#include "oled.h"
#include "eeprom.h"
#include "lora.h"
I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef hi2c3;
SPI_HandleTypeDef hspi1;
TIM_HandleTypeDef htim6;
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_I2C3_Init(void);
static void MX_SPI1_Init(void);
static void MX_TIM6_Init(void);
static void MX_I2C1_Init(void);
/* USER CODE BEGIN PFP */
float readSHS30(void);
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_I2C3_Init();
  MX_SPI1_Init();
  MX_TIM6_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
	OLED_Init();
	LORA_Init();
	unsigned char b2[16];
	// 读写EEPROM
	flashWrite(MCU_Start_Address_Bank1,"hello",strlen("hello"));
	uint8_t test_eeprom[strlen("hello")];
	flashRead(MCU_Start_Address_Bank1,test_eeprom,strlen("hello"));
	sprintf((char*)b2, "r:%s",test_eeprom);
	OLED_ShowString(5, 2, b2, 16);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		char b3[6];
		float temperature = readSHS30();
		sprintf(b3,"%.2f",temperature);
		OLED_ShowString(0, 0, b3, 16);
		uint8_t g_lora_tx_buf[23]; // lora发送缓存
		for(int i=0;i<6;i++){
			g_lora_tx_buf[i]= b3[i];
		}
		LORA_Tx(g_lora_tx_buf,6);
		HAL_Delay(3000);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_4;
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_I2C1
                              |RCC_PERIPHCLK_I2C3;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  PeriphClkInit.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}
static void MX_I2C1_Init(void)
{
  hi2c1.Instance = I2C1;
  hi2c1.Init.Timing = 0x00707CBB;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief I2C3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C3_Init(void)
{

  hi2c3.Instance = I2C3;
  hi2c3.Init.Timing = 0x00707CBB;
  hi2c3.Init.OwnAddress1 = 0;
  hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c3.Init.OwnAddress2 = 0;
  hi2c3.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
  hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Analogue filter
  */
  if (HAL_I2CEx_ConfigAnalogFilter(&hi2c3, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Digital filter
  */
  if (HAL_I2CEx_ConfigDigitalFilter(&hi2c3, 0) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C3_Init 2 */
	 HAL_Delay(100); // 延时以初始化完成
  /* USER CODE END I2C3_Init 2 */

}

/**
  * @brief SPI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI1_Init(void)
{

  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief TIM6 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM6_Init(void)
{

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 0;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 65535;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM6_Init 2 */

  /* USER CODE END TIM6_Init 2 */

}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4|GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_5, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);

  /*Configure GPIO pin : PC14 */
  GPIO_InitStruct.Pin = GPIO_PIN_14;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PC15 */
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PA4 PA9 PA10 PA11
                           PA12 */
  GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB0 PB5 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_5;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
float readSHS30(void){
	unsigned char data[2];
	
	data[0] = 0x24;//不使能时钟伸缿 
	data[1] = 0x0B;//中重复濧测量精庿
	
	HAL_I2C_Master_Transmit(&hi2c1, 0x94, data, 2, 10);
    //0x94是鿚过0x4A向左移一位得来的_0表示冿1表示读,这里朿低位丿0_0X4A为STS30地址
	
	HAL_Delay(10);
	
	HAL_I2C_Master_Receive(&hi2c1, 0x95, data, 2, 10);
    //0x94是鿚过0x4A向左移一位再加一得来的,0表示冿1表示读,这里朿低位丿1_0X4A为STS30地址
 
	return (float)(-45)+175*(data[0]<<8|data[1])/65535;
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */

eeprom.h

#ifndef __EEPROM_H
#define __EEPROM_H

#include "main.h"
//MAX_3KB
#define MCU_Start_Address_Bank1 0x08080000
//MAX_3KB
#define MCU_Start_Address_Bank2 0x08080C00

void flashWrite(uint32_t address,uint8_t *data,uint8_t length);
void flashRead(uint32_t address,uint8_t *data,uint8_t length);

#endif

eeprom.c

#include "eeprom.h"

//MAX 3KB
void flashWrite(uint32_t address,uint8_t *data,uint8_t length){
  HAL_FLASHEx_DATAEEPROM_Unlock();// 解锁Flash

  for(uint8_t i=0;i< length;i++){  
    *(__IO uint8_t *)address = (uint8_t) data[i];
    address+=1;
  }

  HAL_FLASHEx_DATAEEPROM_Lock();// 上锁Flash
}


//MAX 3KB
void flashRead(uint32_t address,uint8_t *data,uint8_t length){
  for(uint8_t i=0;i< length;i++){     
    data[i]=*(__IO uint8_t *)address;
    address+=1;
  }
}

NODE_B

  • 接收温度数据并显示到OLED屏幕
    main.c
/* USER CODE BEGIN SysInit */

/* USER CODE END SysInit */

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_I2C3_Init();
MX_SPI1_Init();
MX_TIM6_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
// 初始化OLED
OLED_Init();
unsigned char b2[16];
LORA_Init();

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
fn_lora_rx_handler();
OLED_ShowString(0, 0, b2, 16);
}
/* USER CODE END 3 */
void fn_lora_rx_handler(void){
	unsigned char s_length = LORA_Rx((unsigned char*)g_lora_rx_buf);
	if(g_lora_rx_buf[0] != '\0'){
		HAL_UART_Transmit(&huart2,g_lora_rx_buf,16,160);
	}
    if(g_lora_rx_buf[0]!='\0'){
		char b3[6];
		for(int i=0;i<6;i++){
			 b3[i]=g_lora_rx_buf[i];
	}
    OLED_ShowString(28,2,(uint8_t *)b3,16);
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_RESET);
    HAL_Delay(1000);
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_SET);
  }
}

效果

NODE_B显示NODE_A的温度
posted @ 2024-05-29 00:50  qsBye  阅读(7)  评论(0编辑  收藏  举报