bigmaxx (bigmaxx) wrote in ru_radio_electr,
bigmaxx
bigmaxx
ru_radio_electr

Categories:

Трабл с таймером STM32

Что-то никак "не выходит каменный цветок" с таймером STM32.
Задача - генерить на выходе Output Compare импульсы Step для шагового двигателя.
Время между их передними фронтами меняется (разгон/торможение).
За основу взял известный принцип: 16-битный счетчик таймера считает постоянно по максимальному модулю 65536.
Очередная задержка формируется перезаписью регистра СС, с прибавлением её длительности к текущему значению СС.
Используется 2 канала CC, срабатывающих с фиксированным сдвигом.
Вначале срабатывает OC2; в его прерывании делаются расчёты и операции по подготовке шага.
Затем срабатывает OC1, по которому формируется собственно фронт шагового импульса.
Однако никак не получается запустить эти прерывания в нужной последовательности.
Сейчас застрял на том, что примерно один раз за цикл счетчика (~65 mc) возникают флаги прерывания в каналах СС 3 и 4, для которых и СС events, и генерация прерываний запрещены. Такое впечатление, что Update Event таймера сбрасывает все эти запреты, хотя оно тоже запрещено, да и даташиту такое поведение не соответствует.
Ниже - картинка с анализатора и текст обработчика прерывания.
Прошу не тратить буквы на то, чтобы лажать HAL и LL драйверы; тут явно в чем-то другом дело.

UPD: Описанная проблема решена, расчётные тайминги прерываний пошли. Но вот ещё вопрос, раз такое дело. Вот по CC Match изменился уровень внутреннего выходного сигнала OCxREF - я так понимаю, взвелся некий триггер. Как этот триггер программно вернуть обратно? Задать через регистр CCMR OCM=Forced active/inactive? И если да, сбрасывают ли его какие-то другие действия/события?



void TIM3_IRQHandler(void)
{
if (LL_TIM_IsActiveFlag_CC1(TIM3)) //начался импульс STEP1
{
LL_TIM_ClearFlag_CC1(TIM3);
sm_driver_PostStepA();
}
if (LL_TIM_IsActiveFlag_CC2(TIM3)) //подготовка к STEP1
{
LL_TIM_ClearFlag_CC2(TIM3);
speed_cntr_PreStep(0); //Из этой функции вызывается тестовый ногодрыг для Cannel1, дающий правильный тайминг
}
if (LL_TIM_IsActiveFlag_CC3(TIM3)) //начался импульс STEP2 - это прерывание и CC3 event запрещены!!!
{
LL_TIM_ClearFlag_CC3(TIM3);
//++++++++++++++++++++++++++++ А это тестовый ногодрыг для Cannel2, и сюда прога вообще не должна попадать
HAL_GPIO_WritePin(StpMotor2_Current_GPIO_Port,StpMotor2_Current_Pin,GPIO_PIN_SET); //Set PA4
HAL_GPIO_WritePin(StpMotor2_Current_GPIO_Port,StpMotor2_Current_Pin,GPIO_PIN_RESET); //Reset PA4
//++++++++++++++++++++++++++++
// sm_driver_PostStepB();
}
if (LL_TIM_IsActiveFlag_CC4(TIM3)) //подготовка к STEP2
{
LL_TIM_ClearFlag_CC4(TIM3);
// speed_cntr_PreStep(1);
}
}
Subscribe
  • Post a new comment

    Error

    Comments allowed for members only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 19 comments