ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
21 ноября
136269 Топик полностью
MBedder, терминатор (03.11.2008 11:28, просмотров: 231) ответил leon_ на Масштабирование 16-разрядных данных АЦП в 16-разрядный результат.
Оформил, перевел свои каменты на русский, убрал лишние советы, чтобы не сбивать людей с толку. Проверь перед тем, как я отправлю это в "Исходники"  ;******************************************************************************* ; Умножение знаковых (sdat) и беззнаковых (dat) 16-битных данных на ; знаковый (scoef) или беззнаковый (coef) 16-битный коэффициент с получением ; 16-битного результата (например, для масштабирования значений АЦП). ; ; Диапазон беззнаковых целых значений dat: 0..65535 в прямом коде. ; Диапазон знаковых целых значений sdat: -32768..+32767 в дополнительном коде. ; ; Диапазон беззнаковых целых значений coef: 0..65535 в прямом коде, что ; соответствует диапазону 0..0.99998 в представлении fractional 0.16 (q16) ; Диапазон знаковых целых значений scoef: -32768..+32767 в дополнительном коде, ; что соответствует диапазону -1..+0.99998 в представлении fractional 1.15 (q15) ; ; Точность результатов без округления: [0,0..1,0) младшего разряда ; Точность результатов с округлением: [-0,5..0,5) младшего разряда ; ; Обсуждение в конфе AVR в октябре 2008г. - http://caxapa.ru/134681.html, ; http://caxapa.ru/135412.html, http://caxapa.ru/135949.html ; ; (c) leon_, MBedder ;******************************************************************************* ;------------------------------------------------------------------------------- ; Код для проверки подпрограмм масштабирования: ; .equ dat = 65432 ; Беззнаковое тестовое число .equ sdat = dat/2 ; Знаковое тестовое число .equ coef = int(0.87654*65536) ; Беззнаковый тестовый коэффициент .equ scoef = coef/2 ; Знаковый тестовый коэффициент .cseg scalings: ; Тест 1. Беззнаковые данные, беззнаковый коэффициент и беззнаковый результат: ldi r20,low(dat ) ; Беззнаковые данные в r21r20, ldi r21,high(dat) ldi r22,low(coef) ; Беззнаковый коэффициент в r23r22, ldi r23,high(coef) rcall scale16uu ; Беззнаковый результат будет в r19r18. ; Тест 2. Знаковые данные, беззнаковый коэффициент и знаковый результат: ldi r20,low(-sdat) ; Знаковые данные в r21r20, ldi r21,high(-sdat) ldi r22,low(coef) ; Беззнаковый коэффициент в r23r22, ldi r23,high(coef) rcall scale16su ; Знаковый результат будет в r19r18. ; Тест 3. Беззнаковые данные, знаковый коэффициент и знаковый результат: ldi r20,low(-scoef) ; Знаковый коэффициент в r23r22, ldi r21,high(-scoef) ldi r22,low(dat) ; Безнаковые данные в r21r20, ldi r23,high(dat) rcall scale16su ; Знаковый результат будет в r19r18. ; Тест 4. Знаковые данные, знаковый коэффициент и знаковый результат: ldi r20,low(-sdat) ; Знаковые данные в r21r20, ldi r21,high(-sdat) ldi r22,low(-scoef) ; Знаковый коэффициент в r23r22, ldi r23,high(-scoef) rcall scale16ss ; Знаковый результат будет в r19r18. rjmp scalings ; ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- ; Собственно подпрограммы масштабирования: ; ;------------------------------------------------------------------------------- ; 1. Беззнаковые данные, беззнаковый коэффициент и беззнаковый результат. ; ; r21:r20 - данные в диапазоне 0..65535 ; r23:r22 - коэффициент в диапазоне (0.0..0.99999)*65536 ; r19:r18 - результат в диапазоне 0..65535 ; ; Фактически выполнена операция r19:r18:r17 = r23:r22 * r21:r20, т.е. ; r17 может быть использован для получения более точного результата ; ; 17 слов кода, 20 тактов + ret ; 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) ; Округление sbci r18,high(-128) ; sbci r19,byte3(-128) ; ret ; ;------------------------------------------------------------------------- ;------------------------------------------------------------------------- ; 2. Знаковые данные, беззнаковый коэффициент и знаковый результат: ; ; r21:r20 - данные в диапазоне -32768..+32767 ; r23:r22 - коэффициент в диапазоне (0.00000..0.99999)*65536 ; ; 3. Беззнаковые данные, знаковый коэффициент и знаковый результат: ; ; r21:r20 - коэффициент в диапазоне (-1.0000..+0.99999)*32768 ; r23:r22 - данные в диапазоне 0..65535 ; r19:r18 - результат в диапазоне -32768..+32767 ; ; Фактически выполнена операция r19:r18:r17 = r23:r22 * r21:r20, т.е. ; r17 может быть использован для получения более точного результата ; ; 18 слов кода, 21 такт + ret ; 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) ; Округление sbci r18,high(-128) ; sbci r19,byte3(-128) ; ret ; ;------------------------------------------------------------------------- ;------------------------------------------------------------------------- ; 4. Знаковые данные, знаковый коэффициент и знаковый результат. ; ; r21:r20 - данные в диапазоне -32768..+32767 ; r23:r22 - коэффициент в диапазоне (-1.0000..+0.99999)*32768 ; r19:r18 - результат в диапазоне -32768..+32767 ; ; Фактически выполнена операция r19:r18:r17 = r23:r22 * r21:r20, т.е. ; r17 может быть использован для получения более точного результата ; ; 20 слов кода, 23 такта + ret ; 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) ; Округление sbci r18,high(-128) ; sbci r19,byte3(-128) ; ret ; ;-------------------------------------------------------------------------