ШИМ на Atmega32 и Atmega48\168PA. В чем отличия?

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 9
Зарегистрирован: Ср мар 30, 2011 18:55:28

Сообщение G-VIRUS »

Всем здравствуйте. Я новичок, изучаю микроконтроллеры. У меня есть Atmega32, на которой я делаю свои опыты, и все хорошо. Недавно приобрел Atmega168PA (он на плате клона Arduino Pro Mini 5v), и решил попробовать поработать с аппаратным ШИМ на нем, но не получается, нога не выдает требуемое напряжение. Цеплялся мультиметром к каждой ноге, которая может давать ШИМ (смотрел по даташиту), не понимаю, не работает. Заметил одну вещь, что ноги OCxx на МК Atmega32 имеют только одно назначение (по схеме), а вот на Atmega48 и Atmega168PA на ноге OC2A, к примеру, есть еще и MOSI и PCINT3, слышал, что чтобы подать ШИМ на ногу, надо через фьюзы это сконфигурить. Требуемый фьюз не нашел, либо это делается не так :( Но шим не работает, вот код (пробовал на Atmega48 и 168PA):

Код: Выделить всё

#define F_CPU 8000000UL // atmega48 8 MHz

#include <avr/io.h>
#include <util/delay.h>

#define msleep _delay_ms

void pwm_init()
{
    // switch off voltage on every D and B ports
    PORTB = 0x00;
    PORTD = 0x00;
    // enable PD5, PD6, PD3 and PB3 for PWM output
    DDRB  = 0x08;
    DDRD  = 0x68;
    // setup timers for hardware pwm
    TCCR0A |= (1 << COM1B1) | (0 << COM1B0) | (1 << WGM10) | (0 << WGM11) | (1 << COM1A1) | (0 << COM1A0);
    TCCR0B |= (1 << WGM12) | (0 << WGM13) | (1 << CS10);
    TCCR2A |= (1 << COM1B1) | (0 << COM1B0) | (1 << WGM10) | (0 << WGM11) | (1 << COM1A1) | (0 << COM1A0);
    TCCR2B |= (1 << WGM12) | (0 << WGM13) | (1 << CS10);
}

int main(void)
{
    pwm_init();

    while(1)
    {
        OCR0A = OCR0B = OCR2A = OCR2B = 0x00;
        msleep(1000);
        OCR0A = OCR0B = OCR2A = OCR2B = 0x3F;
        msleep(1000);
        OCR0A = OCR0B = OCR2A = OCR2B = 0x7F;
        msleep(1000);
        OCR0A = OCR0B = OCR2A = OCR2B = 0xFF;
        msleep(1000);
    }

    return 0;
}
подскажите, что делаю не так? Спасибо.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Несмотря на то, что расположение битов в регистрах настройки таймера скорее всего совпадают во всех трех таймерах, крайне некорректно использовать имена битов таймера1 для настроек таймеров 0 и 2. Легко где-нибудь влетите с таким подходом.

Вы запускаете 5ый режим таймеров. Т.е. ШИМ с фазовой коррекцией. Поглядите в ДШ до какого значения будет считать счетчик и думаю станет понятно почему у Вас ничего не работает.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Z_h_e писал(а):Несмотря на то, что расположение битов в регистрах настройки таймера скорее всего совпадают во всех трех таймерах
нифига! у нулевого и второго таймера количество регистров даже не совпадает с количеством регистров первого таймера! И биты конфигурации располагаются иначе.
Z_h_e писал(а):крайне некорректно использовать имена битов таймера1 для настроек таймеров 0 и 2
не надо смягчать ситуацию: недопустимо!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Для регистров TCCRnA и TCCRnB биты которые использует товарищ ТС находятся на одних местах, разве что WGM13 совсем нет, но там бит только чтение (по случайности). Но это абсолютно ничего не меняет. С таким же успехом можно использовать имена битов регистра DDR для настройки таймера, вернее даже так лучше, ибо сразу будет видно что чушь какая-то в коде, а эти имена не сразу то и заметишь что левые.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Сообщения: 9
Зарегистрирован: Ср мар 30, 2011 18:55:28

Сообщение G-VIRUS »

Z_h_e писал(а):Несмотря на то, что расположение битов в регистрах настройки таймера скорее всего совпадают во всех трех таймерах, крайне некорректно использовать имена битов таймера1 для настроек таймеров 0 и 2. Легко где-нибудь влетите с таким подходом.
Да, это я совсем забаранил, не заметил глупую копипасту
Z_h_e писал(а):Вы запускаете 5ый режим таймеров. Т.е. ШИМ с фазовой коррекцией. Поглядите в ДШ до какого значения будет считать счетчик и думаю станет понятно почему у Вас ничего не работает.
Я сверился с даташитом, переделал все следующим образом

Код: Выделить всё

#define F_CPU 8000000UL // atmega48 8 MHz

#include <avr/io.h>
#include <util/delay.h>

#define msleep _delay_ms

void pwm_init()
{
    PORTB = 0x00;
    DDRB  = 0x08;
    TCCR2A |= (1 << COM2A1) | (0 << COM2A0) | (0 << COM2B1) | (0 << COM2B0) | (0 << WGM21) | (1 << WGM20);
    TCCR2B |= (0 << FOC2A) | (0 << FOC2B ) | (0 << WGM22) | (1 << CS20);
}

int main(void)
{
    pwm_init();

    while(1)
    {
        OCR2A = 0x00;
        msleep(1000);
        OCR2A = 0x3F;
        msleep(1000);
        OCR2A = 0x7F;
        msleep(1000);
        OCR2A = 0xFF;
        msleep(1000);
    }

    return 0;
}

но ШИМа все равно нет, либо я по-прежнему не понимаю, либо проблема уже в камне

UPD: он как-то совсем коротко и один раз прокручивается. Видимо, опять с настройками что-то не то

Добавлено after 1 hour 40 minutes 30 seconds:
Странно, пересобрал, прошил, меряю мультиметром ногу - вроде работает. Показывает 1.25, 2.49 и 4.95, вроде все верно!
Реклама
Ответить

Вернуться в «AVR»