;В пике сделать работу модуля 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                  ДАЛЬШЕ