Доброго всем времени суток!
В программе используется таймер 2, в прерывании по переполнению которого корректируется значение счетчика этого таймера (TIM2->CNT). На данный момент значение выставляется фиксированным (100). Первый канал таймера настроен на выход в режиме PWM Mode 1. Так вот когда я смотрю выходной сигнал, наблюдается сильное дрожание фронтов (в пределах 10-12 тактов), хотя, как мне кажется дрожание должно быть в пределах 1-3 тактов (в зависимости от текущей команды, которая совпадает с моментом возникновения прерывания). В чем ошибка?
Код инициализации таймера:
Код
TIM_TimeBaseInitTypeDef tb2;
TIM_OCInitTypeDef TIM_OCInitStructure;
//Таймер 2 --------------------------------------------
tb2.TIM_Period = 7200;
tb2.TIM_Prescaler = 0;
tb2.TIM_ClockDivision = 0;
tb2.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &tb2);
// PWM1 Mode configuration: Channel1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 3600;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);
TIM_ARRPreloadConfig(TIM2, DISABLE);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
// TIM2 enable counter
TIM_Cmd(TIM2, ENABLE);
Код инициализации прерывания:
Код
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = 28;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
Код прерывания:
Код
void TIM2_IRQHandler(void)
{
TIM2->CNT = 0x0000;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
Ну и на всякий случай настройка порта:
Код
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
Пробовал проделывать тоже самое на меге128 - дрожание есть, но в пределах 2-х тактов.
Еще заметил такую особенность: если в прерывании присваивать значение таймера какой-то переменной:
Код
void TIM2_IRQHandler(void)
{
TIM2->CNT = cnt;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
, а в основном цикле по нажатию кнопки менять значение этой переменной, то в зависимости от уровня оптимизации наюлюдается разное дрожание. Дрожание также меняется в зависимости от настройки приоритета прерывания и от количества конструкций типа if.
Так можно ли добиться какой-нибудь стабильности? Не хочется переходить на мегу128
Сообщение отредактировал Sprite - Jan 18 2011, 06:00