Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: 8 канальный шим на avr
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
at90
Люди как реализовать 8 канальный 8 битный программный шим для управления светодиодами на С. sad.gif
okela
Цитата(at90 @ May 11 2005, 16:59)
Люди как реализовать 8 канальный 8 битный программный шим для управления светодиодами на С. sad.gif
*


Вобщем-то без разницы на каком языке реализовать этот алгоритм.
Если в общих чертах то это в моём представлении выглядит примерно так.

Пишется процедура прерывания для таймера работающего в автомате, который работает с частотой достаточной для заданной точности (fшим*256).
Объявляются 8 переменных, которые будут определять скважность по каждому каналу ШИМ (например в %). И каждая из этих переменных привязывается к одному биту какого-то 8-битного порта (для 50% пол-периода -0, пол-периода -1).
По каждому прерыванию таймера делается обновление информации выводимой в порт по всем разрядам.
at90
Цитата(okela @ May 11 2005, 17:47)
Цитата(at90 @ May 11 2005, 16:59)
Люди как реализовать 8 канальный 8 битный программный шим для управления светодиодами на С. sad.gif
*


Вобщем-то без разницы на каком языке реализовать этот алгоритм.
Если в общих чертах то это в моём представлении выглядит примерно так.

Пишется процедура прерывания для таймера работающего в автомате, который работает с частотой достаточной для заданной точности (fшим*256).
Объявляются 8 переменных, которые будут определять скважность по каждому каналу ШИМ (например в %). И каждая из этих переменных привязывается к одному биту какого-то 8-битного порта (для 50% пол-периода -0, пол-периода -1).
По каждому прерыванию таймера делается обновление информации выводимой в порт по всем разрядам.
*


я так реализовал шим на 16 градаций
Сделал массив на 16 элементов
Каждый элемент массива выводил в порт за один тик тамера.
Изменяя биты изменял яркость.
Но на 256 делать массив на 256 -зто как то неразумно.
Слишком много уходит памяти
okela
Цитата(at90 @ May 11 2005, 18:24)
я так реализовал шим на 16 градаций
Сделал массив на 16 элементов
Каждый элемент массива выводил в порт за один тик тамера.
Изменяя биты изменял яркость.
Но на 256 делать массив на 256 -зто как то неразумно.
Слишком много уходит памяти


Имелось ввиду держать в памяти не массивы значений для каждого тика таймера, а char переменные для каждого канала, хранящих значения длительности импульса (паузы) для одного периода. Эти значения равны
числам переполнений таймера..... Как-то так. blush.gif
TMX
unsigned char PWM_cnt, PWM_x[8]; // лучше сделать регистровыми

interrupt timer_ISR // обработчик прерывания таймера
{
unsigned char mask, i;
if (++PWM_cnt == 0) // переполнение
PWM_PORT = 0;
for (i = 0, mask = 0x01; mask; i++, mask <<= 1)
if (++PWM_x[i] == 0)
PWM_PORT |= mask; // установка выходного бита
}
at90
Цитата(TMX @ May 12 2005, 17:31)
unsigned char PWM_cnt, PWM_x[8];      // лучше сделать регистровыми

interrupt timer_ISR                            // обработчик прерывания таймера
{
unsigned char mask, i;
  if (++PWM_cnt == 0)                      // переполнение
    PWM_PORT = 0;
  for (i = 0, mask = 0x01; mask; i++, mask <<= 1)
    if (++PWM_x[i] == 0)
      PWM_PORT |= mask;                  // установка выходного бита
}
*


А как мы задаём длительность каждого периода или у нас на выходе меандр?
MicronSys
Написал на скорую руку ( VMLAB + WinAvr + Atmega8 )

#include <avr\io.h> // Most basic include files
#include <avr\interrupt.h> // Add the necessary ones
#include <avr\signal.h> // here

unsigned char count=0x00;
unsigned char i[8];
unsigned char temp=0x00;
SIGNAL(SIG_OVERFLOW0)
{
count++;
if (count<i[0]) temp|=1;
else temp&=~1;
if (count<i[1]) temp|=2;
else temp&=~2;
if (count<i[2]) temp|=4;
else temp&=~4;
if (count<i[3]) temp|=8;
else temp&=~8;
if (count<i[4]) temp|=16;
else temp&=~16;
if (count<i[5]) temp|=32;
else temp&=~32;
if (count<i[6]) temp|=64;
else temp&=~64;
if (count<i[7]) temp|=128;
else temp&=~128;

PORTD=temp;
}


int main(void)
{
DDRD=0xFF; PORTD=0x00;
i[0]=0x00;
i[1]=0x10;
i[2]=0x20;
i[3]=0x30;
i[4]=0x40;
i[5]=0x50;
i[6]=0x60;
i[7]=0x70;
TCNT0=0x00; TCCR0=0x02; TIMSK|=(1<<TOIE0);
sei();
while(1)
{ // Infinite loop; define here the
asm("nop");
}

}
MicronSys
или так ( VMLAB 3.11 + WINAVR + ATMEGA8 )
#include <avr\io.h> // Most basic include files
#include <avr\interrupt.h> // Add the necessary ones
#include <avr\signal.h> // here

