Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
11.02.2007, 12:58
|
|
Прописка
Регистрация: 27.12.2005
Сообщений: 134
Сказал спасибо: 6
Сказали Спасибо 15 раз(а) в 7 сообщении(ях)
|
ШИМ по экспоненте, или помигать плавно светодиодами;)
Нужна программа (пишу на CVAVR), переключающая ПЛАВНО два светодиода(т.е. один тухнет, второй зажигается так, что суммарная яркость сохраняется). Это всё произвожу в отдельной функции, куда отправляю битовые маски, соответствующие номерам переключаемых светодиодов. Основная программа занимается только многократным вызовом функции с разными параметрами, чем достигается перемигивание всех светодиодов, висящих на порте.Но оно не плавное... Изменяю по принципу ШИРИНА2ГО_ИМПУЛЬСА=const-ШИРИНА1ГО_ИМПУЛЬСА. Может, кто сталкивался с подобной проблемой, и знает формулу получше?
|
|
|
|
11.02.2007, 17:45
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.05.2006
Адрес: Москва
Сообщений: 3,559
Сказал спасибо: 76
Сказали Спасибо 326 раз(а) в 230 сообщении(ях)
|
вот пример из пакета WinAVR
Код:
|
/* --------- avr123.nm.ru/z8.htm
*
* Simple AVR demonstration. Controls a LED that can be directly
* connected from OC1/OC1A to GND. The brightness of the LED is
* controlled with the PWM. After each period of the PWM, the PWM
* value is either incremented or decremented, that's all.
*
* $Id: demo.c,v 1.6.2.3 2006/01/05 21:33:08 joerg_wunsch Exp $
*/
#include ‹inttypes.h›
#include ‹avr/io.h›
#include ‹avr/interrupt.h›
#include ‹avr/sleep.h›
#include "iocompat.h" /* Note [1] */
enum { UP, DOWN };
ISR (TIMER1_OVF_vect) /* Note [2] */
{
static uint16_t pwm; /* Note [3] */
static uint8_t direction;
switch (direction) /* Note [4] */
{
case UP:
if (++pwm == TIMER1_TOP)
direction = DOWN;
break;
case DOWN:
if (--pwm == 0)
direction = UP;
break;
}
OCR = pwm; /* Note [5] */
}
void
ioinit (void) /* Note [6] */
{
/* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). */
TCCR1A = TIMER1_PWM_INIT;
/*
* Start timer 1.
*
* NB: TCCR1A and TCCR1B could actually be the same register, so
* take care to not clobber it.
*/
TCCR1B |= TIMER1_CLOCKSOURCE;
/*
* Run any device-dependent timer 1 setup hook if present.
*/
#if defined(TIMER1_SETUP_HOOK)
TIMER1_SETUP_HOOK();
#endif
/* Set PWM value to 0. */
OCR = 0;
/* Enable OC1 as output. */
DDROC = _BV (OC1);
/* Enable timer 1 overflow interrupt. */
TIMSK = _BV (TOIE1);
sei ();
}
int
main (void)
{
ioinit ();
/* loop forever, the interrupts are doing the rest */
for (;;) /* Note [7] */
sleep_mode();
return (0);
} |
__________________
Обучалка AVR PIC ARM начинающим программирование курс самоучитель шаг за шагом с нуля, CVAVR, PROTEUS, MPLAB, WinAVR, IAR, KEIL электроника - http://proavr.narod.ru
|
|
|
|
12.02.2007, 20:48
|
|
Прописка
Регистрация: 27.12.2005
Сообщений: 134
Сказал спасибо: 6
Сказали Спасибо 15 раз(а) в 7 сообщении(ях)
|
У меня алгоритм тот же, только реализовывал без прерываний.
void blink(char a,char b)
{
short int k=100,m=0,n=0;
while(k›0)
{
m=k;
while(m›0)
{
PORTB=a;
delay_us(100);
m--;
}
n=100-k;
while(n›0)
{
PORTB=b;
delay_us(100);
n--;
}
k--;
}
void main()
{
while(1)
{
blink(0b00000001,0b00000010);
blink(0b00000010,0b00000100);
blink(0b00000100,0b00000010);
/*и так далее, разнообразные комбинациии светодиодов*/
blink(0b00001000,0b00000001);
}
}
Перемигивается более-менее плавно, если переключаю только 2 светодиода, при переходах к остальным - через раз...
то резко гаснут, то резко зажигаются. Грешу пока на нелинейность восприятия глазом яркости ШИМ вспышек, да на послесвечение светодиода и дрейф драйверов, но может в программе проблема?
|
|
|
|
12.02.2007, 21:06
|
|
Почётный гражданин KAZUS.RU
Регистрация: 30.10.2006
Сообщений: 1,755
Сказал спасибо: 0
Сказали Спасибо 80 раз(а) в 56 сообщении(ях)
|
Сообщение от elcreator
|
Грешу пока на нелинейность восприятия глазом яркости ШИМ вспышек, да на послесвечение светодиода и дрейф драйверов, но может в программе проблема?
|
Вы абсолютно правы, подобная нелинейность действительно существует. Вам необходимо разделить этот процесс на два - три участка, особенно в области малой-большой яркости и использовать там другие постоянные. Кроме того, Вам придется подобрать светодиоды по параметрам, в силу существенного разброса характеристик интенсивности излучения от протекающего тока.
С уважением, Алексей.
|
|
|
|
13.02.2007, 21:06
|
|
Вид на жительство
Регистрация: 23.04.2006
Сообщений: 308
Сказал спасибо: 14
Сказали Спасибо 13 раз(а) в 12 сообщении(ях)
|
Может проще поставить дополнительно фотодиод, с помощью которого МК будет контролировать суммарную яркость пары светодиодов? При этом можно уйти от разброса характеристик светодиодов.
|
|
|
|
13.02.2007, 21:56
|
|
Заблокирован
Регистрация: 18.12.2004
Сообщений: 630
Сказал спасибо: 0
Сказали Спасибо 11 раз(а) в 9 сообщении(ях)
|
Хотя в литературе пишут о "пропорциональности" (в первом приближении) зависимости яркости свечения светодиодов от точка через светодиод, но по моему практическому опыту это наблюдается только для средних значений, что подтверждает мнение ALEX__A. На этом эффекте я тоже набил пару шишек...
Навскидку могу предложить такой вариант (поскольку я с математикой "не дружу" - уж извините, попытаюсь "на пальцах"), чтобы длительность импульсов в области минимальных значений была не от нуля, а имела какую-то "постоянную составляющую", играясь которой можно было бы как-то линеаризировать зависимость яркости от среднего тока, проходящего через светодиод. Возможно, что то же стоит использовать и для диапазона максимальных длительностей?
Другой вариант - разбить диапазон изменений на три части, в каждой из которых использовать свой наклон линии зависимости (что-то по типу S-образной кривой)?
Учтите, что это - "мысли вслух", а не собственно рекомендации.
|
|
|
|
13.02.2007, 22:55
|
|
Прохожий
Регистрация: 30.11.2006
Сообщений: 3
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
|
Привет!Знакомая задача. К сожалению С СИ я на вы, не могу оценить код. Но подобную задачу делал для 3 светодиодов и на AVR ASM. Я считаю делать эту программу без прерываний не очень красиво, я пытался код получается громоздкий и не гибкий. Вкратце раскажу про свой алгоритм. Таймер0 является просто генератором, который изменяет переменную "Angle" от 0 до 255 постоянно, тут же осуществляется сравнение этой переменной с тремя другими "Angle1,2,3" содержащими яркость разных светодиодов, и тут же принимается решение выводить в канал "1" или "0". ШИМ мы обеспечили 14 строк на асем-ле. В основной программе меняем "Angle1,2,3" получаем красивый ШИМ на выходе. Менять значения "Angle1,2,3" на мой взгляд тоже лучше в обработчике прерывания, мне подошел Timer1 т.к. на нем можно сделать медленно. И основная проблема зделать линейное нарастание, к сожалению не решил из-за простой пречины не могу найти характеристику светодиода где-бы была показана зависимость я ркости от скважности (есть подозрение что она линейная, а жуткие погрешности это возможности нашего восприятия, что является индивидуальным). Напрашивается вывод - а есть-ли смысл. Но все таки для упрощения кода и для возможных будущих идей закон и зменения яркости я описал в таблице из которой потом и беру данные (Timer1)
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 04:07.
|
|