Например TDA7294

Форум РадиоКот • Просмотр темы - Управление адресной светодиодной лентой с помощью atmega8
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Чт апр 18, 2024 15:12:53

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Управление адресной светодиодной лентой с помощью atmega8
СообщениеДобавлено: Вт дек 19, 2023 21:55:10 
Родился

Зарегистрирован: Сб окт 07, 2023 21:34:17
Сообщений: 12
Рейтинг сообщения: 0
Доброго времени дня! Помогите пожалуйста новичку. Пытаюсь управлять адресной светодиодной лентой (WS2811) с помощью atmega8 (далее - МК). Хочу просто зажечь самый первый светодиод в ленте зеленым цветом. Но у меня вся лента просто загорается белым.
Лента питается от отдельного источника 12В.
МК питается от 5В через USB. (тактирование от внутреннего кварца. Частоту в коде задал 8МГц)
Нули питания МК и ленты соединены между собой на макетной плате.
Управляющий сигнал идет от PORTB.1 через резистор 220 Ом.
В коде прописал 3 цикла (по одному на каждый цвет в светодиоде).
Насколько я знаю цвет загорается когда сперва передаем логическую единицу в течение 0.8мкс, а ноль в течение 0.45 мкс. А гаснет светодиод при передаче единицы в течение 0.4мкс, а нуля в течение 0.85мкс.
Зеленый цвет ставлю включаю (байты G7...G0), а красный(R7...R0) и синий(B7...B0) выключаю.

Может я в коде что то напутал? Или дело в МК и он не может такие управляющие импульсы выдавать? Нигде не могу найти решение. Везде только уроки по ардуино с уже готовыми библиотеками, в которых неизвестно что и как происходит. А я хочу сам ручками с нуля все сделать.

Сам код программы в Atmel Studio:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

int main(void)
{
DDRB=0b1111111;
PORTB=0b0000000;
while (1)
{
for(int i=0;i<8;++i) //передаем биты 1 в G7...G0
{
PORTB=0b0000010;
_delay_us(0.8);
PORTB=0b0000000;
_delay_us(0.4);
}

for(int i=0;i<8;++i) //передаем биты 0 в R7...R0
{
PORTB=0b0000010;
_delay_us(0.4);
PORTB=0b0000000;
_delay_us(0.85);
}

for(int i=0;i<8;++i) //передаем биты 0 в B7...B0
{
PORTB=0b0000010;
_delay_us(0.4);
PORTB=0b0000000;
_delay_us(0.85);
}
_delay_us(50);
}
}


Вложения:
скрин2.jpg [228.78 KiB]
Скачиваний: 25
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Вт дек 19, 2023 23:13:43 
Мучитель микросхем
Аватар пользователя

Карма: 8
Рейтинг сообщений: 64
Зарегистрирован: Пт фев 17, 2017 11:18:07
Сообщений: 429
Откуда: Ставрополь-Донское
Рейтинг сообщения: 0
посмотри осцилом - что ты передаешь. будет три байтных посылок с зазорами. это не прокатит.
растаскивай свои байты втрое - в битовую последовательность и передавай по SPI.

_________________
LIVE - EVIL


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 07:52:31 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21797
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
сперва передаем логическую единицу в течение 0.8мкс, а ноль в течение 0.45 мкс. А гаснет светодиод при передаче единицы в течение 0.4мкс, а нуля в течение 0.85мкс.
for(int i=0;i<8;++i) //передаем биты 1 в G7...G0
{
PORTB=0b0000010;
_delay_us(0.8 );
PORTB=0b0000000;
_delay_us(0.4);
}

for(int i=0;i<8;++i) //передаем биты 0 в R7...R0
{
PORTB=0b0000010;
_delay_us(0.4);
PORTB=0b0000000;
_delay_us(0.85);
}

