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 */
}
Related
I have a small program running on stm32wb55. It tests the TIM2 timer with a delay function called wait_us(). The program runs correctly when I compile it with Keil uVision 5, but when I compile it with STM32CubeIDE it gets stuck in the function get_us(). Is there a bug in STM32CubeIDE?
/* 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);
void PeriphCommonClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
extern void initialize_tim2(void);
extern void wait_us(volatile uint32_t us);
/* 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();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
initialize_tim2();
TIM2->CR1 |= 0x0001;
wait_us(10);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOB, LD1_Pin);
HAL_Delay(500);
}
/* USER CODE END 3 */
}
#include "stm32wbxx.h"
volatile uint32_t tim2_counter;
void initialize_tim2(void)
{
RCC->APB1ENR1 |= 0x00000001;
TIM2->CR1 = 0x0004;
TIM2->CR2 = 0x0000;
TIM2->PSC = 0;
TIM2->ARR = 32;
TIM2->DIER = 0x0001;
TIM2->CNT = 0;
NVIC_SetPriority(TIM2_IRQn, 0);
tim2_counter = 0;
}
void TIM2_IRQHandler(void)
{
TIM2->SR &= (~0x001F);
++tim2_counter;
}
uint32_t get_us(void)
{
return tim2_counter;
}
void wait_us(volatile uint32_t us)
{
volatile uint32_t tickstart, now, IRQ_status;
// Get current interrupt status of TIM2 and enable it.
// Needs to be done with all interrupts disabled to prevent race condition?
__disable_irq();
IRQ_status = NVIC_GetEnableIRQ(TIM2_IRQn);
NVIC_EnableIRQ(TIM2_IRQn);
__enable_irq();
tickstart = get_us();
now = tickstart; //<-processing never reaches here under STM32CubeIDE.
while((now - tickstart) < us)
{
now = get_us();
}
// Return to previous interrupt status of TIM2.
// Needs to be done with all interrupts disabled to prevent race condition?
__disable_irq();
if(0 == IRQ_status)
{
NVIC_DisableIRQ(TIM2_IRQn);
}
else
{
NVIC_EnableIRQ(TIM2_IRQn);
}
__enable_irq();
}
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 */
So I am trying to read data from a strain load cell, which has a 2mV/V output, using the INA128P amplifier and LTC1296CCN ADC. The ADC datasheet states it works in half duplex operation and suggests a 3 wire bidirectional connection. To configure the ADC, after setting the CS low I should send an 8 bit word to the ADC's Din and then from the Dout a null bit, the 12 bit data and then zeros are transmitted until the CS goes high again. I have tried full duplex and half duplex but i keep receiving zeros from my code. Below is my code and the circuit (the parts are on a breadboard)
/* 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>
/* 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 hspi1;
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_SPI1_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 */
char uart_buf[100];
char boofer[100];
uint8_t ADC_buf[2];
uint8_t input_word[2];
int uart_buf_len;
int length;
uint16_t testdata[100];
uint8_t i = 0;
uint16_t sample;
/* 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_USART2_UART_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
// CS pin should default high
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
uart_buf_len = sprintf(uart_buf, "SPI test\r\n");
HAL_UART_Transmit(&huart2, (uint8_t *)uart_buf, uart_buf_len, 100);
//input word is 10100110
input_word[0] = 167;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
//HAL_SPI_Transmit(&hspi1, input_word, 1, 100);
//HAL_SPI_Receive(&hspi1, ADC_buf, 2, 100);
HAL_SPI_TransmitReceive(&hspi1, input_word, ADC_buf, 2, 100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
sample = (((uint16_t) ADC_buf[0] << 9)|(((uint16_t)ADC_buf[1] << 1))) >> 4;
testdata[i] = sample;
//uart_buf_len = sprintf(uart_buf, testdata[i]);
//HAL_UART_Transmit_IT(&huart2, (uint16_t *)uart_buf, 2);
length =sprintf(boofer,"%d\n",testdata[i]) + 1;
HAL_UART_Transmit(&huart2, boofer, length, 100);
i++;
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Circuit
I am trying to retrieve sound from MEMS microphones of my board, STM32F746G-Discovery. I am trying to use BSP Library. My board has wm8994 audio codec, and its schematic is here.
I wrote a code which appears below:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32746g_discovery_audio.h"
#include "wm8994.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define AUDIO_BLOCK_SIZE ((uint32_t)0xFFFE)
#define AUDIO_NB_BLOCKS ((uint32_t)4)
/* 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 hi2c3;
SAI_HandleTypeDef hsai_BlockA2;
SAI_HandleTypeDef hsai_BlockB2;
DMA_HandleTypeDef hdma_sai2_b;
DMA_HandleTypeDef hdma_sai2_a;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_SAI2_Init(void);
static void MX_I2C3_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
void BSP_AUDIO_IN_TransferComplete_CallBack(void);
void BSP_AUDIO_IN_HalfTransfer_CallBack(void);
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t audio_rec_buffer_state;
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t res = 0;
uint16_t internal_buffer[AUDIO_BLOCK_SIZE];
uint32_t bytesread = 0;
/* USER CODE END 1 */
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* 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();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SAI2_Init();
MX_I2C3_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
audio_rec_buffer_state = BUFFER_OFFSET_NONE;
res = BSP_AUDIO_IN_Init(INPUT_DEVICE_DIGITAL_MICROPHONE_2, 35, AUDIO_FREQUENCY_44K);
if(!res) {
res = BSP_AUDIO_IN_Record(internal_buffer, AUDIO_BLOCK_SIZE);
for (int block_number = 0; block_number < AUDIO_NB_BLOCKS; ++block_number) {
while(audio_rec_buffer_state != BUFFER_OFFSET_HALF);
audio_rec_buffer_state = BUFFER_OFFSET_NONE;
while(audio_rec_buffer_state != BUFFER_OFFSET_FULL);
audio_rec_buffer_state = BUFFER_OFFSET_NONE;
}
BSP_AUDIO_IN_Stop(CODEC_PDWN_SW);
BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, 35, AUDIO_FREQUENCY_44K);
BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
res = BSP_AUDIO_OUT_Play(internal_buffer, AUDIO_BLOCK_SIZE);
BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
// Callback Functions
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
audio_rec_buffer_state = BUFFER_OFFSET_FULL;
return;
}
void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
audio_rec_buffer_state = BUFFER_OFFSET_HALF;
return;
}
The problem here is that when I perform debugging, the program enters an IRQ function, and cannot exit from there. The function is below:
void DMA2_Stream7_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream7_IRQn 0 */
/* USER CODE END DMA2_Stream7_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_sai2_b);
/* USER CODE BEGIN DMA2_Stream7_IRQn 1 */
/* USER CODE END DMA2_Stream7_IRQn 1 */
}
What's the problem? I hope everything is clear. I am very new to stm32 so I am very sorry if I forget something. Thank you for your response in advance.
Note: I actually wanted to add photos of configuration of SAI peripherals in CubeMX, but I needed to add a lot of links so stackoverflow though my question as spam. I therefore had to remove them.
samples different from 0
I am working with the stm32cubeid platform and the stm32f407ve development board, I am trying to sample a sinusoidal signal that I generate in the same compiler and apply the fast fourier transform functions. When displaying the variables after applying the fft the spaces that They should have a 0 stored, according to the code, negative or positive values close to 0 appear, this does not affect the operation of the code, but I do not understand why this happens.This is all I have written in the generated code generated with the stm32cubeid.
#include "main.h"
#include "arm_math.h"
#include "arm_const_structs.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define Fs 4096;
/* 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 hadc1;
/* USER CODE BEGIN PV */
#define SIGNAL_BUFFER_LENGTH 4096
float signalBuffer[2*SIGNAL_BUFFER_LENGTH];
float fftBuffer[2*SIGNAL_BUFFER_LENGTH];
float magnitudes[SIGNAL_BUFFER_LENGTH];
/* USER CODE END PV */
uint32_t k;
uint32_t cont1,cont2;
uint32_t start;
uint32_t stopi;
uint32_t delta;
float32_t maxValue; /* Max FFT value is stored here */
uint32_t maxIndex;
float frecuencia=10.0;
float32_t Ts;
float tiempo;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_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 */
#define ARM_CM_DEMCR (*(uint32_t*)0xE000EDFC)
#define ARM_CM_DWT_CTRL (*(uint32_t*)0xE0001000)
#define ARM_CM_DWT_CYCCNT (*(uint32_t*)0xE0001004)
if(ARM_CM_DWT_CTRL !=0){
ARM_CM_DEMCR |= 1<<24;
ARM_CM_DWT_CYCCNT =0;
ARM_CM_DWT_CTRL |= 1<<0;
}
/* 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_ADC1_Init();
/* USER CODE BEGIN 2 */
Ts=1.0/(float)Fs;
for(k=0;k<2*SIGNAL_BUFFER_LENGTH;k+=2 )
{
signalBuffer[k]=10*(float)sin(2*PI*k/2*Ts*frecuencia);
signalBuffer[k+1]=0;
}
//k++;
start= ARM_CM_DWT_CYCCNT;
arm_cfft_f32(&arm_cfft_sR_f32_len4096,signalBuffer,0,1);
arm_cmplx_mag_f32(signalBuffer,magnitudes,4096);
arm_max_f32(magnitudes, 4096, &maxValue, &maxIndex);
stopi = ARM_CM_DWT_CYCCNT;
delta=stopi-start;
tiempo=delta/8.0E07*1000.0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}