I implemented this software to connect to an SPS 30 PM sensor and it will not connect. I wrote my own drivers but only ever recieved back 0xff for bytes. I then implemented sps30-i2c-3.1.1 on a custom board using an STM32L071KZT6 MCU. The I2c bus has several sensors on it and they communicate well. I have three sps30 sensors and they all do the same. I modified the sensirion_hw_i2c_implementation for my i2c bus and should be correct. Its the same initialization as in my main.c, I am using STM32CubeIDE for this project. What are the chances i have three faulty sensors? I am not sure what i am doing wrong. I will paste my implementation below:
sensirion_hw_i2c_implementation:
include
include "sensirion_arch_config.h"
include "sensirion_i2c.h"
/**
Create new I2C instance. You may also use a different interface, e.g. hi2c2,
depending on your CubeMX configuration
*/
static I2C_HandleTypeDef hi2c1;
/**
Initialize all hard- and software components that are needed for the I2C
communication.
/
void sensirion_i2c_init(void) {
// hi2c1.Instance = I2C1;
//hi2c1.Init.ClockSpeed = 100000;
// hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
// hi2c1.Init.OwnAddress1 = 0;
// hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
// hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
// hi2c1.Init.OwnAddress2 = 0;
// hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
// hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
/ Enable the remapping of Pins 6/7 to 8/9 and the I2C clock before the
initialization of the GPIO Pins in HAL_I2C_Init(). This is a fix of the
code generated by CubeMX v4.16.0 */
//HAL_AFIO_REMAP_I2C1_ENABLE();
// HAL_RCC_I2C1_CLK_ENABLE();
Sleep for a given number of microseconds. The function should delay the
execution for at least the given time, but may also sleep longer.
@param useconds the sleep time in microseconds
*/
void sensirion_sleep_usec(uint32_t useconds) {
uint32_t msec = useconds / 1000;
if (useconds % 1000 > 0) {
msec++;
}
/*
Increment by 1 if STM32F1 driver version less than 1.1.1
Old firmwares of STM32F1 sleep 1ms shorter than specified in HAL_Delay.
This was fixed with firmware 1.6 (driver version 1.1.1), so we have to
fix it ourselves for older firmwares
*/
if (HAL_GetHalVersion() < 0x01010100) {
msec++;
}
HAL_Delay(msec);
}
main.c:
/ USER CODE BEGIN Header /
/**
@file : main.c
@brief : Main program body
@attention
Copyright (c) 2024 STMicroelectronics.
All rights reserved.
This software is licensed under terms that can be found in the LICENSE file
in the root directory of this software component.
If no LICENSE file comes with this software, it is provided AS-IS.
/
/ USER CODE END Header /
/ Includes ------------------------------------------------------------------*/
include "main.h"
//#include "bme680.c"
include "bme680.h"
include "HDC2080.h"
include "TDE5531.h"
include "sps30pm.h"
include "sps30.h"
include
include
include
include
include
include
/ Private includes ----------------------------------------------------------/
/ USER CODE BEGIN Includes /
//#include "ssd1306.c"
//#include "fonts.c"
/ USER CODE END Includes /
/ Private typedef -----------------------------------------------------------/
/ USER CODE BEGIN PTD /
define DELAY_PERIOD_MS (15*1000) // 15 seconds
/ USER CODE END PTD /
/ Private define ------------------------------------------------------------/
/ USER CODE BEGIN PD /
/ USER CODE END PD /
/ Private macro -------------------------------------------------------------/
/ USER CODE BEGIN PM /
/ Set the temperature, pressure and humidity settings /
bme_sensor.tph_sett.os_hum = BME680_OS_2X;
bme_sensor.tph_sett.os_pres = BME680_OS_4X;
bme_sensor.tph_sett.os_temp = BME680_OS_8X;
bme_sensor.tph_sett.filter = BME680_FILTER_SIZE_3;
/ Set the remaining gas sensor settings and link the heating profile /
bme_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
/ Create a ramp heat waveform in 3 steps /
bme_sensor.gas_sett.heatr_temp = 320; / degree Celsius /
bme_sensor.gas_sett.heatr_dur = 150; / milliseconds /
/ Select the power mode /
/ Must be set before writing the sensor configuration /
bme_sensor.power_mode = BME680_FORCED_MODE;
/ Set the required sensor settings needed /
set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL
| BME680_GAS_SENSOR_SEL;
/ Set the desired sensor configuration /
rslt = bme680_set_sensor_settings(set_required_settings,&bme_sensor);
/ Set the power mode /
rslt = bme680_set_sensor_mode(&bme_sensor);
HDC2080 hdc_sensor;
num_err = HDC2080_init(&hdc_sensor, &hi2c1);
TDE5531 CO2_sensor;
num_err = 0;
num_err = TDE5531_init(&CO2_sensor, &hi2c1);
//SPS30 pm_sensor;
//rdy = SPS30_init(&pm_sensor, &hi2c1);
/* Get the total measurement duration so as to sleep or wait till the
measurement is complete */
uint16_t meas_period;
bme680_get_profile_dur(&meas_period, &bme_sensor);
/* Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
/
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/* Configure for the selected ADC regular channel to be converted.
/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure for the selected ADC regular channel to be converted.
/
sConfig.Channel = ADC_CHANNEL_3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure for the selected ADC regular channel to be converted.
/
sConfig.Channel = ADC_CHANNEL_4;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure for the selected ADC regular channel to be converted.
/
sConfig.Channel = ADC_CHANNEL_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/ USER CODE BEGIN ADC_Init 2 /
/ USER CODE END ADC_Init 2 /
}
/**
@brief CRC Initialization Function
@param None
@retval None
*/
static void MX_CRC_Init(void)
{
/ USER CODE BEGIN CRC_Init 0 /
/ USER CODE END CRC_Init 0 /
/ USER CODE BEGIN CRC_Init 1 /
/ USER CODE END CRC_Init 1 /
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
if (HAL_CRC_Init(&hcrc) != HAL_OK)
{
Error_Handler();
}
/ USER CODE BEGIN CRC_Init 2 /
//uint8_t pmAddrPtr[2]= {0xD1, 0x00};
status = HAL_I2C_Mem_Read(&hi2c1, 0x18 << 1, 0xFBFA, 2, pim_buf, 2, 1000);
if (status == HAL_OK){
serial_string10("version: \n");
HAL_UART_Transmit(&huart1, data, 10, 1000);
HAL_Delay(1000);
HAL_UART_Transmit(&huart1, pim_buf, 2, 1000);
HAL_Delay(1000);
return 1;
}// end if
return 0;
}// end getPIM_id
/**
@brief Retargets the C library printf function to the USART.
@param None
@retval None
/
PUTCHAR_PROTOTYPE
{
/ Place your implementation of fputc here /
/ e.g. write a character to the USART1 and Loop until the end of transmission /
HAL_UART_Transmit(&huart1, (uint8_t )&ch, 1, 0xFFFF);
return ch;
}
/ 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
/**
@brief Reports the name of the source file and the source line number
where the assert_param error has occurred.
@param file: pointer to the source file name
@param line: assert_param error line source number
@retval None
/
void assert_failed(uint8_t file, uint32_t line)
{
/ USER CODE BEGIN 6 /
/ User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) /
/ USER CODE END 6 /
}
I implemented this software to connect to an SPS 30 PM sensor and it will not connect. I wrote my own drivers but only ever recieved back 0xff for bytes. I then implemented sps30-i2c-3.1.1 on a custom board using an STM32L071KZT6 MCU. The I2c bus has several sensors on it and they communicate well. I have three sps30 sensors and they all do the same. I modified the sensirion_hw_i2c_implementation for my i2c bus and should be correct. Its the same initialization as in my main.c, I am using STM32CubeIDE for this project. What are the chances i have three faulty sensors? I am not sure what i am doing wrong. I will paste my implementation below:
sensirion_hw_i2c_implementation:
include
include "sensirion_arch_config.h"
include "sensirion_i2c.h"
/**
/**
communication. / void sensirion_i2c_init(void) { // hi2c1.Instance = I2C1; //hi2c1.Init.ClockSpeed = 100000; // hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; // hi2c1.Init.OwnAddress1 = 0; // hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; // hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; // hi2c1.Init.OwnAddress2 = 0; // hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; // hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; / Enable the remapping of Pins 6/7 to 8/9 and the I2C clock before the
hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x00303D5B; 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;
HAL_I2C_Init(&hi2c1); }
/**
/**
/**
/**
@param useconds the sleep time in microseconds */ void sensirion_sleep_usec(uint32_t useconds) { uint32_t msec = useconds / 1000; if (useconds % 1000 > 0) { msec++; }
/*
HAL_Delay(msec); }
main.c:
/ USER CODE BEGIN Header / /**
/ / USER CODE END Header / / Includes ------------------------------------------------------------------*/
include "main.h"
//#include "bme680.c"
include "bme680.h"
include "HDC2080.h"
include "TDE5531.h"
include "sps30pm.h"
include "sps30.h"
include
include
include
include
include
include
/ Private includes ----------------------------------------------------------/ / USER CODE BEGIN Includes / //#include "ssd1306.c" //#include "fonts.c" / USER CODE END Includes /
/ Private typedef -----------------------------------------------------------/ / USER CODE BEGIN PTD /
define DELAY_PERIOD_MS (15*1000) // 15 seconds
/ USER CODE END PTD /
/ Private define ------------------------------------------------------------/ / USER CODE BEGIN PD /
/ USER CODE END PD /
/ Private macro -------------------------------------------------------------/ / USER CODE BEGIN PM /
/ USER CODE END PM /
/ Private variables ---------------------------------------------------------/ ADC_HandleTypeDef hadc;
CRC_HandleTypeDef hcrc;
I2C_HandleTypeDef hi2c1; I2C_HandleTypeDef hi2c3;
RTC_HandleTypeDef hrtc;
SPI_HandleTypeDef hspi1;
UART_HandleTypeDef huart1; UART_HandleTypeDef huart4;
/ USER CODE BEGIN PV / uint8_t data[10] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; char serial_msg[10]; void serial_string10(char str[10]); uint8_t ver_buf[3]; uint8_t id_buf[49]; uint8_t pim_buf[3]; uint8_t rdy; uint8_t num_err; char i2c_reading_buf[100]; //int8_t rslt = BME680_OK;
/ USER CODE END PV /
/ Private function prototypes -----------------------------------------------/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC_Init(void); static void MX_I2C1_Init(void); static void MX_SPI1_Init(void); static void MX_USART1_UART_Init(void); static void MX_USART4_UART_Init(void); static void MX_CRC_Init(void); static void MX_RTC_Init(void); static void MX_I2C3_Init(void); / USER CODE BEGIN PFP / uint8_t getPMversion(); int8_t bme680I2cRead(uint8_t dev_id, uint8_t reg_addr, uint8_t reg_data, uint16_t len); int8_t bme680I2cWrite(uint8_t dev_id, uint8_t reg_addr, uint8_t reg_data, uint16_t len); uint8_t getSFA30_id(); uint8_t getPIM_id();
define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
/ USER CODE END PFP /
/ Private user code ---------------------------------------------------------/ / USER CODE BEGIN 0 /
/ USER CODE END 0 /
/**
@retval int / int main(void) { / USER CODE BEGIN 1 */
/ USER CODE END 1 /
/ MCU Configuration--------------------------------------------------------/
/ Reset of all peripherals, Initializes the Flash interface and the Systick. / HAL_Init();
/ USER CODE BEGIN Init /
/ USER CODE END Init /
/ Configure the system clock / SystemClock_Config();
/ USER CODE BEGIN SysInit /
/ USER CODE END SysInit /
/ Initialize all configured peripherals / MX_GPIO_Init(); MX_ADC_Init(); MX_I2C1_Init(); MX_SPI1_Init(); MX_USART1_UART_Init(); MX_USART4_UART_Init(); MX_CRC_Init(); MX_RTC_Init(); MX_I2C3_Init(); / USER CODE BEGIN 2 /
struct bme680_dev bme_sensor; bme_sensor.dev_id = BME680_I2C_ADDR_PRIMARY; bme_sensor.intf = BME680_I2C_INTF; bme_sensor.read = bme680I2cRead; bme_sensor.write = bme680I2cWrite; bme_sensor.delay_ms = HAL_Delay; bme_sensor.amb_temp = 25;
int8_t rslt = BME680_OK; rslt = bme680_init(&bme_sensor);
uint8_t set_required_settings;
/ Set the temperature, pressure and humidity settings / bme_sensor.tph_sett.os_hum = BME680_OS_2X; bme_sensor.tph_sett.os_pres = BME680_OS_4X; bme_sensor.tph_sett.os_temp = BME680_OS_8X; bme_sensor.tph_sett.filter = BME680_FILTER_SIZE_3;
/ Set the remaining gas sensor settings and link the heating profile / bme_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS; / Create a ramp heat waveform in 3 steps / bme_sensor.gas_sett.heatr_temp = 320; / degree Celsius / bme_sensor.gas_sett.heatr_dur = 150; / milliseconds /
/ Select the power mode / / Must be set before writing the sensor configuration / bme_sensor.power_mode = BME680_FORCED_MODE;
/ Set the required sensor settings needed / set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL;
/ Set the desired sensor configuration / rslt = bme680_set_sensor_settings(set_required_settings,&bme_sensor);
/ Set the power mode / rslt = bme680_set_sensor_mode(&bme_sensor);
HDC2080 hdc_sensor;
num_err = HDC2080_init(&hdc_sensor, &hi2c1);
TDE5531 CO2_sensor;
num_err = 0;
num_err = TDE5531_init(&CO2_sensor, &hi2c1);
//SPS30 pm_sensor;
//rdy = SPS30_init(&pm_sensor, &hi2c1);
/* Get the total measurement duration so as to sleep or wait till the
measurement is complete */ uint16_t meas_period; bme680_get_profile_dur(&meas_period, &bme_sensor);
struct bme680_field_data bme_data;
struct sps30_measurement m; int16_t ret; while (sps30_probe() != 0) { printf("SPS sensor probing failed\n"); sensirion_sleep_usec(1000000); / wait 1s / } printf("SPS sensor probing successful\n");
// Init lcd using one of the stm32HAL i2c typedefs // ssd1306_Init(&hi2c1);
/ USER CODE END 2 /
/ Infinite loop / / USER CODE BEGIN WHILE / while (1) { / USER CODE END WHILE /
// HAL_Delay(meas_period); / Delay till the measurement is ready /
// rslt = bme680_get_sensor_data(&bme_data, &bme_sensor);
// printf("T: %.2f degC, P: %.2f hPa, H %.2f %%rH ", bme_data.temperature / 100.0f, // bme_data.pressure / 100.0f, bme_data.humidity / 1000.0f ); / Avoid using measurements from an unstable heating setup / // if(bme_data.status & BME680_GASM_VALID_MSK) // printf(", G: %d ohms", bme_data.gas_resistance);
// printf("\r\n");
// if (bme_sensor.power_mode == BME680_FORCED_MODE) { // rslt = bme680_set_sensor_mode(&bme_sensor); // }
sensirion_sleep_usec(SPS30_MEASUREMENT_DURATION_USEC); / wait 1s / ret = sps30_read_measurement(&m); if (ret < 0) { printf("error reading measurement\n");
/ printf("Hello World\n\r"); HAL_Delay(1000); HAL_UART_Transmit(&huart1, "hello\n", 6, 1000); HAL_Delay(1000); rdy = sps30_wake(&pm_sensor); rdy = getPMversion(); rdy = getSFA30_id(); rdy = getPIM_id(); rdy = sps30_start_int(&pm_sensor); // HAL_Delay(5000); // HAL_Delay(5000); // HAL_Delay(5000); // HAL_Delay(5000); rdy = sps30_getData(&pm_sensor); rdy = sps30_getStatus(&pm_sensor); rdy = 1; // if (rdy == sps30_rdy(&pm_sensor)){ // rdy = sps30_stop(&pm_sensor); // rdy = sps30_getData(&pm_sensor); //}// end if /
} / USER CODE END 3 / }
/**
@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_OSCILLATORTYPE_LSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 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_HSI; 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_0) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1 |RCC_PERIPHCLK_I2C3|RCC_PERIPHCLK_RTC; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1; PeriphClkInit.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1; PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } }
/**
@retval None */ static void MX_ADC_Init(void) {
/ USER CODE BEGIN ADC_Init 0 /
/ USER CODE END ADC_Init 0 /
ADC_ChannelConfTypeDef sConfig = {0};
/ USER CODE BEGIN ADC_Init 1 /
/ USER CODE END ADC_Init 1 /
/* Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) / hadc.Instance = ADC1; hadc.Init.OversamplingMode = DISABLE; hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1; hadc.Init.Resolution = ADC_RESOLUTION_12B; hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.ContinuousConvMode = DISABLE; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc.Init.DMAContinuousRequests = DISABLE; hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.LowPowerFrequencyMode = DISABLE; hadc.Init.LowPowerAutoPowerOff = DISABLE; if (HAL_ADC_Init(&hadc) != HAL_OK) { Error_Handler(); }
/* Configure for the selected ADC regular channel to be converted. / sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
/* Configure for the selected ADC regular channel to be converted. / sConfig.Channel = ADC_CHANNEL_3; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
/* Configure for the selected ADC regular channel to be converted. / sConfig.Channel = ADC_CHANNEL_4; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); }
/* Configure for the selected ADC regular channel to be converted. / sConfig.Channel = ADC_CHANNEL_5; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN ADC_Init 2 /
/ USER CODE END ADC_Init 2 /
}
/**
@retval None */ static void MX_CRC_Init(void) {
/ USER CODE BEGIN CRC_Init 0 /
/ USER CODE END CRC_Init 0 /
/ USER CODE BEGIN CRC_Init 1 /
/ USER CODE END CRC_Init 1 / hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; if (HAL_CRC_Init(&hcrc) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN CRC_Init 2 /
/ USER CODE END CRC_Init 2 /
}
/**
@retval None */ static void MX_I2C1_Init(void) {
/ USER CODE BEGIN I2C1_Init 0 /
/ USER CODE END I2C1_Init 0 /
/ USER CODE BEGIN I2C1_Init 1 /
/ USER CODE END I2C1_Init 1 / hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x00303D5B; 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 /
}
/**
@retval None */ static void MX_I2C3_Init(void) {
/ USER CODE BEGIN I2C3_Init 0 /
/ USER CODE END I2C3_Init 0 /
/ USER CODE BEGIN I2C3_Init 1 /
/ USER CODE END I2C3_Init 1 / hi2c3.Instance = I2C3; hi2c3.Init.Timing = 0x00303D5B; 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 /
/ USER CODE END I2C3_Init 2 /
}
/**
@retval None */ static void MX_RTC_Init(void) {
/ USER CODE BEGIN RTC_Init 0 /
/ USER CODE END RTC_Init 0 /
RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0};
/ USER CODE BEGIN RTC_Init 1 /
/ USER CODE END RTC_Init 1 /
/* Initialize RTC Only / hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 127; hrtc.Init.SynchPrediv = 255; hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); }
/ USER CODE BEGIN Check_RTC_BKUP /
/ USER CODE END Check_RTC_BKUP /
/* Initialize RTC and set the Time and Date / sTime.Hours = 0x0; sTime.Minutes = 0x0; sTime.Seconds = 0x0; sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sTime.StoreOperation = RTC_STOREOPERATION_RESET; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } sDate.WeekDay = RTC_WEEKDAY_MONDAY; sDate.Month = RTC_MONTH_JANUARY; sDate.Date = 0x1; sDate.Year = 0x0;
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN RTC_Init 2 /
/ USER CODE END RTC_Init 2 /
}
/**
@retval None */ static void MX_SPI1_Init(void) {
/ USER CODE BEGIN SPI1_Init 0 /
/ USER CODE END SPI1_Init 0 /
/ USER CODE BEGIN SPI1_Init 1 /
/ USER CODE END SPI1_Init 1 / / SPI1 parameter configuration/ 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(); } / USER CODE BEGIN SPI1_Init 2 /
/ USER CODE END SPI1_Init 2 /
}
/**
@retval None */ static void MX_USART1_UART_Init(void) {
/ USER CODE BEGIN USART1_Init 0 /
/ USER CODE END USART1_Init 0 /
/ USER CODE BEGIN USART1_Init 1 /
/ USER CODE END USART1_Init 1 / huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN USART1_Init 2 /
/ USER CODE END USART1_Init 2 /
}
/**
@retval None */ static void MX_USART4_UART_Init(void) {
/ USER CODE BEGIN USART4_Init 0 /
/ USER CODE END USART4_Init 0 /
/ USER CODE BEGIN USART4_Init 1 /
/ USER CODE END USART4_Init 1 / huart4.Instance = USART4; huart4.Init.BaudRate = 115200; huart4.Init.WordLength = UART_WORDLENGTH_8B; huart4.Init.StopBits = UART_STOPBITS_1; huart4.Init.Parity = UART_PARITY_NONE; huart4.Init.Mode = UART_MODE_TX_RX; huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart4.Init.OverSampling = UART_OVERSAMPLING_16; huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; if (HAL_UART_Init(&huart4) != HAL_OK) { Error_Handler(); } / USER CODE BEGIN USART4_Init 2 /
/ USER CODE END USART4_Init 2 /
}
/**
@retval None / static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; / USER CODE BEGIN MX_GPIO_Init_1 / / USER CODE END MX_GPIO_Init_1 */
/ GPIO Ports Clock Enable / HAL_RCC_GPIOA_CLK_ENABLE(); HAL_RCC_GPIOB_CLK_ENABLE();
/Configure GPIO pin Output Level / HAL_GPIO_WritePin(GPIOB, ERVH_Pin|ERVL_Pin, GPIO_PIN_RESET);
/Configure GPIO pin Output Level / HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
/Configure GPIO pins : CO2Ready_Pin TempHumReady_Pin / GPIO_InitStruct.Pin = CO2Ready_Pin|TempHumReady_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/Configure GPIO pins : ERVH_Pin ERVL_Pin / GPIO_InitStruct.Pin = ERVH_Pin|ERVL_Pin; 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);
/Configure GPIO pin : PA12 / GPIO_InitStruct.Pin = 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 pin : INTPIM_Pin / GPIO_InitStruct.Pin = INTPIM_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(INTPIM_GPIO_Port, &GPIO_InitStruct);
/ USER CODE BEGIN MX_GPIO_Init_2 / / USER CODE END MX_GPIO_Init_2 / }
/ USER CODE BEGIN 4 / void serial_string10(char temp[10]){
}//end serial strin10
uint8_t getPMversion(){ HAL_StatusTypeDef status;
}///end getpmversion
int8_t bme680I2cRead(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len) { int8_t result;
if (HAL_I2C_Master_Transmit(&hi2c1, (dev_id << 1), ®_addr, 1, HAL_MAX_DELAY) != HAL_OK) { result = -1; } else if (HAL_I2C_Master_Receive (&hi2c1, (dev_id << 1) | 0x01, reg_data, len, HAL_MAX_DELAY) != HAL_OK) { result = -1; } else { result = 0; }
return result; }/// end bme read
int8_t bme680I2cWrite(uint8_t dev_id, uint8_t reg_addr, uint8_t reg_data, uint16_t len) { int8_t result; int8_t buf;
// Allocate and load I2C transmit buffer buf = malloc(len + 1); buf[0] = reg_addr; memcpy(buf + 1, reg_data, len);
if (HAL_I2C_Master_Transmit(&hi2c1, (dev_id << 1), (uint8_t *) buf, len + 1, HAL_MAX_DELAY) != HAL_OK) { result = -1; } else { result = 0; }
free(buf); return result; }// end bme write
uint8_t getSFA30_id(){ HAL_StatusTypeDef status; id_buf[48] = '\n';
}//end getSFA30_id
uint8_t getPIM_id(){ HAL_StatusTypeDef status; pim_buf[2] = '\n';
}// end getPIM_id
/**
@retval None / PUTCHAR_PROTOTYPE { / Place your implementation of fputc here / / e.g. write a character to the USART1 and Loop until the end of transmission / HAL_UART_Transmit(&huart1, (uint8_t )&ch, 1, 0xFFFF);
return ch; }
/ USER CODE END 4 /
/**
ifdef USE_FULL_ASSERT
/**
endif / USE_FULL_ASSERT /