; 25/01/2020 ; DeBug 8+1 bit ; Код из Help отладки симулятор USART ; bcf TRISC,6 ; Make RC6 an output ; movlw 19h ; 9600 baud @4MHz movlw 0x01 ; Много/Максимум baud @ 48 MHz для симулятора movwf SPBRG,ACCESS ; bsf TXSTA,TXEN,ACCESS ; Enable transmit bsf TXSTA,BRGH,ACCESS ; Select high baud rate bsf BAUDCTL,BRG16,ACCESS; Select 16 бит режим генератора baud rate ; Примерно 400-500 кбит при тактовой 50 МГц bsf RCSTA,SPEN,ACCESS ; Enable Serial Port bsf RCSTA,CREN,ACCESS ; Enable continuous reception ; Extern Table_Sinus PCPWM_Page ; BSR for PCPWM Task movlf 0x3A,DeBug_BufLcd+9,BANKED; Порог перехода от 9 к А в знакогенераторе. ; movlf 0x0,PCPWM_MK1+0,BANKED; Мл. Байт Множителя масштабирования для 12 бит ; movlf 0x14,PCPWM_MK1+1,BANKED; Ст. Байт Множителя масштабирования для 12 бит movlf 0x50,DeBug_Counter,BANKED; Отладочный счётчик единичных приращений амплитуды clrf PCPWM_AmpSin+0,BANKED ; Буфер Амплитуды синусоиды после вычислений V/F младший байт clrf PCPWM_AmpSin+1,BANKED ; clrf PCPWM_AmpSin3+0,BANKED ; Амплитуда 3й гармоники после вычислений V/F clrf PCPWM_AmpSin3+1,BANKED ; Амплитуда 3й гармоники после вычислений V/F bra DeBugLoopAmp ; Ненавязчивая добавка 0x0D к каждому 0x0A в выходном потоке - заставила передавать текстом ; вместо двоичных значений. HexNibSend andlw 0x0F ; чистим старший нибл Акб addlw 0x30 ; cpfsgt DeBug_BufLcd+9,BANKED; Пропуск если Порог9 > WREG addlw 0x7 ; иначе Прибавляем смещение до А ByteSend movwf TXREG,ACCESS ; nop ; Время для установки флагов USART ; btfss PIR1,TXIF,ACCESS ; Флаг прерывания от USART btfss TXSTA,TRMT,ACCESS ; Флаг пустого буфера передачи bra $-2 ; return SendHexWord macro ArgA,Adr1,Lit1 ; 23/01/2020 вроде не должен портить аргумент - портит лишь РабРег. movlw Lit1 ; Разделитель полей в выходном файле rcall ByteSend ; разделитель swapf ArgA+1,W,Adr1 ; Порядок выдачи - rcall HexNibSend ; первыми старшие разряды movf ArgA+1,W,Adr1 ; rcall HexNibSend ; второй старший разряд swapf ArgA+0,W,Adr1 ; rcall HexNibSend ; третий разряд movf ArgA+0,W,Adr1 ; rcall HexNibSend ; младший разряд endm DeBugLoopAmp: EXTERN PDC_TableLoad ; call PDC_TableLoad ; clrf DeBug_BufLcd+0,BANKED ; Отладочный переполняющийся clrf DeBug_BufLcd+1,BANKED ; 16 бит счетчик ; movlw 0x0D ; Разделитель полей в выходном файле ; rcall ByteSend ; разделитель movlw 0x0A ; Разделитель полей в выходном файле rcall ByteSend ; разделитель SendHexWord PCPWM_AmpSin+0,BANKED,"%" ; =====0====== PCPWM_AmpSin+0,BANKED ; Буфер Амплитуды синусоиды после вычислений V/F SendHexWord PCPWM_AmpSin3+0,BANKED,"@" ; =====0====== PCPWM_AmpSin3+0,BANKED ; Буфер Амплитуды 3 гармоники после вычислений V/F DeBugLoop: movlw ";";0x0D ; Разделитель полей в выходном файле rcall ByteSend ; разделитель movlw 0x0A ; Разделитель полей в выходном файле rcall ByteSend ; разделитель ; ============ Присваивание полей макроса реальным именам ============= PDC_16L equ PDC0L ; PDC_16H equ PDC0H ; Angle_8 equ DeBug_BufLcd+1 ; BSF EECON1, EEPGD,ACCESS ; Point to PROGRAM memory NotSendSinus ; Сразу по 2 штуки увеличиваем ; Inc16 DeBug_BufLcd+0,BANKED ; Отладочный переполняющийся Add16L DeBug_BufLcd+0,BANKED,0x10 ; накопитель угла ; movf DeBug_BufLcd+1,W,BANKED ; 12 бит счетчик ; andlw 0xF0 ; чистим младший нибл Акб ; bz $+6 ; Через GoTo bnc $+6 ; Через GoTo goto EndDeBugLoop ; ; movf DeBug_BufLcd+1,W,BANKED ; 12 бит счетчик ; andlw 0x0F ; чистим старший нибл Акб ; movwf DeBug_BufLcd+1,BANKED ; для выборки синуса ; movwf TBLPTRH,ACCESS ; при отладке ; movff DeBug_BufLcd+0,TBLPTRL ; ; ; btfss TBLPTRL,0,ACCESS ; Таблица синусов - двух байтные числа ; bra NotSendSinus ; =========== Код кусков макроса начинается здесь (всё кроме отладочного вывода в УСАРТ) ;; Формируем 12 бит указатель из 16 бит адреса - 9 команд с пересылкой в указатель таблицы. ; Добавлено буферирование для 3й гармоники swapf Angle_8-1,W,BANKED ; Младший нибл стал младшим в Акб andlw 0x0F ; чистим старший нибл Акб movwf TBLPTRL,ACCESS ; Буферизуем результат младшего нибла swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб andlw 0xF0 ; чистим младший нибл Акб iorwf TBLPTRL,F,ACCESS ; Средний нибл в младшем байте указателя swapf Angle_8+0,W,BANKED ; Старший байт адреса с поменянными ниблами в Акб movwf SynAdrH,BANKED; Старший байт адреса таблицы синусов и 3 гармоники тоже andlw 0x03;0x0F ; чистим старший нибл Акб для 1/4 периода movwf TBLPTRH,ACCESS ; Старший нибл в старшем байте указателя. movwf Tbl3GPtrBuf+1,BANKED ; старший байт указателя нужен дважды. movff TBLPTRL,Tbl3GPtrBuf+0 ; младший байт указателя нужен дважды. ;**************************************************************************************** ; SendHexWord DeBug_BufLcd+0,BANKED,"&";=====00====== movff TBLPTRL+0,DeBug_BufLcd+2 movff SynAdrH,DeBug_BufLcd+3 SendHexWord DeBug_BufLcd+2,BANKED,"&"; Вход счетчик угла 12 бит ; SendHexWord DeBug_BufLcd+0,BANKED,"#";=====1====== Номер таблицы синуса старый SendHexWord TBLPTRL+0,ACCESS,"#"; Номер таблицы синуса новый с проверкой конвертатора ;**************************************************************************************** ;**** добавка вычислений 3 гармоники btfsc SynAdrH,2,BANKED ; 1/4 = Почти Старший бит 12 бит угла bra Reverse3G ; Вычитаем смещение из конца Add16L TBLPTRL,ACCESS,Tab_Sin3G ; Прибавляем смещение к Началу ; адреса таблицы 3 гармоники bra DoneAdr3G Reverse3G ; Обратное движение с другого конца половины/четверти синусоиды ; bcf TBLPTRH,3,ACCESS ; Старший бит 12 бит угла movf TBLPTRL,W,ACCESS ; sublw low(Tab_Sin3G+0x400) ; Из Конца таблицы movwf TBLPTRL,ACCESS ; movf TBLPTRH,W,ACCESS ; Старший байт btfss _C ; Если в прошлом вычитании Заем incfsz WREG,W,ACCESS ; Увеличим Старший БАЙТ Вычитаемого на 1, sublw high(Tab_Sin3G+0x400); Из Конца таблицы movwf TBLPTRH,ACCESS ; DoneAdr3G tblrd*+ ; Читаем единственный байт синуса из таблицы в защёлку TABLAT ;**************************************************************************************** ;=====0====== movff TABLAT,DeBug_BufLcd+2 ; clrf DeBug_BufLcd+3,BANKED ; btfsc TABLAT,MSB,ACCESS ; расширение setf DeBug_BufLcd+3,BANKED ; знака SendHexWord DeBug_BufLcd+2,BANKED,"~";=====0====== выход таблицы 3 гармоники со знаком ;**************************************************************************************** ; Умножение знакового байта из таблицы на беззнаковую амплитуду 3 гармоники ; Выходной результат (-127|+127)*(0|16448); В (амплитуда) сохраняется без изменений ; Результат 3 байта (без старшего) сразу складываем/вычитаем с константой 0x7f7f01 и ; в выходной буферок MiddlePoint+0,BANKED ; Имеем 2 знака (половинки периода синуса и знак 3 гармоники) их необходимо перемножить ; с получением единого результата - прибавлять или вычитать без знаковое произведение ; (0|127)*(0|16448) к/из константы серединки 0x7f7f01 #define _Sign3G RevCalc_Flag,1,BANKED ;1= Произведение знаков 3й гармоники и угла ; Минус * минус = дают плюс, два toggle тоже дают плюс. bcf _Sign3G ; итоговый знак - 0=прибавлять 1=вычитать btfsc TABLAT,MSB,ACCESS ; Знак из таблицы синуса btg _Sign3G ; btfsc SynAdrH,3,BANKED ; Знак из указателя таблицы синуса btg _Sign3G ; btfsc TABLAT,MSB,ACCESS ; Знак из таблицы синуса negf TABLAT,ACCESS ; Sin = -1 * Sin станет положительным ; 3 байта результата инициализируем - это постоянная составляющая центра ; надо немного больше сделать - нижнее ограничение наступает слегка раньше верхнего. ; Возможно её надо зависеть от амплитуды и DTCON movlf 0x01,SynMulBuf+0,BANKED ; Инициализация мл 0 байта результата movlf 0x7F,SynMulBuf+1,BANKED ; Инициализация ср 1 байта результата movlf 0x7F,SynMulBuf+2,BANKED ; Инициализация ст 2 байта результата ; Накопитель с константой 0x7f7f01 середины диапазона. ; Результаты умножения синусов на амплитуду надо ; либо вычесть из либо прибавить к накопителю ; в зависимости от произведения знаков в адрес*синус. ; Умножаем гармонику на амплитуду ; перемножаем младшие байты movf TABLAT,W,ACCESS ; Единственный положительный байт синуса mulwf PCPWM_AmpSin3+0,BANKED; МлБ Амплитуды 3й гармоники после вычислений V/F movf PRODL,W,ACCESS ; Средние байты множим, прибавляем btfsc _Sign3G ; Общий фрагмент до раздвоения bra Sub3GFromMiddle ; Вычитаем из средней точки addwf SynMulBuf+0,f,BANKED ; Add movf PRODH,W,ACCESS ; products addwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; clrf WREG,ACCESS ; с учётом переноса ; addwfc MiddlePoint+2,f,BANKED ; Самый старший байт результата btfsc _C ; Без порчи РабРега учёт переноса incf SynMulBuf+2,f,BANKED ; Самый старший байт результата ; Перемножаем младший на старший со смещением 1 байт в середину movf TABLAT,W,ACCESS ; Единственный положительный байт синуса mulwf PCPWM_AmpSin3+1,BANKED; СтБ Амплитуды 3й гармоники после вычислений V/F movf PRODL,W,ACCESS ; Средние байты множим, прибавляем addwf SynMulBuf+1,f,BANKED ; Add cross movf PRODH,W,ACCESS ; products addwfc SynMulBuf+2,f,BANKED ; к накопителю результата со смещением в 1 байт ; clrf WREG,ACCESS ; с учётом переноса ; addwfc MiddlePoint+3,f,BANKED ; Самый старший байт результата - будет отброшен ; *** вроде умножение 3 гармоники на амплитуду и прибавление к константе закончено. bra DoneAdd3G2Middle Sub3GFromMiddle subwf SynMulBuf+0,F,BANKED; младший Subtract WREG from f movf PRODH,W,ACCESS ; products subwfb SynMulBuf+1,F,BANKED; средний Subtract WREG from f btfss _C ; Инверсный Заём, Без порчи РабРега учёт переноса decf SynMulBuf+2,f,BANKED ; Самый старший байт результата ; Перемножаем младший на старший со смещением 1 байт из середины movf TABLAT,W,ACCESS ; Единственный положительный байт синуса mulwf PCPWM_AmpSin3+1,BANKED; СтБ Амплитуды 3й гармоники после вычислений V/F movf PRODL,W,ACCESS ; Средние байты множим, прибавляем subwf SynMulBuf+1,F,BANKED ; младший Subtract WREG from f movf PRODH,W,ACCESS ; products subwfb SynMulBuf+2,F,BANKED ; старший Subtract WREG from f DoneAdd3G2Middle movff Tbl3GPtrBuf+0,TBLPTRL ; младший байт указателя таблицы синусов восстановлен. movff Tbl3GPtrBuf+1,TBLPTRH ; старший байт указателя таблицы синусов восстановлен. ; для вычисления опорной/основной фазы. ;**** ;--- ; btfss TBLPTRL,0,ACCESS ; Таблица синусов - двух байтные числа ; bra NotSendSinus ; Отладочные строки - в макросе их нет ;--- ; bcf TBLPTRL,0,ACCESS ; Таблица синусов - ОДНО байтные положительные числа btfsc SynAdrH,2,BANKED ; 1/4 = Почти Старший бит 12 бит угла bra Reverse ; Вычитаем Add16L TBLPTRL,ACCESS,Table_Sinus ; Начальный адрес таблицы синусов основной частоты ;#ifdef PCPWM_CoSinus; Yes ; Экономия ~2 Кб ПЗУ ценой усложнения фазного вычислителя на ~10 циклов bra DoneAdress Reverse ; Обратное движение с другого конца половины/четверти синусоиды ; bcf TBLPTRH,3,ACCESS ; Старший бит 12 бит угла movf TBLPTRL,W,ACCESS ; sublw low(Table_Sinus+0x400) ; Из Конца таблицы movwf TBLPTRL,ACCESS ; movf TBLPTRH,W,ACCESS ; Старший байт btfss _C ; Если в прошлом вычитании Заем incfsz WREG,W,ACCESS ; Увеличим Старший БАЙТ Вычитаемого на 1, sublw high(Table_Sinus+0x400); Из Конца таблицы movwf TBLPTRH,ACCESS ; DoneAdress ; ***** Конец попытки укоротить таблицу вдвое ;1) Перемножаем младшие байты: tblrd*+ ; Читаем единственный байт синуса из таблицы movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса mullw 0x08 ; Превращаем синус 8+1 в 12 бит movff16 PRODL,SynMulBuf+6; буферируем - будет нужно ниже ;**************************************************************************************** ; movff16 PRODL,DeBug_BufLcd+6;,BANKED; ******** Отладка USART ; movwf DeBug_BufLcd+7,BANKED; ******** Отладка USART ; clrf DeBug_BufLcd+7,BANKED; ******** Отладка USART SendHexWord PRODL,ACCESS,"=" ;=====2====== Значение основного синуса из таблицы ;**************************************************************************************** movf PRODL,W,ACCESS ; Младший байт 16 бит синуса mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт movf PRODL,W,ACCESS ; Средние байты множим, прибавляем btfsc SynAdrH,3,BANKED ; 1/4 = Почти Старший бит 12 бит угла bra SubFromMiddle ; Вычитаем addwf SynMulBuf+0,f,BANKED ; Add movf PRODH,W,ACCESS ; products addwfc SynMulBuf+1,f,BANKED ; к накопителю результата btfsc _C ; Без порчи РабРега учёт переноса incf SynMulBuf+2,f,BANKED ; Самый старший байт результата ; tblrd*+ ; Читаем старший байт синуса ;2) Перемножаем старшие байты: movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 movf PRODL,W,ACCESS ; Средние байты множим, прибавляем addwf SynMulBuf+2,f,BANKED ; Add ; movf PRODH,W,ACCESS ; products ; Старший ; addwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт ; btfsc _C ; Без порчи РабРега учёт переноса ; позже ; incf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен ; складываем в серединку. ;3) старший Sin на младший Amp, прибавляем к середине результата movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт movf PRODL,W,ACCESS ; Средние байты множим, прибавляем addwf SynMulBuf+1,f,BANKED ; Add movf PRODH,W,ACCESS ; products addwfc SynMulBuf+2,f,BANKED ; к накопителю результата ; btfsc _C ; Без порчи РабРега учёт переноса ; позже ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен ;4) Младший Sin на старший Amp, прибавляем к середине результата movf SynMulBuf+6,W,BANKED; буфер Sin младшего ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт movf PRODL,W,ACCESS ; Средние байты множим, прибавляем addwf SynMulBuf+1,f,BANKED ; Add movf PRODH,W,ACCESS ; products addwfc SynMulBuf+2,f,BANKED ; к накопителю результата ; btfsc _C ; Без порчи РабРега учёт переноса ; позже ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен bra ExitMul SubFromMiddle ; Вычитаем из накопителя subwf SynMulBuf+0,f,BANKED ; Subtract WREG from f movf PRODH,W,ACCESS ; products subwfb SynMulBuf+1,f,BANKED ; из накопителя результата btfss _C ; Инверсный Заём, Без порчи РабРега учёт переноса decf SynMulBuf+2,f,BANKED ; Самый старший байт результата ; tblrd*+ ; Читаем старший байт синуса ;2) Перемножаем старшие байты: movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старший байт <0x10 movf PRODL,W,ACCESS ; Старшие байты множим, вычитаем subwf SynMulBuf+2,f,BANKED ; Subtract WREG from f ; movf PRODH,W,ACCESS ; products ; Старший ; subwfc SynMulBuf+1,f,BANKED ; к накопителю результата ; байт ; btfss _C ;Инверсный Заём, Без порчи РабРега учёт переноса; позже ; decf SynMulBuf+2,f,BANKED ; Самый старший байт ; отброшен ; вычитаем из серединки перекрёстные умножения. ;3) старший Sin на младший Amp, вычитаем из середки результата movf SynMulBuf+7,W,BANKED ; Старший байт 16 бит синуса <0x10 mulwf PCPWM_AmpSin+0,BANKED; Буфер Амплитуды синусоиды после вычислений V/F младший байт movf PRODL,W,ACCESS ; Средние байты множим, вычитаем subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f movf PRODH,W,ACCESS ; products subwfb SynMulBuf+2,f,BANKED ; из накопителю результата ; btfsc _C ; Без порчи РабРега учёт переноса ; позже ; incf SynMulBuf+3,f,BANKED ; Самый старший байт ; отброшен ;4) Младший Sin на старший Amp, прибавляем к середине результата movf SynMulBuf+6,W,BANKED; буфер Sin младшего ;movf TABLAT,W,ACCESS ; Единственный байт 8+1 бит синуса mulwf PCPWM_AmpSin+1,BANKED; Буфер Амплитуды синусоиды старшой байт movf PRODL,W,ACCESS ; Средние байты множим, вычитаем subwf SynMulBuf+1,f,BANKED ; Subtract WREG from f movf PRODH,W,ACCESS ; products subwfb SynMulBuf+2,f,BANKED ; из накопителя результата ExitMul ; Тут должно быть положительное число макс амплитудой 23 бит ;#ifdef __DEBUG;******* отладчик АКБ покажет ; movf SynMulBuf+0,W,BANKED; Результат вычислений младший байт ; movf SynMulBuf+1,W,BANKED; Результат средний0 байт ; movf SynMulBuf+2,W,BANKED; Результат средний1 байт ; movf SynMulBuf+3,W,BANKED; старший байт всегда = 0 должен быть ; #endif ;**************************************************************************************** SendHexWord SynMulBuf+1,BANKED,"*" ; =====3====== Значение синусов * Амплитуды со средней точкой без знака ;**************************************************************************************** ; 16 бит выходного значения сравниваем с верхним и нижним порогом ограничителей, присваиваем пороги при пересечении. ; вычитаем нижний порог для смещения точки 0. ; Ограниченные 16 бит для превращения в 11-12 бит ШИМ - умножаем на коэффициент 16 бит, ; результат 32 бита усекаем до 11-12 бит ; Вычитание нижнего порога 1/10 с обнулением при заёме movlw low(0xFFFF/0xA);,W ,A1A ; Младший байт 10% от 0xFFFF subwf SynMulBuf+1,F,BANKED ; Вычитаем А из В, результат в: В=B-A movlw high(0xFFFF/0xA);,W,A1A ; Старший байт, 10% от 0xFFFF ; btfss _C ; Если в прошлом вычитании Заем ; incfsz ArgA+1,W,A1A ; Увеличим Старший БАЙТ Вычитаемого на 1, subwfb SynMulBuf+2,F,BANKED ; и вычтем старшие байты - результат в В #ifdef PCPWM_Board; Yes ; Плата настольная без периферии/контроля условий запуска bnc ZeroPoint ;При заёме - выход на минимум для синхро учебной платы #else bnc BotWithoutPWM;При заёме - обнуление выхода в боевой плате #endif ; Вычитание удвоенного порога 1/5 с присвоением Макс при отсутствии заёма movlw low(0xFFFF-0xFFFF/0x5);,W ,A1A ; Младший байт 10% от 0xFFFF subwf SynMulBuf+1,W,BANKED ; Вычитаем А из В для сравнения movlw high(0xFFFF-0xFFFF/0x5);,W,A1A ; Старший байт, 10% от 0xFFFF subwfb SynMulBuf+2,W,BANKED ; и вычтем старшие байты - результат в В bc MaxPoint ;При отсутствии заёма - Максимальное значение ;**************************************************************************************** SendHexWord SynMulBuf+1,BANKED,"+" ; =====4====== Зажатое / ограниченног Значение синус * Амплитуду без знака ;**************************************************************************************** ; Выходное значение зажато между границами, теперь его надо отмасштабировать из ХХХХ в строго 11 бит например FXM1680U2 SynMulBuf+4, bnk, SynMulBuf+1, bnk, PCPWM_MK1+0, bnk;, SynMulBuf+0, bnk; Умножаем на коэфф movff PRODL,PDC_16L ; Младший модулятор movff PRODH,PDC_16L-1 ; Старший модулятор ; movff SynMulBuf+6,PDC_16L ; Младший модулятор ; movff SynMulBuf+7,PDC_16L-1 ; Старший модулятор ;**************************************************************************************** movff PRODL,DeBug_BufLcd+4 ; Младший модулятор movff PRODH,DeBug_BufLcd+5 ; Старший модулятор ;**************************************************************************************** bra Done MaxPoint: ; 05/01/2019 отлаживал верхнюю полку на осциллограммах подробно ; В момент равенства PDC=4*PTPer-DTCon - наблюдается глюк формирователя DT - одновременное ; открытие транзисторов на малое время ~ 0.1 мкСек. ;PcPwmPdcMax :2;F,BANKED; Значение PDC верхней полки - не портим ; movf DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit movf PcPwmTopDT,W,BANKED; Вычитаемое #2 = Интервал времени для заряда конденсаторов при верхней полке bz TopWithoutCharge ; При нулевом времени - ничего не вычитаем movff PcPwmPdcMax+1,SynMulBuf+0 ; Буферок старшего байта для заёмов subwf PcPwmPdcMax+0,W,BANKED ; Уменьшаемое, результат в АКБ btfss _C ; Инверсный заём decf SynMulBuf+0,F,BANKED ; Отработка заёма bsf _C ; Чистим инверсный заём subfwb DTCON,W,ACCESS ; Вычитаемое #1 - Dead Time Unit ; Инверсный заём формируем btfss _C ; Инверсный заём decf SynMulBuf+0,F,BANKED ; Отработка заёма movwf PDC_16L,ACCESS ; Мл.модулятор верхней полки movff SynMulBuf+0,PDC_16L-1;,ACCESS ; Ст.модулятор верхней полки ;**************************************************************************************** movwf DeBug_BufLcd+4,BANKED; Мл.модулятор верхней полки в УСАРТ movff SynMulBuf+0,DeBug_BufLcd+5;,BANKED; Ст.модулятор верхней полки в УСАРТ ;**************************************************************************************** bra Done TopWithoutCharge movff PcPwmPdcMax+0,PDC_16L;,ACCESS; Мл.модулятор верхней полки movff PcPwmPdcMax+1,PDC_16L-1;,ACCESS; Ст.модулятор верхней полки ;**************************************************************************************** movff PcPwmPdcMax+0,DeBug_BufLcd+4;,BANKED; Мл.модулятор верхней полки в УСАРТ movff PcPwmPdcMax+1,DeBug_BufLcd+5;,BANKED; Ст.модулятор верхней полки в УСАРТ ;**************************************************************************************** bra Done ZeroPoint: ; Выходное значение =0, пропуск умножения и сравнения верхнего порога ; Двойной защитный интервал времени PDC - численно равен значению DTCON - по причине вдвое более ; высокой тактовой генератора DT. ; В момент равенства PDC=DTCon - наблюдается глюк формирователя DT - одновременное ; открытие транзисторов на малое время ~ 0.1 мкСек. ; ***** При этом равенстве глюк модуля формирования DT - *** отсутствие *** защитного интервала.***** ; Для преодоления глюка - надо программно обеспечить минимальное значение модулятора ВЫШЕ счётчика DT. ; clrf SynMulBuf+0,BANKED ; Буферок старшего байта для переноса movf PcPwmTopDT,W,BANKED; Слагаемое #1 = Интервал времени для заряда конденсаторов при верхней полке bz BotWithoutPWM ; При нулевом времени - ничего не складываем addwf DTCON,W,ACCESS ; Слагаемое №2 btfsc _C ; incf SynMulBuf+0,F,BANKED ; Буферок старшего байта для переноса movwf PDC_16L,ACCESS ; Младший модулятор movff SynMulBuf+0,PDC_16L-1;,ACCESS; Ст.модулятор ;**************************************************************************************** movwf DeBug_BufLcd+4,BANKED; Мл.модулятор ZeroPoint в УСАРТ movff SynMulBuf+0,DeBug_BufLcd+5;,BANKED; Ст.модулятор ZeroPoint в УСАРТ ;**************************************************************************************** ; movlf 0x19,PDC_16L,ACCESS ;Отладка Младший модулятор bra Done BotWithoutPWM clrf PDC_16L,ACCESS ; Младший модулятор clrf PDC_16L-1,ACCESS ;; Старший модулятор ;**************************************************************************************** clrf DeBug_BufLcd+4,BANKED ; Младший модулятор clrf DeBug_BufLcd+5,BANKED ; Старший модулятор ;**************************************************************************************** Done: ;**************************************************************************************** ; 23/01/2020 Есть мнение что при чтении модулятора в симуляторе МпЛаб - байты меняются местами ; movff PDC_16L,DeBug_BufLcd+4 ; Младший модулятор ; movff PDC_16L-1,DeBug_BufLcd+5 ; Старший модулятор SendHexWord DeBug_BufLcd+4,BANKED,"$";=====5====== Значение в PDC ;**************************************************************************************** goto DeBugLoop ; SinTabLdDbg Angle_1+2,PDC0L ; номер элемента и адрес куда заслать EndDeBugLoop ; Отладочное увеличение амплитуды. decfsz DeBug_Counter,F,BANKED; отладочный счетчик ед приращений bra Inc16Amp incf DeBug_Counter,F,BANKED; возвращаем единичку Add16L PCPWM_AmpSin+0,BANKED,0xD ; Буфер Амплитуды синусоиды bra DoneAddAmp Inc16Amp Inc16 PCPWM_AmpSin+0,BANKED ; ; Буфер Амплитуды синусоиды ; infsnz PCPWM_AmpSin3,F,BANKED; Амплитуда 3й гармоники после вычислений V/F ; decf PCPWM_AmpSin3,F,BANKED; 0xFF не пересекаем DoneAddAmp ; Нужны 2 амплитуды - синуса и 3й гармоники. Для плавного возрастания уровня ; 3 гармоники от 0 до 1 надо от основной амплитуды отнять ; 3. Амплитуда 3 гармоники (0|16448) подчинена/вычисляется из амплитуды основной. ; Если основная (0|0xFFF) меньше 2/5= 1638 то амплитуда 3 гармоники = 0. ; Иначе она равна разнице (1638|4095-1638=0|2457)*6.6943 = (0|16448). ; С фиксированной точкой 16b*16b=32/16b это будет например 6.6943*256=1713.74 множитель разницы. ; При достижении начала ограничения выходного синуса (амплитуда 0xCCC=3276) амплитуда 3 гармоники ;= - 1638 = 1638 * 1714 = 2 807 532 / 256 = 10 966.92 = 2/3 от максимальной|2/12 от основной. ;Отношение 2/12 к 3/12 тоже 2/3 - плановый график выполняется. movff16 PCPWM_AmpSin,SynMulBuf+0 ; Копируем для НЕ порчи Sub16L SynMulBuf+0,BANKED,d'1638' ; Вычитаем начало роста 3 гармоники bc NonZeroAmp3 ; Инверсный заём ; Если основная (0|0xFFF) меньше 2/5= 1638 то амплитуда 3 гармоники = 0. clrf PCPWM_AmpSin3+0,BANKED ; Амплитуда 3й гармоники после вычислений V/F clrf PCPWM_AmpSin3+1,BANKED ; Амплитуда 3й гармоники после вычислений V/F bra DoneAmp3 NonZeroAmp3 ; Иначе она равна разнице (1638|4095-1638=0|2457)*6.6943 = (0|16448). ; С фиксированной точкой 16b*16b=32/16b это будет например 6.6943*256=1713.74 множитель разницы. ; Результат умножения SynMulBuf+2 : PCPWM_AmpSin3+0 : PCPWM_AmpSin3+1 младший байт только для переносов movlw low(d'1713') ; Младшие байты mulwf SynMulBuf+0,BANKED ; перемножаем movff PRODL,SynMulBuf+2 ; спасаем результат movff PRODH,PCPWM_AmpSin3+0; спасаем результат movlw high(d'1713') ; старшие байты mulwf SynMulBuf+1,BANKED ; перемножаем movff PRODL,PCPWM_AmpSin3+1 ; спасаем результат, старший байт будет отброшен movlw low(d'1713') ; Младший байт со старшим mulwf SynMulBuf+1,BANKED ; перемножаем ; ArgB,A1B,ArgA,A1A ; в памяти Младший-Старший идут ; Результат будет B=B+A Add16 PCPWM_AmpSin3+0,BANKED,PRODL,ACCESS; Складываем перекрёст с серединкой movlw high(d'1713') ; старший байт с младшим mulwf SynMulBuf+0,BANKED ; перемножаем Add16 PCPWM_AmpSin3+0,BANKED,PRODL,ACCESS; Складываем перекрёст с серединкой ; В PCPWM_AmpSin3 должна быть (0|16440) величина. DoneAmp3 movf PCPWM_AmpSin+1,W,BANKED ; старшой байт andlw 0xF0 ; чистим младший нибл Акб bnz $+6 goto DeBugLoopAmp nop nop halt sleep bra $-2