Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: проблемка с таймером T3 atmega1280
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
klen
по внешенму прерыванию сбрасывается счетный регистр запускается таймер T3, при срабатывании прерывания OCRB подымается пин, при срабатывании прерывания OCR3B пин опускается, таймер останавливается. Все, ждем нового внешнего прерывания.

Тоесть задача - выставить импульс фиксированной длительность относительно внешнего(типа ШИМ такой у меня). Проблема втом что если в основном цикле произвести запись в OCR3A/B для двигания ипульса таймер не работает(вернее что происходит неизвестно но импульсы на пине пропадают вообще). В симуляторе код AVRStudio рабтает.


Код
uint16_t PWM_val = 0x1111;

//-------------------------------------------------------
void SetPWM_Value() __attribute__ (( noinline ));
void SetPWM_Value()
{
  cli();
  // ожидание окончания импульса открытия тиристора
  if (PWM_val > PWM_MIN) PWM_val = PWM_MIN;
  // запись значений Pl (время активации  импульса открытия тиристора)
  OCR3B = PWM_val;
  // запись значений Ph (время снятия импульса открытия тиристора)
  OCR3A  = OCR3B + PWM_PULSE_TIME;
  sei();
}

// инициализация ШИМ петли
void InitPWM()
{
  // установка режима внешних прерываний
  // по подъему сигнала
  EICRA |= _BV(ISC11)| _BV(ISC10);
  // разрешение внешнего прерывания INT1
  EIMSK |= _BV(INT1);
  // установка режима таймера T3
  // разрешение прерываний OC1A OC1 OVF
  TIMSK3 = 0;
  TIMSK3 = _BV(OCIE3A) | _BV(OCIE3B);

  SetPWM_Value();

  // установка режима CTC таймера
  TCCR3B = 0;
  TCCR3B |= _BV(WGM32);

}

//-------------------------------------------------------
// запуск таймера T3
void StartPwmTimer()
{
  TCCR3B |= _BV(CS30);
}
//-------------------------------------------------------
// останов таймера T3
void StopPwmTimer()
{
  TCCR3B &= ~_BV(CS30);
}

void PWM_Update()
{
   PWM_val =  [b]расчитанное знпчение[/b];
   SetPWM_Value();
}  

//-------------------------------------------------------
// бработчик прерывания INT1 по
ISR(INT1_vect)
{
  cli();
  
  TCNT3L = 0x00;
  TCNT3H = 0x00;
  // запуск таймера T3, отсчет момета открытия тиристора TIMER3_COMPB
  StartPwmTimer();
  sei();
}
//-------------------------------------------------------
ISR(TIMER3_COMPA_vect)
{
  cli();
  // сброс  импульса открытия тиристора
  DownPWM();
  // останов таймера
  StopPwmTimer();
  sei();
}
//-------------------------------------------------------
ISR(TIMER3_COMPB_vect)
{
  cli();
  // установка импулса открытия тиристора
  UpPWM();
  sei();
}
Палыч
Цитата(klen @ Nov 16 2007, 12:46) *
Проблема втом что если в основном цикле произвести запись в OCR3A/B для двигания ипульса таймер не работает(вернее что происходит неизвестно но импульсы на пине пропадают вообще). В симуляторе код AVRStudio рабтает.
Насколько я понял суть проблемы - Вы в основном цикле вызываете PWM_Update(), которая и изменяет регистры OCR3A/B. На блок-схеме таймера 3 в DS показано, что регистры OCR3A/B сравниваются с TCNT3 на равенство (а не меньше/больше). Возможно, что при изменении OCR3A/B Вы "перескакиваете" через значение TCNT3 при работающем таймере - вот равенство и не срабатывает; отсюда и затык всей логики...

P.S. Кстати, Вы не проверяете OCR3B + PWM_PULSE_TIME на переполнение, возможно результат не помещается в 16 разрядов
Сергей Борщ
Мысль вслух - насколько память мне изменяет, эти регистры (во всяком случае в старых мегах) имеют неотключаемую двойную буферизацию. И перезапись регистров из буферов происходит в момент compare. Это не может влиять?
klen
Да вообщем то что выше Вами указано я знал и учитывал. Просто все переставала работать. через 8 часов траха с двумя строчками кода и разными реализациями на одном таймера того что я хотел еще раз написал так как указано в листинге. Все заработало. ПОЧЕМУ??? непойму - ШАЙТАН-БАЙРАН wacko.gif

главно дело пошло дальше.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.