cancel
Showing results for 
Search instead for 
Did you mean: 

I2C_WaitOnFlagUntilTimeout, TIM16, I2C, Servo, HAL_GetTick()

grzeniux
Associate II

I added a TIM16 to the project with interrupts to handle the servo
Unfortunately, after adding it, the program started to crash
Below are screenshots of where it started to crash
Does anyone know how to fix this?

This is how I configured TIM16:

450766dc-6fcf-4043-9dfa-b7276695bd72.png

22_i2c_1.png22_i2c_2.png22_i2c_3.png22_i2c_4.png

 

this is an i2c configuration:

i2c.jpg

 

 

 

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Your call stack suggests you're calling lcd functions within an interrupt handler, which isn't ideal, but without first calling lcd_init. Doesn't appear to be related to TIM16.

TDK_0-1703714260297.png

 

Initialize the lcd before using it. Try to avoid blocking calls within an interrupt context. It can work, but you need systick to have higher priority than what you're currently in.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

5 REPLIES 5
TDK
Guru

Your call stack suggests you're calling lcd functions within an interrupt handler, which isn't ideal, but without first calling lcd_init. Doesn't appear to be related to TIM16.

TDK_0-1703714260297.png

 

Initialize the lcd before using it. Try to avoid blocking calls within an interrupt context. It can work, but you need systick to have higher priority than what you're currently in.

If you feel a post has answered your question, please click "Accept as Solution".
grzeniux
Associate II

"Doesn't appear to be related to TIM16." - However, when I turn it off, everything works

"systick to have higher priority" - zero is the highest priority? I have set 0

"Your call stack suggests you're calling lcd functions within an interrupt handler," - I use this to refresh LCDs, it seemed the most effective option to me

 

int main(void)
{
  /* USER CODE BEGIN 1 */
lcd_init(&disp);
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
  HAL_GPIO_WritePin(GPIOB, Pump, GPIO_PIN_SET);
 
  /* 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_USART2_UART_Init();
  MX_I2C1_Init();
  MX_TIM1_Init();
  MX_TIM6_Init();
  MX_ADC1_Init();
  MX_TIM7_Init();
  MX_TIM16_Init();
  /* USER CODE BEGIN 2 */
 
  HAL_GPIO_WritePin(GPIOA, Pump, GPIO_PIN_SET);
  HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1); // Serwomechanizm
 // HAL_ADC_Start_DMA (&hadc1, &buffer, 1); // potencjometr
  HAL_ADC_Start_IT (&hadc1); // potencjometr
 
//  HAL_ADC_Start(&hadc1); // potencjometr
  HAL_TIM_Base_Start_IT(&htim6);
  sprintf((char *)disp.f_line, "Elo");
  sprintf((char *)disp.s_line, "Moze wodeczki?");
  disp.addr = (0x27 << 1);
  disp.bl = true;
  lcd_display(&disp);

 

I2C.pngI2C_2.pngI2C_3.pngI2C_4.png

when I placed: lcd_init(&disp); at the beginning of the maina, other errors appeared

 

 

 

 

 

 

 

 

Jnevi.1
Senior

you mentioned tim16. in your irq handler you refer to tim6? is this correct?

and you should not put your display init routine at the very beginning because then your spi/i2c/whatever your type of display is won't be initialized at that time. so after your pheripherals init but before the timers are started

in your irq handler you should only set some flag and update your display in the main loop. doing display update stuff in your irq handler may be an option but normaly is bad as TDK mentioned

grzeniux
Associate II

"you mentioned tim16. in your irq handler you refer to tim6? is this correct?"

I used the TIM6 as a timer to refresh the LCD and to check whether the tap switches were pressed. - but I understand that this is not correct

I use the TIM16 for servo operation
Here a simple example:

// htim16.Instance->CCR1 = 25; // 0 degree
// HAL_Delay(2000);
// htim16.Instance->CCR1 = 50; // 45 degree
// HAL_Delay(2000);
// htim16.Instance->CCR1 = 75; // 90 degree
// HAL_Delay(2000);
// htim16.Instance->CCR1 = 110; // 153 degree
// HAL_Delay(2000);
// htim16.Instance->CCR1 = 125; // 180 degree
// HAL_Delay(5000);

 

When I have option 1, the display does not show anything, it is blank, even though debugging everything goes on

When I have option 2, the display works normally
If I understand correctly, it is like switching the TIM16 on and off (options 1 and 2)
So there is a connection with the TIM16
Do you have any ideas gentlemen?

PWM_TIM16.png

 

 

 

 

 

 

 

 

TDK
Guru

> Do you have any ideas gentlemen?

Be a little more systematic than turning a knob and seeing if it works or not. Look at the stack trace, understand what is happening. Realize that trying to use the LCD prior to it being initialized isn't likely to work well.

> when I placed: lcd_init(&disp); at the beginning of the maina, other errors appeared

So correct them. If you need help, post your modified code and related errors.

If you feel a post has answered your question, please click "Accept as Solution".