Это шуткатакой? :facepalm: :)))
Любезный, у вас частота ядра МК - 8 МГц. То есть всего ОДНА одноцикловая инструкция (а они далеко не все одноцикловые, особенно условное и безусловное ветвление кода) выполняется за 0,125 мкс.
Каким таким таинственным способом может быть реализована функция _delay_us(0.4), например, если она не кратна 0,125?
Каким таким образом вы полагаете исполнение цикла и управление портом за 0 мкс?
С чего вы вообще взяли, что функция _delay_us() в состоянии оперировать дробным аргументом?


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 08:42:26 
Друг Кота
Аватар пользователя

Карма: 46
Рейтинг сообщений: 2030
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Сообщений: 6618
Откуда: Сердце Пармы
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Я делал с ассемблерной вставкой
Спойлер
Код:
//void Send(uint8_t r, uint8_t g, uint8_t b) {                                   // Послать элемент на ленту
//void Send(flash uint8_t *addr) {                                   // Послать элемент на ленту по указателю из флеша
void Send(uint8_t *addr) {                                   // Послать элемент на ленту по указателю из ОЗУ
     #asm
        ;ldd  r26,y+2              ; Загрузить в r26 &b
        ;ldd  r27,y+1              ; Загрузить в r26 &r
        ;ld   r25,y                ; Загрузить в r26 g   
        MOVW R30,R26
        ;lpm  r26,z++      ;Загрузка по указателю из флеш
        ;lpm  r27,z++
        ;lpm  r25,z
        ld   r26,z++         ;Загрузка по указателю из ОЗУ
        ld   r27,z++
        ld   r25,z
        ldi  r30,24               ; Загрузить в r22 количество передаваемых бит
        dec  r30                  ; уменьшить количество передаваемых бит на 1
     label_1:                     ; Начало цикла
        brmi label_2              ; Если все биты передались выйти 
        in   r31,0x18             ; запомним состояние порта   !!!!0х18 - адрес порта, автоматизировать не смог!!!!   
     #endasm
     PIN_WS2812=1;          // поднимем пин
     #asm
        ;настройка задержек при изменении тактовой частоты производится изменением числа НОПов
        ;nop                       ; Подождать
        ;nop                       ; Подождать     
        nop                       ; Подождать
        sbrs r27,7                ; Пропустить следующую команду если бит в регистре r27 установлен
        out  0x18,r31             ; восстановим состояние порта (низкий уровень на пине) - с этой командой не пляшет общее время посылки
        ;      !!!!0х18 - адрес порта, автоматизировать не смог!!!!
        ;nop                       ; Подождать
        nop                       ; Подождать
        lsl  r25                   ; g<<1
        rol  r26                   ; b<<1 через перенос чтобы была непрерывность
        rol  r27                   ; r<<1 через перенос чтобы была непрерывность
        dec  r30                   ; уменьшить количество передаваемых бит на 1
     #endasm
     PIN_WS2812=0;          //  Пин к земле
     #asm
        ;nop                       ; Подождать
        ;nop                       ; Подождать
        rjmp label_1              ; Перейти к началу цикла
     label_2:                     ; Выйти из функции
     #endasm                     
     PIN_WS2812=0;          // Пин к земле
    } 
код не допилен до удобоваримого вида, но рабочий.
ПС написано и проверено в Кодевижен.
задефайнены:
#define uint8_t unsigned char
#define PIN_WS2812 PORTB.0

вызов:
Спойлер
Код:
for (i=0;i<sizeof(Chkala);i+=3)  {Send(&Chkala[i]);};
где Chkala[] - массив с выводимыми данными

_________________
Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 11:31:12 
Сверлит текстолит когтями

