stm32f051r8t6 TIM14 interrupt handler not working after reset - c

I am using STM32CubeMX to generate code into IAR, and I am using a stm32f051r8t6 microcontroller,
The problem I am having is that when first loading the code onto the chip, it all works perfect, however after pressing restart on either the board or IAR debugger, the TIM14 interrupt handler is not entered, but as soon as I leave the debugger and enter again, it starts working until I press restart. Has anybody come across this problem before? My code is below
static void MX_TIM14_Init(void);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM14)
{
HAL_GPIO_WritePin(GPIOA, USART1_TE_Pin, GPIO_PIN_SET);
}
}
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_ADC_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_TIM14_Init();
HAL_TIM_Base_Start(&htim14);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
FslBufferControl();
MimModeCheck();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 0 */
/* USER CODE END TIM14_Init 0 */
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 47999;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 1;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}

You need to add to enable the interrupt.
MX_TIM14_Init();
HAL_NVIC_EnableIRQ(TIM14_IRQn); // <----------------------------
HAL_TIM_Base_Start(&htim14);
Just check the IRQn TIM14 UG event number. They are defined in the IRQn_Type enum type defined in the STM32F___.h file where ___ is the model of your micro (you will find it in the include folder)

Related

STM32 Timer Interrupts causing Debug problems

I'm using STM32MP157A-DK1 Discovery kit with STM32MP157A MPU.
My problem is that when I terminate the debug and launch again my code stop in void HardFault_Handler(void); (in stm32mp1xx_it.c). The first debugging time works ok, the problem was in the second debug.
I tried removing HAL_TIM_Base_Start_IT(&htim14); and the problem stopped, but I need the timer. Also tried switching timers and the others also give me the same debugging problem.
I checked the hardware configuration (.ioc file) and it's all in default values except the timers that I'm using.
int main(void) {
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the system clock */
SystemClock_Config();
}
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
}else{
/* IPCC initialisation */
MX_IPCC_Init();
/* OpenAmp initialisation ---------------------------------*/
MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
}
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM14_Init();
/* USER CODE BEGIN 2 */
/*
* Create Virtual UART device
* defined by a rpmsg channel attached to the remote device
*/
log_info("Virtual UART0 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart0) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART0 failed.\r\n");
Error_Handler();
}
log_info("Virtual UART1 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart1) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART1 failed.\r\n");
Error_Handler();
}
//Need to register callback for message reception by channels
if(VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
if(VIRT_UART_RegisterCallback(&huart1, VIRT_UART_RXCPLT_CB_ID, VIRT_UART1_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
HAL_TIM_Base_Start_IT(&htim14); //Here is the trouble maker
while(1){
OPENAMP_check_for_message();
}
}
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if(htim == &htim14){
//do something
}
}
void VIRT_UART0_RxCpltCallback(VIRT_UART_HandleTypeDef *huart) {
//log_info("Msg received on VIRTUAL UART0 channel: %s \n\r", (char*) huart->pRxBuffPtr);
}
void VIRT_UART1_RxCpltCallback(VIRT_UART_HandleTypeDef *huart) {
log_info("Msg received on VIRTUAL UART1 channel: %s \n\r", (char*) huart->pRxBuffPtr);
}
I'm using Windows 10, STM32CubeIDE (Version: 1.8.0, Build: 11526_20211125_0815 (UTC)), STM32CubeMX (Version: 6.4.0-RC4, Build: 20211122-2105 (UTC)).
I just put
TIM14->DIER &= ~(TIM_IT_UPDATE);
TIM14->CR1 &= ~(TIM_CR1_CEN);
before call timer initialization
MX_TIM14_Init();
The problem was in Production Mode the A7 core controls all M4's peripherical, so it only reset the interruption when I reset the core A7. This code I use turn off the interrupt to prevent a interrupt call before initialization. You must call it for every peripheric interrupt (check how to disable it, for timers just change the TIM number. Ex: TIM3, TIM17, ...)
Don't know if it's the best way, it's working until now though.
Final main() code:
int main(void) {
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the system clock */
SystemClock_Config();
}
if(IS_ENGINEERING_BOOT_MODE()){
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
}else{
/* IPCC initialisation */
MX_IPCC_Init();
/* OpenAmp initialisation ---------------------------------*/
MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
}
/* USER CODE BEGIN SysInit */
TIM14->DIER &= ~(TIM_IT_UPDATE);
TIM14->CR1 &= ~(TIM_CR1_CEN);
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_TIM14_Init();
/* USER CODE BEGIN 2 */
/*
* Create Virtual UART device
* defined by a rpmsg channel attached to the remote device
*/
log_info("Virtual UART0 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart0) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART0 failed.\r\n");
Error_Handler();
}
log_info("Virtual UART1 OpenAMP-rpmsg channel creation\r\n");
if(VIRT_UART_Init(&huart1) != VIRT_UART_OK){
log_err("VIRT_UART_Init UART1 failed.\r\n");
Error_Handler();
}
//Need to register callback for message reception by channels
if(VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
if(VIRT_UART_RegisterCallback(&huart1, VIRT_UART_RXCPLT_CB_ID, VIRT_UART1_RxCpltCallback) != VIRT_UART_OK){ Error_Handler();}
HAL_TIM_Base_Start_IT(&htim14); //Here is the trouble maker
while(1){
OPENAMP_check_for_message();
}
}

