Цитата(slava59 @ 5.1.2010, 11:33)

Привет. Я потихоньку крапаю на ATTiny26, хотя в принципе кристалл большого значения не имеет.
Мне пришлось в рамках другого проекта заниматься вопросом программирования таймеров для ATMega32. Так вот использовать надо таймер № 1, у которого есть два компаратора OC1A и OC1B. Сконфигурировать таймер надо так чтобы снимать сигнал с вывода OC1B - PD4. Режим таймера - Fast PWM. Для автоматического генерирования программы инициальзации периферии у атмеги очень удобно использовать генератор кода по адресу:
http://www.jarkonkotisivu.org/AVRcoder/Вот что у меня получилось:
// Init_Timers
//
http://www.jarkonkotisivu.org/AVRcoder/m32/timer1.phtml// XTAL - 8мгц, предделитель не используется
TCCR1B = 0x00; //Stop the timer
OCR1AH=0x80; // значение 0x8000 -> 4000 uS -> это период генерируемых импульсов в моем случае 250 гц
OCR1AL=0x00; // надо изменить чтобы получить ~30 кгц
OCR1BH=0x10; // значение 0x1000 -> 500 uS -> длительность генерируемого импульса
OCR1BL=0x00; // надо изменить чтобы получить нужную длительность
ICR1H=0x00;
ICR1L=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
TCCR1A = 0x63;
TCCR1B = 0x59;
// Далее надо установить регистр маски прерываний от таймера TIMSK
// Timer(s)/Counter(s) Interrupt(s) initialization
//TIMSK -> OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
// | |
// -> Timer/Counter1, Output Compare B Match Interrupt Enable
// -> Timer/Counter1, Output Compare A Match Interrupt Enable
//
TIMSK = 0x18; //0b00011000
На этом процедура инициализации таймера заканчивается.
Далее надо в основном теле программы вставить процедуры обработки прерываний от OC1A и OC1B
// Timer 1 compare A interrupt service routine
#pragma vector = TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_Interrupt(void)
{
}
// Timer 1 compare A interrupt service routine
#pragma vector = TIMER1_COMPB_vect
__interrupt void TIMER1_COMPB_Interrupt(void)
{
}
Обе процедуры пока пустые. В них надо разместить присвоение значений регистрам OCR1A и OCR1B.
Это нужно для раздельной регулировки длительности импульса и периода.
В основном теле программы надо сначала глобально запретить прерывания затем инициализировать периферию,
не забыв определить вывод PD4 как выход (на нем и будут формироваться выходные импульсы). После этого
глобально разрешить прерывания и уйти в бесконечный цикл, в котором просто проверять напряжения с потенциометров
регулировки частоты и длительности.
При использовании такого подхода не будет никакого джиттера в формируемом сигнале. Именно с такой проблемой столкнулся skif
когда делал свою прошивку.
Конечно это еще не все. Надо добавить внешний триггер, ктр. будет раздваивать выход таймера на два плеча моста.
Таким образом мы получаем аппаратно формируемый ШИМ и ЧИМ, а процессор может во время своего бесконечного цикла
делать еще какие-то дела, например индикацию.