Карма: 20
Рейтинг сообщений: 296
Зарегистрирован: Сб май 05, 2012 20:24:52
Сообщений: 1220
Откуда: KN34PC, Болгария
Рейтинг сообщения: 0
Каким таким таинственным способом может быть реализована функция _delay_us(0.4), например, если она не кратна 0,125?
Ето 1 цикл (ticks). Пересчитывайте из библиотечного кода. Получается задержка МК в 1 такт.
Спойлер
Код:
void _delay_us(double __us)
{
        double __tmp ;
#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
  !defined(__DELAY_BACKWARD_COMPATIBLE__) &&       \
  __STDC_HOSTED__
        uint32_t __ticks_dc;
        extern void __builtin_avr_delay_cycles(unsigned long);
        __tmp = ((F_CPU) / 1e6) * __us;

        #if defined(__DELAY_ROUND_DOWN__)
                __ticks_dc = (uint32_t)fabs(__tmp);

        #elif defined(__DELAY_ROUND_CLOSEST__)
                __ticks_dc = (uint32_t)(fabs(__tmp)+0.5);

        #else
                //round up by default
                __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
        #endif

        __builtin_avr_delay_cycles(__ticks_dc);

#else
        uint8_t __ticks;
        double __tmp2 ;
        __tmp = ((F_CPU) / 3e6) * __us;
        __tmp2 = ((F_CPU) / 4e6) * __us;
        if (__tmp < 1.0)
                __ticks = 1;
        else if (__tmp2 > 65535)
        {
                _delay_ms(__us / 1000.0);
        }
        else if (__tmp > 255)
        {
                uint16_t __ticks=(uint16_t)__tmp2;
                _delay_loop_2(__ticks);
                return;
        }
        else
                __ticks = (uint8_t)__tmp;
        _delay_loop_1(__ticks);
#endif
}

8000000 / 3000000 * 0.4 = 1.0666 -> _delay_loop_1(1); будет 1 такт (tick).
А и каждое меньшее число чем 0.4 сокращается до 1 такт.
(Автор кода решает, нужно ли это. В данном случае я бы пропустил написание этой строки).


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 11:43:13 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21797
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
Пересчитывайте из библиотечного кода. Получается задержка МК в 1 такт.

Не получается. Просто вызов функции и возврат из нее - это ЧЕТЫРЕ машинных цикла. То есть 0,5 мкс при 8 МГц системной частоты.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 11:45:12 
Сверлит текстолит когтями

Карма: 20
Рейтинг сообщений: 296
Зарегистрирован: Сб май 05, 2012 20:24:52
Сообщений: 1220
Откуда: KN34PC, Болгария
Рейтинг сообщения: 0
Возможно. Переход с C на ASM мне не близок.
Код:
PORTB=0b0000010;
PORTB=0b0000000;
в других быстрых устройствах работает (напр. AD98XX) напрямую без задержек даже на 16, 32 MHz. Но WS2811 не отличается особой скоростью. Бы добавил целое число задержки.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 12:17:18 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21797
Откуда: Московская область, Фрязино
Рейтинг сообщения: 3
WS2811 не отличается особой скоростью.
Времена диаграммы автор озвучил. Можно сделать на nop-ах в АСМе, точно посчитав циклы.
Но лучше делать аппаратно на таймере, либо SPI. Скорость там достаточно высокая с учетом выбранной частоты работы МК.
Возможно.

Тут есть два варианта.
Либо это макрос и его тело вставляется вместо функции, а содержимое считается не в рантайме, а на этапе компиляции. Тогда там можно откалибровать с точностью до 1 машинного цикла на основании дефайна системной частоты.
Либо это полноценная функция с передачей в нее аргумента и внутренним циклом. Тогда ни о каких единицах микросекунд речи быть не может.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 12:39:29 
Друг Кота
Аватар пользователя

