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

 
 
> Ламерский вопрос по timer1 Atmega88
brag
сообщение Sep 15 2014, 20:43
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Привет всем!
Собственно в сабже есть режим CTC и в нем есть фичи Clear OC1A/OC1B on Compare Match (Set output to low level) и Set OC1A/OC1B on Compare Match (Set output to high level).
Как ими пользоватся? wink.gif
В смысле, если я настрою выход OC1B как Clear OC1A/OC1B on Compare Match, то как сделать Set? Получается только путем переконфигурировать и дождатся события(или форс вручную)?

Вообще задача стоит так. Таймер T считает от 0 до X, при достижении X сбрасывается в 0 и так по кругу.
Когда T==0 set OC1A(или B,не важно). Когда T=a clear OC1A/B, при чем a<X. Тоесть обычный PWM.
Но, таймер должен еще сбрасыватся по компаратору(или внешнему пину), при чем с определенной задержкой.

Пока реализация вот такая. Режим CTC TOP=OCR1A. Clear OC1B on Compare Match и в OCR1B=a; OCR1A изначально равно X.
Код
ISR(TIMER1_CAPT_vect){
    OCR1A=ICR1+delay; // сброс таймера при достижении OCR1A
}

ISR(TIMER1_COMPA_vect){
    OCR1A=X;
}

Все было бы ок, если бы можно было заставить выход OC1B установится в лог1, когда таймер сбрасывается.
Ржим PWM не канает из за буфферизации OCR1x...

Можно как-то так, но эт как-то слишком глючно. На пример, если a слишком маленькое - есть риск что таймер его обгонит еще до того, как мы успеем обновить OCR1B и выход будет всегда висеть в единице, а это чревато последствиями sm.gif
Код
init(){
    TCCR1A=(1<<COM1B1)|(0<<COM1B0); //Clear OC1B on Compare Match
}

ISR(TIMER1_CAPT_vect){
    int t=ICR1+delay; // сброс таймера при достижении OCR1A
    OCR1A=t;
    OCR1B=t;
    TCCR1A=(1<<COM1B1)|(1<<COM1B0); // Set OC1B on Compare Match
}

ISR(TIMER1_COMPA_vect){
    OCR1A=X;
    OCR1B=a;
    TCCR1A=(1<<COM1B1)|(0<<COM1B0); //Clear OC1B on Compare Match
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
brag
сообщение Sep 17 2014, 08:17
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата
Не пойдет, ICP1 отключена и прерывание TIMER1_CAPT_vect никогда не сработает.

Все там нормально срабатывает: When the Input Capture Register(ICR1) is set by the WGM13:0 to be used as the TOP value, the ICF1 Flag is set when the counter reaches the TOP value. режим WGM14.
В принципе TIMER1_CAPT_vect можно заменить на TIMER1_OVF_vect, будет точно такое же поведение.

Данный алгоритм работает, но прерываний других использовать нельзя(кроме аварийных). Что в принципе не является особой проблеммой, работать с остальной периферией можно в вечном цикле.

Цитата
Ещё один путь - взять МК с двумя ICP1 и ICP3 модулями, таймеры пусть работают синхронно, один модуль будет срабатывать от входного события, а второй будет выдавать fast pwm (14/15). Как-то так.

На сколько я помню, у AVR нету синхронизации между T1 и T3. Если даже изначально TCNT1==TCNT3 (хотя как это сделать я не представляю синхронизацию сделать можно через TSM,PSR) - если ICP1 словит входное событие, запишет ICP3=ICP1+блабла, Т3 сбросится при достижении ICP3, a T1 продолжит дальше считать - вот тут они и рассинхронизируются.
Если уж менять железо, то лучше рядом с Atmega88 поставить CPLD и сделать на нем нужную логику. Таймер нужен 12-битный максимум, + еще 2 регистра(типа OCR1A и OCR1B) тоже 12-битных, + сумматор + немного логики. EPM3064 должно хватить - 36 MC уйдет под регистры и еще 28 останется для логики. А,да еще как-то надо загружать туда регистр из атмеги, допустим по spi, тогда нужен еще 1 буфферный 12-битный регистр, тогда возможно понадобится cpld на больше макроячеек.
Ну или найти другой МК, где это можно реализовать аппаратными средствами.
Go to the top of the page
 
+Quote Post



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

 


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


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