Технический форум

Технический форум (http://www.tehnari.ru/)
-   Микропроцессоры (http://www.tehnari.ru/f115/)
-   -   ATmega8 - плавное разгорание и затухание светодиода (http://www.tehnari.ru/f115/t246715/)

Счастье 30.05.2016 17:25

ATmega8 - плавное разгорание и затухание светодиода
 
Вложений: 1
Всем привет!
Как же давно я не писала прошивку, а под рукой сейчас по этому вопросу нет примеров.
Может кто быстренько подскажет?
Есть микроконтроллер, в дип-корпусе
Вложение 286621
Задача такая:
например для порта B0 написать программу, чтобы светодиод плавно разгорался и затухал.
Хоть убей, не помню тонкости вопроса, вот шим-модуляцию.
Когда-то давно мне объясняли, на тренировочной плате такой код реализовывала
Цитата:

* Author: Who
*/

#define F_CPU 8000000UL
#include <Util/delay.h>
#include <avr/io.h>

int main(void)
{
DDRD=0b10000000;
TCCR2=0b01101100;

while(1)
{
OCR2=50;
_delay_ms(2000);
OCR2=205;
_delay_ms(2000);


//TODO:: Please write your application code
}
}
Вот после команды инициализации порта я смутно понимаю, почему именно такие значения.
Мне бы пояснений немножко))

nml 31.05.2016 13:15

Судя по тексту, на тренировочной плате был 40-ногий АВР, типа меги16, или 8535, у которой на PD7 выход ШИМа OC2

Для вашего случая на B0 можно организовать только программное переключение, аппаратный ШИМ не получится.

Программа в примере - переключает яркость светодиода на 2 сек, по заполнению 1/5 и 4/5 приблизительно, по яркости на глаз - думаю вполовину будет.

Счастье 31.05.2016 13:27

Ну да, это я поняла, а как хоть примерно это реализовать программно?

wss60 31.05.2016 15:26

У меня получилось как-то так:
Код:

// winavr

#define F_CPU 8000000UL

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


volatile unsigned char pwm;            // шим
volatile unsigned char pwm_counter; // яркость
                unsigned char rev;        // переключение режимов
               

int main(void)
{

        DDRB = 0x01;
       
        TCCR0 |= (0<<CS02)|(1<<CS01)|(0<<CS00); // настройка тактирования таймера
        TIMSK |= (1<<TOIE0);                    // настройка прерывания по переполнению
        sei();                                        // включить глобальные прерывания
       
       
        while(1)
        {
                // плавное мигание светодиодом
                switch(rev)
                {
                        case 0:        // плавное разгорание
                                pwm_counter++;
                                if(pwm_counter == 255)
                                {
                                        rev = 1;
                                };_delay_ms(4); // время разгорания
                        break;
                        case 1: // плавное затухание
                                pwm_counter--;
                                if(pwm_counter == 0)
                                {
                                        rev = 0;
                                };_delay_ms(6); // время затухания
                        break;
                }
        }
}

SIGNAL(TIMER0_OVF_vect)
{
        TCNT0 = 200; // частота шим

        // программный  ШИМ
        if(pwm++ < pwm_counter)
        {
                PORTB|=_BV(0); // зажечь светодиод
        }else{
                PORTB&=~_BV(0);// погасить светодиод
        }
       
       
}


Счастье 31.05.2016 16:00

О боже, спасииииибо, человече!!!!!!
Раааботает!!))))
Ураа!!!
Можно , я код украду для своей Эйвы?)))
Ну пожалуйста!)))

wss60 31.05.2016 16:08

Цитата:

Сообщение от Счастье (Сообщение 2386143)
Можно , я код украду для своей Эйвы?)))

Я не против)))

Счастье 31.05.2016 16:28

Я добавила пару строк и для порта С и моргает сразу несколько, на старенькой отладочной платке проверила, спасиибо!)))
 
Цитата:

// winavr

#define F_CPU 8000000UL

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


volatile unsigned char pwm; // шим
volatile unsigned char pwm_counter; // яркость
unsigned char rev; // переключение режимов


int main(void)
{

DDRB = 0x01;
DDRC = 0b00111111;

TCCR0 |= (0<<CS02)|(1<<CS01)|(0<<CS00); // настройка тактирования таймера
TIMSK |= (1<<TOIE0); // настройка прерывания по переполнению
sei(); // включить глобальные прерывания


while(1)
{
// плавное мигание светодиодом
switch(rev)
{
case 0: // плавное разгорание
pwm_counter++;
if(pwm_counter == 255)
{
rev = 1;
};_delay_ms(4); // время разгорания
break;
case 1: // плавное затухание
pwm_counter--;
if(pwm_counter == 0)
{
rev = 0;
};_delay_ms(6); // время затухания
break;
}
}
}

SIGNAL(TIMER0_OVF_vect)
{
TCNT0 = 200; // частота шим

// программный ШИМ
if(pwm++ < pwm_counter)
{
PORTB|=_BV(0);
PORTC|=_BV(0);
PORTC|=_BV(1);
PORTC|=_BV(2);
PORTC|=_BV(3);
PORTC|=_BV(4);
PORTC|=_BV(5); // зажечь светодиод
}else{
PORTB&=~_BV(0);
PORTC&=~_BV(0);
PORTC&=~_BV(1);
PORTC&=~_BV(2);
PORTC&=~_BV(3);
PORTC&=~_BV(4);
PORTC&=~_BV(5);// погасить светодиод
}


}
Как индус, давно не практиковалась))) Исправлюсь)))


Часовой пояс GMT +4, время: 20:33.

Powered by vBulletin® Version 4.5.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.