Карма: 93
Рейтинг сообщений: 1351
Зарегистрирован: Вт мар 16, 2010 22:02:27
Сообщений: 14054
Откуда: ДОНЕЦК
Рейтинг сообщения: 0
Два простейших решения -
1. сделать проект под ардуиноIDE, спользуя библиотеку Adafruit_NeoPixel;
(в составе IDE достаточно "платформ" под атмегу8)
2. использовать ассемблер при максимально возможной частоте МК.
( к примеру таким фрагментом:
Спойлер
Код:
;
;
;         trd2812_ma.txt
;
;         файл обработчика передачи массива
; из буфера вывода в линейку на основе WS2812B
; базовый МК из линейки АТМЕЛ при тактовой частоте
; от 16 Мегагерц ( 0,000000062 S)
;
; требуемые интервалы по даташиту WS2812B
;
;Data transfer time( TH+TL=1.25µs±600ns)
;  T0H  0 code ,high voltage time  0.4us   ±150ns
;  T1H  1 code ,high voltage time  0.8us   ±150ns
;  T0L  0 code ,low voltage time   0.85us  ±150ns
;  T1L  1 code ,low voltage time   0.45us  ±150ns
;  RES  low voltage time  Above 50µs
; исходный уровень линии связи = 0
; данные передаются пакетами из трех байт на точку
; старшими битами вперед в последовательности
; соответствующей G - R - B цветам точки
; количество блоков должно соответствовать
; количеству точек в ленте
;
; реальные данные согласно тест - отладки дебаггером (версия1!)
; авр-студио 4.19
;
; Data transfer time( TH+TL=1.38µs -10ns)
;  T0H  0 code ,high voltage time  0.44us  ±10ns
;  T1H  1 code ,high voltage time  0.88us  ±10ns
;  T0L  0 code ,low voltage time   0.94us  ±10ns
;  T1L  1 code ,low voltage time   0.50us  ±10ns
;  RES  low voltage time  192,88uS (Above 50µs)
;
; длина прерывания с пакетом загрузки (x60*3) = 2175uS (0.002175)
; интервал между прерываниями (irq t/c0) = 0.004S (4000uS)
;
;             define datas
; .equ port_out = PORTB ; порт вывода (по усмотрению)
; .equ out_line = 0 ; линия вывода данных
; .equ bufout = SRAM_START ; начальный адрес буфера вывода
; .equ pixel = 60 ; количество точек в линейке/ленте
; .equ bufout_size = (pixel * 3) ; не может быть более объема ОЗУ - стек!!!


;таблица обьявленных имен - переназначение регистров РОН
;
; .def name = r31 ; ZH регистр (полный)
; .def name = r30 ; ZL регистр (полный)
; .def name = r29 ; YH регистр (полный)
; .def name = r28 ; YL регистр (полный)
; .def name = r27 ; XH регистр (полный) указатель текущей ячейки массива bufout
; .def name = r26 ; XL регистр (полный) указатель текущей ячейки массива bufout
; .def name = r25 ; регистр (полный) BH
; .def name = r24 ; регистр (полный) BL
; .def name = r23 ; регистр (полный)
; .def name = r22 ; регистр (полный)
; .def name = r21 ; регистр (полный)
; .def name = r20 ; регистр (полный)
; .def name = r19 ; регистр (полный)
; .def name = r18 ; регистр (полный)
; .def tmp1 = r17 ; регистр (полный) счетчик байт вывода
; .def tmp0 = r16 ; регистр (полный) буфер выводимого байта
; .def regn = r15 ; регистр (урезан)
; .def regn = r14 ; регистр (урезан)
; .def regn = r11 ; регистр (урезан)
; .def regn = r10 ; регистр (урезан)
; .def regn = r9 ; регистр (урезан)
; .def regn = r8 ; регистр (урезан)
; .def regn = r7 ; регистр (урезан)
; .def regn = r6 ; регистр (урезан)
; .def regn = r5 ; регистр (урезан)
; .def regn = r4 ; регистр (урезан)
; .def regn = r3 ; регистр (урезан)
; .def regn = r2 ; регистр (урезан)
; .def matr = r1 ; регистр (урезан) r1 по возможности не использовать!!!
; .def madr = r0 ; регистр (урезан) r0 по возможности не использовать!!!
;
;----------
;  .macro   ;; ввод и предобработка данных
;     
;     
;    .endmacro
;
;----------
;
; определение буфера вывода в области данных
;  .dseg
;  .org bufout
;point0: .byte 3 ; g:r:b
;point1: .byte 3 ; g:r:b
;point2: .byte 3 ; g:r:b
;point3: .byte 3 ; g:r:b
;point4: .byte 3 ; g:r:b
;point5: .byte 3 ; g:r:b
;point6: .byte 3 ; g:r:b
;point7: .byte 3 ; g:r:b
;point8: .byte 3 ; g:r:b
;point9: .byte 3 ; g:r:b
;point10: .byte 3 ; g:r:b
;point11: .byte 3 ; g:r:b
;point12: .byte 3 ; g:r:b
;point13: .byte 3 ; g:r:b
;point14: .byte 3 ; g:r:b
;point15: .byte 3 ; g:r:b
;point16: .byte 3 ; g:r:b
;point17: .byte 3 ; g:r:b
;point18: .byte 3 ; g:r:b
;point19: .byte 3 ; g:r:b
;point20: .byte 3 ; g:r:b
;point21: .byte 3 ; g:r:b
;point22: .byte 3 ; g:r:b
;point23: .byte 3 ; g:r:b
;point24: .byte 3 ; g:r:b
;point25: .byte 3 ; g:r:b
;point26: .byte 3 ; g:r:b
;point27: .byte 3 ; g:r:b
;point28: .byte 3 ; g:r:b
;point29: .byte 3 ; g:r:b
;point30: .byte 3 ; g:r:b
;point31: .byte 3 ; g:r:b
;point32: .byte 3 ; g:r:b
;point33: .byte 3 ; g:r:b
;point34: .byte 3 ; g:r:b
;point35: .byte 3 ; g:r:b
;point36: .byte 3 ; g:r:b
;point37: .byte 3 ; g:r:b
;point38: .byte 3 ; g:r:b
;point39: .byte 3 ; g:r:b
;point40: .byte 3 ; g:r:b
;point41: .byte 3 ; g:r:b
;point42: .byte 3 ; g:r:b
;point43: .byte 3 ; g:r:b
;point44: .byte 3 ; g:r:b
;point45: .byte 3 ; g:r:b
;point46: .byte 3 ; g:r:b
;point47: .byte 3 ; g:r:b
;point48: .byte 3 ; g:r:b
;point49: .byte 3 ; g:r:b
;point50: .byte 3 ; g:r:b
;point51: .byte 3 ; g:r:b
;point52: .byte 3 ; g:r:b
;point53: .byte 3 ; g:r:b
;point54: .byte 3 ; g:r:b
;point55: .byte 3 ; g:r:b
;point56: .byte 3 ; g:r:b
;point57: .byte 3 ; g:r:b
;point58: .byte 3 ; g:r:b
;point59: .byte 3 ; g:r:b
;
;----------

  .cseg
bptr0:
  nop
   .org (bptr0 + (256 - (bptr0 & 0x00FF)))
slot0:
     ; 6/14 (6-4=2 посему роль остатка выполняет CBI)
    cbi port_out,out_line ; 2 цикла
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    ret ; 4 цикла
    .org (slot0+16)
slot1:
    nop ; 13/7 (13-4=9)
    nop
    nop
    nop
    nop
    nop
    nop
    cbi port_out,out_line ; 2 цикла
    nop
    nop
    ret ; 4 цикла
    ;.org 0x0060
    .org (slot1+16)
xslot0:
    ; 6/14 (6-5=1 посему роль остатка выполняет CBI с избытком в 1 nop)
    cbi port_out,out_line ; 2 цикла
    cbr zl,(1<<5) ; модификация указателя 1 цикл
    nop
    nop
    nop
    nop
    nop
    nop ; -2 цикла на ld tmp0,x+
    dec tmp1 ; 1 цикл
    brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле)
    rjmp trasstt ; 2 цикла
    .org (xslot0+16)
