Технический форум
Вернуться   Технический форум > Электроника, самоделки и техника > Форум по электронике > Микропроцессоры


Ответ
 
Опции темы Опции просмотра
Старый 30.05.2016, 17:25   #1 (permalink)
Счастье
Не очень хороший человек
 
Аватар для Счастье
 
Регистрация: 01.12.2012
Сообщений: 6,155
Записей в дневнике: 18
Сказал(а) спасибо: 1,305
Поблагодарили 755 раз(а) в 231 сообщениях
Репутация: 98885
Post ATmega8 - плавное разгорание и затухание светодиода

Всем привет!
Как же давно я не писала прошивку, а под рукой сейчас по этому вопросу нет примеров.
Может кто быстренько подскажет?
Есть микроконтроллер, в дип-корпусе
arduino-atmega8-pins.png
Задача такая:
например для порта 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
}
}
Вот после команды инициализации порта я смутно понимаю, почему именно такие значения.
Мне бы пояснений немножко))
__________________
Все будет хорошо.
Счастье вне форума   Ответить с цитированием

Старый 30.05.2016, 17:25
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

Бывает, что в аналогичных темах можно найти множество нужной информации

Плавное угасание светодиода
Светодиоды, плавное включение и затухание цикличное
Плавное затухание светодиода
Плавное затухание света в салоне автомобиля
затухание экрана

Старый 31.05.2016, 13:15   #2 (permalink)
nml
Member
 
Аватар для nml
 
Регистрация: 15.08.2013
Адрес: Minsk
Сообщений: 145
Сказал(а) спасибо: 1
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 713
По умолчанию

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

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

Программа в примере - переключает яркость светодиода на 2 сек, по заполнению 1/5 и 4/5 приблизительно, по яркости на глаз - думаю вполовину будет.
nml вне форума   Ответить с цитированием
Старый 31.05.2016, 13:27   #3 (permalink)
Счастье
Не очень хороший человек
 
Аватар для Счастье
 
Регистрация: 01.12.2012
Сообщений: 6,155
Записей в дневнике: 18
Сказал(а) спасибо: 1,305
Поблагодарили 755 раз(а) в 231 сообщениях
Репутация: 98885
По умолчанию

Ну да, это я поняла, а как хоть примерно это реализовать программно?
__________________
Все будет хорошо.
Счастье вне форума   Ответить с цитированием
Старый 31.05.2016, 15:26   #4 (permalink)
wss60
Member
 
Аватар для wss60
 
Регистрация: 09.08.2015
Адрес: Minsk
Сообщений: 245
Сказал(а) спасибо: 12
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 3649
По умолчанию

У меня получилось как-то так:
Код:
// 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);// погасить светодиод
	}
	
	
}
wss60 вне форума   Ответить с цитированием
Старый 31.05.2016, 16:00   #5 (permalink)
Счастье
Не очень хороший человек
 
Аватар для Счастье
 
Регистрация: 01.12.2012
Сообщений: 6,155
Записей в дневнике: 18
Сказал(а) спасибо: 1,305
Поблагодарили 755 раз(а) в 231 сообщениях
Репутация: 98885
По умолчанию

О боже, спасииииибо, человече!!!!!!
Раааботает!!))))
Ураа!!!
Можно , я код украду для своей Эйвы?)))
Ну пожалуйста!)))
__________________
Все будет хорошо.
Счастье вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Старый 31.05.2016, 16:08   #6 (permalink)
wss60
Member
 
Аватар для wss60
 
Регистрация: 09.08.2015
Адрес: Minsk
Сообщений: 245
Сказал(а) спасибо: 12
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 3649
По умолчанию

Цитата:
Сообщение от Счастье Посмотреть сообщение
Можно , я код украду для своей Эйвы?)))
Я не против)))
wss60 вне форума   Ответить с цитированием
Старый 31.05.2016, 16:28   #7 (permalink)
Счастье
Не очень хороший человек
 
Аватар для Счастье
 
Регистрация: 01.12.2012
Сообщений: 6,155
Записей в дневнике: 18
Сказал(а) спасибо: 1,305
Поблагодарили 755 раз(а) в 231 сообщениях
Репутация: 98885
По умолчанию

Я добавила пару строк и для порта С и моргает сразу несколько, на старенькой отладочной платке проверила, спасиибо!)))
 
Цитата:
// 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);// погасить светодиод
}


}
Как индус, давно не практиковалась))) Исправлюсь)))
__________________
Все будет хорошо.
Счастье вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




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

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.