Вт дек 19, 2023 21:55:10
Вт дек 19, 2023 23:13:43
Ср дек 20, 2023 07:52:31
Ср дек 20, 2023 08:42:26
//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; // Пин к земле
}
for (i=0;i<sizeof(Chkala);i+=3) {Send(&Chkala[i]);};
Ср дек 20, 2023 11:31:12
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
}
Ср дек 20, 2023 11:43:13
Ср дек 20, 2023 11:45:12
PORTB=0b0000010;
PORTB=0b0000000;
Ср дек 20, 2023 12:17:18
Ср дек 20, 2023 12:39:29
;
;
; 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 цикла
;----------
Ср дек 20, 2023 12:55:46
3 цикла на вызов (rcall) и 4 на возврат (ret). итого 7 циклов.КРАМ писал(а):Просто вызов функции и возврат из нее - это ЧЕТЫРЕ машинных цикла
Ср дек 20, 2023 13:41:52
Ср дек 20, 2023 13:58:43
Ср дек 20, 2023 14:41:36
Ср дек 20, 2023 20:05:07
Сб дек 23, 2023 10:21:25
#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();
}