ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
21 ноября
135949
leon_ (27.10.2008 22:30, просмотров: 14518)
Масштабирование 16-разрядных данных АЦП в 16-разрядный результат. http://caxapa.ru/135412.html
;************************************************************************* ; Умножение знаковых и беззнаковых 16-битных данных (d) на знаковый или ; беззнаковый 16-битный коэффициент k с получением 16-битного результата ; (например, для масштабирования значений АЦП). ; ; Диапазон беззнаковых значений: 0x0000..0xFFFF в прямом коде ; Диапазон знаковых значений: 0x8000..0x7FFF в дополнительном коде ; Интерпретация этих значений как действительных чисел зависит от под- ; разумеваемого положения десятичных точек в каждом конкретном случае. ; ; Точность результатов без округления: [0,0..1,0) младшего разряда ; Точность результатов с округлением: [-0,5..0,5) младшего разряда ; ; Обсуждение в конфе AVR от 11.10.2008 - http://caxapa.ru/134681.html ;************************************************************************* ;------------------------------------------------------------------------- ; Scaling test code ;------------------------------------------------------------------------- .equ d = 0x40C0 .equ k = 0x40C0 .include <m128def.inc> ldi r16, high(RAMEND) out SPH, r16 ldi r16, low(RAMEND) out SPL, r16 scalings: ; unsigned*unsigned scaling test ; 1. Беззнаковые данные, беззнаковый коэффициент и беззнаковый результат. ldi r20,low(d) ; unsigned ldi r21,high(d) ldi r22,low(k) ; unsigned ldi r23,high(k) rcall scale16uu ; unsigned r19r18 ; signed*unsigned scaling test ; 2. Знаковые данные, беззнаковый коэффициент и знаковый результат. ldi r20,low(d) ; signed ldi r21,high(d) ldi r22,low(k) ; unsigned ldi r23,high(k) rcall scale16su ; signed r19r18 ; unsigned*signed scaling test ; 3. Беззнаковые данные, знаковый коэффициент и знаковый результат. ldi r20,low(k) ; signed ldi r21,high(k) ldi r22,low(d) ; unsigned ldi r23,high(d) rcall scale16su ; signed r19r18 ; signed*signed scaling test ; 4. Знаковые данные, знаковый коэффициент и знаковый результат. ldi r20,low(d) ; signed ldi r21,high(d) ldi r22,low(k) ; signed ldi r23,high(k) rcall scale16ss ; signed r19r18 rjmp scalings ;------------------------------------------------------------------------- ;------------------------------------------------------------------------- ; Scaling routines ;------------------------------------------------------------------------- ;------------------------------------------------------------------------- ; Scales unsigned r21:r20 by unsigned r23:r22 value ; ; Any registers can be used as operands ; ; Result stored in r19:r18 ; 17 program words, 20 clocks + ret ; ; 1. Беззнаковые данные, беззнаковый коэффициент и беззнаковый результат. ; r21:r20 данные АЦП в диапазоне 0x0000..0xFFFF | 0.16-> 0,0..1,0 | 0.16-> 0,0..1,0 ; r23:r22 коэффициент в диапазоне 0x0000..0xFFFF | 0.16-> 0,0..1,0 | 16.0-> 0..65535 ; r19:r18 результат в диапазоне 0x0000..0xFFFF | 0.16-> 0,0..1,0 | 16.0-> 0..65535 ; r19:r18:r17 = r23:r22 * r21:r20 scale16uu: clr r2 mul r23, r21 movw r18, r0 mul r22, r20 mov r17, r1 mul r23, r20 add r17, r0 adc r18, r1 adc r19, r2 mul r21, r22 add r17, r0 adc r18, r1 adc r19, r2 subi r17, low(-128) ; truncation sbci r18, high(-128) sbci r19, byte3(-128) ret ;------------------------------------------------------------------------- ;------------------------------------------------------------------------- ; Scales signed r21:r20 by unsigned r23:r22 value ; ; Only r16..r23 registers can be used as operands ; due to the xMULSx command limitations ; ; Result stored in r19:r18 ; 18 program words, 21 clocks + ret ; ; 2. Знаковые данные, беззнаковый коэффициент и знаковый результат. ; r21:r20 данные АЦП в диапазоне 0x8000..0x7FFF | 0.16-> -0,5..0,5 | 0.16-> -0,5..0,5 ; r23:r22 коэффициент в диапазоне 0x0000..0xFFFF | 0.16-> 0,0..1,0 | 16.0-> 0..65535 ; r19:r18 результат в диапазоне 0x8000..0x7FFF | 0.16-> -0,5..0,5 | 16.0-> -32767..32767 ; 3. Беззнаковые данные, знаковый коэффициент и знаковый результат. ; r21:r20 коэффициент в диапазоне 0x8000..0x7FFF | 0.16-> -0,5..0,5 | 16.0-> -32767..32767 ; r23:r22 данные АЦП в диапазоне 0x0000..0xFFFF | 0.16-> 0,0..1,0 | 0.16-> 0,0..1,0 ; r19:r18 результат в диапазоне 0x8000..0x7FFF | 0.16-> -0,5..0,5 | 16.0-> -32767..32767 ; r19:r18:r17 = r23:r22 * r21:r20 scale16su: clr r2 mulsu r21, r23 movw r18, r0 mul r22, r20 mov r17, r1 mul r23, r20 add r17, r0 adc r18, r1 adc r19, r2 mulsu r21, r22 sbc r19, r2 add r17, r0 adc r18, r1 adc r19, r2 subi r17, low(-128) ; truncation sbci r18, high(-128) sbci r19, byte3(-128) ret ;------------------------------------------------------------------------- ;------------------------------------------------------------------------- ; Scales signed r21:r20 by signed r23:r22 value ; ; Only r16..r23 registers can be used as operands ; due to the xMULSx command limitations ; ; Result stored in r19:r18 ; 20 program words, 23 clocks + ret ; ; 4. Знаковые данные, знаковый коэффициент и знаковый результат. ; r21:r20 данные АЦП в диапазоне 0x8000..0x7FFF | 0.16-> -0,5..0,5 | 1.15-> -1,0..1,0 ; r23:r22 коэффициент в диапазоне 0x8000..0x7FFF | 1.15-> -1,0..1,0 | 0.16-> -0,5..0,5 ; r19:r18 результат в диапазоне 0x8000..0x7FFF | 0.16-> -0,5..0,5 | 0.16-> -0,5..0,5 ; ; r21:r20 данные АЦП в диапазоне 0x8000..0x7FFF | 1.15-> -1,0..1,0 | 0.16-> -0,5..0,5 ; r23:r22 коэффициент в диапазоне 0x8000..0x7FFF | 16.0-> -32767..32767 | 17.0-> -65535..65535 ; r19:r18 результат в диапазоне 0x8000..0x7FFF | 16.0-> -32767..32767 | 16.0-> -32767..32767 ; Для формата 17.0 в R21:R20 записывать только 16 старших разрядов коэффициента ; r19:r18:r17 = ( r23:r22 * r21:r20 ) << 1 scale16ss: clr r2 fmuls r23, r21 movw r18, r0 fmul r22, r20 adc r18, r2 mov r17, r0 fmulsu r23, r20 sbc r19, r2 add r17, r0 adc r18, r1 adc r19, r2 fmulsu r21, r22 sbc r19, r2 add r17, r0 adc r18, r1 adc r19, r2 subi r17, low(-128) ; truncation sbci r18, high(-128) sbci r19, byte3(-128) ret ;-------------------------------------------------------------------------