STM32L496ZG, 7 segments display task, SysTick interrut not called? - c

I made progress with the last task of blinking all leds over and over again.
Now I'm trying to show actual time (two modes, one showing time in HHMM and the second MMSS) on my 7 segments displayer.
Segments from A to G are responsible arefor digit "parts", DP is dot.
Connection between segments and pins is represented on board as follows:
A → GPIO_G[0]
B → GPIO_G[1]
C → GPIO_G[2]
D → GPIO_G[3]
E → GPIO_G[4]
F → GPIO_G[5]
G → GPIO_G[6]
DP → GPIO_G[9]
Base transistors NPN responsible for seeing of the digit:
DIG_1 → GPIO_B[2]
DIG_2 → GPIO_B[3]
DIG_3 → GPIO_B[4]
DIG_4 → GPIO_B[5]
I'm using JOY_UP and JOY_DOWN for change of mode:
JOY_UP → GPIO_E[2]
JOY_DOWN → GPIO_E[3]
Here is my code:
main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* Copyright (c) 2021 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"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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 ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
void switchInit(void);
void baseTransistInit(void);
void segmentsInit();
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
HAL_PWREx_EnableVddIO2();
switchInit();
baseTransistInit();
segmentsInit();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
SysTick_Config(SystemCoreClock / 1000); // SysTick_Handler() called within 1ms
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
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_MSI;
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();
}
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
void switchInit(void)
{
GPIO_InitTypeDef Joys;
Joys.Mode = GPIO_MODE_INPUT;
Joys.Pin = GPIO_PIN_2 /* JOY_UP */ | GPIO_PIN_3 /* JOY_DOWN */;
Joys.Pull = GPIO_PULLUP;
Joys.Speed = GPIO_SPEED_LOW;
Joys.Alternate = 0;
HAL_GPIO_Init(GPIOE, &Joys);
}
void baseTransistInit(void)
{
GPIO_InitTypeDef Transistors;
Transistors.Mode = GPIO_MODE_OUTPUT_PP;
Transistors.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
Transistors.Pull = GPIO_NOPULL;
Transistors.Speed = GPIO_SPEED_LOW;
Transistors.Alternate = 0;
HAL_GPIO_Init(GPIOB, &Transistors);
}
void segmentsInit()
{
GPIO_InitTypeDef Segments;
Segments.Mode = GPIO_MODE_OUTPUT_PP;
Segments.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_9;
Segments.Pull = GPIO_NOPULL;
Segments.Speed = GPIO_SPEED_LOW;
Segments.Alternate = 0;
HAL_GPIO_Init(GPIOG, &Segments);
}
/* 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 */
}
#endif /* USE_FULL_ASSERT */
stm32l4xx_it.c:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file stm32l4xx_it.c
* #brief Interrupt Service Routines.
******************************************************************************
* #attention
*
* Copyright (c) 2021 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 "stm32l4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define SEG_A 0
#define SEG_B 1
#define SEG_C 2
#define SEG_D 3
#define SEG_E 4
#define SEG_F 5
#define SEG_G 6
#define SEG_DP 9
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
int hourFirst = 1, hourSecond = 5;
int minuteFirst = 3, minuteSecond = 0;
int secondFirst = 0, secondSecond = 0;
int showHHMM = 0, showMMSS = 0;
int buttonMs = 0;
int buttonDelay = 500;
int miliSeconds = 0;
const uint16_t tableOfSegments[] = {
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E | 1 << SEG_F, // DIGIT 0
1 << SEG_B | 1 << SEG_C, // DIGIT 1
1 << SEG_A | 1 << SEG_B | 1 << SEG_E | 1 << SEG_D | 1 << SEG_G, // DIGIT 2
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E, // DIGIT 3
1 << SEG_B | 1 << SEG_C | 1 << SEG_G | 1 << SEG_F, // DIGIT 4
1 << SEG_A | 1 << SEG_F | 1 << SEG_G | 1 << SEG_C | 1 << SEG_D, // DIGIT 5
1 << SEG_A | 1 << SEG_F | 1 << SEG_G | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E, // DIGIT 6
1 << SEG_A | 1 << SEG_B | 1 << SEG_C, // DIGIT 7
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_E | 1 << SEG_F | 1 << SEG_G, // DIGIT 8
1 << SEG_A | 1 << SEG_B | 1 << SEG_C | 1 << SEG_D | 1 << SEG_F | 1 << SEG_G, // DIGIT 9
};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
void changeSeconds();
void changeMinutes();
void changeHours();
void inputHandling();
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void changeSeconds()
{
if(secondSecond < 9)
secondSecond++;
else if(secondSecond == 9)
{
if(secondFirst < 5)
{
secondSecond = 0;
secondFirst++;
}
else // secondSecond == 9 && secondFirst == 5
{
secondSecond = 0;
secondFirst = 0;
changeMinutes();
}
}
}
void changeMinutes()
{
if(minuteSecond < 9)
minuteSecond++;
else if(minuteSecond == 9)
{
if(minuteFirst < 5)
{
minuteSecond = 0;
minuteSecond++;
}
else // minutesSecond == 9 && minutesFirst == 5
{
minuteSecond = 0;
minuteFirst = 0;
changeHours();
}
}
}
void changeHours()
{
if(hourFirst <= 1 && hourSecond < 9)
hourSecond++;
else if(hourFirst <= 1 && hourSecond == 9)
{
hourSecond = 0;
hourFirst++;
}
else if(hourFirst == 2 && hourSecond < 3)
hourSecond++;
else
{
hourSecond = 0;
hourFirst = 0;
}
}
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* #brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* #brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* #brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* #brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* #brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* #brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* #brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* #brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* #brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
miliSeconds++;
inputHandling();
if((miliSeconds % 1000) == 0 || miliSeconds == 1)
{
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5, GPIO_PIN_RESET);
if(showHHMM)
{
if(miliSeconds / 1000 == 0)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[hourFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[hourSecond], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 2)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 3)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteSecond], GPIO_PIN_SET);
return;
}
else if(miliSeconds / 1000 == 4)
{
miliSeconds = 0;
}
changeSeconds();
}
else if(showMMSS)
{
if(miliSeconds / 1000 == 0)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[minuteSecond], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 2)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[secondFirst], GPIO_PIN_SET);
}
else if(miliSeconds / 1000 == 3)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOG, tableOfSegments[secondSecond], GPIO_PIN_SET);
return;
}
else if(miliSeconds / 1000 == 4)
{
miliSeconds = 0;
}
changeSeconds();
}
}
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32L4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32l4xx.s). */
/******************************************************************************/
/* USER CODE BEGIN 1 */
void inputHandling()
{
buttonMs++;
if(buttonMs < buttonDelay)
return;
if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2 ) == GPIO_PIN_RESET)
{
buttonMs = 0;
showMMSS = 1;
showHHMM = 0;
return;
}
else if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == GPIO_PIN_RESET)
{
buttonMs = 0;
showMMSS = 0;
showHHMM = 1;
return;
}
}
/* USER CODE END 1 */
My code in SysTick_Handler is just for the start (in the beginning I want to see if digits are correctly seen one by one within 1 second of change from digit to digit).
But... it doesn't work. My board is showing no change in my displayer after running my code. I can only guess that SysTick_Handler() isn't called at all, but I can't be sure.
Maybe you know what the problem is? Thanks in advance for all answers.

