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

 
 
> Atmega48 6 ШИМ
kennykiller
сообщение May 3 2012, 07:29
Сообщение #1





Группа: Участник
Сообщений: 10
Регистрация: 9-02-11
Пользователь №: 62 817



В даташшите на МК Atmega48 написано что у него есть 6 ШИМ.
Написал программу для плавного зажигания светодиодов.

вот основной кусок

Код
void pause (unsigned int a)
{
unsigned int i;
for (i=a;i>0;i--);
}

void init_pwm (void)
{

DDRB=0b1110;
DDRD=0b1100000;


TCCR1A=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM10);
TCCR1B=(1<<CS10)|(0<<CS11)|(0<<CS12);

TCCR0A=(1<<COM0A1)|(1<<COM0B1)|(1<<WGM00);
TCCR0B=(1<<CS00)|(0<<CS01)|(0<<CS02);

OCR1A=0x00; //PB1
OCR1B=0x00; //PB2

OCR0A=0x00; //PD6
OCR0B=0x00; //PD5

}


Соответственно получаем 4 ШИМ на выходах PB1, PB2, PD6 и PD5.
Просьба знающих людей ответить на следующие вопросы:

1. Как получить еще 2 ШИМ? Пробовал через TCCR2A и TCCR2B как написано в даташите не получатся, и на каких вообще выходах должны быть эти 2 ШИМа?

2. Почему на выходах PB1 и PB2 напряжение плавно нарастает с 0 до 5 В и остается на 5 В, а на выходах PD6 и PD5 плавно нарастает с 0 до 5 В затем скачком сбрасывается до 0 и снова плавно нарастает. Разве они не должны одинаково работать?


Спасибо огромное за помощь.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
hd44780
сообщение May 4 2012, 08:39
Сообщение #2


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Вообще volatile "заставляет" компилятор не делать никаких предположений о значении переменных. Т.е. переменная всегда берётся из её места в памяти, даже если она осталась где-то в регистрах.

Хотя, если честно, то я вот этого
Цитата
функция pause() перестанет работать как только вы включите оптимизацию

не понимаю. С какой стати?
Про _delay_ms(), _delay_us() тоже вставлю свои 5 копеек. У меня они НИКОГДА нормально не работали в WinAVR. Всегда хрен знает что с ними творится. Может тоже "отрыжки" оптимизации влияют - не знаю, не исследовал их. Собственно поэтому я и не люблю этот компилятор. Может я и не прав.
Хотите надёжно - делайте на таймерах. В avrLib есть по-моему готовая реализация.

PS. В CvAVR delay_ms всегда работает как часы. Не сочтите за рекламу.

Сообщение отредактировал hd44780 - May 4 2012, 08:42


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
ReAl
сообщение May 4 2012, 08:48
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(hd44780 @ May 4 2012, 11:39) *
Вообще volatile "заставляет" компилятор не делать никаких предположений о значении переменных. Т.е. переменная всегда берётся из её места в памяти, даже если она осталась где-то в регистрах.
Не только «берется», но и «кладётся», если уж на то пошло.
Вообще-то компилятор может выбросить вообще весь код, если от этого не меняется observable behavior программы, извините мне моё обычное занудство с терминологией из стандартов С/С++, а не из надписей на заборах. Холостой цикл его не меняет, так как просто задержка не «замечается» компилятром. Есть еще задержки памяти разного рода, кешей и винчестера — откуда ему об этом всём знать?
Может, если переменная ляжет в регион внешнего ОЗУ меги64, к которому несколько тактов ожидания — цикл в разы удлиннится по сравнению с переменной во внутренней памяти, а тот в разы относительно переменной в регистре. Если ему обращать на это внимание, он вообще оптимизировать не сможет.
Если компилятор может выкинуть весь код кроме последнего оператора тут:
Код
    float a, b, c;
    int i;
    ...
    i = (int)a;
    i =  b*sqrt(i*i + c*c) + 0.5f;
    // может я знаю, что этот код выше выполняется гарантированно дольше, чем нужная мне задержка — какого беса он его убрал?
    i = 0;
То почему ему нельзя выбросить пустой цикл — ничего не делающий реального?
Ещё тут почитайте. Он не только выбросить ничего не делающий с его точки зрения код имеет право, но и переставлять местами делающий что-то полезное даже с его точки зрения.

Так вот volatile говорит компилятору, что он не может строить предположений о «видимости» работы с данной переменной снаружи независимо от её размещения в памяти, регистрах, ...
Даже если он работает с ней только в памяти (например, pic16 просто не сильно-то и может держать переменные в регистрах и имеет команду декремента с пропуском прямо на памяти).

Цитата(hd44780 @ May 4 2012, 11:39) *
Про _delay_ms(), _delay_us() тоже вставлю свои 5 копеек. У меня они НИКОГДА нормально не работали. Всегда хрен знает что с ними творится. Может тоже "отрыжки" оптимизации влияют - не знаю, не исследовал их.
Они всегда работали нормально (ну с учётом того, что не учитывали время в прерываниях, так этого никто и не обещал).
Просто всегда нужно было включать оптимизацию и им на вход подавать константы, а не переменные, так это вроде всегда было в документации описано.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post



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

 


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


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