unsigned char count=0x00;
unsigned char i[8]={0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70};
unsigned char temp=0x00;
unsigned char t=0x00;
SIGNAL(SIG_OVERFLOW0)
{
count++;
for(t=0;t<8;t++)
{
if (count<i[t]) temp|=(1<<t);
else temp&=~(1<<t);
}
PORTD=temp;
}


int main(void)
{
DDRD=0xFF; PORTD=0x00;
TCNT0=0x00; TCCR0=0x02; TIMSK|=(1<<TOIE0);
sei();
while(1)
{ // Infinite loop; define here the
asm("nop");
}

}
TMX
Цитата(at90 @ May 12 2005, 17:38)
[А как мы задаём длительность каждого периода или  у нас на выходе меандр?
*

Скважность на каждом выходе порта PWM_PORT зависит от содержимого элемента PWM_x. Получается управление по фазе. Попробуйте в симуляторе посмотреть.
TMX
Цитата(MicronSys @ May 12 2005, 17:50)


А Вы бы не могли сравнить производительность трех приведенных кусков кода?
Время выполнения обработчика прерывания в тактах?
MicronSys
{

сount++;

for(t=0;t<8;t++)
if (count<i[t]) temp|=(1<<t);
else temp&=~(1<<t);

PORTD=temp;

}
Этот кусок кода при 1 Меге выполняется 0.51 ms
после компиляции в режиме оптимизации 0.38 ms
TMX
Цитата(MicronSys @ May 13 2005, 09:11)
Этот кусок кода при 1 Меге выполняется 0.51 ms
после компиляции в режиме оптимизации 0.38 ms
*

Насколько я помню, надо управлять яркостью: если напрямую, то частота ШИМ должна быть не менее 50 Гц чтобы не было моргания, т.е. для 8-битного частота срабатывания таймера: 50 х 256 = ок.12,5 кГц соотв. период таймера - 80 мкс. Ну, при тактовой частоте 10 МГц будет вполне нормальный результат.
at90
Перепробовал все куски кодов. Все работают нормально. Только чего хотел не получил!!!!!!!! Светодиод всё равно вспыхивает резковато. Изменение яркости видно лиш на половине интервала, потом изменение незаметно.
Светодио зелёный 6 кд. Чатоту прерывания взял как подсказали 12.5 кгц
sseett
Так и должно быть, ведь яркость свечения не линейно зависит от протекающего через светодиод тока.
P.S.
Как-то делал ребенку елочную гирлянду (то же 8 каналов ШИМ) на сверхярких светодиодах и обнаружил, что использовать более 16 градаций уровня яркости не имеет смысла, изменение яркости практически не заметно.
at90
Цитата(sseett @ May 18 2005, 07:07)
Так и должно быть, ведь яркость свечения  не линейно зависит от протекающего через светодиод тока.
P.S.
Как-то делал ребенку елочную гирлянду (то же 8 каналов ШИМ) на сверхярких светодиодах и обнаружил, что использовать более 16 градаций уровня яркости не имеет смысла, изменение яркости практически не заметно.
*


Я поначалу тоже делал на 16 градаций но уменя получилось слишком ступенчатое изменение яркости,на 256 получьше
at90
думаю надо составить талицу значений для разных градаций
at90
Интересно а как смешивают цвета шимом в светодиодных экранах!!!!!!!!! и получают 16 млн цветов
GeorgyBey
Цитата(at90 @ May 18 2005, 08:25)
Интересно а как смешивают цвета шимом в светодиодных экранах!!!!!!!!! и получают 16 млн цветов
*


16 Млн. градаций - чистая арифметика. Белый цвет = Red+Green+Blue (RGB).
На каждый цвет по 8 бит, итого 2 в степени (8х3=24).
НО excl.gif И светодиод светит не пропорционально току и глаз хорошо различает слабые яркости и плохо большие (логарифмическая характеристика чуствительности человеческих органов). Так что - табличное преобразование яркости каждого цвета пикселя в хрен знает какой код (те кто сделал НЕ СКАЖУТ) - однозначно.
Лучше делать на ПЛИСах. А в контроллерах так:
Переполнение счетчика - включает светодиод (вывод на "0"), сравнение с константой - выключает.
Если счетчик имеет 2 константы (Мега48) на счетчик = 2 ШИМа.
На пиксель нужно 3 ШИМа.
ВСЕ ШИМы (счетчики) пикселей строки экрана стартуют одновременно, ШИМы одного пикселя (и остальных тоже) выключаются вразнобой - кому как предписано Константами.
Константа = яркость (без поправки на светодиод и глаз).
Ко всем Константам (полученным из сигнала через таблицу) КАЖДОГО ЦВЕТА нужно добавлять "регулирующую" константу (процентов 25 по "весу"), тогда изменяя эту рег.константу можно проводить цветокоррекцию изображения.
Так что для модуля 16х16 пикселей (по 3 светодиода) нужно 16х3=48 ШИМов.
И каждая строка светит 1/16 кадра, коих 50 минимум.
А еще информацию для строки нужно выложить на входы всех 48 ШИМов и ОДНИМ хлопом (тактом) вписать в отработку. Иначе динамика в картинке будет неизвестно какая.
Дерзайте cheers.gif
at90
Лучьше для шимов взять готовый драйвер! Есть DM163 драйвер на 24 канала(8X3) с 8бит шим для цвета и 6 бит для коррекции.и Стоит всего smile.gif 100р.
at90
А как реализовать драйвер на Плис. И какую нада Плис взять?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.