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

 
 
> 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
Ответов
ReAl
сообщение May 5 2012, 08:24
Сообщение #2


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

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



И я ещё маленько про то, что volatile != не_делать_предположения_о_значении_и_брать_всегда_из_памяти.
volatile это нечто большее. Имеем код:
Код
unsigned char i;
void foo() {
    i = 0xFF;
    PORTB = 0xFF;
    while (--i) {}
    PORTB = 0;
}
Ну так вот если переменная i не объявлена volatile, то компилятор имеет полное право сделать, к примеру, такой код, в котором пожелание «переменная всегда берётся из её места в памяти, даже если она осталась где-то в регистрах» выполнено на 100%:
Код
foo:
    ldi    r16, 0xFF
    out    PORTB, r16
    sts    i, r16
    ldi    r16, 0
    out    PORTB, r16
loop:
    lds    r16, i
    dec    r16
    sts    i, r16
    brne loop
    ret
Несколько не то, чего ожидали, правда? Но это допустимый код. Допустимо будет сгенерировать и такое:
Код
unsigned char i;
void foo() {
    i = 0xFF;
    while (--i) {}
    PORTB = 0xFF;
    PORTB = 0;
}
Все эти три куска с точки зрения компилятора эквивалентны по наблюдаемому поведению. Допустимым будет даже досчитать от 0xFF до 0xAD перед первой записью в PORTB, от 0xAC до 0x0F между записями в порт и от 0x0E до 0 после второй записи. И даже прогнать цикл, пишущий в i числа от 1 до 0xFF по нарастающей и только в конце 0.
Конечно, маловероятно, чтобы какой-то компилятор сгенерировал эти коды, он просто выбросит цикл вообще.
Но компилятор имеет право переставлять обращения к не-volatile переменным между собой и обращениями к volatile-переменным. А вот менять порядок обращения к volatile-переменным он не имеет права (как раз об этом в той длинной теме на sources.ru по линку в предыдущем моём сообщении). Это слово означает не только то, что значение переменной может измениться «само по себе» («не делать никаких предположений о значении переменных»), но и что само обращение как таковое может что-то поменять во «внешнем мире», в том числе как-то повлиять на значение этой или других volatile-переменых (пример — умножитель в MSP430).
Кстати, «не делать никаких предположений о значении переменных» не запрещает компилятору выбросить из нескольких идущих подряд записей в порт все, кроме последнего. Запрещают это только возможные «побочные» эффекты самого факта записи.


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



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

 


RSS Текстовая версия Сейчас: 31st July 2025 - 21:44
Рейтинг@Mail.ru


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