Перейти к содержанию
    

Конфигурирование timer1 (Atmega16) в режим PWM

Добрый день,

Подскажите плз в чем может быть проблема , хочу сделать два канала ШИМ 8 bit на выходы OC1A,OC1B , использую timer1 конфигурирую его для работы в режиме Fast Mode 8 bit

 

#define setbit(x,y) (x|=(1<<y))

#define clearbit(x,y) (x&=~(1<<y))

#define checkbit(x,y) (x&(1<<y))

 

TCCR1B = 2; //clk/8

setbit(DDRD,PD5);

setbit(DDRD,PD4);

 

setbit(TCCR1A,WGM10);

clearbit(TCCR1A,WGM11);

setbit(TCCR1B,WGM12);

clearbit(TCCR1B,WGM13); установка режима fast mode

 

setbit(TCCR1A,COM1A0);

setbit(TCCR1A,COM1A1);

setbit(TCCR1A,COM1B0);

setbit(TCCR1A,COM1B1); управление выводом

 

OCR1AH=255/256;

OCR1AL=255%256;

//setbit(TIMSK,OCIE1A); //INT CompareA enable

 

OCR1BH=255/256;

OCR1BL=255%256;

//setbit(TIMSK,OCIE1B); //INT CompareA enable

 

По отдельности выводы OC1A и OC1B работают , а вместе не хотят .

В чем может быть причина?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот тебе работающий пример из СVAVR.

Кстати, ты не забыл OC1A OC1B (PD4, PD5) сделать выходами?

 

DDRD=0x30;

 

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 1000,000 kHz clk/8

// Mode: Fast PWM top=00FFh

// OC1A output: Non-Inv.

// OC1B output: Non-Inv.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0xA1;

TCCR1B=0x0A;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x80; //pwm1 0...FF

OCR1BH=0x00;

OCR1BL=0x80; // pwm2 0...FF

 

Вот тебе работающий пример из СVAVR.

Кстати, ты не забыл OC1A OC1B (PD4, PD5) сделать выходами?

 

DDRD=0x30;

 

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 1000,000 kHz clk/8

// Mode: Fast PWM top=00FFh

// OC1A output: Non-Inv.

// OC1B output: Non-Inv.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: Off

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0xA1;

TCCR1B=0x0A;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x80; //pwm1 0...FF

OCR1BH=0x00;

OCR1BL=0x80; // pwm2 0...FF

 

Пардон, вижу, что не забыл:

setbit(DDRD,PD5);

setbit(DDRD,PD4);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот тебе работающий пример из СVAVR.

Огромное спасибо, причину нашел она была не в программе , а в том что я не туда припаял светодиод на котором смотрел ШИМ.

Ваша программа дала мне уверенность, зная что она точно работает стал искать причину в другом и нашел! А так полдня копался в программе

думал в настройках ШИМа косяк.

Большое спасибо!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в том что я не туда припаял светодиод на котором смотрел ШИМ.
Не скупитесь на осциллограф!

Облегчит Вам существование весьма и весьма;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не буду создавать новую тему спрошу тут также про Timer 1

МК Atmega 32

Задача использую Timer 1

Нужно генерировать два прерывания

1:с изменяющей частотой от 500Гц до 11кГц, главное менять состояние вывода на PD5 аппаратно, но можно и программно

2:с частотой 1/64с 15.625мс или 64Гц. При этот состояние вывода PD4 не нужно.

Поменять выводы пины PD5 и PD4 можно, как и прерывания.

 

делаю так, режим FastPWM(14). но наверное можно и CTC(12)

инициализация таймера

//    Инициализация таймера 1
    //    Выбор источника тактого сигнала и коэфф. предделителя 
    TCCR1B|=(0<<CS12)|(1<<CS11)|(0<<CS10);     // коэфф. 8
    //    Режим работы FASTPWM - сброс при совпадении
    TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<WGM11); //WGM10-0 по defualt
    TIMSK|=(1<<OCIE1A)|(1<<OCIE1B);    //Разеришь прерывание по событию "совпадение А" таймера 1
                    //Разеришь прерывание по событию "совпадение B" таймера 1
    TCCR1A|=(1<<COM1A0);//Разрешить изменения состояние выхода на противоположное
    ICR1=0x464F;//15.625мс
    OCR1B=0x464F;//15.625мс
    OCR1A=0x08FF;//500Гц

Ну и обработка прерывания

*/
//    Прерывание по совпадению таймера 1 A
#pragma vector=TIMER1_COMPA_vect
__interrupt void StepDriver(void)
{
//PORTD ^= (1<<(5)); попытка программно менять состояние пина.
// что то делаем    
}
//    Прерывание 15.625мс 
#pragma vector=TIMER1_COMPB_vect
__interrupt void SpeedUpDown(void)
{
// что то делаем
//OCR1A= новое значение
}

 

В результате на выходе PD5 получаю постоянно частоту 1/64с 64гц.

 

в чем я ошибся?

Изменено пользователем Roger

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в чем я ошибся?
Один таймер - одна частота. Вероятно, нужно задействовать ещё один таймер, если есть свободный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Один таймер - одна частота. Вероятно, нужно задействовать ещё один таймер, если есть свободный.

 

Есть таймер 2 свободный... но посчитал, он не подойте чтобы использовать его для прерывания 1/64с

А всякими финтами можно добится поставленной задачи?

Изменено пользователем Roger

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

но посчитал, он не подойте чтобы использовать его для прерывания 1/64с
Зависит от используемой тактовой частоты и требуемой точности

F= 9,216 MГц -> 64,2857 1/c

F=14,746 MГц -> 64,0017 1/c

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зависит от используемой тактовой частоты и требуемой точности

F= 9,216 MГц -> 64,2857 1/c

F=14,746 MГц -> 64,0017 1/c

Да забыл указать

18.432МГц

Точность для 1/64с не так уж и важна

Изменено пользователем Roger

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18.432МГц
Помнится, что для m32 Fmax=16МГц... На такой тактовой частоте 64 прерывания от этого таймера не получить, но 128 - можно (128,5714 1/с). Прийдётся применять ещё программное деление на два.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прийдётся применять ещё программное деление на два.

 

А это пояснить можно?

мое предположение сводиться к тому что, пропускать одно прерывание.... я ошибаюсь?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, каждое второе прерывание - пропускать (выходить из прерывания ничего не делая).

спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...