cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 ADC and timer interupt

Cezar Chirila
Associate II
Posted on April 19, 2017 at 20:11

Hello!

I want to build a project where i need to do about 3500 readings from a CCD sensor in a short period a time. The signal i want to read has a frequency of about 0.35MHz, which should be fine as long as i use  13.5cycles for sampling time. 

The problem is in the intrerupt. Here is how my program works:

  • TIM2,3,4 are started in PWM mode, needed for the CCD
  • In main loop:

  • If the reading has been done (it is only done once), send the data over serial port
  • In interupt of TIM1:

  • If the reading hasn t been done already, start ADC, read current pixel and put it in a vector, increment current pixel unless the last pixel has been reached, when then I say that the reading is over.

Unfortunately I do not get anything in the serial output. What can be the problem? Is the interupt routine not called? 

Here it is: 

void TIM1_UP_IRQHandler(void)

{

/* USER CODE BEGIN TIM1_UP_IRQn 0 */

if(read_all == 0){

HAL_ADC_Start(&hadc1);

aTxBuffer[current_pixel] = HAL_ADC_GetValue(&hadc1);

if(current_pixel == last_pixel){

read_all = 1;

current_pixel = 3;

}

else

current_pixel++;

}

/* USER CODE END TIM1_UP_IRQn 0 */

HAL_TIM_IRQHandler(&htim1);

/* USER CODE BEGIN TIM1_UP_IRQn 1 */

/* USER CODE END TIM1_UP_IRQn 1 */

}

I have also attached all the code. Thank you!

#stm32f103 #timer-interrupt #hal #adc
1 REPLY 1
Cezar Chirila
Associate II
Posted on April 20, 2017 at 19:08

I think I have found the problem, but I do not know hot to fix it. 

In main.c I have a variable:

uint16_t testPixel = 1;

uint8_t myChar[5];

In the infinite loop, i just send it every second via UART:

itoa(testPixel, myChar, 10);

HAL_UART_Transmit(&huart1,myChar,sizeof(myChar),10);

HAL_Delay(1000);

Then in stm32f1xx_it.c I have :

extern testPixel;

[...]

void TIM1_UP_IRQHandler(void)

{

/* USER CODE BEGIN TIM1_UP_IRQn 0 */

testPixel = 2;

/* USER CODE END TIM1_UP_IRQn 0 */

HAL_TIM_IRQHandler(&htim1);

/* USER CODE BEGIN TIM1_UP_IRQn 1 */

/* USER CODE END TIM1_UP_IRQn 1 */

}

When I upload the code and test it, I receive over UART '1111', instead of 2. 

Here is how the Timer is set-up:

static void MX_TIM1_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig;

TIM_OC_InitTypeDef sConfigOC;

TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;

htim1.Instance = TIM1;

htim1.Init.Prescaler = 0;

htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

htim1.Init.Period = 80-1;

htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

htim1.Init.RepetitionCounter = 0;

if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

{

Error_Handler();

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

{

Error_Handler();

}

sConfigOC.OCMode = TIM_OCMODE_PWM1;

sConfigOC.Pulse = 10;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

{

Error_Handler();

}

sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

sBreakDeadTimeConfig.DeadTime = 0;

sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

{

Error_Handler();

}

HAL_TIM_MspPostInit(&htim1);

}