MPASM 5.77 PCPWM_3F_4431.ASM 1-25-2019 21:30:30 PAGE 47 LOC OBJECT CODE LINE SOURCE TEXT VALUE 000438 391B M swapf Angle_2+2-1,W,BANKED ; Младший нибл стал младшим в Акб 00043A 0B0F M andlw 0x0F ; чистим старший нибл Акб 00043C 6EF6 M movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла 00043E 391C M swapf Angle_2+2+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб 000440 0BF0 M andlw 0xF0 ; чистим младший нибл Акб 000442 12F6 M iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя 000444 391C M swapf Angle_2+2+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб 000446 0B0F M andlw 0x0F ; чистим старший нибл Акб 000448 6EF7 M movwf TBLPTRH,ACCESS ; Старший нибл в старшем байте указателя. M ;; Итого 12 бит в указателе - 9 команд с пересылкой в указатель таблицы. M ; Но длинна таблицы 11 бит значений - младший бит всегда фиксирован 00044A 90F6 M bcf TBLPTRL,0,ACCESS ; Таблица синусов - двух байтные числа M Add16L TBLPTRL,ACCESS,Table_Sinus ; Начальный адрес таблицы синусов 00044C 0E?? M movlw LOW(Table_Sinus) ; Младший байт 00044E 26F6 M addwf TBLPTRL,F,ACCESS ; ; А + В, результат В=B+A M 000450 0E?? M movlw HIGH(Table_Sinus) ; Старший байт 000452 22F7 M addwfc TBLPTRL+1,F,ACCESS ; и сложим старшие байты - результат в В M ;1) Перемножаем младшие байты: 000454 0009 M tblrd*+ ; Читаем младший байт синуса из таблицы синусов 000456 50F5 M movf TABLAT,W,ACCESS ; Младший байт 16 бит синуса 000458 6F35 M movwf SynMulBuf+7,BANKED; буферируем - будет нужен ниже M 00045A 0344 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт M movff16 PRODL,SynMulBuf ; спасаем результат 00045C CFF3 F12E M movff PRODL,SynMulBuf ; Младший 000460 CFF4 F12F M movff PRODL+1,SynMulBuf+1 ; Старший M 000464 0009 M tblrd*+ ; Читаем старший байт синуса 000466 50F5 M movf TABLAT,W,ACCESS ; Старший байт 16 бит синуса M ;2) Перемножаем старшие байты: 000468 0345 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 M movff16 PRODL,SynMulBuf+2 ; спасаем результат в старшую половину 00046A CFF3 F130 M movff PRODL,SynMulBuf+2 ; Младший 00046E CFF4 F131 M movff PRODL+1,SynMulBuf+2+1 ; Старший M ; Все 4 байта результата инициализированы - можно складывать в серединку. M M ;3) старший Sin на младший Amp, прибавляем к середине результата 000472 0344 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт M M ; ArgB,A1B,ArgA,A1A ; в памяти Младший-Старший идут ; Результат будет B=B+A M Add16 SynMulBuf+1,BANKED,PRODL,ACCESS; Складываем перекрёст с серединкой 000474 50F3 M movf PRODL,W ,ACCESS ; Младший байт 000476 272F M addwf SynMulBuf+1,F,BANKED ; ; А + В, результат В=B+A M 000478 50F4 M movf PRODL+1,W,ACCESS ; Старший байт 00047A 2330 M addwfc SynMulBuf+1+1,F,BANKED ; и сложим старшие байты - результат в В M ;4) Младший Sin на старший Amp, прибавляем к середине результата 00047C 5135 M movf SynMulBuf+7,W,BANKED; буфер Sin младшего 00047E 0345 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт M Add16 SynMulBuf+1,BANKED,PRODL,ACCESS; Складываем перекрёст с серединкой 000480 50F3 M movf PRODL,W ,ACCESS ; Младший байт 000482 272F M addwf SynMulBuf+1,F,BANKED ; ; А + В, результат В=B+A M 000484 50F4 M movf PRODL+1,W,ACCESS ; Старший байт 000486 2330 M addwfc SynMulBuf+1+1,F,BANKED ; и сложим старшие байты - результат в В M 000488 AEF5 M btfss TABLAT,7,ACCESS ; Знак Старший байт 16 бит синуса 00048A D??? M bra ExitMul M ;Sub16 ArgB,A1B,ArgA,A1A ; в памяти Младший-Старший идут ; Результат B=B-A M Sub16 SynMulBuf+2,BANKED,PCPWM_AmpSin+0,BANKED; в соответствии с кодом FXM1616S M ; Результат будет B=B-A 00048C 5144 M movf PCPWM_AmpSin+0,W ,BANKED ; Младший байт 00048E 5F30 M subwf SynMulBuf+2,F,BANKED ; Вычитаем А из В, результат в: В=B-A M 000490 5145 M movf PCPWM_AmpSin+0+1,W,BANKED ; Старший байт 000492 5B31 M subwfb SynMulBuf+2+1,F,BANKED ; и вычтем старшие байты - результат в В M 000494 M ExitMul M ; Отладка показала что здесь имеем знаковое число размаха от 8 355 585/0x7f7f01 до -8 355 585/0x8080FF M ; Для возврата к беззнаковому - надо прибавить эти пол диапазона к результату 000494 0E01 M movlw 0x01; ; Складывание 32 бит результата с константой 0x7f7f01 000496 272E M ADDWF SynMulBuf+0,F,BANKED; младший 000498 0E7F M movlw 0x7F; ; Складывание 32 бит результата с константой 0x7f7f01 00049A 232F M ADDWFC SynMulBuf+1,F,BANKED; средний-1 00049C 0E7F M movlw 0x7F; ; Складывание 32 бит результата с константой 0x7f7f01 00049E 2330 M ADDWFC SynMulBuf+2,F,BANKED; средний-2 M ; Вычитание нижнего порога 1/10 с обнулением при заёме 0004A0 0E99 M movlw low(0xFFFF/0xA);,;,W ,A1A ; Младший байт 10% от 0xFFFF 0004A2 5F2F M subwf SynMulBuf+1,F,BANKED ; Вычитаем А из В, результат в: В=B-A M 0004A4 0E19 M movlw high(0xFFFF/0xA);,;,W,A1A ; Старший байт, 10% от 0xFFFF 0004A6 5B30 M subwfb SynMulBuf+2,F,BANKED ; и вычтем старшие байты - результат в В 0004A8 E3?? M bnc ZeroPoint ;При заёме - обнуление выхода M ; Вычитание удвоенного порога 1/5 с присвоением Макс при отсутствии заёма 0004AA 0ECC M movlw low(0xFFFF-0xFFFF/0x5);,;,W ,A1A ; Младший байт 10% от 0xFFFF 0004AC 5D2F M subwf SynMulBuf+1,W,BANKED ; Вычитаем А из В для сравнения M 0004AE 0ECC M movlw high(0xFFFF-0xFFFF/0x5);,;,W,A1A ; Старший байт, 10% от 0xFFFF 0004B0 5930 M subwfb SynMulBuf+2,W,BANKED ; и вычтем старшие байты - результат в В 0004B2 E2?? M bc MaxPoint ;При отсутствии заёма - Максимальное значение M ; Выходное значение зажато между границами, теперь его надо отмасштабировать из ХХХХ в строго 11 бит нап ример M FXM1680U2 SynMulBuf+4, bnk, SynMulBuf+1, bnk, PCPWM_MK1+0, bnk;, SynMulBuf+0, bnk; Умножаем на коэфф M M ;B_Arg+0=0, выход используется 2 старших байта M ;Выход находится PRODL:PRODH непосредственно M 0004B4 512F M movf SynMulBuf+1+0,w,bnk ; Старший Б х Мл А 0004B6 0321 M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+0 0004B8 CFF4 F132 M movff PRODH,SynMulBuf+4+0 ; Буферируем в нулевой результат M 0004BC 5130 M movf SynMulBuf+1+1,w,bnk ; Старшие байты 0004BE 0321 M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+1 M M ; прибавляем ст байт к 16 бит результату с переносом 0004C0 5132 M movf SynMulBuf+4+0,w,bnk ; Буфер используем 0004C2 26F3 M addwf PRODL,f,ACCESS ; к накопителю результата со смещением в 1 байт 0004C4 6AE8 M clrf WREG,ACCESS ; с учётом переноса 0004C6 22F4 M addwfc PRODH,f,ACCESS ; M 0004C8 CFF3 FF77 M movff PRODL,PDC1L ; Младший модулятор 0004CC CFF4 FF76 M movff PRODH,PDC1L-1 ; Старший модулятор M M 0004D0 D??? M bra Done M 0004D2 M MaxPoint: