F439_CPP_BMP390_Barometric_Pressure_and_Altimeter_01 1.0
STM32F439 BMP390 barometric pressure and altimeter tutorial
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1/* USER CODE BEGIN Header */
18/* USER CODE END Header */
19/* Includes ------------------------------------------------------------------*/
20#include "main.h"
21
22/* Private includes ----------------------------------------------------------*/
23/* USER CODE BEGIN Includes */
24#include <math.h>
25#include <stdio.h>
26
27#include "bmp3.h"
28#include "common.h"
29#include "i2c_spi_interface.h"
30
31/* USER CODE END Includes */
32
33/* Private typedef -----------------------------------------------------------*/
34/* USER CODE BEGIN PTD */
35
36/* USER CODE END PTD */
37
38/* Private define ------------------------------------------------------------*/
39/* USER CODE BEGIN PD */
40
49#define LOCAL_QNH_CALIBRATION
50
51#ifdef LOCAL_QNH_CALIBRATION
53#define SEA_LEVEL_PRESSURE_PA 102057.7
54#else
56#define SEA_LEVEL_PRESSURE_PA 101325.0
57#endif
58
59/* USER CODE END PD */
60
61/* Private macro -------------------------------------------------------------*/
62/* USER CODE BEGIN PM */
63
64/* USER CODE END PM */
65
66/* Private variables ---------------------------------------------------------*/
68I2C_HandleTypeDef hi2c1;
69
71TIM_HandleTypeDef htim1;
72
74UART_HandleTypeDef huart1;
75
76/* USER CODE BEGIN PV */
79
81static struct bmp3_dev bmp390;
82
83/* USER CODE END PV */
84
85/* Private function prototypes -----------------------------------------------*/
86void SystemClock_Config(void);
87static void MX_GPIO_Init(void);
88static void MX_USART1_UART_Init(void);
89static void MX_I2C1_Init(void);
90static void MX_TIM1_Init(void);
91/* USER CODE BEGIN PFP */
92
93/* USER CODE END PFP */
94
95/* Private user code ---------------------------------------------------------*/
96/* USER CODE BEGIN 0 */
97
98#ifdef REDIRECT_PRINTF
99#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
100
101PUTCHAR_PROTOTYPE
102{
103 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
104
105 return ch;
106}
107#endif
108
109void delayUS (uint16_t us)
110{
111 __HAL_TIM_SET_COUNTER(&htim1, 0); // set the counter value a 0
112 while (__HAL_TIM_GET_COUNTER(&htim1) < us); // wait for the counter to reach the us input in the parameter
113}
114
122static double calculateAltitudeFt(double pressurePa)
123{
124 double altitudeM = 44330.0 * (1.0 - pow(pressurePa / SEA_LEVEL_PRESSURE_PA, 1.0 / 5.255));
125
126 return altitudeM * 3.28084;
127}
128/* USER CODE END 0 */
129
134int main(void)
135{
136
137 /* USER CODE BEGIN 1 */
138
139 /* USER CODE END 1 */
140
141 /* MCU Configuration--------------------------------------------------------*/
142
143 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
144 HAL_Init();
145
146 /* USER CODE BEGIN Init */
147
148 /* USER CODE END Init */
149
150 /* Configure the system clock */
152
153 /* USER CODE BEGIN SysInit */
154
155 /* USER CODE END SysInit */
156
157 /* Initialize all configured peripherals */
158 MX_GPIO_Init();
160 MX_I2C1_Init();
161 MX_TIM1_Init();
162 /* USER CODE BEGIN 2 */
163
164 HAL_TIM_Base_Start(&htim1);
165
166 printf("\x1b[2J\x1b[H"); // Clear the dumb terminal screen
167
168 {
169 int8_t rslt;
170 uint16_t settings_sel;
171 struct bmp3_settings settings = { 0 };
172
173 bmp390Intf.i2c = &hi2c1;
174 bmp390.intf_ptr = &bmp390Intf;
175
176 bmp3_interface_init(&bmp390, BMP3_I2C_INTF);
177 rslt = bmp3_init(&bmp390);
178
179 if (rslt == BMP3_OK)
180 {
181 printf("BMP3 init OK, chip_id=0x%02X\r\n", bmp390.chip_id);
182
183 settings.press_en = BMP3_ENABLE;
184 settings.temp_en = BMP3_ENABLE;
185 settings.odr_filter.press_os = BMP3_OVERSAMPLING_2X;
186 settings.odr_filter.temp_os = BMP3_OVERSAMPLING_2X;
187 settings.odr_filter.odr = BMP3_ODR_25_HZ;
188
189 settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR;
190
191 rslt = bmp3_set_sensor_settings(settings_sel, &settings, &bmp390);
192 bmp3_check_rslt("bmp3_set_sensor_settings", rslt);
193
194 settings.op_mode = BMP3_MODE_NORMAL;
195 rslt = bmp3_set_op_mode(&settings, &bmp390);
196 bmp3_check_rslt("bmp3_set_op_mode", rslt);
197 }
198 else
199 {
200 printf("BMP3 init FAILED, rslt=%d\r\n", rslt);
201 }
202 }
203
204 /* USER CODE END 2 */
205
206 /* Infinite loop */
207 /* USER CODE BEGIN WHILE */
208 while (1)
209 {
210 /* USER CODE END WHILE */
211
212 /* USER CODE BEGIN 3 */
213 {
214 int8_t rslt;
215 struct bmp3_status status = { { 0 } };
216 struct bmp3_data data = { 0 };
217
218 rslt = bmp3_get_status(&status, &bmp390);
219
220 if ((rslt == BMP3_OK) && (status.intr.drdy == BMP3_ENABLE))
221 {
222 rslt = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &bmp390);
223
224 if (rslt == BMP3_OK)
225 {
226 double tempF = (data.temperature * 9.0 / 5.0) + 32.0;
227 double altitudeFt = calculateAltitudeFt(data.pressure);
228 double pressureInHg = data.pressure * 0.0002952998751;
229
230 printf("\x1b[5;0H");
231 printf("T: %.2f degF, P: %.2f Pa, %.2f inHg, Alt: %.2f ft\r\n", tempF, data.pressure, pressureInHg,
232 altitudeFt);
233 }
234
235 /* Re-reading status clears the data-ready flag latched above. */
236 rslt = bmp3_get_status(&status, &bmp390);
237 }
238
239 /* Print cadence is decoupled from the sensor's ODR so the terminal
240 * output stays slow enough to read without a screen capture. */
241 HAL_Delay(1000);
242 }
243 }
244 /* USER CODE END 3 */
245}
246
251{
252 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
253 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
254
257 __HAL_RCC_PWR_CLK_ENABLE();
258 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
259
263 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
264 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
265 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
266 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
267 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
268 RCC_OscInitStruct.PLL.PLLM = 8;
269 RCC_OscInitStruct.PLL.PLLN = 180;
270 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
271 RCC_OscInitStruct.PLL.PLLQ = 4;
272 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
273 {
275 }
276
279 if (HAL_PWREx_EnableOverDrive() != HAL_OK)
280 {
282 }
283
286 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
287 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
288 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
289 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
290 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
291 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
292
293 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
294 {
296 }
297}
298
302static void MX_I2C1_Init(void)
303{
304
305 /* USER CODE BEGIN I2C1_Init 0 */
306
307 /* USER CODE END I2C1_Init 0 */
308
309 /* USER CODE BEGIN I2C1_Init 1 */
310
311 /* USER CODE END I2C1_Init 1 */
312 hi2c1.Instance = I2C1;
313 hi2c1.Init.ClockSpeed = 100000;
314 hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
315 hi2c1.Init.OwnAddress1 = 0;
316 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
317 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
318 hi2c1.Init.OwnAddress2 = 0;
319 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
320 hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
321 if (HAL_I2C_Init(&hi2c1) != HAL_OK)
322 {
324 }
325
328 if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
329 {
331 }
332
335 if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
336 {
338 }
339 /* USER CODE BEGIN I2C1_Init 2 */
340
341 /* USER CODE END I2C1_Init 2 */
342
343}
344
348static void MX_TIM1_Init(void)
349{
350
351 /* USER CODE BEGIN TIM1_Init 0 */
352
353 /* USER CODE END TIM1_Init 0 */
354
355 TIM_ClockConfigTypeDef sClockSourceConfig = {0};
356 TIM_MasterConfigTypeDef sMasterConfig = {0};
357
358 /* USER CODE BEGIN TIM1_Init 1 */
359
360 /* USER CODE END TIM1_Init 1 */
361 htim1.Instance = TIM1;
362 htim1.Init.Prescaler = 180 - 1;
363 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
364 htim1.Init.Period = 65535;
365 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
366 htim1.Init.RepetitionCounter = 0;
367 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
368 if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
369 {
371 }
372 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
373 if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
374 {
376 }
377 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
378 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
379 if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
380 {
382 }
383 /* USER CODE BEGIN TIM1_Init 2 */
384
385 /* USER CODE END TIM1_Init 2 */
386
387}
388
392static void MX_USART1_UART_Init(void)
393{
394
395 /* USER CODE BEGIN USART1_Init 0 */
396
397 /* USER CODE END USART1_Init 0 */
398
399 /* USER CODE BEGIN USART1_Init 1 */
400
401 /* USER CODE END USART1_Init 1 */
402 huart1.Instance = USART1;
403 huart1.Init.BaudRate = 19200;
404 huart1.Init.WordLength = UART_WORDLENGTH_8B;
405 huart1.Init.StopBits = UART_STOPBITS_1;
406 huart1.Init.Parity = UART_PARITY_NONE;
407 huart1.Init.Mode = UART_MODE_TX_RX;
408 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
409 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
410 if (HAL_UART_Init(&huart1) != HAL_OK)
411 {
413 }
414 /* USER CODE BEGIN USART1_Init 2 */
415
416 /* USER CODE END USART1_Init 2 */
417
418}
419
423static void MX_GPIO_Init(void)
424{
425 /* USER CODE BEGIN MX_GPIO_Init_1 */
426
427 /* USER CODE END MX_GPIO_Init_1 */
428
429 /* GPIO Ports Clock Enable */
430 __HAL_RCC_GPIOC_CLK_ENABLE();
431 __HAL_RCC_GPIOH_CLK_ENABLE();
432 __HAL_RCC_GPIOA_CLK_ENABLE();
433 __HAL_RCC_GPIOB_CLK_ENABLE();
434
435 /* USER CODE BEGIN MX_GPIO_Init_2 */
436
437 /* USER CODE END MX_GPIO_Init_2 */
438}
439
440/* USER CODE BEGIN 4 */
441
442
443/* Documented on the prototype in main.h. */
444void _Error_Handler(const char *file, int line)
445{
446 __disable_irq();
447
448#ifdef REDIRECT_PRINTF
449 char buf[80];
450
451 snprintf(buf, sizeof(buf),
452 "Trapped in _Error_Handler(). Called from: %s, line: %d\r\n",
453 file, line);
454 printf("%s", buf);
455#endif
456
457 /* User can add an implementation to report the HAL error return state. */
458 while(1)
459 {
460 }
461}
462
463/* USER CODE END 4 */
464
465
466#ifdef USE_FULL_ASSERT
474void assert_failed(uint8_t *file, uint32_t line)
475{
476 /* USER CODE BEGIN 6 */
477 /* assert_param() can fire from inside any HAL call -- including before
478 * REDIRECT_PRINTF's UART is fully set up, or from an unusual calling
479 * context -- so this only attempts to report when REDIRECT_PRINTF is
480 * available, then halts either way. Continuing after a failed HAL
481 * parameter check is undefined behavior, not something safe to log
482 * and ignore. */
483 __disable_irq();
484
485#ifdef REDIRECT_PRINTF
486 {
487 char buf[96];
488
489 snprintf(buf, sizeof(buf),
490 "assert_param failed: file %s, line %lu\r\n",
491 (char *)file, (unsigned long)line);
492 printf("%s", buf);
493 }
494#endif
495
496 while (1)
497 {
498 }
499 /* USER CODE END 6 */
500}
501#endif /* USE_FULL_ASSERT */
static void MX_TIM1_Init(void)
TIM1 Initialization Function.
Definition main.c:348
TIM_HandleTypeDef htim1
TIM1 handle, used as delayUS()'s free-running microsecond counter.
Definition main.c:71
UART_HandleTypeDef huart1
USART1 handle, used for printf() output via REDIRECT_PRINTF.
Definition main.c:74
static void MX_I2C1_Init(void)
I2C1 Initialization Function.
Definition main.c:302
static double calculateAltitudeFt(double pressurePa)
Converts pressure to altitude using the barometric formula (International Standard Atmosphere model),...
Definition main.c:122
static void MX_USART1_UART_Init(void)
USART1 Initialization Function.
Definition main.c:392
void SystemClock_Config(void)
System Clock Configuration.
Definition main.c:250
#define SEA_LEVEL_PRESSURE_PA
Sea-level pressure (Pa) used as the altitude reference.
Definition main.c:53
int main(void)
The application entry point.
Definition main.c:134
static struct bmp3_dev bmp390
BMP390 driver device handle (Bosch bmp3_dev).
Definition main.c:81
void _Error_Handler(const char *file, int line)
Reports a fatal error and halts. See _Error_Handler() in main.c.
Definition main.c:444
void delayUS(uint16_t us)
Busy-waits for the given number of microseconds using TIM1 (1 MHz counter – see MX_TIM1_Init()'s pres...
Definition main.c:109
static I2C_SPI_Interface bmp390Intf
I2C bus/address binding passed to the BMP390 driver as intf_ptr.
Definition main.c:78
static void MX_GPIO_Init(void)
GPIO Initialization Function.
Definition main.c:423
I2C_HandleTypeDef hi2c1
I2C1 handle, used by the BMP390 driver's read/write callbacks.
Definition main.c:68
: Header for main.c file. This file contains the common defines of the application.
#define Error_Handler()
Calls _Error_Handler() with the caller's own file/line.
Definition main.h:77