2019-08-30 12:12 AM
I am using stm32cube with the HAL functions to start my project. I have everything running fine. I have my adc trigger using OCP2 of my pwm and this works like a charm. But wen i use the uart somehow my adc does not want to trigger anymore and i do not get any interrupts for the adc anymore. How can the UART do this even when it does not use interrupts?
2019-08-30 07:33 AM
Please post your code. Otherwise its just pot shots in the dark. Which style of HAL functions are you using: polled, interrupt or DMA? If the answer is "polled", my response is "don't do that".
2019-08-30 07:45 AM
Depends where you use it. If you use the HAL UART Transmit in a callback it can block interrupts. Callbacks are done under interrupt context.
2019-08-30 07:55 AM
Sorry, here is my code.
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_ADC3_Init();
MX_DAC1_Init();
MX_ETH_Init();
MX_HRTIM_Init();
MX_TIM2_Init();
MX_UART4_Init();
MX_USB_OTG_FS_PCD_Init();
/* USER CODE BEGIN 2 */
HAL_HRTIM_WaveformCountStart(&hhrtim,(HRTIM_TIMERID_MASTER | HRTIM_TIMERID_TIMER_A | HRTIM_TIMERID_TIMER_C));//start master,timer A and timer C
HAL_HRTIM_WaveformOutputStart(&hhrtim,(HRTIM_OUTPUT_TA1 | HRTIM_OUTPUT_TA2 | HRTIM_OUTPUT_TC1 | HRTIM_OUTPUT_TC2)); //enable hrtimer A en C outputs
HAL_DAC_Start(&hdac1, DAC_CHANNEL_1); //enable DAC output 1, this sends the scaled ADC value to pin PA4
HAL_ADC_Start_IT(&hadc3); //enable ADC
HAL_TIM_OC_Start(&htim2, TIM_CHANNEL_1);//start TIM2 that is used for data trigger and use polling not interrupt
//HAL_ADC_Start_DMA(&hadc3, (uint32_t *)adc_array, (uint32_t)1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(check_timer_interrupt_flag_set(&htim2,OC1_FLAG)) //check if OC_INTERRUPT has passed
{
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_9); // toggle pin E9
send_info_uart();
}
}
/* USER CODE END 3 */
}
void send_info_uart(void)
{
HAL_UART_Transmit(&huart4,(uint8_t *)aTxBuffer, sizeof(aTxBuffer),500)
}
uint8_t check_timer_interrupt_flag_set(TIM_HandleTypeDef *handle,uint32_t number)
{
if(handle->Instance->SR & number)
{
handle->Instance->SR ^= number;
return 1;
}
else
{return 0;}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
HRTIM_CompareCfgTypeDef timera_comp,adc_comp;
//adc_converted_value=adc_array[0];
adc_converted_value = HAL_ADC_GetValue(&hadc3);
float temp = adc_converted_value*0.00763;
timera_comp.CompareValue = (uint16_t) temp;
if(timera_comp.CompareValue<3){timera_comp.CompareValue=3;}
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, &timera_comp);
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_1, &timera_comp);
adc_comp.CompareValue = (uint16_t) (temp / 2 );
HAL_HRTIM_WaveformCompareConfig(&hhrtim, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_2, &adc_comp);
HAL_DAC_SetValue(&hdac1,DAC_CHANNEL_1,DAC_ALIGN_12B_R,(adc_converted_value*0.0625));
//HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_9);
}
2019-08-30 12:35 PM
The SW architecture looks weird.
First, don't use float inside an interrupt (callback), you can most of the time use a int32_t temp_x100000 = adc_converted_Value *763;
Then in the main loop you look for a Timer status flag. Where will it be cleared for next time it's going to be tested?
USART send or receive take time (115200bps = 100usec per byte, so if core runs at 80MHz, that's 8000 cycles... significant.
2019-08-30 01:05 PM
The check_timer_interrupt_flag_set function resets the flag. It seems i found the problem. I use timer a compare 2 to trigger my adc. This has to do with current meas. I want to adjust this every time i trigger so that when i the adc samples it is always in the middle of the duty cycle. When i do this my adc loses its trigger. When i put this in comment there is no problem. I just need to find a solid way to make sure the adc triggers every cycle in the middle of the duty cycle.
2019-08-30 01:24 PM
solved the problem by making the variable in the interrupt static.
2019-08-30 01:24 PM
solved the problem by making the variable in the interrupt static.Now it does what it should do.