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

 
 
 
Reply to this topicStart new topic
> Реализация 2-канального ШИМ на таймере T0 ATmega88
koluna
сообщение May 23 2008, 07:38
Сообщение #1


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

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Здравствуйте!

Необходимо организовать двух-канальный ШИМ (вообще-то трёх-канальный, но для начала - двух-канальный).
256 градаций хватит.
Активный уровень - низкий (управление драйвером MBI1801 светодиодов).

Решил это осуществить на 8-битном таймере T0.
Выходы обоих каналов ШИМ - выводы OC0 (OC0A, OC0B).

Алгоритм следующий.
Загружаем в регистры сравнения соответствующие длительностям ШИМ значения.
Настраиваем таймер в режиме Normal, разрешаем прерывание по переполнению, режим работы блока сравнения (управление выводами OC0) - "состояние выводов меняется на противоположное".
Т. е., при равенстве счётного регистра и регистра сравнения состояние вывода OC0 меняется на противоположное. Далее, при переполнении таймера (период ШИМ) - состояние опять меняется на противоположное. Т. о., получается ШИМ,

Вкратце, код тестовой программы такой:

Код
...

void TIMER0_OVF_vect(void)
{
    TCCR0B |= (1 << FOC0A) | (1 << FOC0B);
    sei();
    return;
};

...

int main (void)
{
        ...

    OCR0A = n_red;
    OCR0B = n_green;
    TCNT0 = 0x00;
    TIMSK0 |= 1 << TOIE0;
    TCCR0A = 0b01010000;
    sei();
    TCCR0B = 0b00000011;
    
        ...
};


Всё просто, код маленький, работает.
Изначально выводы OC0 настраиваю как выходы и перевожу в состояние "1".
Но заметил странную особенность, которую никак объяснить не могу!
При выполнении команды TCCR0A = 0b01010000 состояние выводов OC0 меняется на противоположное, т. е., на "0".
Вопрос. Почему?
Ни в Евстифееве, ни в даташите на контроллер я ответа на свой вопрос не нашёл...
Обидно... несколько пугает и обескураживает wink.gif
Помогите разобраться, пожалуйста!

Спасибо заранее!


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
GDI
сообщение May 23 2008, 08:03
Сообщение #2


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Может лучше перейти в режим Fast-PWM? там состояние этих выводов устанавливается аппаратно. А еще у атмел есть apnote на тему много канального ШИМ реализуемого программно, судя по всему это как раз ваш случай.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
koluna
сообщение May 23 2008, 09:32
Сообщение #3


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

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Цитата(GDI @ May 23 2008, 12:03) *
Может лучше перейти в режим Fast-PWM? там состояние этих выводов устанавливается аппаратно. А еще у атмел есть apnote на тему много канального ШИМ реализуемого программно, судя по всему это как раз ваш случай.


Я читал про этот режим. Но в этом режиме каждый из таймеров, к великому огорчению, может обеспечить только один канал ШИМ.
Два 8-битных таймера - два канала. А мне нужно 3 канала smile.gif
Третий таймер у меня занят smile.gif

Про ШИМ у атмела почитаем, спасибо smile.gif

Сообщение отредактировал n_bogoyavlensky - May 23 2008, 09:33


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
GDI
сообщение May 23 2008, 09:41
Сообщение #4


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

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата
Но в этом режиме каждый из таймеров, к великому огорчению, может обеспечить только один канал ШИМ

Откуда такие данные? Я конечно с мега88 не работал но у других мег такого что то не припомню.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 23 2008, 10:19
Сообщение #5


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(n_bogoyavlensky @ May 23 2008, 06:38) *
Код
int main (void)
{
OCR0A = n_red;
OCR0B = n_green;
TCNT0 = 0x00;
TIMSK0 |= 1 << TOIE0;
TCCR0A = 0b01010000;
sei();
TCCR0B = 0b00000011;
}

Изначально выводы OC0 настраиваю как выходы и перевожу в состояние "1". Но заметил странную особенность, которую никак объяснить не могу! Почему при выполнении команды TCCR0A = 0b01010000 состояние выводов OC0 меняется на противоположное, т. е., на "0"?


1) Установка OC0А, OC0В должна быть выполнена до установки DDR соответствующего пина. У вас этого не видно.

2) Как вы определили, что именно после выполнения команды TCCR0A=0х50, состояние пинов OC0А, OC0В меняется?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
koluna
сообщение May 23 2008, 11:09
Сообщение #6


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

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Цитата(GDI @ May 23 2008, 13:41) *
Откуда такие данные? Я конечно с мега88 не работал но у других мег такого что то не припомню.


Евстифеев (про меги книжка).
И даташит.
Правда не дословно это написано...
Так написано в таблице управление выводами OCn:
OCnB, OCnC - зарезервировано.

Блииин... какойже я невнимательный... несколько раз читал и только сейчас обратил внимание на нижние в таблице два режима... "Сбрасывается или устанавливается при равенстве регистров и устанавливается или сбрасывается при достижении счётчиком максимального значения...".
Т. е., всё замечательно yeah.gif
Виноват...

Цитата(=GM= @ May 23 2008, 14:19) *
1) Установка OC0А, OC0В должна быть выполнена до установки DDR соответствующего пина. У вас этого не видно.


А откуда это следует? Можно ссылочку на страницу даташита, пожалуйста? smile.gif
Т. е., как на работу влияет последовательность установки регистров сравнения и настройки DDR?

Цитата
2) Как вы определили, что именно после выполнения команды TCCR0A=0х50, состояние пинов OC0А, OC0В меняется?


Создавал временные задержки и по длительности импульсов определил кусок кода smile.gif


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
koluna
сообщение May 23 2008, 12:21
Сообщение #7


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

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Сделал в Fast PWM, три канала, как надо.
Два канала на Т0, один на Т2.
Получил идеальную ШИМ.
Ребят, спасибо! smile.gif

Но с =GM= вопрос ещё не закрыт wink.gif


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
=GM=
сообщение May 23 2008, 12:23
Сообщение #8


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(n_bogoyavlensky @ May 23 2008, 10:09) *
А откуда это следует? Можно ссылочку на страницу даташита, пожалуйста? Т. е., как на работу влияет последовательность установки регистров сравнения и настройки DDR?

... с =GM= вопрос ещё не закрыт

Щас мы его закроем: документ 2545м, с.94, цитата

The setup of the OC0x should be performed before setting the Data Direction Register for the port pin to output. The easiest way of setting the OC0x value is to use the Force Output Compare (FOC0x) strobe bits in Normal mode. The OC0x Registers keep their values even when changing between Waveform Generation modes.
Be aware that the COM0x1:0 bits are not double buffered together with the compare value. Changing the COM0x1:0 bits will take effect immediately.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post

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

 


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


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