реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Прерывание Update Event таймера 2, Сильное дрожание фронтов
Sprite
сообщение Jan 17 2011, 06:10
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Доброго всем времени суток!

В программе используется таймер 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 sad.gif

Сообщение отредактировал Sprite - Jan 18 2011, 06:00
Go to the top of the page
 
+Quote Post
Sprite
сообщение Jan 19 2011, 03:56
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 173
Регистрация: 11-05-08
Пользователь №: 37 414



Поставлю вопрос по другому: какое максимальное количество тактов может занимать одна инструкция процессора (stm32f103)? Если 10-12 тактов, то вопрос закрыт, иначе буду думать, где слабое звено программы.
Go to the top of the page
 
+Quote Post
zoddy
сообщение Jan 20 2011, 08:49
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 42
Регистрация: 4-12-05
Из: Екатеринбург
Пользователь №: 11 773



Цитата(Sprite @ Jan 19 2011, 08:56) *
Поставлю вопрос по другому: какое максимальное количество тактов может занимать одна инструкция процессора (stm32f103)? Если 10-12 тактов, то вопрос закрыт, иначе буду думать, где слабое звено программы.


Ну, я так полагаю, ... Вы не там копаете... Разберитесь сперва с тем, что вы хотите в конечном итоге получить...
Судя по приведенным фрагментам кода, Вы настраиваете таймер на переполнение при CNT=7200, при достижении счетчиком CNT=3600 произойдет махание ножкой в соответствии с режимом PWM1. По переполнению счетчика, происходит событие Update, счетчик итак начинает считать с CNT=0 и вы опять же зачем-то подсовываете в него значение 0x00, при этом, учитывая, что событие Update генерируется с задержной на несколько тактов, плюс вход в прерывание 12 тактов... , а счетчик уже начал считать... и на каком-то такте вы его снова обнулили.... вот и получается ваше дрожжжжание фронта.
В данном случае, логичней было бы изменять длительность периода таймера в регистре ARR... или значение длительности импульса в регистре совпадения CCR1.... а не пытаться изменить значение счетного регистра, да еще при этом на запущенном таймере.
В общем, не мешало бы вам почитать вдумчиво Reference Manual.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th June 2025 - 01:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01375 секунд с 7
ELECTRONIX ©2004-2016