Related

Functions return successfully but BMX160 sensor does produce any data

I am implementing the bmi160 and bmm150 drivers from Bosch in order to get data from the BMX160 (pinout board made by DFRobot) because from what I have gathered. I changed the chip id to match the bmx160 chip id. Upon all the initializations I am given valid returns of 0 yet when I get to reading the data, I do not get good data from the chip. I have made sure the device is getting voltage and is found by my board (STM32F0). I2C clock is set to the standard mode with a default clock speed.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* Copyright (c) 2022 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 "bmm150.h"
#include "bmi160.h"
#include <stdio.h>
// #include "stm32f0xx_hal_uart.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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 ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
// UART_HandleTypeDef huart1;
struct bmi160_dev bmi;
struct bmm150_dev bmm;
struct bmm150_settings bmm_settings;
struct bmm150_mag_data mag;
struct bmi160_sensor_data accel;
struct bmi160_sensor_data gyro;
int8_t rslt, rslt1, rslt2, rslt3, rslt4, rslt5, rslt6, rslt7;
int8_t rslt_data, rslt_data1, rslt_data2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
// static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Auxiliary function declarations */
int8_t bmm150_aux_read(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, void *intf_ptr);
int8_t bmm150_aux_write(uint8_t reg_addr, uint8_t *aux_data, uint16_t len, void *intf_ptr);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t Buffer[25] = {0};
uint8_t Space[] = " - ";
uint8_t StartMSG[] = "Starting I2C Scanning: \r\n";
uint8_t EndMSG[] = "Done! \r\n\r\n";
int8_t user_i2c_read(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
HAL_StatusTypeDef status = HAL_OK;
while (HAL_I2C_IsDeviceReady(&hi2c1, (uint8_t)(id << 1), 3, 100) != HAL_OK)
{
rslt = 0;
}
status = HAL_I2C_Master_Transmit(&hi2c1, (uint8_t)(id << 1), &reg_addr, 1, 1000);
if (status != HAL_OK)
{
rslt = (-1);
}
HAL_Delay(100);
status = HAL_I2C_Master_Receive(&hi2c1, (uint8_t)(id << 1), data, len, 10000);
if (status != HAL_OK)
{
rslt = (-1);
}
return rslt;
}
int8_t user_i2c_write(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
HAL_StatusTypeDef status = HAL_OK;
while (HAL_I2C_IsDeviceReady(&hi2c1, (uint8_t)(id << 1), 3, 100) != HAL_OK)
{
}
uint8_t tx_buffer[len + 1];
tx_buffer[0] = reg_addr;
memcpy(&tx_buffer[1], data, len);
status = HAL_I2C_Master_Transmit(&hi2c1, (uint8_t)(id << 1), tx_buffer, len + 1, 1000);
if (status != HAL_OK)
{
rslt = (-1);
}
return rslt;
}
void user_delay_ms(uint32_t period)
{
HAL_Delay(period);
}
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t i = 0, ret;
/* 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_I2C1_Init();
// rslt = i2c_ping_device(&hi2c1, 0x00);
/* USER CODE BEGIN 2 */
bmi.id = BMI160_I2C_ADDR;
bmi.chip_id = BMI160_CHIP_ID;
bmi.intf = BMI160_I2C_INTF;
bmi.read = &user_i2c_read;
bmi.write = &user_i2c_write;
bmi.delay_ms = &user_delay_ms;
bmm.chip_id = BMM150_DEFAULT_I2C_ADDRESS;
bmm.intf = BMM150_I2C_INTF;
bmm.read = (bmm150_read_fptr_t)bmm150_aux_read;
bmm.write = (bmm150_write_fptr_t)bmm150_aux_write;
bmm.delay_us = &user_delay_ms;
bmm.intf_ptr = bmm.chip_id;
rslt = bmi160_init(&bmi);
// pingStatus = i2cs_ping_device(BMI160_I2C_ADDR);
bmi.aux_cfg.aux_sensor_enable = BMI160_ENABLE;
bmi.aux_cfg.aux_i2c_addr = bmm.chip_id;
bmi.aux_cfg.manual_enable = BMI160_ENABLE;
bmi.aux_cfg.aux_rd_burst_len = BMI160_AUX_READ_LEN_3;
rslt1 = bmi160_aux_init(&bmi);
rslt2 = bmm150_init(&bmm);
bmi.accel_cfg.odr = BMI160_ACCEL_ODR_100HZ;
bmi.accel_cfg.range = BMI160_ACCEL_RANGE_2G;
bmi.accel_cfg.bw = BMI160_ACCEL_BW_NORMAL_AVG4;
bmi.accel_cfg.power = BMI160_ACCEL_NORMAL_MODE;
bmi.gyro_cfg.odr = BMI160_GYRO_ODR_100HZ;
bmi.gyro_cfg.range = BMI160_GYRO_RANGE_2000_DPS;
bmi.gyro_cfg.bw = BMI160_GYRO_BW_NORMAL_MODE;
bmi.gyro_cfg.power = BMI160_GYRO_NORMAL_MODE;
rslt3 = bmi160_set_sens_conf(&bmi);
bmm_settings.preset_mode = BMM150_PRESETMODE_REGULAR;
rslt4 = bmm150_set_presetmode(&bmm_settings, &bmm);
bmm_settings.pwr_mode = BMM150_POWERMODE_FORCED;
rslt5 = bmm150_set_op_mode(&bmm_settings, &bmm);
uint8_t aux_addr = 0x42;
uint8_t mag_data[8] = {0};
uint8_t index;
bmi.aux_cfg.aux_odr = 8;
rslt6 = bmi160_config_aux_mode(&bmi);
rslt7 = bmi160_set_aux_auto_mode(BMM150_REG_CHIP_ID, &bmi);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
user_delay_ms(100);
rslt_data = bmi160_get_sensor_data((BMI160_ACCEL_SEL | BMI160_GYRO_SEL), &accel, &gyro, &bmi);
rslt_data1 = bmi160_read_aux_data_auto_mode(mag_data, &bmi);
rslt_data2 = bmm150_aux_mag_data(mag_data, &mag, &bmm);
/* USER CODE END WHILE */
printf("****************\n");
printf("ACC X: %d, Y: %d, Z: %d\n", accel.x, accel.y, accel.z);
printf("GYRO X: %d, Y: %d, Z: %d\n", gyro.x, gyro.y, gyro.z);
printf("MAG X : %d Y : %d Z : %d\n", mag.x, mag.y, mag.z);
printf("################\n");
/* USER CODE BEGIN 3 */
}
/* 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};
/** 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_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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief I2C1 Initialization Function
* #param None
* #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 = 0x200009FE;
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 */
}
// 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;
// huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
// huart1.Init.OverSampling = UART_OVERSAMPLING_16;
// if (HAL_UART_Init(&huart1) != HAL_OK)
// {
// Error_Handler();
// }
// /* USER CODE BEGIN USART1_Init 2 */
// /* USER CODE END USART1_Init 2 */
// }
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOB_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
/* 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 */
}
int8_t bmm150_aux_read(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, void *intf_ptr)
{
int8_t rslt;
rslt = bmi160_aux_read(reg_addr, reg_data, len, &bmi);
return rslt;
}
int8_t bmm150_aux_write(uint8_t reg_addr, uint8_t *reg_data, uint16_t len, void *intf_ptr)
{
int8_t rslt;
rslt = bmi160_aux_write(reg_addr, reg_data, len, &bmi);
return rslt;
}
#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 */
}
#endif /* USE_FULL_ASSERT */
The print statements in the while loop are supposed to provide the results. The Accel data and Gyro data both are 0 for x,y,z and 0 on the sensor time. The mag data provides -32768 for the x,y,z values. I have checked that all functions return 0 several times but still I am confused on why I am not getting good data. I am also using the latest code from Bosch's github repo for both the bmi160 and bmm150.
Here is the I2C configure that is called by the MX_12C1_INIT().
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if (hi2c->Instance == I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
/**I2C1 GPIO Configuration
PB8 ------> I2C1_SCL
PB9 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
This is using a STM32F030R8T6 Processor that is supplied voltage by a st-link-v2.
When creating circuitry, a number of issues could arise during the process which we are not aware of. A common issue is powering one are of the circuit with one voltage and communicating with the circuit using a different voltage. Both sensor and PLC need to be running on same voltage over the comms channel / pins.
The next step to debugging a circuit in this case would be to ensure that your "breakout board" or the sensor have pull up resistors. I have always found (40-50 different samples) that I do not need to add pull up resistors to break out boards. I have never had to add any.
The next issue I usually run into is addressing. Most ICs / sensors have a mechanism which allows you to select which address to use. If you hold the voltage low (0v), it will have a certain address while if you hold the voltage high (3.3v or 5v or whatever) it might be a different address. If you failed to add any connector to the pin (floating), it will be invalid and sensor will not start.
Another common issue is protocol. Some chips enable certain protocols by default and you may need to modify the internal settings in order to change them. By protocol, I am referring to either I2C, SPI or U(S)ART. This is unlikely but I've added it for completeness.
The issue most people think is happening is that the sensor is fried due to ESD. The likelyhood of your circuit being damaged is wildly low and it is certainly stronger than you think. I doubt you have damaged the circuit in any way.
To answer further, i would certainly require a picture of your circuit as the driver code should not be an issue at all. I generally find that driver code, even when outdated or for an earlier model, will generally still gather simple data relative to the ealier model.

Need help to read Accelerometer with I2C DMA

I'm try to read acceleration from KX132 accelerometer with a STM32F446ZE through I2C with DMA. I create a project with STMCubeMX and enable DMA and interruptions.
The accelerometer has six register each one of 1 byte where save acceleration in this format: XOUT_L,XOUT_H, YOUT_L, YOUT_H, ZOUT_L, ZOUT_H.
I want to read this registers continously with I2C DMA but I have a problem, only can read once time and never jump the complete transfer interruption again. I'll leave parts of my code so you can understand what i'm doing.
This configuration it was create by STMCubeMX. I choose DMA_CIRCULAR mode to repeat reading by DMA but doesn't work.
i2c.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "i2c.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
I2C_HandleTypeDef hi2c2;
DMA_HandleTypeDef hdma_i2c2_rx;
DMA_HandleTypeDef hdma_i2c2_tx;
/* I2C2 init function */
void MX_I2C2_Init(void)
{
/* USER CODE BEGIN I2C2_Init 0 */
/* USER CODE END I2C2_Init 0 */
/* USER CODE BEGIN I2C2_Init 1 */
/* USER CODE END I2C2_Init 1 */
hi2c2.Instance = I2C2;
hi2c2.Init.ClockSpeed = 100000;
hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C2_Init 2 */
/* USER CODE END I2C2_Init 2 */
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(i2cHandle->Instance==I2C2)
{
/* USER CODE BEGIN I2C2_MspInit 0 */
/* USER CODE END I2C2_MspInit 0 */
__HAL_RCC_GPIOF_CLK_ENABLE();
/**I2C2 GPIO Configuration
PF0 ------> I2C2_SDA
PF1 ------> I2C2_SCL
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C2;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
/* I2C2 clock enable */
__HAL_RCC_I2C2_CLK_ENABLE();
/* I2C2 DMA Init */
/* I2C2_RX Init */
hdma_i2c2_rx.Instance = DMA1_Stream2;
hdma_i2c2_rx.Init.Channel = DMA_CHANNEL_7;
hdma_i2c2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_i2c2_rx.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_i2c2_rx.Init.PeriphInc = DMA_PINC_ENABLE;
hdma_i2c2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c2_rx.Init.Mode = DMA_CIRCULAR;
hdma_i2c2_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
hdma_i2c2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c2_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_i2c2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_i2c2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c2_rx);
/* I2C2_TX Init */
hdma_i2c2_tx.Instance = DMA1_Stream7;
hdma_i2c2_tx.Init.Channel = DMA_CHANNEL_7;
hdma_i2c2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_i2c2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2c2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2c2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_i2c2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_i2c2_tx.Init.Mode = DMA_CIRCULAR;
hdma_i2c2_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_i2c2_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
if (HAL_DMA_Init(&hdma_i2c2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c2_tx);
/* I2C2 interrupt Init */
HAL_NVIC_SetPriority(I2C2_EV_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C2_EV_IRQn);
HAL_NVIC_SetPriority(I2C2_ER_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(I2C2_ER_IRQn);
/* USER CODE BEGIN I2C2_MspInit 1 */
/* USER CODE END I2C2_MspInit 1 */
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
{
if(i2cHandle->Instance==I2C2)
{
/* USER CODE BEGIN I2C2_MspDeInit 0 */
/* USER CODE END I2C2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C2_CLK_DISABLE();
/**I2C2 GPIO Configuration
PF0 ------> I2C2_SDA
PF1 ------> I2C2_SCL
*/
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0);
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_1);
/* I2C2 DMA DeInit */
HAL_DMA_DeInit(i2cHandle->hdmarx);
HAL_DMA_DeInit(i2cHandle->hdmatx);
/* I2C2 interrupt Deinit */
HAL_NVIC_DisableIRQ(I2C2_EV_IRQn);
HAL_NVIC_DisableIRQ(I2C2_ER_IRQn);
/* USER CODE BEGIN I2C2_MspDeInit 1 */
/* USER CODE END I2C2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
Set DMA interruptions.
dma.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure DMA */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
/* DMA1_Stream7_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
I use HAL_I2C_Mem_Read_DMA() because i can select the register from acceleremoter it save the accelerations. When I run this code in debug mode, HAL_I2C_Mem_Read_DMA() works fine and I can read 6 bytes of acceleration on rxData1 enter to while(1) and stop in HAL_Delay(50). After that, jump to DMA Interruption on stm32f4xx_it.c specifically on DMA1_Stream2_IRQHandler() function (describes below). Here excecute HAL_DMA_IRQHandler(&hdma_i2c2_rx) and go to HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c2) describe in main.c. After all that the code come back to HAL_Delay(50) from while(1) and never go jump to interrupt for refresh data from accelerometer.
I hope you can help me. I'm not sure if I'm doing it right, if you have a tips it will be hopefull for me or if you need more information feel free to ask me.
main.c
#include "stdio.h"
#include "main.h"
#include "dma.h"
#include "i2c.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#define KX132_ADDRESS 0x1E
#define READ 0x01
#define WRITE 0x00
#define RX_BUFF_LEN 12
uint8_t BUFF_ADDRESS = 0x63;
uint8_t XOUT_L = 0x08;
static uint8_t rxData1[RX_BUFF_LEN];
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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 ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
#define RX_BUFF_LEN 12
static uint8_t rxData1[RX_BUFF_LEN];
extern DMA_HandleTypeDef hdma_i2c2_rx;
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_DMA_Init();
MX_I2C2_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_I2C_Mem_Read_DMA(&hi2c2, (uint16_t)(KX132_ADDRESS << 1) | READ, XOUT_L, 1, (uint8_t *)rxData1, 6);
while (1)
{
HAL_Delay(50);
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c2)
{
/* Toggle LED: Transfer in transmission process is correct */
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);
}
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c2)
{
/* Toggle LED: Transfer in transmission process is correct */
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle)
{
/* Turn LED3 on: Transfer error in reception/transmission process */
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__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.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 180;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Activate the Over-Drive mode
*/
if (HAL_PWREx_EnableOverDrive() != 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_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* 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 */
}
#endif /* USE_FULL_ASSERT */
DMA Interruption
stm32f4xx_it.c
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_i2c2_rx;
extern DMA_HandleTypeDef hdma_i2c2_tx;
extern I2C_HandleTypeDef hi2c2;
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* #brief This function handles DMA1 stream2 global interrupt.
*/
void DMA1_Stream2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream2_IRQn 0 */
/* USER CODE END DMA1_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_i2c2_rx);
/* USER CODE BEGIN DMA1_Stream2_IRQn 1 */
/* USER CODE END DMA1_Stream2_IRQn 1 */
}
/**
* #brief This function handles DMA1 stream7 global interrupt.
*/
void DMA1_Stream7_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream7_IRQn 0 */
/* USER CODE END DMA1_Stream7_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_i2c2_tx);
/* USER CODE BEGIN DMA1_Stream7_IRQn 1 */
/* USER CODE END DMA1_Stream7_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

BMP280 send wrong values

I try to read temperature from BMP280 but I take a wrong values. Temperature in my room approximately 22 degrees so I expect to receive approximately 2200. But my program send me 715.
I use SPI connection. CS pin is set by shift register. I am sure that it work. And this is my code:
main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* Copyright (c) 2022 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"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "func.h"
#include "BMP280.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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 ---------------------------------------------------------*/
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #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_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
Init();
uint8_t id = 0;
BMP280_Data data;
uint8_t s[30] = {0};
uint8_t len = 0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
ReadId(&id);
ReadAll(&data);
len = sprintf((char *)s, "Id: %i Temperature: %li ", id, data.temp);
HAL_UART_Transmit(&huart1, s, len, 0x1000);
HAL_Delay(2000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_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_HSE;
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();
}
}
/**
* #brief SPI2 Initialization Function
* #param None
* #retval None
*/
static void MX_SPI2_Init(void)
{
/* USER CODE BEGIN SPI2_Init 0 */
/* USER CODE END SPI2_Init 0 */
/* USER CODE BEGIN SPI2_Init 1 */
/* USER CODE END SPI2_Init 1 */
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI2_Init 2 */
/* USER CODE END SPI2_Init 2 */
}
/**
* #brief USART1 Initialization Function
* #param None
* #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;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_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_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, SR_OE_Pin|SR_L_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : SR_OE_Pin SR_L_Pin */
GPIO_InitStruct.Pin = SR_OE_Pin|SR_L_Pin;
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);
}
/* USER CODE BEGIN 4 */
/* 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 */
}
#endif /* USE_FULL_ASSERT */
func.c
#include "func.h"
void sr(uint8_t *confBuf){
HAL_GPIO_WritePin(SR_OE_GPIO_Port, SR_OE_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_SPI_Transmit(&hspi2, confBuf, 2, 0x1000);
HAL_Delay(1);
HAL_GPIO_WritePin(SR_L_GPIO_Port, SR_L_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SR_L_GPIO_Port, SR_L_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(SR_OE_GPIO_Port, SR_OE_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
}
void dc(Devices d){
uint8_t ConfBuf[2] = {0b11111111, 0b11111111};
switch(d){
case(LSM6DSL_):
ConfBuf[0] = 0b11111110;
ConfBuf[1] = 0b11101110;
break;
case(BMP280_):
ConfBuf[0] = 0b11111101;
ConfBuf[1] = 0b11111010;
break;
default:
ConfBuf[0] = 0b11111111;
ConfBuf[1] = 0b11111111;
break;
}
sr(ConfBuf);
}
void spi_read_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len){
for(int i = 0; i < len; i++){
Reg |= 0b10000000;
dc(d);
HAL_SPI_Transmit(&hspi2, &Reg, 1, 0x1000);
HAL_SPI_Receive(&hspi2, Data, 1, 0x1000);
dc(0);
Reg++;
Data++;
}
}
void spi_write_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len){
for(int i = 0; i < len; i++){
Reg &= 0b01111111;
dc(d);
HAL_SPI_Transmit(&hspi2, &Reg, 1, 0x1000);
HAL_SPI_Transmit(&hspi2, Data, 1, 0x1000);
dc(0);
Reg++;
Data++;
}
}
func.h
#ifndef FUNC_H
#define FUNC_H
#include "main.h"
extern SPI_HandleTypeDef hspi2;
typedef enum {LSM6DSL_ = 1, BMP280_} Devices;
void sr(uint8_t *confBuf);
void dc(Devices d);
void spi_read_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len);
void spi_write_reg(Devices d, uint8_t Reg, uint8_t *Data, uint8_t len);
#endif
bmp280.c
#include "BMP280.h"
#include <stdio.h>
void Init(){
uint8_t conf[2] = {0b00100111, 0b00100000};
spi_write_reg(BMP280_, (uint8_t)CONFIG_L_REG, conf, 2);
}
void Reset(){
uint8_t data = (uint8_t)0xB6;
spi_write_reg(BMP280_, (uint8_t)RES_REG, &data, 1);
}
void ReadId(uint8_t *id){
spi_read_reg(BMP280_, (uint8_t)ID_REG, id, 1);
}
//0x88 / 0x89 dig_T1 unsigned short
//0x8A / 0x8B dig_T2 signed short
//0x8C / 0x8D dig_T3 signed short
//0x8E / 0x8F dig_P1 unsigned short
//0x90 / 0x91 dig_P2 signed short
//0x92 / 0x93 dig_P3 signed short
//0x94 / 0x95 dig_P4 signed short
//0x96 / 0x97 dig_P5 signed short
//0x98 / 0x99 dig_P6 signed short
//0x9A / 0x9B dig_P7 signed short
//0x9C / 0x9D dig_P8 signed short
//0x9E / 0x9F dig_P9 signed short
//0xA0 / 0xA reserved reserved
void ReadV(){
uint8_t Dig_T1[2] = {0};
uint8_t Dig_T2[2] = {0};
uint8_t Dig_T3[2] = {0};
uint8_t Dig_P1[2] = {0};
uint8_t Dig_P2[2] = {0};
uint8_t Dig_P3[2] = {0};
uint8_t Dig_P4[2] = {0};
uint8_t Dig_P5[2] = {0};
uint8_t Dig_P6[2] = {0};
uint8_t Dig_P7[2] = {0};
uint8_t Dig_P8[2] = {0};
uint8_t Dig_P9[2] = {0};
uint8_t Raw_data[6] = {0};
spi_read_reg(BMP280_, DIG_T1_L_REG, Dig_T1, 2);
dig_T1 = (Dig_T1[1] << 8) | Dig_T1[0];
spi_read_reg(BMP280_, DIG_T2_L_REG, Dig_T2, 2);
dig_T2 = (Dig_T2[1] << 8) | Dig_T2[0];
spi_read_reg(BMP280_, DIG_T3_L_REG, Dig_T3, 2);
dig_T3 = (Dig_T3[1] << 8) | Dig_T3[0];
spi_read_reg(BMP280_, DIG_P1_L_REG, Dig_P1, 2);
dig_P1 = (Dig_P1[1] << 8) | Dig_P1[0];
spi_read_reg(BMP280_, DIG_P2_L_REG, Dig_P2, 2);
dig_P2 = (Dig_P2[1] << 8) | Dig_P2[0];
spi_read_reg(BMP280_, DIG_P3_L_REG, Dig_P3, 2);
dig_P3 = (Dig_P3[1] << 8) | Dig_P3[0];
spi_read_reg(BMP280_, DIG_P4_L_REG, Dig_P4, 2);
dig_P4 = (Dig_P4[1] << 8) | Dig_P4[0];
spi_read_reg(BMP280_, DIG_P5_L_REG, Dig_P5, 2);
dig_P5 = (Dig_P5[1] << 8) | Dig_P5[0];
spi_read_reg(BMP280_, DIG_P6_L_REG, Dig_P6, 2);
dig_P6 = (Dig_P6[1] << 8) | Dig_P6[0];
spi_read_reg(BMP280_, DIG_P7_L_REG, Dig_P7, 2);
dig_P7 = (Dig_P7[1] << 8) | Dig_P7[0];
spi_read_reg(BMP280_, DIG_P8_L_REG, Dig_P8, 2);
dig_P8 = (Dig_P8[1] << 8) | Dig_P8[0];
spi_read_reg(BMP280_, DIG_P9_L_REG, Dig_P9, 2);
dig_P9 = (Dig_P9[1] << 8) | Dig_P9[0];
spi_read_reg(BMP280_, DATA_L_REG, &Raw_data[0], 1);
spi_read_reg(BMP280_, DATA_L_REG+1, &Raw_data[1], 1);
spi_read_reg(BMP280_, DATA_L_REG+2, &Raw_data[2], 1);
spi_read_reg(BMP280_, DATA_L_REG+3, &Raw_data[3], 1);
spi_read_reg(BMP280_, DATA_L_REG+4, &Raw_data[4], 1);
spi_read_reg(BMP280_, DATA_L_REG+5, &Raw_data[5], 1);
raw_temp = Raw_data[0] << 12 | Raw_data[1] << 4 | Raw_data[2]>>4;
raw_pres = Raw_data[3] << 12 | Raw_data[4] << 4 | Raw_data[5]>>4;
}
int32_t CompensateTemp(int32_t adc_T){
int32_t var1, var2, T;
var1 = ((((adc_T>>3) - ((int32_t)dig_T1<<1))) * ((int32_t)dig_T2)) >> 11;
var2 = (((((adc_T>>4) - ((int32_t)dig_T1)) * ((adc_T>>4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
int32_t CompensatePres(int32_t adc_P){
int64_t var1, var2, p;
var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)dig_P6;
var2 = var2 + ((var1*(int64_t)dig_P5)<<17);
var2 = var2 + (((int64_t)dig_P4)<<35);
var1 = ((var1 * var1 * (int64_t)dig_P3)>>8) + ((var1 * (int64_t)dig_P2)<<12);
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)dig_P1)>>33;
if(var1 == 0){
return 0; // avoid exception caused by division by zero
}
p = 1048576-adc_P;
p = (((p<<31)-var2)*3125)/var1;
var1 = (((int64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
var2 = (((int64_t)dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)dig_P7)<<4);
return (uint32_t)p;
}
void ReadAll(BMP280_Data *data){
ReadV();
data->raw_temp = raw_temp;
data->raw_pres = raw_pres;
data->temp = CompensateTemp(raw_temp);
data->pres = CompensatePres(raw_pres);
}
bmp280.h
#ifndef BMP280_H
#define BMP280_H
#include "func.h"
extern UART_HandleTypeDef huart1;
#define ID_REG 0xD0
#define RES_REG 0x0E
#define DIG_T1_L_REG 0x88
#define DIG_T2_L_REG 0x8A
#define DIG_T3_L_REG 0x8C
#define DIG_P1_L_REG 0x8E
#define DIG_P2_L_REG 0x90
#define DIG_P3_L_REG 0x92
#define DIG_P4_L_REG 0x94
#define DIG_P5_L_REG 0x96
#define DIG_P6_L_REG 0x98
#define DIG_P7_L_REG 0x9A
#define DIG_P8_L_REG 0x9C
#define DIG_P9_L_REG 0x9E
#define DATA_L_REG 0xF7
#define CONFIG_L_REG 0xF4
#define TEMP_DIF 0
#define TEMP_COF 4
#define RES_DIF 0
#define PRES_COF 1
//0x88 / 0x89 dig_T1 unsigned short
//0x8A / 0x8B dig_T2 signed short
//0x8C / 0x8D dig_T3 signed short
//0x8E / 0x8F dig_P1 unsigned short
//0x90 / 0x91 dig_P2 signed short
//0x92 / 0x93 dig_P3 signed short
//0x94 / 0x95 dig_P4 signed short
//0x96 / 0x97 dig_P5 signed short
//0x98 / 0x99 dig_P6 signed short
//0x9A / 0x9B dig_P7 signed short
//0x9C / 0x9D dig_P8 signed short
//0x9E / 0x9F dig_P9 signed short
//0xA0 / 0xA reserved reserved
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int32_t t_fine;
int32_t raw_temp;
int64_t raw_pres;
typedef struct{
int32_t raw_temp;
int32_t raw_pres;
int32_t temp;
int32_t pres;
}BMP280_Data;
void Reset();
void Init();
void ReadId(uint8_t *id);
void ReadV();
void ReadAll();
int32_t CompensateTemp(int32_t adc_T);
int32_t CompensatePres(int32_t adc_P);
#endif
I use Compensate formula from BMP280 datasheet.
Please help me and sorry for my bad english.

STM32F407 - SDIO | FATFS - save file to sd card

Problem :
Even the card is present or not, The SD card is mounted .
I can’t write a file to the sd card.
Context :
I read a lot of books, documentations and tutorials, I can’t find a way to make it work.
From the STM IDE debugger, I can’t get rich errors as I find with Python or Javascript. This is why I’m asking help. Except with printf but this is only personal comment to my terminal.
Technical specifications :
Mac OS - 10.15.4
CubeMX - 5.6.1
STM32 IDE - SDIO / FATFS
STM32F407VG - Discovery board
SD Card Board :
https://www.amazon.fr/Module-Lecteur-Carte-Double-Arduino/dp/B07MG4LZRW/ref=pd_rhf_se_p_img_12?_encoding=UTF8&psc=1&refRID=WJGA2Y1B8XK0H658VV8C
code
Main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* #file : main.c
* #brief : Main program body
******************************************************************************
* #attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "fatfs.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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 ---------------------------------------------------------*/
SD_HandleTypeDef hsd;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDIO_SD_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
extern char SDPath[4]; /* SD logical drive path */
extern FATFS SDFatFS; /* File system object for SD logical drive */
extern FIL SDFile; /* File object for SD */
FIL myFile;
UINT myBytes;
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #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_SDIO_SD_Init();
MX_FATFS_Init();
/* USER CODE BEGIN 2 */
if(f_mount(&SDFatFS, SDPath, 0) == FR_OK)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
if(f_open(&SDFile, "F7FILE2.TXT", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13, GPIO_PIN_SET);
char myData[] = "Helllo";
if(f_write(&SDFile,myData, sizeof(myData), &myBytes) == FR_OK)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_15, GPIO_PIN_SET);
}
f_close(&SDFile);
}
}
else
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14, GPIO_PIN_SET);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
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.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 72;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses 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_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief SDIO Initialization Function
* #param None
* #retval None
*/
static void MX_SDIO_SD_Init(void)
{
/* USER CODE BEGIN SDIO_Init 0 */
/* USER CODE END SDIO_Init 0 */
/* USER CODE BEGIN SDIO_Init 1 */
/* USER CODE END SDIO_Init 1 */
hsd.Instance = SDIO;
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = 3;
/* USER CODE BEGIN SDIO_Init 2 */
/* USER CODE END SDIO_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_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
/*Configure GPIO pins : PD12 PD13 PD14 PD15 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|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(GPIOD, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* 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 */
/* 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,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
What I have done since the first post.
The problem comes from the open function. I got a FR_DISK_ERR.
When debugging, the script follows this line :
FRESULT f_open (
FIL* fp, /* Pointer to the blank file object */
const TCHAR* path, /* Pointer to the file name */
BYTE mode /* Access mode and file open mode flags */
)
{
FRESULT res;
DIR dj;
FATFS *fs;
#if !_FS_READONLY
DWORD dw, cl, bcs, clst, sc;
FSIZE_t ofs;
#endif
DEF_NAMBUF
if (!fp) return FR_INVALID_OBJECT;
/* Get logical drive */
mode &= _FS_READONLY ? FA_READ : FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_CREATE_NEW | FA_OPEN_ALWAYS | FA_OPEN_APPEND | FA_SEEKEND;
res = find_volume(&path, &fs, mode); /* The script failed at this line ! */
if (res == FR_OK) {
dj.obj.fs = fs;
INIT_NAMBUF(fs);
res = follow_path(&dj, path); /* Follow the file path */
The script failed at the line res = find_volume and jump to the end of the open function :
if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */
LEAVE_FF(fs, res);
In regard of the variables asked by the open function :
FRESULT f_open (
FIL* fp, /* Pointer to the blank file object */
const TCHAR* path, /* Pointer to the file name */
BYTE mode /* Access mode and file open mode flags */
)
I think variables fp and mode are OK. The mistake could be about the const TCHAR* path as you said.
f_open(&SDFile, "F7FILE2.TXT", FA_CREATE_ALWAYS | FA_WRITE);
I have investigated about the find_volume but I can't follow the behaviour when debugging... there is types of error the function can return :
1 - Get sector size (multiple sector size cfg only)
#if _MAX_SS != _MIN_SS /* Get sector size (multiple sector size cfg only) */
if (disk_ioctl(fs->drv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;
if (SS(fs) > _MAX_SS || SS(fs) < _MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;
#endif
2 - An error occured in the disk I/O layer
/* Find an FAT partition on the drive. Supports only generic partitioning rules, FDISK and SFD. */
bsect = 0;
fmt = check_fs(fs, bsect); /* Load sector 0 and check if it is an FAT-VBR as SFD */
if (fmt == 2 || (fmt < 2 && LD2PT(vol) != 0)) { /* Not an FAT-VBR or forced partition number */
for (i = 0; i < 4; i++) { /* Get partition offset */
pt = fs->win + (MBR_Table + i * SZ_PTE);
br[i] = pt[PTE_System] ? ld_dword(pt + PTE_StLba) : 0;
}
i = LD2PT(vol); /* Partition number: 0:auto, 1-4:forced */
if (i) i--;
do { /* Find an FAT volume */
bsect = br[i];
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
} while (LD2PT(vol) == 0 && fmt >= 2 && ++i < 4);
}
if (fmt == 4) return FR_DISK_ERR; /* An error occured in the disk I/O layer */
3 - Check if bitmap location is in assumption (at the first cluster)
/* Check if bitmap location is in assumption (at the first cluster) */
if (move_window(fs, clust2sect(fs, fs->dirbase)) != FR_OK) return FR_DISK_ERR;
There is a screenshoot about the FATFS configuration but even with FF_USE_LFN set to 1 Enable LFN with static working buffer on the BSS. Always NOT thread-safe. I got FR_DISK_ERR ...
Do you have an idea ?
Final answer :
From the find_volume function, I found Exfat was not enable as FF_USE_LFN
I got a FR_NO_FILE_SYSTEM. I take a time to take a look on the web and I found SDIO on STM32 can't work without DMA... Also you need to set-up pull-up resistors except for the CLK.
This post solve all my problems :
https://community.st.com/s/question/0D50X00009XkWceSAF/stm32f411re-stm32cube-fatfs-sdio-sdcard-always-returns-frdiskerr
Also keep the wiring as short as possible between the stm32 card and your external sd card proto board.
I got a lot of problem because I was using long wiring.
My first guess (without seeing you FatFs configuration) is going to be that you haven't enabled Long File Names (LFS). As such FatFs is only configured to work with 8.3 filenames. These can only be 8 characters long. As such "F7FILE2.TXT" isn't being handled properly.
To enable LFS you should set FF_USE_LFN = 1. (More options are available and please pick the one most applicable to your situation.)

Use of created LCD instance in an Interrupt routine

I'm working on a project which uses STM32F103C8T6 and HD44780 LCD (2x16) to produce variable frequency PWM. I use the "4ilo HD44780 LCD library" and create an instance of LCD in the main.c called "&lcd".
The problem is when trying to use print something to LCD in the Interrupt routine, I got some errors about undeclaring &lcd because the declaration of LCD is in the main.c file not STM32F1xx_it.h. I tried to place the Interrupt handler in main.c but not a success.
any help would be appreciated
this is STM32F1xx_it.h :
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
if(EXTI->PR & EXTI_PR_PR0)
{
EXTI->PR |= EXTI_PR_PR0;
if(GPIOA->IDR & 0x0002) //0000 0000 0000 0010 -> check A1 status
{
power+=IncDec_Power_value;
if (power > maxpowerlimit) power = maxpowerlimit;
}
else
{
power-=IncDec_Power_value;
if (power < minpowerlimit) power = minpowerlimit;
}
}
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
and main.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32f1xx.h"
#include "lcd.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define LCDD4Port GPIOB
#define LCDD4Pin GPIO_PIN_12
#define LCDD5Port GPIOB
#define LCDD5Pin GPIO_PIN_13
#define LCDD6Port GPIOB
#define LCDD6Pin GPIO_PIN_14
#define LCDD7Port GPIOB
#define LCDD7Pin GPIO_PIN_15
#define LCDRegisterSelectPort GPIOB
#define LCDRegisterSelectPin GPIO_PIN_5
#define LCDEnablePort GPIOB
#define LCDEnablePin GPIO_PIN_7
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
extern volatile float power;
extern volatile float time;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void Display(Lcd_HandleTypeDef lcd)
{
Lcd_cursor(&lcd, 1, 2);
Lcd_float(&lcd, power, sizeof(power)+1);
Lcd_string(&lcd, " ");
Lcd_cursor(&lcd, 1, 10);
Lcd_float(&lcd, time, sizeof(time)+1);
Lcd_string(&lcd, " ");
}
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #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();
/* USER CODE BEGIN 2 */
Lcd_PortType ports[] ={LCDD4Port, LCDD5Port, LCDD6Port, LCDD7Port};
Lcd_PinType pins[] = {LCDD4Pin, LCDD5Pin, LCDD6Pin, LCDD7Pin};
Lcd_HandleTypeDef lcd;
lcd = Lcd_create(ports, pins, LCDRegisterSelectPort, LCDRegisterSelectPin, LCDEnablePort,
LCDEnablePin, LCD_4_BIT_MODE);
Lcd_clear_Display(&lcd);
Lcd_cursor(&lcd, 0, 2);
Lcd_string(&lcd, "POWER");
Lcd_cursor(&lcd, 0, 10);
Lcd_string(&lcd, "TIME");
Lcd_cursor(&lcd, 1, 2);
Lcd_float(&lcd, power, sizeof(power)+1);
Lcd_string(&lcd, " ");
Lcd_cursor(&lcd, 1, 10);
Lcd_float(&lcd, time, sizeof(time)+1);
Lcd_string(&lcd, " ");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
Lcd_cursor(&lcd, 1, 2);
Lcd_float(&lcd, power, sizeof(power)+1);
Lcd_string(&lcd, " ");
Lcd_cursor(&lcd, 1, 10);
Lcd_float(&lcd, time, sizeof(time)+1);
Lcd_string(&lcd, " ");
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}

Resources