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

 
 
 
Reply to this topicStart new topic
> проблемка с таймером T3 atmega1280, перестает работь при изменении регистров OCR3A/B
klen
сообщение Nov 16 2007, 09:46
Сообщение #1


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



по внешенму прерыванию сбрасывается счетный регистр запускается таймер 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();
}
Go to the top of the page
 
+Quote Post
Палыч
сообщение Nov 16 2007, 14:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(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 разрядов

Сообщение отредактировал Палыч - Nov 16 2007, 14:36
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 16 2007, 15:25
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Мысль вслух - насколько память мне изменяет, эти регистры (во всяком случае в старых мегах) имеют неотключаемую двойную буферизацию. И перезапись регистров из буферов происходит в момент compare. Это не может влиять?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
klen
сообщение Nov 16 2007, 16:02
Сообщение #4


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Да вообщем то что выше Вами указано я знал и учитывал. Просто все переставала работать. через 8 часов траха с двумя строчками кода и разными реализациями на одном таймера того что я хотел еще раз написал так как указано в листинге. Все заработало. ПОЧЕМУ??? непойму - ШАЙТАН-БАЙРАН wacko.gif

главно дело пошло дальше.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 11:03
Рейтинг@Mail.ru


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