sprintf cause my program stop working in keil

This is my main function and I don't know why when I simulate it in proteos I figured that the code runs up to sprintf and next lines doesn't run and when I comment it the "salam" printed on lcd
I use mingw compiler and I have installed all librarys
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 */
char q[5] = "salam" ;
int a = 6541;
//float b = a/7;
LCD1602_Begin8BIT(RS_GPIO_Port,RS_Pin,E_Pin,D0_GPIO_Port,D0_Pin,D1_Pin,D2_Pin,D3_Pin,D4_GPIO_Port,D4_
Pin,D5_Pin,D6_Pin,D7_Pin);
LCD1602_setCursor(1,1);
//snprintf(q, 20, "%10d", 1234567);
//LCDCHAR_Puts(0, 0, q);
//char command1[50], command2[50]; // Added
//char *temp[] = {NULL, command1, command2, NULL}; // Modified
//temp[0]="sum";
LCD1602_print("mahdi kahrizi");
LCD1602_2ndLine();
sprintf(q,"%d",a);
LCD1602_print(q);
the problem starts from here.
char q[5] = "salam" ;
q is too short to store this word. It has to be at least 6 chars long.
It is Undefined Behaviour as you write outside the array bounds.
When you change the length of the q to be longer
snprintf(q, sizeof(q), "%d", a);

STM32 using CubeMX and STMStudio: 'int main()' doesn't work

I'm learning to code on STM32F429ZI Nucleo board and I've been trying to read temperature from ADC1 temperature sensor using STMStudio.
The code I found in one of tutorials didn't work so I tried checking value of "check" variable at various parts of code and then I've noticed that, not only the value of "check" variable doesn't change anywhere inside the main function, but also the STMStudio doesn't see any variables declared inside of the main function.
Any idea why is that?
I've tried different code which uses button to light up LED to check if the board is ok and it worked just fine.
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
uint16_t SenseADC;
float check = 0;
float Temperature;
float Vsense;
/* USER CODE END PV */
/* 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 */
/* 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 */
HAL_ADC_Start(&hadc1);
check = 2;
const float V25 = 0.76; // [V]
const float Vsupply = 3.0; // [V]
const float ADCResolution = 4095;
const float avg_slope = 0.0025; // [V/deg. C]
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK){
check = 3;
SenseADC = HAL_ADC_GetValue(&hadc1);
Vsense=(SenseADC*Vsupply)/ADCResolution;
Temperature = (Vsense - V25)/avg_slope + 25;
HAL_ADC_Start(&hadc1);
}
}
}
The compiler must have noticed that the check variable is only written and never read, and optimized away the writes as having no purpose. For debugging purposes, you can declare it as volatile to force all writes to get through to memory.
The const values in the program are likewise victims of the optimization, the compiler has used the values directly in the code, possibility precalculating parts of the expressions.

MCU as SPI Slave, read data

