Чт сен 20, 2012 20:20:51
uint8 buffer[5];
uint8 index = 0;
uint8 bit;
bit = buffer[index >> 3] >> (index & 255) & 1;
if (index == 8 * sizeof(buffer))
{
// complete!
}
// ======
uint8 buffer[5];
uint8 shift = 7;
uint8 index = 0;
uint8 bit;
bit = buffer[index] >> shift & 1;
if (--shift == 0)
{
shift = 7;
if (++index == sizeof(buffer)
{
// complete!
}
}
// ======
uint8 buffer[5];
uint8 shift = 7;
uint8 index = 0;
uint8 bit;
bit = buffer[index] >> shift & 1;
index = index + (shift == 0);
shift = shift - 1 & 7;
if (index == sizeof(buffer))
{
// complete!
}
Чт сен 20, 2012 20:29:36
;************************************************
;* ;;/Вычитание распакованных BCD;;* *
;************************************************
ldwi X,(VALUE1+3) ; Получаем значения
ldwi Y,(VALUE1+6)
ld temp,-X
ld temp1,-Y
sub temp,temp1 ; Вычитаем
brpl SAVE_FORW ; Число положительное -это хорошо , меньше мороки
sbr Flags,1<<fl_Cset ; Запоминаем флаг С
neg temp ; Ивертируем полученую разницу
ldi temp1,10 ; Вычитаем из 10 ,что получилось
sub temp1,temp
DIV_FORW:
st Y,temp1
; Здесь выход
; Ниже тоже что и выше но с учётом переноса
ld temp1,-Y
ld temp,-X
sbrc Flags,fl_Cset
sec
cbr Flags,1<<fl_Cset
sbc temp,temp1
brpl SAVE_FORW
sbr Flags,1<<fl_Cset
neg temp
ldi temp1,10
sub temp1,temp
rjmp DIV_FORW
SAVE_FORW:
mov temp1,temp
rjmp DIV_FORW
Чт сен 20, 2012 21:29:16
menzoda писал(а):Может кто добавит что-нибудь покрасивее/побыстрее?
mov R0, #8 ; bits counter
loop: rlc A ; get bit into C
mov P0.0, C ; move C bit into port pin
djnz R0, loop ; repeat 8 times
rlc A ; preserve ACC
Пт сен 21, 2012 05:57:26
Пт сен 21, 2012 06:44:26
Ну, элементом "И" дело не обойдётся, IMHO. Скорей нужен D-триггер.BOB51 писал(а):Насчет "джиттера":
почему процесс ждет прерывание , а не прерывание процесс?
предварительный вывод данных в прот и стробирование аппаратным сигналом от таймера (OCxA/OCxB) с помощью внешнего элемента "И", а прерывание по таймеру всего лишь меняет выводимую информацию для следующего такта
Пт сен 21, 2012 11:24:38
Уважаемый BOB51, речь идёт всего лишь об одном способе из множества, как вы, наверное, понимаете.BOB51 писал(а):А я к "религиозным маньякам" не отношусь - для пользы дела не побрезгую и разного рода "рассыпухой"
Пт сен 21, 2012 15:03:10
Ага, когда первый раз пробегал мимо этой темы, то хотел линк именно на этот код дать, но сохранённые протухли. Потом вспомнил, что телесистемы переезжали когда-то, нашел одну тему по ключевым словам, а в другом линке уже просто поменял начало.Леонид Иванович писал(а):На ATmega8 применял такой "выравниватель":
- Код:
DDS: in XL,TCNT1L ;TCNT1L = 4..7
sbrs XL,0
rjmp PC+1
sbrs XL,1
lpm XL,Z
Эти два алгоритма писались для разных задач. Первичный вариант с IJMP легко растаскивается на большие времена, например, если в коде есть запрет прерывания на какое-то время (другое короткое прерывание или там запуск записи EEPROM). Надо выровнять до десятков тактов -- пожалуйста, константу нужную в MAX_JITTER и всё (это к коду по первому линку, там тоже под gnu-тый avr-as).Kavka писал(а):Так же быстро как с IJMP и просто супер компактно.
Пт сен 21, 2012 17:04:00
Пт сен 21, 2012 18:04:56
Сб сен 22, 2012 08:59:49
swpb R8 ; shift R9:R8 8 bits right
mov.b R8, R8 ; clear MSB
mov.b R9, R10
swpb R9
mov.b R9, R9
swpb R10
add.w R10, R8 ; leave only 24 bits of the result
mov.w #0x4000, R4 ; number to invert
mov.w #0x443F, R5 ; 765.0
invert:
mov.w R5, R15 ; R15=order
add.w #0x4100, R15 ; extract the order
xor.w #0x3F80, R15 ; adjust the order
and.w #0x7F80, R15 ; clear the sign bit
incd.w R15 ; R15[1:0] is the loop counter
and.b #0x7F, R5 ; leave only mantissa bits
mov.w R4, R6 ; R7:R6 = copy of original mantissa d
mov.w R5, R7
bis.b #0x80, R7 ; add hidden 1
mov.b rev(R5), R5 ; get table entry in eax
clr.w R4 ; R5:R4 = x_0
nrl: mov.w R4, &MPY32L ; N-R iteration: compute d*x_n
mov.w R5, &MPY32H
mov.w R6, &OP2L
mov.w R7, &OP2H
nop ; needed for the MPY32
mov.w &RES1, R8 ; R9:R8 = d*x_n
mov.w &RES2, R9
add.w #0x80, R8 ; rounding off
addc.w #0, R9
swpb R8 ; shift R9:R8 8 bits right
mov.b R8, R8 ; clear MSB
mov.b R9, R10
swpb R9
mov.b R9, R9
swpb R10
add.w R10, R8 ; leave only 24 bits of the result
inv.w R8 ; subtract the result from 2.0
inv.w R9
inc.w R8 ; rounding off
addc.b #0, R9 ; R9:R8 = 2.0 - d*x_n
mov.w R8, &OP2L ; compute x_n*(2.0 - d*x_n)
mov.w R9, &OP2H
nop ; needed for the MPY32
mov.w &RES1, R4 ; R5:R4 = x_n*(2.0 - d*x_n)
mov.w &RES2, R5
add.w #0x40, R4 ; rounding off
addc.w #0, R5
rlc R4 ; aligning R5:R4
rlc R5
swpb R4 ; shift R5:R4 8 bits right
mov.b R4, R4 ; clear MSB
mov.b R5, R10
swpb R5
mov.b R5, R5
swpb R10
add.w R10, R4 ; R5:R4 = x_(n+1)
dec.w R15 ; update the counter
bit.b #1, R15 ; to perform 2 iterations of
jnz nrl ; Newton - Raphson
and.b #0x7F, R5 ; get rid of hidden 1
jnz $+6 ; jump over the next line
add.w #0x80, R15 ; correction for a power of 2
add.w R15, R5 ; add the order; R5:R4 = 1/d
ret
rev:
db 11111111b, 11111101b, 11111011b, 11111001b, 11110111b, 11110101b, 11110100b, 11110010b
db 11110000b, 11101110b, 11101101b, 11101011b, 11101001b, 11101000b, 11100110b, 11100100b
db 11100011b, 11100001b, 11100000b, 11011110b, 11011101b, 11011011b, 11011010b, 11011000b
db 11010111b, 11010101b, 11010100b, 11010011b, 11010001b, 11010000b, 11001111b, 11001101b
db 11001100b, 11001011b, 11001010b, 11001000b, 11000111b, 11000110b, 11000101b, 11000100b
db 11000010b, 11000001b, 11000000b, 10111111b, 10111110b, 10111101b, 10111100b, 10111011b
db 10111010b, 10111001b, 10111000b, 10110111b, 10110110b, 10110101b, 10110100b, 10110011b
db 10110010b, 10110001b, 10110000b, 10101111b, 10101110b, 10101101b, 10101100b, 10101011b
db 10101010b, 10101001b, 10101000b, 10101000b, 10100111b, 10100110b, 10100101b, 10100100b
db 10100011b, 10100011b, 10100010b, 10100001b, 10100000b, 10011111b, 10011111b, 10011110b
db 10011101b, 10011100b, 10011100b, 10011011b, 10011010b, 10011001b, 10011001b, 10011000b
db 10010111b, 10010111b, 10010110b, 10010101b, 10010101b, 10010100b, 10010011b, 10010011b
db 10010010b, 10010001b, 10010001b, 10010000b, 10001111b, 10001111b, 10001110b, 10001110b
db 10001101b, 10001100b, 10001100b, 10001011b, 10001011b, 10001010b, 10001001b, 10001001b
db 10001000b, 10001000b, 10000111b, 10000111b, 10000110b, 10000101b, 10000101b, 10000100b
db 10000100b, 10000011b, 10000011b, 10000010b, 10000010b, 10000001b, 10000001b, 10000000b
Сб сен 22, 2012 11:31:04
Эта штука тоже теряется в глубинах истории программизма.BOB51 писал(а):Одно из его решений я прикошачил в качестве макроса-псевдокоманды и для аврок:
.macro xchrr ; псевдокоманда "обмен регистра/акумулятора/ с регистром"
eor @0,@1 ; вызывается как xchrr rd,rs
eor @1,@0
eor @0,@1
.endmacro
a ^= b;
b ^= a;
a ^= b;
a ^= b ^= a ^= b;
a = a + b;
b = a - b;
a = a - b;
xorwf prev_buttons, w ; в W -- маска кнопок, поменявиших своё значение
xorwf prev_buttons, f ; в prev_buttons -- новое значение кнопок заменило старое
; а третий xorwf var, w , который восстановил бы в W старое значение, завершив обмен -- не делаем.
Сб сен 22, 2012 11:57:54
Сб сен 22, 2012 12:26:24
(z) (z) (z)
movlw K movwf F clrf F clrw movf F,d ---> tstf F
\-> movfw F
(c,dc,z) | (z) (z) (c) (c)
{<add>|<sub>| and | ior | xor }lw K { comf | rlf | rrf | swapf } F,d
{ add | sub | and | ior | xor }wf F,d
(z) |
{ incf | decf | incfsz | decfsz } F,d { bcf | bsf | btfsc | btfss } F,bit
(/to,/pd)
clrwdt sleep nop call goto retlw K <return> <retfie>
+----------+
| irp | rp1 | rp0 | /to | /pd | z | dc | c |
+-----+-----+-----+-----+-----+-----+-----+-----+
----------
{ set | clr | skp[n] } { c | dc | z } b[n]{ c | dc | z }
; в зависимости от константы генерируется код минимальной длины
movlfww .macro val,dst
__tst_skip
.switch (val)
.case 0
clrf dst
.else
.case $FF
clrf dst
decf dst,f
.else
.case $01
clrf dst
incf dst,f
.else
.case $FE
clrf dst
decf dst,f
decf dst,f
.else
.case $02
clrf dst
incf dst,f
incf dst,f
.else
.case (other)
xorlw val
movwf dst
xorlw val
xorwf dst,f
.endif
.endm
; обнуляем маску
wswitch .macro *
wswmsk .set 0
.endm
; каждый раз делаем xor с результатом xor из новой константы для сравнивания и
; xor-сборки всех предыдущих констант.
; ну а в W сидит xor исходного значения и всех предыдущих констант
wcase .macro *val,lab
__tst_skip
xorlw (val^wswmsk)
wswmsk .set val
jz lab
.endm
; если надо, то в конце, после всех несовпадений, восстанавливаем значение W
wsrest .macro *
xorlw wswmsk
wswmsk .set 0
.endm
; Использовать как-то так
wswitch
wcase 'A', recv_a
wcase 'B', recv_b
wcase 'C', recv_c
wrest ; только если нужно после всех несовпадений восстановить W
; обработка default ветки
...
recv_a:
...
recv_b:
...
; dst=(w&mask)|(dst&~mask)
; w =(w^dst)&mask
InsBitsW .macro dst,mask
__tst_skip
xorwf dst,w
.IF 'mask[0.1]'=='#' ; это аргумент разбирается, тут выделяется первый символ и проверка на #
andlw mask[1.0] ; а тут все символы, кроме первого
.ELSE
andwf mask,w
.ENDIF
xorwf dst,f
.endm
Сб сен 22, 2012 12:33:00
Сб сен 22, 2012 12:37:11
Да, это отличный пример того, что оптимизация алгоритма должна идти до оптимизации кода и математику нужно знатьYS писал(а):Ух ё, про обращение числа - вообще фантастика!
Сб сен 22, 2012 15:04:45
А вот у Z80 - любой бит в доступной области, адресованной как ОЗУ
Сб сен 22, 2012 18:16:50
Сб сен 22, 2012 18:36:22
Сб сен 22, 2012 22:55:09
Пн сен 24, 2012 08:19:19
Модераторы, поддержите?ILYAUL писал(а):Предлагаю тему прекрипить.