Привет, Edward Nedeliaev.
Решение ниже (в реальности не проверялось, но принцип, думаю, ясен):
; Предполагается, что ножки для ШИМ располагаются в ; битах порта PWMPort. ; Buf1, Buf2 - две буферные последовательности по 16 байт, ; на момент начала цикла там должны быть все нули ; Выводимые ШИМ значения располагаются в ячейках ; PWMval_1 ... PWMval4 ; Получение и расчет этих значений можно разместить ; вместо NOP (44 шт.) и в паузе между циклами, ; либо сократить размер кода почти в 2 раза, ; за счет совмещения двух циклов. ; Паузы между циклами сейчас нет, все тики одинаковые. ; Можно выводить еще два канала ШИМ без увеличения ; длительности цикла. ; Можно сократить каждый тик на 1 команду - ; в зависимости от условий задачи. ; ;memset(&Buf1[0], 0, 16); ;memset(&Buf2[0], 0, 16); ;for(;;) ;{ ; // Выводим Buf1, заполняем Buf2 ; PWMPort = Buf1[0]; ; for (i=1; i<16; i++) ; { ; Sleep(ONE_TICK); ; PWMPort ^= Buf1[i] ; } ; // Очистка Buf1 и заполнение Buf2 ; // выполняется вместо Sleep(); ; memset(&Buf1[1], 0, 15); ; Buf2[0] = PWMbit_All; ; Buf2[PWMval_1 & 0x0F] ^= PWMbit_1; ; Buf2[PWMval_2 & 0x0F] ^= PWMbit_2; ; Buf2[PWMval_3 & 0x0F] ^= PWMbit_3; ; Buf2[PWMval_4 & 0x0F] ^= PWMbit_4; ; ; // Выводим Buf2, заполняем Buf1 ; PWMPort = Buf2[0]; ; for (i=1; i<16; i++) ; { ; Sleep(ONE_TICK); ; PWMPort ^= Buf2[i] ; } ; // Очистка Buf2 и заполнение Buf1 ; // выполняется вместо Sleep(); ; memset(&Buf2[1], 0, 15); ; Buf1[0] = PWMbit_All; ; Buf1[PWMval_1 & 0x0F] ^= PWMbit_1; ; Buf1[PWMval_2 & 0x0F] ^= PWMbit_2; ; Buf1[PWMval_3 & 0x0F] ^= PWMbit_3; ; Buf1[PWMval_4 & 0x0F] ^= PWMbit_4; ;} ; PWMbit_1 EQU 1 PWMbit_2 EQU 2 PWMbit_3 EQU 4 PWMbit_4 EQU 8 PWMbit_All EQU PWMbit_1+PWMbit_2+PWMbit_3+PWMbit_4
PWM_Start: Tick0: MOVF Buf1+0,W ;Выводим первый буфер MOVWF PWMPort ;Выставляем все выходы в начальное сост. MOVF PWMval_1,W ANDLW 0x0F ADDLW Buf2 MOVWF FSR ;Подготовили адрес для PWMbit_1 во втором буфере Tick1: MOVF Buf1+1,W ;Выводим первый буфер XORWF PWMPort,F MOVLW PWMbit_All ;Первые ячейки буферов должны быть в 1 MOVWF Buf2+0 ;Чистим первую ячейку второго буфера MOVLW PWMbit_1 XORWF INDF ;Установили бит во 2 буфере для PWMbit_1 Tick2: MOVF Buf1+2,W XORWF PWMPort,F MOVF PWMval_2,W ANDLW 0x0F ADDLW Buf2 MOVWF FSR ;Подготовили адрес для PWMbit_2 Tick3: MOVF Buf1+3,W XORWF PWMPort,F MOVLW PWMbit_2 XORWF INDF CLRF Buf1+1 ;Чистим уже выведенный первый буфер CLRF Buf1+2 Tick4: MOVF Buf1+4,W XORWF PWMPort,F MOVF PWMval_3,W ANDLW 0x0F ADDLW Buf2 MOVWF FSR Tick5: MOVF Buf1+5,W XORWF PWMPort,F MOVLW PWMbit_3 XORWF INDF CLRF Buf1+3 CLRF Buf1+4 Tick6: MOVF Buf1+6,W XORWF PWMPort,F MOVF PWMval_4,W ANDLW 0x0F ADDLW Buf2 MOVWF FSR Tick7: MOVF Buf1+7,W XORWF PWMPort,F MOVLW PWMbit_4 XORWF INDF CLRF Buf1+5 CLRF Buf1+6 Tick8: MOVF Buf1+8,W XORWF PWMPort,F NOP NOP NOP NOP Tick9: MOVF Buf1+9,W XORWF PWMPort,F NOP NOP NOP NOP TickA: MOVF Buf1+10,W XORWF PWMPort,F NOP NOP NOP NOP TickB: MOVF Buf1+11,W XORWF PWMPort,F NOP NOP NOP NOP TickC: MOVF Buf1+12,W XORWF PWMPort,F NOP NOP NOP NOP TickD: MOVF Buf1+13,W XORWF PWMPort,F CLRF Buf1+7 CLRF Buf1+8 CLRF Buf1+9 CLRF Buf1+10 TickE: MOVF Buf1+14,W XORWF PWMPort,F CLRF Buf1+11 CLRF Buf1+12 CLRF Buf1+13 CLRF Buf1+14 TickF: MOVF Buf1+15,W XORWF PWMPort,F CLRF Buf1+15 NOP NOP ;Здесь пауза между циклами NOP ;Выравнивание для GOTO ;Далее то же самое еще раз, но выводимый буфер ;и рассчитываемый буфер меняются местами Tick10: MOVF Buf2+0,W MOVWF PWMPort MOVF PWMval_1,W ANDLW 0x0F ADDLW Buf1 MOVWF FSR Tick11: MOVF Buf2+1,W XORWF PWMPort,F MOVLW PWMbit_All ;Первые ячейки буферов должны быть в 1 MOVWF Buf1+0 ;Чистим первую ячейку первого буфера MOVLW PWMbit_1 XORWF INDF Tick12: MOVF Buf2+2,W XORWF PWMPort,F MOVF PWMval_2,W ANDLW 0x0F ADDLW Buf1 MOVWF FSR Tick13: MOVF Buf2+3,W XORWF PWMPort,F MOVLW PWMbit_2 XORWF INDF CLRF Buf2+1 CLRF Buf2+2 Tick14: MOVF Buf2+4,W XORWF PWMPort,F MOVF PWMval_3,W ANDLW 0x0F ADDLW Buf1 MOVWF FSR Tick15: MOVF Buf2+5,W XORWF PWMPort,F MOVLW PWMbit_3 XORWF INDF CLRF Buf2+3 CLRF Buf2+4 Tick16: MOVF Buf2+6,W XORWF PWMPort,F MOVF PWMval_4,W ANDLW 0x0F ADDLW Buf1 MOVWF FSR Tick17: MOVF Buf2+7,W XORWF PWMPort,F MOVLW PWMbit_4 XORWF INDF CLRF Buf2+5 CLRF Buf2+6 Tick18: MOVF Buf2+8,W XORWF PWMPort,F NOP NOP NOP NOP Tick19: MOVF Buf2+9,W XORWF PWMPort,F NOP NOP NOP NOP Tick1A: MOVF Buf2+10,W XORWF PWMPort,F NOP NOP NOP NOP Tick1B: MOVF Buf2+11,W XORWF PWMPort,F NOP NOP NOP NOP Tick1C: MOVF Buf2+12,W XORWF PWMPort,F NOP NOP NOP NOP Tick1D: MOVF Buf2+13,W XORWF PWMPort,F CLRF Buf2+7 CLRF Buf2+8 CLRF Buf2+9 CLRF Buf2+10 Tick1E: MOVF Buf2+14,W XORWF PWMPort,F CLRF Buf2+11 CLRF Buf2+12 CLRF Buf2+13 CLRF Buf2+14 Tick1F: MOVF Buf2+15,W XORWF PWMPort,F CLRF Buf2+15 NOP GOTO PWM_Start ; END
Удачи, Алексей.