xslot1:
    nop ; 13/7 (13-5=8)
    cbr zl,(1<<5) ; модификация указателя 1 цикл
    nop
    nop
    nop
    nop
    nop
    cbi port_out,out_line ; 2 цикла
           ; -2 цикла на ld tmp0,x+
      dec tmp1 ; 1 цикл
    brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле)
    rjmp trasstt ; 2 цикла
;
ends_trd:
      pop tmp0
      pop tmp1
      pop xl
      pop xh
         pop zl
         pop zh ; восстановить рабочую область из стека
   ret
;----------
;
; предварительно:
; линия out_line настроена на вывод
; исходный уровень out_line =0
; указатель стека усатновлен на RAMEND
; массив данных (bufout:bufout_size) предварительно загружен
; флаг готовности массива данных установлен
;
mass_trm:
     push zh
     push zl
     push xh
     push xl
     push tmp1
     push tmp0 ; храним рабочую область в стеке
res_line:
     ldi tmp0,4
     ser tmp1
     cbi port_out,out_line
res_time:
     dec tmp1
     brne res_time
     dec tmp0
     brne res_time ; =>50uS time out
     ldi xh,high (bufout)
     ldi xl,low (bufout) ; загрузка начального адреса массива
        ; в указатель
     ldi tmp1,bufout_size
     ldiw z,slot0 ; адрес начала таблицы в указателе
