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