I have an master which i cant control it just sends clock with data. I congifured my stm32f4 as full-duplex slave. And i managed to synchronize them with HAL function:
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)spi_buffer, (uint8_t *)spi_buffer, 16, 2000);
// receive 16 bytes then send them for debugg
Im sending from slave the bytes which i get from master, in purpose of debugging,
and the data is same, so its perfectly synchronized and seems like slave reading all data master sends. Here is the images(sorry cant dowload it with stackoverflow cuz i low on points):
https://imgur.com/wa6rF5J - ocsillo's image
https://imgur.com/a/ZVCPaNT - zoomed up
The problem is that i dont know how to read that data, its 16bytes which i need somehow to read without slowing the spi down. All my attempts to do that are failed.
Thw whole code are:
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_USB_DEVICE_Init();
MX_SPI1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
uint8_t collect_bits[16] = {0};
char string_array[21] = {0};
uint8_t spi_buffer[16] ={0} ;
uint8_t flag_when_start_print = 0;
spi_buffer[0] = 5;
uint8_t spi_transmit[16] = {0};
HAL_SPI_Init(&hspi1); //init spi
while (1)
{
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)spi_buffer, (uint8_t *)spi_buffer, 16, 2000);
if (spi_buffer[0] == 0xFE) // just tring to catch 0xFE, doesnt work
{
sprintf(string_array, "%X", spi_buffer[0]); // just simple convertation for PC output
CDC_Transmit_FS((uint8_t*)string_array, sizeof(string_array)); // print result. }
}
}
The important fact that the beggining of the messge i want to catch is always starts with 0xFE0010, so after those bytes i need to read next 13bytes

Writing data to micro SD card from microcontroller STM32F401RET6

I am using the board Nucleo F401RE based on micro-controller STM32F401RET6. I connected to the board a Micro SD slot, and interested in writing data to the SD Card and read data from it. I used the software STM32CubeX to generate code and in particular the SD library with built-in functions. I tried to write a simple code which writes an array to a specific array and tries to read the same data afterwords. The code is as follows:
uint32_t to_send[512] = {1, 2, 3, 4, 5};
uint32_t to_receive[512];
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_SDIO_SD_Init();
char buffer[14] = "Hello, world\n";
uint64_t address = 0x00;
HAL_SD_ErrorTypedef write_result = HAL_SD_WriteBlocks(&hsd, to_send, address, 512, 1);
HAL_SD_ErrorTypedef read_result = HAL_SD_ReadBlocks(&hsd, to_receive, 0x00, 512, 1);
HAL_UART_Transmit(&huart2, (uint8_t *) &write_result, 1, 1000);
HAL_UART_Transmit(&huart2, (uint8_t *) &read_result, 1, 1000);
while (1)
{
//HAL_UART_Transmit(&huart2, (uint8_t *)buffer, 14, 1000);
HAL_UART_Transmit(&huart2, (uint8_t *)to_receive, 512, 1000);
}
Though, I don't succeed in writing the data, the function HAL_SD_WriteBlocks() returns the value SD_CMD_CRC_FAIL, which means that : "Command response received (but CRC check failed)". What am I missing ? I checked the hardware configuration many times and the micro SD card is correctly connected to the microcontroller. I can add the implementation of the HAL built-in functions if needed. Thank you.
Make sure that your sdio clock is within valid limits (see function SystemClock_Config):
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 8
#define PLL_N 336
/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P 2
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
When using the defines above when initialize the clock (RCC_OscInitTypeDef) the SDIO clock will be 336 / (7*2) = 25Mhz
(Given that PLL_M is the same as the HSE / HSI)
If the frequency is too high (>50Mhz) then perhaps you will get errors in the communication which will explain your symptoms.
I didnt use usart for my project, i write the value to sd card and read the value ,
you must arrange the code for your expectations, my code is
#include "main.h"
#include "stm32f4xx_hal.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
SD_HandleTypeDef hsd;
/* USER CODE BEGIN PV */
/* Private variables --------------------------------------------------------*/
uint8_t to_send[512] = "sener suat sd card";
uint8_t to_receive[512];
uint8_t sener[3]={7,5,4};
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SDIO_SD_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
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();
/* USER CODE BEGIN 2 */
uint32_t address = 0x55;
HAL_SD_MspInit(&hsd);
HAL_SD_Init(&hsd);
HAL_SD_WriteBlocks(&hsd,to_send,address,1,500);
HAL_Delay(100);
HAL_SD_ReadBlocks(&hsd,to_receive,address,1,500);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
}

Resources