;     ldiw z,(bptr0 + (256 - (bptr0 & 0x00FF)))
;----------
trasstt:
    ld tmp0,x+ ; 2 цикла
slot_0:
      sbi port_out,out_line ; 2 цикла реально до установки 3 цикла
         bst tmp0,7 ; 1 цикл
         bld zl,4 ; 1 цикл
         icall ; 3 цикла = 4 цикла от out_line=1
;----------
slot_1:
      sbi port_out,out_line
      bst tmp0,6 ; 1 цикл
         bld zl,4 ; 1 цикл
         icall ; 3 цикла
;----------
slot_2:
      sbi port_out,out_line
      bst tmp0,5 ; 1 цикл
         bld zl,4 ; 1 цикл
         icall ; 3 цикла
;----------
slot_3:
      sbi port_out,out_line
      bst tmp0,4 ; 1 цикл
         bld zl,4 ; 1 цикл
         icall ; 3 цикла
;----------
slot_4:
      sbi port_out,out_line
      bst tmp0,3 ; 1 цикл
         bld zl,4 ; 1 цикл
         icall ; 3 цикла
;----------
slot_5:
      sbi port_out,out_line
      bst tmp0,2 ; 1 цикл
         bld zl,4 ; 1 цикл
         icall ; 3 цикла
;----------
slot_6:
      sbi port_out,out_line
      bst tmp0,1 ; 1 цикл
         bld zl,4 ; 1 цикл
         icall ; 3 цикла
;----------
slot_7:
      sbi port_out,out_line
      ;sbr zl,(1<<6) ; модификация указателя под завершающий фрагмент
      sbr zl,(1<<5)
                  ; 1 цикл
      bst tmp0,0 ; 1 цикл
         bld zl,4 ; 1 цикл
         ijmp ; 3 цикла
;----------

)
:roll:


Вернуться наверх
 
В сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 12:55:46 
Модератор
Аватар пользователя

Карма: 153
Рейтинг сообщений: 2802
Зарегистрирован: Сб авг 14, 2010 15:05:51
Сообщений: 18073
Откуда: г. Озерск, Челябинская обл.
Рейтинг сообщения: 0
Медали: 1
Лучший человек Форума 2017 (1)
КРАМ писал(а):
Просто вызов функции и возврат из нее - это ЧЕТЫРЕ машинных цикла
3 цикла на вызов (rcall) и 4 на возврат (ret). итого 7 циклов.

_________________
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 13:41:52 
Друг Кота
Аватар пользователя

Карма: 138
Рейтинг сообщений: 2712
Зарегистрирован: Чт янв 10, 2008 22:01:02
Сообщений: 21797
Откуда: Московская область, Фрязино
Рейтинг сообщения: 0
3 цикла на вызов (rcall) и 4 на возврат

Ну вооот, я то надеялся... :))) :))) :)))
У меня перед носом лежит альбом с инструкциями АВР. Но я поленился посмотреть... :oops:


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 13:58:43 
Друг Кота
Аватар пользователя

Карма: 13
Рейтинг сообщений: 355
Зарегистрирован: Ср ноя 11, 2009 17:19:30
Сообщений: 4279
Откуда: Воронеж
Рейтинг сообщения: 0
Использовал вот эту библиотеку на тини13 с внутренним генератором на 9,6 МГц. Можно либо её вотпрямсразу использовать, либо посмотреть как там всё внутри устроено. Зависит от целей. Уйма условной компиляции на разные случаи, всё программно. Так что это как минимум возможно.

_________________
"Привет!" - соврал он.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 14:41:36 
Друг Кота
Аватар пользователя

