MPASM 5.77 RTOS_INTERRUPT.ASM 2-2-2020 17:03:42 PAGE 31 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00103 #include Proj_Dir\PCPWM_3F\Int_PCPWM_3H_x431.inc ; фазные вычислители с 3 гармоникой проба на зуб. 00001 ; Int_PCPWM_3H_x431.inc Include for: 00002 ; Filename: RTOS_Interrupt.asm * 00003 #include Proj_Dir\PCPWM_3F\PDC_3H_Macro.inc;Макросы повторяющегося кода вынес 0000 00004 Extern Tab_Sin3G,Table_Sinus,Tab_SinEnd ; ; Описаны в PcPWM таблицах 00021A 8EA6 00005 BSF EECON1, EEPGD,ACCESS ; Point to PROGRAM memory 00006 00007 ; 1. **** Кусок макроса - преобразование 16 бит адреса в 12 бит, добавлено копирование 00008 ; смещения в буфер для опорной фазы 00009 Con16v12b TBLPTRL,ACCESS,Angle_1+2,BANKED ; Уход от ввода повторяющегося кода M ;; Формируем 12 бит указатель из 16 бит адреса - 9 команд с пересылкой в указатель таблицы. M ; Добавлено буферирование для 3й гармоники в SynAdrH Старший байт адреса таблицы синусов 00021C 3945 M swapf Angle_1+2+0,W,BANKED ; Младший нибл стал младшим в Акб 00021E 0B0F M andlw 0x0F ; чистим старший нибл Акб 000220 6EF6 M movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла 000222 3946 M swapf Angle_1+2+1,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб 000224 0BF0 M andlw 0xF0 ; чистим младший нибл Акб 000226 12F6 M iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя 000228 3946 M swapf Angle_1+2+1,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M 00022A 6F5E M movwf SynAdrH,BANKED; Старший байт адреса таблицы синусов и 3 гармоники тоже 00022C 0B03 M andlw 0x03;0x0F ; чистим старший нибл Акб для 1/4 периода 00022E 6EF7 M movwf TBLPTRH,ACCESS ; Старший нибл в старшем байте указателя. M M ; swapf Angle_8-1,W,BANKED ; Младший нибл стал младшим в Акб M ; andlw 0x0F ; чистим старший нибл Акб M ; movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла M ; swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M ; andlw 0xF0 ; чистим младший нибл Акб M ; iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя M ; swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M ; 00010 ; выше вроде последнее упоминание входного угла тут 00011 00012 ; movwf SynAdrH,BANKED; Старший байт адреса таблицы синусов и 3 гармоники тоже 00013 ; andlw 0x03;0x0F ; чистим старший нибл Акб для 1/4 периода 00014 ; movwf TBLPTRH,ACCESS ; Старший нибл в старшем байте указателя. 000230 6F60 00015 movwf Tbl3GPtrBuf+1,BANKED ; старший байт указателя нужен дважды. 000232 CFF6 F15F 00016 movff TBLPTRL,Tbl3GPtrBuf+0 ; младший байт указателя нужен дважды. 00017 00018 ;2. **** добавка вычислений 3 гармоники 000236 B55E 00019 btfsc SynAdrH,2,BANKED ; 1/4 = Почти Старший бит 12 бит угла 000238 D??? 00020 bra Reverse3G ; Вычитаем смещение из конца 00021 Add16L TBLPTRL,ACCESS,Tab_Sin3G ; Прибавляем смещение к Началу 00023A 0E?? M movlw LOW(Tab_Sin3G) ; Младший байт 00023C 26F6 M addwf TBLPTRL,F,ACCESS ; ; А + В, результат В=B+A M 00023E 0E?? M movlw HIGH(Tab_Sin3G) ; Старший байт M ; btfsc _C ; Если в прошлом Перенос ; Есть готовая M ; incfsz WREG,W,A1A ; Увеличим Старший БАЙТ Слагаемого на 1, ; Команда сложен ия M ; addwf ArgB+1,F,A1B ; и сложим старшие байты - результат в В ; с переносом 000240 22F7 M addwfc TBLPTRL+1,F,ACCESS ; и сложим старшие байты - результат в В 00022 ; адреса таблицы 3 гармо ники 000242 D??? 00023 bra DoneAdr3G 000244 00024 Reverse3G ; Обратное движение с другого конца половины/четверти синусоиды 00025 ; bcf TBLPTRH,3,ACCESS ; Старший бит 12 бит угла 000244 50F6 00026 movf TBLPTRL,W,ACCESS ; 000246 08?? 00027 sublw low(Tab_Sin3G+0x400) ; Из Конца таблицы 000248 6EF6 00028 movwf TBLPTRL,ACCESS ; 00024A 50F7 00029 movf TBLPTRH,W,ACCESS ; Старший байт 00024C A0D8 00030 btfss _C ; Если в прошлом вычитании Заем 00024E 3CE8 00031 incfsz WREG,W,ACCESS ; Увеличим Старший БАЙТ Вычитаемого на 1, 000250 08?? 00032 sublw high(Tab_Sin3G+0x400); ; Из Конца таблицы 000252 6EF7 00033 movwf TBLPTRH,ACCESS ; 000254 00034 DoneAdr3G 000254 0009 00035 tblrd*+ ; Читаем единственный байт синуса из таблицы в защёлку TABLAT 00036 00037 ;3. **** 00038 ; Умножение знакового байта из таблицы на беззнаковую амплитуду 3 гармоники 00039 ; Выходной результат (-127|+127)*(0|16448); В (амплитуда) сохраняется без изменений 00040 ; Результат 3 байта (без старшего) сразу складываем/вычитаем с константой 0x7f7f01 и 00041 ; в выходной буферок MiddlePoint+0,BANKED 00042 ; Имеем 2 знака (половинки периода синуса и знак 3 гармоники) их необходимо перемножить 00043 ; с получением единого результата - прибавлять или вычитать без знаковое произведение 00044 ; (0|127)*(0|16448) к/из константы серединки 0x7f7f01 00045 #define _Sign3G RevCalc_Flag,1,BANKED ;1= Произведение знаков 3й гармоники и угла 00046 ; Минус * минус = дают плюс, два toggle тоже дают плюс. 000256 93BA 00047 bcf _Sign3G ; итоговый знак - 0=прибавлять 1=вычитать 000258 BEF5 00048 btfsc TABLAT,MSB,ACCESS ; Знак из таблицы синуса 00025A 73BA 00049 btg _Sign3G ; 00025C B75E 00050 btfsc SynAdrH,3,BANKED ; Знак из указателя таблицы синуса 00025E 73BA 00051 btg _Sign3G ; 000260 BEF5 00052 btfsc TABLAT,MSB,ACCESS ; Знак из таблицы синуса 000262 6CF5 00053 negf TABLAT,ACCESS ; Sin = -1 * Sin станет положительным 00054 00055 ;4.***** 3 байта результата инициализируем - это 00056 ; постоянная составляющая центра 00057 ; надо немного больше сделать - нижнее ограничение наступает слегка раньше верхнего. 00058 ; Возможно её надо зависеть от амплитуды и DTCON 00059 movlf 0x01,SynMulBuf+0,BANKED ; Инициализация мл 0 байта результата 000264 0E01 M movlw 0x01 ; в регистр с 7р адресом на 000266 6F61 M movwf SynMulBuf+0,BANKED ; текущей странице File7 00060 movlf 0x7F,SynMulBuf+1,BANKED ; Инициализация ср 1 байта результата 000268 0E7F M movlw 0x7F ; в регистр с 7р адресом на 00026A 6F62 M movwf SynMulBuf+1,BANKED ; текущей странице File7 00061 movlf 0x7F,SynMulBuf+2,BANKED ; Инициализация ст 2 байта результата 00026C 0E7F M movlw 0x7F ; в регистр с 7р адресом на 00026E 6F63 M movwf SynMulBuf+2,BANKED ; текущей странице File7 00062 ; Накопитель с константой 0x7f7f01 середины диапазона. 00063 ; Результаты умножения синусов на амплитуду надо 00064 ; либо вычесть из либо прибавить к накопителю 00065 ; в зависимости от произведения знаков в адрес*синус. 00066 00067 ;5. ****** Умножаем гармонику на амплитуду 00068 ;5А перемножаем младшие байты 000270 50F5 00069 movf TABLAT,W,ACCESS ; Единственный положительный байт синуса 000272 0387 00070 mulwf PCPWM_AmpSin3+0,BANKED; МлБ Амплитуды 3й гармоники после вычислений V/F 000274 50F3 00071 movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000276 B3BA 00072 btfsc _Sign3G ; Общий фрагмент до раздвоения 000278 D??? 00073 bra Sub3GFromMiddle ; Вычитаем из средней точки 00027A 2761 00074 addwf SynMulBuf+0,f,BANKED ; Add 00027C 50F4 00075 movf PRODH,W,ACCESS ; products 00027E 2362 00076 addwfc SynMulBuf+1,f,BANKED ; к накопителю результата 00077 ; clrf WREG,ACCESS ; с учётом переноса 00078 ; addwfc MiddlePoint+2,f,BANKED ; Самый старший байт результата 000280 B0D8 00079 btfsc _C ; Без порчи РабРега учёт переноса 000282 2B63 00080 incf SynMulBuf+2,f,BANKED ; Самый старший байт результата 00081 00082 ;5Б Перемножаем младший на старший со смещением 1 байт в середину 000284 50F5 00083 movf TABLAT,W,ACCESS ; Единственный положительный байт синуса 000286 0388 00084 mulwf PCPWM_AmpSin3+1,BANKED; СтБ Амплитуды 3й гармоники после вычислений V/F 000288 50F3 00085 movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 00028A 2762 00086 addwf SynMulBuf+1,f,BANKED ; Add cross 00028C 50F4 00087 movf PRODH,W,ACCESS ; products 00028E 2363 00088 addwfc SynMulBuf+2,f,BANKED ; к накопителю результата со смещением в 1 байт 00089 ; clrf WREG,ACCESS ; с учётом переноса 00090 ; addwfc MiddlePoint+3,f,BANKED ; Самый старший байт результата - будет отброшен 00091 ; *** вроде умножение 3 гармоники на амплитуду и прибавление к константе закончено. 000290 D??? 00092 bra DoneAdd3G2Middle 00093 00094 ;5А-1 000292 00095 Sub3GFromMiddle 000292 5F61 00096 subwf SynMulBuf+0,F,BANKED; младший Subtract WREG from f 000294 50F4 00097 movf PRODH,W,ACCESS ; products 000296 5B62 00098 subwfb SynMulBuf+1,F,BANKED; средний Subtract WREG from f 000298 A0D8 00099 btfss _C ; Инверсный Заём, Без порчи РабРега учёт переноса 00029A 0763 00100 decf SynMulBuf+2,f,BANKED ; Самый старший байт результата 00101 00102 ;5Б-1 00103 ; Перемножаем младший на старший со смещением 1 байт из середины 00029C 50F5 00104 movf TABLAT,W,ACCESS ; Единственный положительный байт синуса 00029E 0388 00105 mulwf PCPWM_AmpSin3+1,BANKED; СтБ Амплитуды 3й гармоники после вычислений V/F 0002A0 50F3 00106 movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 0002A2 5F62 00107 subwf SynMulBuf+1,F,BANKED ; младший Subtract WREG from f 0002A4 50F4 00108 movf PRODH,W,ACCESS ; products 0002A6 5B63 00109 subwfb SynMulBuf+2,F,BANKED ; старший Subtract WREG from f 00110 0002A8 00111 DoneAdd3G2Middle 0002A8 C15F FFF6 00112 movff Tbl3GPtrBuf+0,TBLPTRL ; младший байт указателя таблицы синусов восстановлен. 0002AC C160 FFF7 00113 movff Tbl3GPtrBuf+1,TBLPTRH ; старший байт указателя таблицы синусов восстановлен. 00114 ; для вычисления опорной/основной фазы. 00115 00116 movff24 SynMulBuf,Syn3HBuf ; Буфер вычисленной середины с 3 гармоникой 0002B0 C161 F169 M movff SynMulBuf,Syn3HBuf ; Младший 0002B4 C162 F16A M movff SynMulBuf+1,Syn3HBuf+1 ; 0002B8 C163 F16B M movff SynMulBuf+2,Syn3HBuf+2 ; Старший 00117 00118 ; **** Где-то здесь будет вход в новый макрос фазного вычислителя. 00119 ; На входе - смещение таблицы уже в TBLPTRL, выход - засылаем в ШИМ указанного адреса 00120 Sin2PdcLoad PDC0L ; Выборка из таблицы и засылка в PWM-0 0000 M local ExitMul,Done,ZeroPoint, MaxPoint,Reverse,DoneAdress 0000 M local OvrLoad,OvrLoad1,TopWithoutCharge,BotWithoutPWM 0000 M local SubFromMiddle M ; код выборки таблицы синусов, умножения на амплитуду,складывания/вычитания с накопителем, M ; нормализации до необходимого значение для PCPWM, вывода в модулятор. M ; Выполняется часто - каждая команда дорога. M M ; **** Где-то здесь будет вход в новый макрос фазного вычислителя. M M M ;6. **** Вычисление опорной/первой фазы M ; bcf TBLPTRL,0,ACCESS ; Таблица синусов - ОДНО байтные положительные числа 0002BC B55E M btfsc SynAdrH,2,BANKED ; 1/4 = Почти Старший бит 12 бит угла 0002BE D??? M bra Reverse ; Вычитаем M M Add16L TBLPTRL,ACCESS,Table_Sinus ; Начальный адрес таблицы синусов основной частоты 0002C0 0E?? M movlw LOW(Table_Sinus) ; Младший байт 0002C2 26F6 M addwf TBLPTRL,F,ACCESS ; ; А + В, результат В=B+A M 0002C4 0E?? M movlw HIGH(Table_Sinus) ; Старший байт M ; btfsc _C ; Если в прошлом Перенос ; Есть готовая M ; incfsz WREG,W,A1A ; Увеличим Старший БАЙТ Слагаемого на 1, ; Команда сложен ия M ; addwf ArgB+1,F,A1B ; и сложим старшие байты - результат в В ; с переносом 0002C6 22F7 M addwfc TBLPTRL+1,F,ACCESS ; и сложим старшие байты - результат в В M M ;#ifdef PCPWM_CoSinus; Yes ; Экономия ~2 Кб ПЗУ ценой усложнения фазного вычислителя на ~10 циклов 0002C8 D??? M bra DoneAdress 0002CA M Reverse ; Обратное движение с другого конца половины/четверти синусоиды M ; bcf TBLPTRH,3,ACCESS ; Старший бит 12 бит угла 0002CA 50F6 M movf TBLPTRL,W,ACCESS ; 0002CC 08?? M sublw low(Table_Sinus+0x400) ; Из Конца таблицы 0002CE 6EF6 M movwf TBLPTRL,ACCESS ; 0002D0 50F7 M movf TBLPTRH,W,ACCESS ; Старший байт 0002D2 A0D8 M btfss _C ; Если в прошлом вычитании Заем 0002D4 3CE8 M incfsz WREG,W,ACCESS ; Увеличим Старший БАЙТ Вычитаемого на 1, 0002D6 08?? M sublw high(Table_Sinus+0x400); ; Из Конца таблицы 0002D8 6EF7 M movwf TBLPTRH,ACCESS ; 0002DA M DoneAdress M ; ***** Конец вычисления 1/2 либо 1/4 адреса таблицы M M ;7. ****** Перемножение основного синуса на основную амплитуду с накоплением в M ; 1) Перемножаем младшие байты: 0002DA 0009 M tblrd*+ ; Читаем единственный байт синуса из таблицы 0002DC 50F5 M movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 0002DE 0D08 M mullw 0x08 ; Превращаем синус 8+1 в 12 бит M movff16 PRODL,SynMulBuf+6; буферируем - будет нужно ниже 0002E0 CFF3 F167 M movff PRODL,SynMulBuf+6 ; Младший 0002E4 CFF4 F168 M movff PRODL+1,SynMulBuf+6+1 ; Старший M 0002E8 50F3 M movf PRODL,W,ACCESS ; Младший байт 16 бит синуса 0002EA 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 0002EC 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 0002EE B75E M btfsc SynAdrH,3,BANKED ; 1/4 = Почти Старший бит 12 бит угла 0002F0 D??? M bra SubFromMiddle ; Вычитаем 0002F2 2761 M addwf SynMulBuf+0,f,BANKED ; Add 0002F4 50F4 M movf PRODH,W,ACCESS ; products 0002F6 2362 M addwfc SynMulBuf+1,f,BANKED ; к накопителю результата 0002F8 B0D8 M btfsc _C ; Без порчи РабРега учёт переноса 0002FA 2B63 M incf SynMulBuf+2,f,BANKED ; Самый старший байт результата M M M ; tblrd*+ ; Читаем старший байт синуса M ;7. ****** 2) Перемножаем старшие байты: 0002FC 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 0002FE 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 000300 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000302 2763 M addwf SynMulBuf+2,f,BANKED ; Add M ; movf PRODH,W,ACCESS ; products ; Старши й M ; addwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен M M ; складываем в серединку. M M ;7. ****** 3) старший Sin на младший Amp, прибавляем к середине результата 000304 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 000306 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 000308 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 00030A 2762 M addwf SynMulBuf+1,f,BANKED ; Add 00030C 50F4 M movf PRODH,W,ACCESS ; products 00030E 2363 M addwfc SynMulBuf+2,f,BANKED ; к накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен M M ;7. ****** 4) Младший Sin на старший Amp, прибавляем к середине результата 000310 5167 M movf SynMulBuf+6,W,BANKED; буфер Sin младшего M ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 000312 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт 000314 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000316 2762 M addwf SynMulBuf+1,f,BANKED ; Add 000318 50F4 M movf PRODH,W,ACCESS ; products 00031A 2363 M addwfc SynMulBuf+2,f,BANKED ; к накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен 00031C D??? M bra ExitMul M 00031E M SubFromMiddle ; Вычитаем из накопителя 00031E 5F61 M subwf SynMulBuf+0,f,BANKED ; Subtract WREG from f 000320 50F4 M movf PRODH,W,ACCESS ; products 000322 5B62 M subwfb SynMulBuf+1,f,BANKED ; из накопителя результата 000324 A0D8 M btfss _C ; Инверсный Заём, Без порчи РабРега учёт переноса 000326 0763 M decf SynMulBuf+2,f,BANKED ; Самый старший байт результата M M ; tblrd*+ ; Читаем старший байт синуса M ;7. ****** 2-2) Перемножаем старшие байты: 000328 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 00032A 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 00032C 50F3 M movf PRODL,W,ACCESS ; Старшие байты множим, вычитаем 00032E 5F63 M subwf SynMulBuf+2,f,BANKED ; Subtract WREG from f M ; movf PRODH,W,ACCESS ; products ; Старши й M ; subwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт M ; btfss _C ;Инверсный Заём, Без порчи РабРега учёт переноса; позже M ; decf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен M M ; вычитаем из серединки перекрёстные умножения. M M ;7. ****** 3-2) старший Sin на младший Amp, вычитаем из середки результата 000330 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 000332 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 000334 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, вычитаем 000336 5F62 M subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f 000338 50F4 M movf PRODH,W,ACCESS ; products 00033A 5B63 M subwfb SynMulBuf+2,f,BANKED ; из накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен M M ;7. ****** 4-2) Младший Sin на старший Amp, прибавляем к середине результата 00033C 5167 M movf SynMulBuf+6,W,BANKED; буфер Sin младшего M ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 00033E 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт 000340 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, вычитаем 000342 5F62 M subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f 000344 50F4 M movf PRODH,W,ACCESS ; products 000346 5B63 M subwfb SynMulBuf+2,f,BANKED ; из накопителя результата M 000348 M ExitMul ; Тут в SynMulBuf должно быть положительное число макс амплитудой 23 бит M M ;8. ****** M ; 16 бит выходного значения сравниваем с верхним и нижним порогом ограничителей, M ; присваиваем пороги при пересечении. M ; вычитаем нижний порог для смещения точки 0. M ; Ограниченные 16 бит для превращения в 11-12 бит ШИМ - умножаем на коэффициент 16 бит, M ; результат 32 бита усекаем до 11-12 бит M ; Вычитание нижнего порога 1/10 с обнулением при заёме 000348 0E99 M movlw low(0xFFFF/0xA);,;,W ,A1A ; Младший байт 10% от 0xFFFF 00034A 5F62 M subwf SynMulBuf+1,F,BANKED ; Вычитаем А из В, результат в: В=B-A M 00034C 0E19 M movlw high(0xFFFF/0xA);,;,W,A1A ; Старший байт, 10% от 0xFFFF M ; btfss _C ; Если в прошлом вычитании Заем M ; incfsz ArgA+1,W,A1A ; Увеличим Старший БАЙТ Вычитаемого на 1, 00034E 5B63 M subwfb SynMulBuf+2,F,BANKED ; и вычтем старшие байты - результат в В M M #ifdef PCPWM_Board; Yes ; Плата настольная без периферии/контроля условий запуска M bnc ZeroPoint ;При заёме - выход на минимум для синхро учебной платы M #else 000350 E3?? M bnc BotWithoutPWM;При заёме - обнуление выхода в боевой плате M #endif M M ; Вычитание удвоенного порога 1/5 с присвоением Макс при отсутствии заёма 000352 0ECC M movlw low(0xFFFF-0xFFFF/0x5);,;,W ,A1A ; Младший байт 10% от 0xFFFF 000354 5D62 M subwf SynMulBuf+1,W,BANKED ; Вычитаем А из В для сравнения M 000356 0ECC M movlw high(0xFFFF-0xFFFF/0x5);,;,W,A1A ; Старший байт, 10% от 0xFFFF 000358 5963 M subwfb SynMulBuf+2,W,BANKED ; и вычтем старшие байты - результат в В 00035A E2?? M bc MaxPoint ;При отсутствии заёма - Максимальное значение M M ;9, ***** 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 00035C 5162 M movf SynMulBuf+1+0,w,bnk ; Старший Б х Мл А 00035E 034A M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+0 000360 CFF4 F165 M movff PRODH,SynMulBuf+4+0 ; Буферируем в нулевой результат M 000364 5163 M movf SynMulBuf+1+1,w,bnk ; Старшие байты 000366 034A M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+1 M M ; прибавляем ст байт к 16 бит результату с переносом 000368 5165 M movf SynMulBuf+4+0,w,bnk ; Буфер используем 00036A 26F3 M addwf PRODL,f,ACCESS ; к накопителю результата со смещением в 1 байт 00036C 6AE8 M clrf WREG,ACCESS ; с учётом переноса 00036E 22F4 M addwfc PRODH,f,ACCESS ; 000370 CFF3 FF79 M movff PRODL,PDC0L ; Младший модулятор 000374 CFF4 FF78 M movff PRODH,PDC0L-1 ; Старший модулятор M ; movff SynMulBuf+6,PDC_16L ; Младший модулятор M ; movff SynMulBuf+7,PDC_16L-1 ; Старший модулятор 000378 D??? M bra Done M 00037A M MaxPoint: M ;10. ***** Верхнее ограничение M ;PcPwmPdcMax :2;F,BANKED; Значение PDC верхней полки - не портим M M ; movf DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit 00037A 515B M movf PcPwmTopDT,W,BANKED; Вычитаемое #2 = Интервал времени для заряда конденсаторов при верхней полке 00037C E0?? M bz TopWithoutCharge ; При нулевом времени - ничего не вычитаем 00037E C14C F161 M movff PcPwmPdcMax+1,SynMulBuf+0 ; Буферок старшего байта для заёмов 000382 5D4B M subwf PcPwmPdcMax+0,W,BANKED ; Уменьшаемое, результат в АКБ 000384 A0D8 M btfss _C ; Инверсный заём 000386 0761 M decf SynMulBuf+0,F,BANKED ; Отработка заёма 000388 80D8 M bsf _C ; Чистим инверсный заём 00038A 546D M subfwb DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit M ; Инверсный заём формируем 00038C A0D8 M btfss _C ; Инверсный заём 00038E 0761 M decf SynMulBuf+0,F,BANKED ; Отработка заёма M 000390 6E79 M movwf PDC0L,ACCESS ; Мл.модулятор верхней полки 000392 C161 FF78 M movff SynMulBuf+0,PDC0L-1;,ACCESS ; Ст.модулятор верхней полки M 000396 D??? M bra Done M 000398 M TopWithoutCharge 000398 C14B FF79 M movff PcPwmPdcMax+0,PDC0L;,ACCESS; Мл.модулятор верхней полки 00039C C14C FF78 M movff PcPwmPdcMax+1,PDC0L-1;,ACCESS; Ст.модулятор верхней полки 0003A0 D??? M bra Done M ;11. **** Нижнее ограничение 0003A2 M ZeroPoint: ; Выходное значение =0, пропуск умножения и сравнения верхнего порога M ; Двойной защитный интервал времени PDC - численно равен значению DTCON - по причине вдвое более M ; высокой тактовой генератора DT. M ; В момент равенства PDC=DTCon - наблюдается глюк формирователя DT - одновременное M ; открытие транзисторов на малое время ~ 0.1 мкСек. M ; ***** При этом равенстве глюк модуля формирования DT - *** отсутствие *** защитного интервала.***** M ; Для преодоления глюка - надо программно обеспечить минимальное значение модулятора ВЫШЕ счётчика DT. M ; 0003A2 6B61 M clrf SynMulBuf+0,BANKED ; Буферок старшего байта для переноса 0003A4 515B M movf PcPwmTopDT,W,BANKED; Слагаемое #1 = Интервал времени для заряда конденсаторов при верхней полке 0003A6 E0?? M bz BotWithoutPWM ; При нулевом времени - ничего не складываем 0003A8 246D M addwf DTCON,W,ACCESS ; Слагаемое №2 0003AA B0D8 M btfsc _C ; 0003AC 2B61 M incf SynMulBuf+0,F,BANKED ; Буферок старшего байта для переноса M 0003AE 6E79 M movwf PDC0L,ACCESS ; Младший модулятор 0003B0 C161 FF78 M movff SynMulBuf+0,PDC0L-1;,ACCESS; Ст.модулятор M M M M ; movlf 0x19,PDC_16L,ACCESS ;Отладка Младший модулятор 0003B4 D??? M bra Done 0003B6 M BotWithoutPWM 0003B6 6A79 M clrf PDC0L,ACCESS ; Младший модулятор 0003B8 6A78 M clrf PDC0L-1,ACCESS ;; Старший модулятор M M ;12 **** Конец нового 02/02/2020 макроса 0003BA M Done: M 00121 00122 movff24 Syn3HBuf,SynMulBuf ; Восстановить вычисленную середину с 3 гармоникой 0003BA C169 F161 M movff Syn3HBuf,SynMulBuf ; Младший 0003BE C16A F162 M movff Syn3HBuf+1,SynMulBuf+1 ; 0003C2 C16B F163 M movff Syn3HBuf+2,SynMulBuf+2 ; Старший 00123 Add24S3 Angle_2,BANKED,Angle_1,BANKED,PcPwmAngle_1,BANKED ; D=B+A Прибавляем опорный угол к смещен ию фазы +1/3 оборота M ; Результат будет D=B+A за 3 цикла на байт, А может быть регистром или литералом M ; С учётом НЕ использования младшего байта - он НЕ засылается в приёмник M 0003C6 5154 M movf PcPwmAngle_1+0,W ,BANKED; Младший байт M ; movlw low(ArgA) ; W=A(0) 0003C8 2543 M addwf Angle_1+0,W,BANKED ; W=B+A M ; movwf ArgD+0,A1D ; D=W ; Сугубо в частотнике байт не используется M 0003CA 5155 M movf PcPwmAngle_1+1,W ,BANKED; Средний байт M ; errorlevel -311 ; Убираем Message[311] M ; movlw high(ArgA) ; W=A(1) M ; errorlevel +311 ; Возвращаем Message[311] 0003CC 2144 M addwfc Angle_1+1,W,BANKED ; W=B+A+C 0003CE 6F47 M movwf Angle_2+1,BANKED ; ; D=B+A M 0003D0 5156 M movf PcPwmAngle_1+2,W,BANKED ; Старший байт M ; movlw upper(ArgA) ; W=A(2) 0003D2 2145 M addwfc Angle_1+2,W,BANKED ; W=B+A+C 0003D4 6F48 M movwf Angle_2+2,BANKED ; ; D=B+A 00124 Con16v12b TBLPTRL,ACCESS,Angle_2+2,BANKED ; Уход от ввода повторяющегося кода - смещение в TBLPTR M ;; Формируем 12 бит указатель из 16 бит адреса - 9 команд с пересылкой в указатель таблицы. M ; Добавлено буферирование для 3й гармоники в SynAdrH Старший байт адреса таблицы синусов 0003D6 3948 M swapf Angle_2+2+0,W,BANKED ; Младший нибл стал младшим в Акб 0003D8 0B0F M andlw 0x0F ; чистим старший нибл Акб 0003DA 6EF6 M movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла 0003DC 3949 M swapf Angle_2+2+1,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб 0003DE 0BF0 M andlw 0xF0 ; чистим младший нибл Акб 0003E0 12F6 M iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя 0003E2 3949 M swapf Angle_2+2+1,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M 0003E4 6F5E M movwf SynAdrH,BANKED; Старший байт адреса таблицы синусов и 3 гармоники тоже 0003E6 0B03 M andlw 0x03;0x0F ; чистим старший нибл Акб для 1/4 периода 0003E8 6EF7 M movwf TBLPTRH,ACCESS ; Старший нибл в старшем байте указателя. M M ; swapf Angle_8-1,W,BANKED ; Младший нибл стал младшим в Акб M ; andlw 0x0F ; чистим старший нибл Акб M ; movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла M ; swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M ; andlw 0xF0 ; чистим младший нибл Акб M ; iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя M ; swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M ; 00125 Sin2PdcLoad PDC1L ; Выборка из таблицы и засылка в PWM-1 0000 M local ExitMul,Done,ZeroPoint, MaxPoint,Reverse,DoneAdress 0000 M local OvrLoad,OvrLoad1,TopWithoutCharge,BotWithoutPWM 0000 M local SubFromMiddle M ; код выборки таблицы синусов, умножения на амплитуду,складывания/вычитания с накопителем, M ; нормализации до необходимого значение для PCPWM, вывода в модулятор. M ; Выполняется часто - каждая команда дорога. M M ; **** Где-то здесь будет вход в новый макрос фазного вычислителя. M M M ;6. **** Вычисление опорной/первой фазы M ; bcf TBLPTRL,0,ACCESS ; Таблица синусов - ОДНО байтные положительные числа 0003EA B55E M btfsc SynAdrH,2,BANKED ; 1/4 = Почти Старший бит 12 бит угла 0003EC D??? M bra Reverse ; Вычитаем M M Add16L TBLPTRL,ACCESS,Table_Sinus ; Начальный адрес таблицы синусов основной частоты 0003EE 0E?? M movlw LOW(Table_Sinus) ; Младший байт 0003F0 26F6 M addwf TBLPTRL,F,ACCESS ; ; А + В, результат В=B+A M 0003F2 0E?? M movlw HIGH(Table_Sinus) ; Старший байт M ; btfsc _C ; Если в прошлом Перенос ; Есть готовая M ; incfsz WREG,W,A1A ; Увеличим Старший БАЙТ Слагаемого на 1, ; Команда сложен ия M ; addwf ArgB+1,F,A1B ; и сложим старшие байты - результат в В ; с переносом 0003F4 22F7 M addwfc TBLPTRL+1,F,ACCESS ; и сложим старшие байты - результат в В M M ;#ifdef PCPWM_CoSinus; Yes ; Экономия ~2 Кб ПЗУ ценой усложнения фазного вычислителя на ~10 циклов 0003F6 D??? M bra DoneAdress 0003F8 M Reverse ; Обратное движение с другого конца половины/четверти синусоиды M ; bcf TBLPTRH,3,ACCESS ; Старший бит 12 бит угла 0003F8 50F6 M movf TBLPTRL,W,ACCESS ; 0003FA 08?? M sublw low(Table_Sinus+0x400) ; Из Конца таблицы 0003FC 6EF6 M movwf TBLPTRL,ACCESS ; 0003FE 50F7 M movf TBLPTRH,W,ACCESS ; Старший байт 000400 A0D8 M btfss _C ; Если в прошлом вычитании Заем 000402 3CE8 M incfsz WREG,W,ACCESS ; Увеличим Старший БАЙТ Вычитаемого на 1, 000404 08?? M sublw high(Table_Sinus+0x400); ; Из Конца таблицы 000406 6EF7 M movwf TBLPTRH,ACCESS ; 000408 M DoneAdress M ; ***** Конец вычисления 1/2 либо 1/4 адреса таблицы M M ;7. ****** Перемножение основного синуса на основную амплитуду с накоплением в M ; 1) Перемножаем младшие байты: 000408 0009 M tblrd*+ ; Читаем единственный байт синуса из таблицы 00040A 50F5 M movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 00040C 0D08 M mullw 0x08 ; Превращаем синус 8+1 в 12 бит M movff16 PRODL,SynMulBuf+6; буферируем - будет нужно ниже 00040E CFF3 F167 M movff PRODL,SynMulBuf+6 ; Младший 000412 CFF4 F168 M movff PRODL+1,SynMulBuf+6+1 ; Старший M 000416 50F3 M movf PRODL,W,ACCESS ; Младший байт 16 бит синуса 000418 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 00041A 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 00041C B75E M btfsc SynAdrH,3,BANKED ; 1/4 = Почти Старший бит 12 бит угла 00041E D??? M bra SubFromMiddle ; Вычитаем 000420 2761 M addwf SynMulBuf+0,f,BANKED ; Add 000422 50F4 M movf PRODH,W,ACCESS ; products 000424 2362 M addwfc SynMulBuf+1,f,BANKED ; к накопителю результата 000426 B0D8 M btfsc _C ; Без порчи РабРега учёт переноса 000428 2B63 M incf SynMulBuf+2,f,BANKED ; Самый старший байт результата M M M ; tblrd*+ ; Читаем старший байт синуса M ;7. ****** 2) Перемножаем старшие байты: 00042A 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 00042C 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 00042E 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000430 2763 M addwf SynMulBuf+2,f,BANKED ; Add M ; movf PRODH,W,ACCESS ; products ; Старши й M ; addwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен M M ; складываем в серединку. M M ;7. ****** 3) старший Sin на младший Amp, прибавляем к середине результата 000432 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 000434 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 000436 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000438 2762 M addwf SynMulBuf+1,f,BANKED ; Add 00043A 50F4 M movf PRODH,W,ACCESS ; products 00043C 2363 M addwfc SynMulBuf+2,f,BANKED ; к накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен M M ;7. ****** 4) Младший Sin на старший Amp, прибавляем к середине результата 00043E 5167 M movf SynMulBuf+6,W,BANKED; буфер Sin младшего M ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 000440 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт 000442 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000444 2762 M addwf SynMulBuf+1,f,BANKED ; Add 000446 50F4 M movf PRODH,W,ACCESS ; products 000448 2363 M addwfc SynMulBuf+2,f,BANKED ; к накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен 00044A D??? M bra ExitMul M 00044C M SubFromMiddle ; Вычитаем из накопителя 00044C 5F61 M subwf SynMulBuf+0,f,BANKED ; Subtract WREG from f 00044E 50F4 M movf PRODH,W,ACCESS ; products 000450 5B62 M subwfb SynMulBuf+1,f,BANKED ; из накопителя результата 000452 A0D8 M btfss _C ; Инверсный Заём, Без порчи РабРега учёт переноса 000454 0763 M decf SynMulBuf+2,f,BANKED ; Самый старший байт результата M M ; tblrd*+ ; Читаем старший байт синуса M ;7. ****** 2-2) Перемножаем старшие байты: 000456 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 000458 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 00045A 50F3 M movf PRODL,W,ACCESS ; Старшие байты множим, вычитаем 00045C 5F63 M subwf SynMulBuf+2,f,BANKED ; Subtract WREG from f M ; movf PRODH,W,ACCESS ; products ; Старши й M ; subwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт M ; btfss _C ;Инверсный Заём, Без порчи РабРега учёт переноса; позже M ; decf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен M M ; вычитаем из серединки перекрёстные умножения. M M ;7. ****** 3-2) старший Sin на младший Amp, вычитаем из середки результата 00045E 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 000460 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 000462 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, вычитаем 000464 5F62 M subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f 000466 50F4 M movf PRODH,W,ACCESS ; products 000468 5B63 M subwfb SynMulBuf+2,f,BANKED ; из накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен M M ;7. ****** 4-2) Младший Sin на старший Amp, прибавляем к середине результата 00046A 5167 M movf SynMulBuf+6,W,BANKED; буфер Sin младшего M ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 00046C 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт 00046E 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, вычитаем 000470 5F62 M subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f 000472 50F4 M movf PRODH,W,ACCESS ; products 000474 5B63 M subwfb SynMulBuf+2,f,BANKED ; из накопителя результата M 000476 M ExitMul ; Тут в SynMulBuf должно быть положительное число макс амплитудой 23 бит M M ;8. ****** M ; 16 бит выходного значения сравниваем с верхним и нижним порогом ограничителей, M ; присваиваем пороги при пересечении. M ; вычитаем нижний порог для смещения точки 0. M ; Ограниченные 16 бит для превращения в 11-12 бит ШИМ - умножаем на коэффициент 16 бит, M ; результат 32 бита усекаем до 11-12 бит M ; Вычитание нижнего порога 1/10 с обнулением при заёме 000476 0E99 M movlw low(0xFFFF/0xA);,;,W ,A1A ; Младший байт 10% от 0xFFFF 000478 5F62 M subwf SynMulBuf+1,F,BANKED ; Вычитаем А из В, результат в: В=B-A M 00047A 0E19 M movlw high(0xFFFF/0xA);,;,W,A1A ; Старший байт, 10% от 0xFFFF M ; btfss _C ; Если в прошлом вычитании Заем M ; incfsz ArgA+1,W,A1A ; Увеличим Старший БАЙТ Вычитаемого на 1, 00047C 5B63 M subwfb SynMulBuf+2,F,BANKED ; и вычтем старшие байты - результат в В M M #ifdef PCPWM_Board; Yes ; Плата настольная без периферии/контроля условий запуска M bnc ZeroPoint ;При заёме - выход на минимум для синхро учебной платы M #else 00047E E3?? M bnc BotWithoutPWM;При заёме - обнуление выхода в боевой плате M #endif M M ; Вычитание удвоенного порога 1/5 с присвоением Макс при отсутствии заёма 000480 0ECC M movlw low(0xFFFF-0xFFFF/0x5);,;,W ,A1A ; Младший байт 10% от 0xFFFF 000482 5D62 M subwf SynMulBuf+1,W,BANKED ; Вычитаем А из В для сравнения M 000484 0ECC M movlw high(0xFFFF-0xFFFF/0x5);,;,W,A1A ; Старший байт, 10% от 0xFFFF 000486 5963 M subwfb SynMulBuf+2,W,BANKED ; и вычтем старшие байты - результат в В 000488 E2?? M bc MaxPoint ;При отсутствии заёма - Максимальное значение M M ;9, ***** 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 00048A 5162 M movf SynMulBuf+1+0,w,bnk ; Старший Б х Мл А 00048C 034A M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+0 00048E CFF4 F165 M movff PRODH,SynMulBuf+4+0 ; Буферируем в нулевой результат M 000492 5163 M movf SynMulBuf+1+1,w,bnk ; Старшие байты 000494 034A M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+1 M M ; прибавляем ст байт к 16 бит результату с переносом 000496 5165 M movf SynMulBuf+4+0,w,bnk ; Буфер используем 000498 26F3 M addwf PRODL,f,ACCESS ; к накопителю результата со смещением в 1 байт 00049A 6AE8 M clrf WREG,ACCESS ; с учётом переноса 00049C 22F4 M addwfc PRODH,f,ACCESS ; 00049E CFF3 FF77 M movff PRODL,PDC1L ; Младший модулятор 0004A2 CFF4 FF76 M movff PRODH,PDC1L-1 ; Старший модулятор M ; movff SynMulBuf+6,PDC_16L ; Младший модулятор M ; movff SynMulBuf+7,PDC_16L-1 ; Старший модулятор 0004A6 D??? M bra Done M 0004A8 M MaxPoint: M ;10. ***** Верхнее ограничение M ;PcPwmPdcMax :2;F,BANKED; Значение PDC верхней полки - не портим M M ; movf DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit 0004A8 515B M movf PcPwmTopDT,W,BANKED; Вычитаемое #2 = Интервал времени для заряда конденсаторов при верхней полке 0004AA E0?? M bz TopWithoutCharge ; При нулевом времени - ничего не вычитаем 0004AC C14C F161 M movff PcPwmPdcMax+1,SynMulBuf+0 ; Буферок старшего байта для заёмов 0004B0 5D4B M subwf PcPwmPdcMax+0,W,BANKED ; Уменьшаемое, результат в АКБ 0004B2 A0D8 M btfss _C ; Инверсный заём 0004B4 0761 M decf SynMulBuf+0,F,BANKED ; Отработка заёма 0004B6 80D8 M bsf _C ; Чистим инверсный заём 0004B8 546D M subfwb DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit M ; Инверсный заём формируем 0004BA A0D8 M btfss _C ; Инверсный заём 0004BC 0761 M decf SynMulBuf+0,F,BANKED ; Отработка заёма M 0004BE 6E77 M movwf PDC1L,ACCESS ; Мл.модулятор верхней полки 0004C0 C161 FF76 M movff SynMulBuf+0,PDC1L-1;,ACCESS ; Ст.модулятор верхней полки M 0004C4 D??? M bra Done M 0004C6 M TopWithoutCharge 0004C6 C14B FF77 M movff PcPwmPdcMax+0,PDC1L;,ACCESS; Мл.модулятор верхней полки 0004CA C14C FF76 M movff PcPwmPdcMax+1,PDC1L-1;,ACCESS; Ст.модулятор верхней полки 0004CE D??? M bra Done M ;11. **** Нижнее ограничение 0004D0 M ZeroPoint: ; Выходное значение =0, пропуск умножения и сравнения верхнего порога M ; Двойной защитный интервал времени PDC - численно равен значению DTCON - по причине вдвое более M ; высокой тактовой генератора DT. M ; В момент равенства PDC=DTCon - наблюдается глюк формирователя DT - одновременное M ; открытие транзисторов на малое время ~ 0.1 мкСек. M ; ***** При этом равенстве глюк модуля формирования DT - *** отсутствие *** защитного интервала.***** M ; Для преодоления глюка - надо программно обеспечить минимальное значение модулятора ВЫШЕ счётчика DT. M ; 0004D0 6B61 M clrf SynMulBuf+0,BANKED ; Буферок старшего байта для переноса 0004D2 515B M movf PcPwmTopDT,W,BANKED; Слагаемое #1 = Интервал времени для заряда конденсаторов при верхней полке 0004D4 E0?? M bz BotWithoutPWM ; При нулевом времени - ничего не складываем 0004D6 246D M addwf DTCON,W,ACCESS ; Слагаемое №2 0004D8 B0D8 M btfsc _C ; 0004DA 2B61 M incf SynMulBuf+0,F,BANKED ; Буферок старшего байта для переноса M 0004DC 6E77 M movwf PDC1L,ACCESS ; Младший модулятор 0004DE C161 FF76 M movff SynMulBuf+0,PDC1L-1;,ACCESS; Ст.модулятор M M M M ; movlf 0x19,PDC_16L,ACCESS ;Отладка Младший модулятор 0004E2 D??? M bra Done 0004E4 M BotWithoutPWM 0004E4 6A77 M clrf PDC1L,ACCESS ; Младший модулятор 0004E6 6A76 M clrf PDC1L-1,ACCESS ;; Старший модулятор M M ;12 **** Конец нового 02/02/2020 макроса 0004E8 M Done: M 00126 00127 movff24 Syn3HBuf,SynMulBuf ; Восстановить вычисленную середину с 3 гармоникой 0004E8 C169 F161 M movff Syn3HBuf,SynMulBuf ; Младший 0004EC C16A F162 M movff Syn3HBuf+1,SynMulBuf+1 ; 0004F0 C16B F163 M movff Syn3HBuf+2,SynMulBuf+2 ; Старший 00128 Add24S3 Angle_2,BANKED,Angle_1,BANKED,PcPwmAngle_2,BANKED ; D=B+A Прибавляем опорный угол к смещен ию фазы +2/3 оборота M ; Результат будет D=B+A за 3 цикла на байт, А может быть регистром или литералом M ; С учётом НЕ использования младшего байта - он НЕ засылается в приёмник M 0004F4 5157 M movf PcPwmAngle_2+0,W ,BANKED; Младший байт M ; movlw low(ArgA) ; W=A(0) 0004F6 2543 M addwf Angle_1+0,W,BANKED ; W=B+A M ; movwf ArgD+0,A1D ; D=W ; Сугубо в частотнике байт не используется M 0004F8 5158 M movf PcPwmAngle_2+1,W ,BANKED; Средний байт M ; errorlevel -311 ; Убираем Message[311] M ; movlw high(ArgA) ; W=A(1) M ; errorlevel +311 ; Возвращаем Message[311] 0004FA 2144 M addwfc Angle_1+1,W,BANKED ; W=B+A+C 0004FC 6F47 M movwf Angle_2+1,BANKED ; ; D=B+A M 0004FE 5159 M movf PcPwmAngle_2+2,W,BANKED ; Старший байт M ; movlw upper(ArgA) ; W=A(2) 000500 2145 M addwfc Angle_1+2,W,BANKED ; W=B+A+C 000502 6F48 M movwf Angle_2+2,BANKED ; ; D=B+A 00129 Con16v12b TBLPTRL,ACCESS,Angle_2+2,BANKED ; Уход от ввода повторяющегося кода - смещение в TBLPTR M ;; Формируем 12 бит указатель из 16 бит адреса - 9 команд с пересылкой в указатель таблицы. M ; Добавлено буферирование для 3й гармоники в SynAdrH Старший байт адреса таблицы синусов 000504 3948 M swapf Angle_2+2+0,W,BANKED ; Младший нибл стал младшим в Акб 000506 0B0F M andlw 0x0F ; чистим старший нибл Акб 000508 6EF6 M movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла 00050A 3949 M swapf Angle_2+2+1,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб 00050C 0BF0 M andlw 0xF0 ; чистим младший нибл Акб 00050E 12F6 M iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя 000510 3949 M swapf Angle_2+2+1,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M 000512 6F5E M movwf SynAdrH,BANKED; Старший байт адреса таблицы синусов и 3 гармоники тоже 000514 0B03 M andlw 0x03;0x0F ; чистим старший нибл Акб для 1/4 периода 000516 6EF7 M movwf TBLPTRH,ACCESS ; Старший нибл в старшем байте указателя. M M ; swapf Angle_8-1,W,BANKED ; Младший нибл стал младшим в Акб M ; andlw 0x0F ; чистим старший нибл Акб M ; movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла M ; swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M ; andlw 0xF0 ; чистим младший нибл Акб M ; iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя M ; swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб M ; 00130 Sin2PdcLoad PDC2L ; Выборка из таблицы и засылка в PWM-2 0000 M local ExitMul,Done,ZeroPoint, MaxPoint,Reverse,DoneAdress 0000 M local OvrLoad,OvrLoad1,TopWithoutCharge,BotWithoutPWM 0000 M local SubFromMiddle M ; код выборки таблицы синусов, умножения на амплитуду,складывания/вычитания с накопителем, M ; нормализации до необходимого значение для PCPWM, вывода в модулятор. M ; Выполняется часто - каждая команда дорога. M M ; **** Где-то здесь будет вход в новый макрос фазного вычислителя. M M M ;6. **** Вычисление опорной/первой фазы M ; bcf TBLPTRL,0,ACCESS ; Таблица синусов - ОДНО байтные положительные числа 000518 B55E M btfsc SynAdrH,2,BANKED ; 1/4 = Почти Старший бит 12 бит угла 00051A D??? M bra Reverse ; Вычитаем M M Add16L TBLPTRL,ACCESS,Table_Sinus ; Начальный адрес таблицы синусов основной частоты 00051C 0E?? M movlw LOW(Table_Sinus) ; Младший байт 00051E 26F6 M addwf TBLPTRL,F,ACCESS ; ; А + В, результат В=B+A M 000520 0E?? M movlw HIGH(Table_Sinus) ; Старший байт M ; btfsc _C ; Если в прошлом Перенос ; Есть готовая M ; incfsz WREG,W,A1A ; Увеличим Старший БАЙТ Слагаемого на 1, ; Команда сложен ия M ; addwf ArgB+1,F,A1B ; и сложим старшие байты - результат в В ; с переносом 000522 22F7 M addwfc TBLPTRL+1,F,ACCESS ; и сложим старшие байты - результат в В M M ;#ifdef PCPWM_CoSinus; Yes ; Экономия ~2 Кб ПЗУ ценой усложнения фазного вычислителя на ~10 циклов 000524 D??? M bra DoneAdress 000526 M Reverse ; Обратное движение с другого конца половины/четверти синусоиды M ; bcf TBLPTRH,3,ACCESS ; Старший бит 12 бит угла 000526 50F6 M movf TBLPTRL,W,ACCESS ; 000528 08?? M sublw low(Table_Sinus+0x400) ; Из Конца таблицы 00052A 6EF6 M movwf TBLPTRL,ACCESS ; 00052C 50F7 M movf TBLPTRH,W,ACCESS ; Старший байт 00052E A0D8 M btfss _C ; Если в прошлом вычитании Заем 000530 3CE8 M incfsz WREG,W,ACCESS ; Увеличим Старший БАЙТ Вычитаемого на 1, 000532 08?? M sublw high(Table_Sinus+0x400); ; Из Конца таблицы 000534 6EF7 M movwf TBLPTRH,ACCESS ; 000536 M DoneAdress M ; ***** Конец вычисления 1/2 либо 1/4 адреса таблицы M M ;7. ****** Перемножение основного синуса на основную амплитуду с накоплением в M ; 1) Перемножаем младшие байты: 000536 0009 M tblrd*+ ; Читаем единственный байт синуса из таблицы 000538 50F5 M movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 00053A 0D08 M mullw 0x08 ; Превращаем синус 8+1 в 12 бит M movff16 PRODL,SynMulBuf+6; буферируем - будет нужно ниже 00053C CFF3 F167 M movff PRODL,SynMulBuf+6 ; Младший 000540 CFF4 F168 M movff PRODL+1,SynMulBuf+6+1 ; Старший M 000544 50F3 M movf PRODL,W,ACCESS ; Младший байт 16 бит синуса 000546 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 000548 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 00054A B75E M btfsc SynAdrH,3,BANKED ; 1/4 = Почти Старший бит 12 бит угла 00054C D??? M bra SubFromMiddle ; Вычитаем 00054E 2761 M addwf SynMulBuf+0,f,BANKED ; Add 000550 50F4 M movf PRODH,W,ACCESS ; products 000552 2362 M addwfc SynMulBuf+1,f,BANKED ; к накопителю результата 000554 B0D8 M btfsc _C ; Без порчи РабРега учёт переноса 000556 2B63 M incf SynMulBuf+2,f,BANKED ; Самый старший байт результата M M M ; tblrd*+ ; Читаем старший байт синуса M ;7. ****** 2) Перемножаем старшие байты: 000558 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 00055A 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 00055C 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 00055E 2763 M addwf SynMulBuf+2,f,BANKED ; Add M ; movf PRODH,W,ACCESS ; products ; Старши й M ; addwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен M M ; складываем в серединку. M M ;7. ****** 3) старший Sin на младший Amp, прибавляем к середине результата 000560 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 000562 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 000564 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000566 2762 M addwf SynMulBuf+1,f,BANKED ; Add 000568 50F4 M movf PRODH,W,ACCESS ; products 00056A 2363 M addwfc SynMulBuf+2,f,BANKED ; к накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен M M ;7. ****** 4) Младший Sin на старший Amp, прибавляем к середине результата 00056C 5167 M movf SynMulBuf+6,W,BANKED; буфер Sin младшего M ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 00056E 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт 000570 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, прибавляем 000572 2762 M addwf SynMulBuf+1,f,BANKED ; Add 000574 50F4 M movf PRODH,W,ACCESS ; products 000576 2363 M addwfc SynMulBuf+2,f,BANKED ; к накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен 000578 D??? M bra ExitMul M 00057A M SubFromMiddle ; Вычитаем из накопителя 00057A 5F61 M subwf SynMulBuf+0,f,BANKED ; Subtract WREG from f 00057C 50F4 M movf PRODH,W,ACCESS ; products 00057E 5B62 M subwfb SynMulBuf+1,f,BANKED ; из накопителя результата 000580 A0D8 M btfss _C ; Инверсный Заём, Без порчи РабРега учёт переноса 000582 0763 M decf SynMulBuf+2,f,BANKED ; Самый старший байт результата M M ; tblrd*+ ; Читаем старший байт синуса M ;7. ****** 2-2) Перемножаем старшие байты: 000584 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 000586 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 000588 50F3 M movf PRODL,W,ACCESS ; Старшие байты множим, вычитаем 00058A 5F63 M subwf SynMulBuf+2,f,BANKED ; Subtract WREG from f M ; movf PRODH,W,ACCESS ; products ; Старши й M ; subwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт M ; btfss _C ;Инверсный Заём, Без порчи РабРега учёт переноса; позже M ; decf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен M M ; вычитаем из серединки перекрёстные умножения. M M ;7. ****** 3-2) старший Sin на младший Amp, вычитаем из середки результата 00058C 5168 M movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 00058E 0385 M mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт 000590 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, вычитаем 000592 5F62 M subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f 000594 50F4 M movf PRODH,W,ACCESS ; products 000596 5B63 M subwfb SynMulBuf+2,f,BANKED ; из накопителю результата M ; btfsc _C ; Без порчи РабРега учёт переноса ; позже M ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен M M ;7. ****** 4-2) Младший Sin на старший Amp, прибавляем к середине результата 000598 5167 M movf SynMulBuf+6,W,BANKED; буфер Sin младшего M ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса 00059A 0386 M mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт 00059C 50F3 M movf PRODL,W,ACCESS ; Средние байты множим, вычитаем 00059E 5F62 M subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f 0005A0 50F4 M movf PRODH,W,ACCESS ; products 0005A2 5B63 M subwfb SynMulBuf+2,f,BANKED ; из накопителя результата M 0005A4 M ExitMul ; Тут в SynMulBuf должно быть положительное число макс амплитудой 23 бит M M ;8. ****** M ; 16 бит выходного значения сравниваем с верхним и нижним порогом ограничителей, M ; присваиваем пороги при пересечении. M ; вычитаем нижний порог для смещения точки 0. M ; Ограниченные 16 бит для превращения в 11-12 бит ШИМ - умножаем на коэффициент 16 бит, M ; результат 32 бита усекаем до 11-12 бит M ; Вычитание нижнего порога 1/10 с обнулением при заёме 0005A4 0E99 M movlw low(0xFFFF/0xA);,;,W ,A1A ; Младший байт 10% от 0xFFFF 0005A6 5F62 M subwf SynMulBuf+1,F,BANKED ; Вычитаем А из В, результат в: В=B-A M 0005A8 0E19 M movlw high(0xFFFF/0xA);,;,W,A1A ; Старший байт, 10% от 0xFFFF M ; btfss _C ; Если в прошлом вычитании Заем M ; incfsz ArgA+1,W,A1A ; Увеличим Старший БАЙТ Вычитаемого на 1, 0005AA 5B63 M subwfb SynMulBuf+2,F,BANKED ; и вычтем старшие байты - результат в В M M #ifdef PCPWM_Board; Yes ; Плата настольная без периферии/контроля условий запуска M bnc ZeroPoint ;При заёме - выход на минимум для синхро учебной платы M #else 0005AC E3?? M bnc BotWithoutPWM;При заёме - обнуление выхода в боевой плате M #endif M M ; Вычитание удвоенного порога 1/5 с присвоением Макс при отсутствии заёма 0005AE 0ECC M movlw low(0xFFFF-0xFFFF/0x5);,;,W ,A1A ; Младший байт 10% от 0xFFFF 0005B0 5D62 M subwf SynMulBuf+1,W,BANKED ; Вычитаем А из В для сравнения M 0005B2 0ECC M movlw high(0xFFFF-0xFFFF/0x5);,;,W,A1A ; Старший байт, 10% от 0xFFFF 0005B4 5963 M subwfb SynMulBuf+2,W,BANKED ; и вычтем старшие байты - результат в В 0005B6 E2?? M bc MaxPoint ;При отсутствии заёма - Максимальное значение M M ;9, ***** 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 0005B8 5162 M movf SynMulBuf+1+0,w,bnk ; Старший Б х Мл А 0005BA 034A M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+0 0005BC CFF4 F165 M movff PRODH,SynMulBuf+4+0 ; Буферируем в нулевой результат M 0005C0 5163 M movf SynMulBuf+1+1,w,bnk ; Старшие байты 0005C2 034A M mulwf PCPWM_MK1+0+1,bnk ; B_Arg+1 * A_Arg+1 M M ; прибавляем ст байт к 16 бит результату с переносом 0005C4 5165 M movf SynMulBuf+4+0,w,bnk ; Буфер используем 0005C6 26F3 M addwf PRODL,f,ACCESS ; к накопителю результата со смещением в 1 байт 0005C8 6AE8 M clrf WREG,ACCESS ; с учётом переноса 0005CA 22F4 M addwfc PRODH,f,ACCESS ; 0005CC CFF3 FF75 M movff PRODL,PDC2L ; Младший модулятор 0005D0 CFF4 FF74 M movff PRODH,PDC2L-1 ; Старший модулятор M ; movff SynMulBuf+6,PDC_16L ; Младший модулятор M ; movff SynMulBuf+7,PDC_16L-1 ; Старший модулятор 0005D4 D??? M bra Done M 0005D6 M MaxPoint: M ;10. ***** Верхнее ограничение M ;PcPwmPdcMax :2;F,BANKED; Значение PDC верхней полки - не портим M M ; movf DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit 0005D6 515B M movf PcPwmTopDT,W,BANKED; Вычитаемое #2 = Интервал времени для заряда конденсаторов при верхней полке 0005D8 E0?? M bz TopWithoutCharge ; При нулевом времени - ничего не вычитаем 0005DA C14C F161 M movff PcPwmPdcMax+1,SynMulBuf+0 ; Буферок старшего байта для заёмов 0005DE 5D4B M subwf PcPwmPdcMax+0,W,BANKED ; Уменьшаемое, результат в АКБ 0005E0 A0D8 M btfss _C ; Инверсный заём 0005E2 0761 M decf SynMulBuf+0,F,BANKED ; Отработка заёма 0005E4 80D8 M bsf _C ; Чистим инверсный заём 0005E6 546D M subfwb DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit M ; Инверсный заём формируем 0005E8 A0D8 M btfss _C ; Инверсный заём 0005EA 0761 M decf SynMulBuf+0,F,BANKED ; Отработка заёма M 0005EC 6E75 M movwf PDC2L,ACCESS ; Мл.модулятор верхней полки 0005EE C161 FF74 M movff SynMulBuf+0,PDC2L-1;,ACCESS ; Ст.модулятор верхней полки M 0005F2 D??? M bra Done M 0005F4 M TopWithoutCharge 0005F4 C14B FF75 M movff PcPwmPdcMax+0,PDC2L;,ACCESS; Мл.модулятор верхней полки 0005F8 C14C FF74 M movff PcPwmPdcMax+1,PDC2L-1;,ACCESS; Ст.модулятор верхней полки 0005FC D??? M bra Done M ;11. **** Нижнее ограничение 0005FE M ZeroPoint: ; Выходное значение =0, пропуск умножения и сравнения верхнего порога M ; Двойной защитный интервал времени PDC - численно равен значению DTCON - по причине вдвое более M ; высокой тактовой генератора DT. M ; В момент равенства PDC=DTCon - наблюдается глюк формирователя DT - одновременное M ; открытие транзисторов на малое время ~ 0.1 мкСек. M ; ***** При этом равенстве глюк модуля формирования DT - *** отсутствие *** защитного интервала.***** M ; Для преодоления глюка - надо программно обеспечить минимальное значение модулятора ВЫШЕ счётчика DT. M ; 0005FE 6B61 M clrf SynMulBuf+0,BANKED ; Буферок старшего байта для переноса 000600 515B M movf PcPwmTopDT,W,BANKED; Слагаемое #1 = Интервал времени для заряда конденсаторов при верхней полке 000602 E0?? M bz BotWithoutPWM ; При нулевом времени - ничего не складываем 000604 246D M addwf DTCON,W,ACCESS ; Слагаемое №2 000606 B0D8 M btfsc _C ; 000608 2B61 M incf SynMulBuf+0,F,BANKED ; Буферок старшего байта для переноса M 00060A 6E75 M movwf PDC2L,ACCESS ; Младший модулятор 00060C C161 FF74 M movff SynMulBuf+0,PDC2L-1;,ACCESS; Ст.модулятор M M M M ; movlf 0x19,PDC_16L,ACCESS ;Отладка Младший модулятор 000610 D??? M bra Done 000612 M BotWithoutPWM 000612 6A75 M clrf PDC2L,ACCESS ; Младший модулятор 000614 6A74 M clrf PDC2L-1,ACCESS ;; Старший модулятор M M ;12 **** Конец нового 02/02/2020 макроса 000616 M Done: M 00131 00132 00133 00134 ;DonePwm3H ; 00135 00136 ; call DelayCuriosity ; Исследование запаса по быстродействию обработчика