Суббота, Май 30, 2020

Семь нот PIC ASM

;В пике сделать работу модуля CCP(CAPTURE/COMPARE/PWM-ЗАХВАТ/СРАВНЕНИЕ/ШИМ(Широтно импульсная модуляция)) как в AVR сложнее.            
            LIST        P=16F628A
            INCLUDE     P16F628A.INC
            __CONFIG    _INTOSC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_ON&_MCLRE_OFF&_LVP_OFF
            ERRORLEVEL  -302
            CBLOCK      20H
            J
            K
            COUNT
            TEMP
            W_TEMP
            STATUS_TEMP
            ENDC
BANK0       MACRO
            BCF         STATUS,RP0
            BCF         STATUS,RP1
            ENDM
BANK1       MACRO
            BSF         STATUS,RP0
            BCF         STATUS,RP1
            ENDM
            ORG         0
            GOTO        START
            ORG         4
            GOTO        ISR
START       MOVLW       7
            MOVWF       CMCON
            BANK1
            BCF         TRISB,3    ;ножка CCP1 как выход
            MOVLW       B'01111111';кнопки подрубаем к порту А
            MOVWF       TRISA      ;через подтягивающие резисторы
            BANK0
            CLRF        PORTB
            CLRF        PORTA
            MOVLW       B'00110001';включаем таймер1 бит(0)в 1
            MOVWF       T1CON      ;предделитель 1/16,от внутреннего такта
MAIN        CLRF        COUNT      ;обнуляем регистр счётчик
            MOVF        PORTA,W    ;копируем состояние кнопок
            MOVWF       TEMP       ;в регистр TEMP
TEST        RRF         TEMP,F     ;сдвигаем всё вправо
            BTFSS       STATUS,C   ;какая нибудь кнопка нажата?т.е. еслть ли 0?
            GOTO        PROC       ;да есть,кнопка нажата,идем на включение звука
            INCF        COUNT,F    ;увеличивая на 1 считаем какая кнопка нажата
            MOVLW       7
            SUBWF       COUNT,W    ;отнимая 7 проверяем цикл будет длиться 7 раз
            BTFSS       STATUS,Z   ;проверяем на 0 результат вычитания
            GOTO        TEST
            GOTO        MAIN       ;если не одна кнопка не нажата всё сначала
PROC        RLF         COUNT,F    ;умножаем на 2
            MOVF        COUNT,W
            CALL        TABLE      ;берём значение из таблицы
            MOVWF       CCPR1L     ;записываем в младший регистр сравнения
            INCF        COUNT,F    ;указываем на следующий байт в таблице
            MOVF        COUNT,W
            CALL        TABLE      ;берём следующий байт
            MOVWF       CCPR1H     ;записываем в старший байт регистра сравнения
            CLRF        TMR1L      ;обнуляем счетчик таймера
            CLRF        TMR1H
            GOTO        CCP1_1000  ;идём на включение 0000 1000 режима CCP1
            
TMR1_CLR    CLRF        TMR1L      ;сюда попадаем если флаг CCP1IF поднялся
            CLRF        TMR1H      ;обнуляем счетчик таймера
            BCF         PIR1,CCP1IF;сбрасываем флаг
            MOVLW       0
            MOVWF       CCP1CON    ;отключаем модуль сравнения
TEST1       MOVF        PORTA,W    ;опять проверяем нажата ли кнопка
            MOVWF       TEMP
            CLRF        COUNT
LOOP        RRF         TEMP,F
            BTFSS       STATUS,C
            GOTO        NEXT
            INCF        COUNT,F
            MOVLW       7
            SUBWF       COUNT,W
            BTFSS       STATUS,Z
            GOTO        LOOP
            GOTO        MAIN
NEXT        BTFSS       PORTB,3    ;проверяем в каком состоянии выход ССР1
            GOTO        CCP1_1000  ;сюда если он 0
            GOTO        CCP1_1001  ;сюда если он 1
CCP1_1000   MOVLW       B'00001000';включаем режим сравнения,который
            MOVWF       CCP1CON    ;будет устанавливать 1-цу на ножке 3 порта Б
            BTFSC       PIR1,CCP1IF;если совпадение CCP1IF=1
            GOTO        TMR1_CLR   ;то идем все обнулять
            GOTO        TEST1      ;иначе идём проверять кнопку
CCP1_1001   MOVLW       B'00001001';устанавливаем режим сравнения
            MOVWF       CCP1CON    ;который будет выставлять при совпадении
            BTFSC       PIR1,CCP1IF;на ножке ССР1 0
            GOTO        TMR1_CLR
            GOTO        TEST1
                   
ISR         MOVWF       W_TEMP     ;пока не используем прерывание
            SWAPF       STATUS,W
            BCF         STATUS,RP0
            MOVWF       STATUS_TEMP   
                     
EXIT_ISR    SWAPF       STATUS_TEMP,W
            MOVWF       STATUS
            SWAPF       W_TEMP,F
            SWAPF       W_TEMP,W
            RETFIE
TABLE       ADDWF       PCL,F       ;к регистру счетчику комманд
            RETLW       51H         ;прибавляем то что находится в
            RETLW       02H         ;рабочем регистре и прыгаем на
            RETLW       11H         ;это "растояние",а потом возвращаемся
            RETLW       02H         ;с записанным значением в рабочий регистр
            RETLW       0D7H
            RETLW       01H
            RETLW       0BCH
            RETLW       01H
            RETLW       8CH
            RETLW       01H
            RETLW       60H
            RETLW       01H
            RETLW       38H
            RETLW       01H
            END



 

НАЗАД                  Assembler AVR                  Си AVR                  ДАЛЬШЕ


Back to Top