Карма: 46
Рейтинг сообщений: 2030
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Сообщений: 6618
Откуда: Сердце Пармы
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Так что это как минимум возможно.
Та ну! у меня тини 13 ленту таскает, (и код отправки данных в ленту я привел), или это ничего не доказывает? :dont_know: и на меге 8 на её 8 МГц тактовой тоже работает...

Добавлено after 53 seconds:
Re: Управление адресной светодиодной лентой с помощью atmega8
правда у меня тайминги приходится ручками подбирать... :oops: :)))

Добавлено after 2 minutes 5 seconds:
Re: Управление адресной светодиодной лентой с помощью atmega8
причем можно хоть указатель на ОЗУ или флеш, хоть непосредственно данные в функцию пихать

_________________
Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Ср дек 20, 2023 20:05:07 
Нашел транзистор. Понюхал.

Карма: -6
Рейтинг сообщений: 0
Зарегистрирован: Вт окт 11, 2022 13:45:06
Сообщений: 152
Рейтинг сообщения: 0
Ув. АRV даже статью накатал. Респект.

viewtopic.php?f=57&t=159702


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Управление адресной светодиодной лентой с помощью atmega
СообщениеДобавлено: Сб дек 23, 2023 10:21:25 
Прорезались зубы
Аватар пользователя

Карма: 7
Рейтинг сообщений: 73
Зарегистрирован: Ср июн 29, 2022 16:25:45
Сообщений: 203
Рейтинг сообщения: 0
Вообще для управления такими диодами удобно использовать SPI или UART.
Но бывают случаи, когда этот интерфейс недоступен. Тогда приходится дрыжками ногать.

В этом случае следует учесть, что 2811/2812 диоды требовательны к длительности именно высокого уровня. Низкий можно немного и растянуть. Главное, не дотягивать до 50 мкс - а то будет сброс ))

У меня на 8 МГц тиньке для управления одиночным диодом работает вот такой код (у тиньки ножек было мало и ножки с последовательными интерфейсами были заняты):

Код:
   #define NOP                           asm volatile ("nop" : : )

   static void decodeByte(uint8_t val, uint8_t* buff){
      uint8_t mask = 128;
      while (mask) {
         *buff = val & mask;
         buff++;
         mask >>= 1;
      }
   }
   
   void setLedColor(uint8_t R, uint8_t G, uint8_t B){
      uint8_t arr[24];
      decodeByte(G,&arr[ 0]);
      decodeByte(R,&arr[ 8]);
      decodeByte(B,&arr[16]);
      cli();
      GPIO_RESET_BIT(LED2812);
      _delay_us(50);
      register uint8_t* parr = arr;
      for ( uint8_t i = 0; i < 24; i++) {
         if (*parr++) {
            // bit == 1
            GPIO_SET_BIT(LED2812);
            NOP;NOP;NOP;NOP;
            GPIO_RESET_BIT(LED2812);
         } else {
            // bit == 0
            GPIO_SET_BIT(LED2812);
            NOP;
            GPIO_RESET_BIT(LED2812);
            NOP;
         }
      }
      GPIO_SET_BIT(LED2812);
      sei();
   }

GPIO_SET_BIT(LED2812); и GPIO_RESET_BIT(LED2812); - это просто макросы вида PORTx |= (1 << bit) и PORTx &= ~(1 << bit)
Длительность нулевой единички получилась около 375 нс, единичной единички - около 875 нс. Длительность ноликов достигает почти 1 мс, но повторюсь, это не настолько критично, как жесткие тайминги единички. Мерялось лог.анализатором с частотой выборки 24 МГц (каждые 41.6 нс выборка).

Для управления несколькими диодами можно разложить сразу все цвета в массив (если хватит памяти), либо аккуратно раскладывать биты прямо на лету, изменив условие на if (*parr & mask), а в конце либо уменьшать маску, либо инкрементировать parr и заново задавая маску. NOP в нулевом состоянии в ветке else тогда надо убрать, там и так будет перебор за счет доп. условий.

Ну и можно посмотреть еще вот тут - тоже управление диодами ногодрыгом.

_________________
Белая и Пушистая


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 34


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

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y