Код: list p=16F84A ; Задава типа на процесора #include <p16F8A.inc> ; Дефиниции за SFR регистрите __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;***********Дефиниране на константи и променливи ******** W EQU 0 f EQU 1
Counter EQU H'0C' Temp EQU H'0D' Key_number EQU H'0E' ;----------Дефиниране на входно-изходните изводи------------- #define Out PORTA.4 ; ***************************************************** ; Потребителска програма ;****************************************************** ORG H'0000' ; вектор на НУ goto start ; Преход към началото на програмата ORG H'0004' ; Вектор на прекъсване goto Int_Service ; Преход към ISR ;******************************************************* ; Начало на програмата ;******************************************************* start bsf STATUS,RB0 ; избор на Банка 1 movlw B'00010100' ; 0000100b ?w movwf OPTION_REG ; (w)? OPTION_REG bcf STATUS RB0 ; избор на Банка 0 clrf PORTB ; 00h? PORTB bsf STATUS,RP0 ; избор на Банка 1 movlw B'11110000' ;11110000b?w movwf TRISB ; RB7-RB4-входове, RB3-RB0-изходи bcf TRISA,4 ; RA4-вход bcf STATUS,RB0 ; Избор на Банка 0 movf PORTB ; четене на PORTB movlw B'10001000' ; 10001000b?w movwf INTCON ; (w) ? INTCON bsf Oat ; RA4=1 (Изгасен светодиод VD5) goto main ; ; ************************************************************ ; Използвани подпрограми ; ************************************************************ ;------ Програма за обслужване на прекъсванията (ISR) ------------- Int_Service btfss INTCON, RBIF ; Бит RBIF=1? (Прекъсване на PORTB ? ) goto end_int ; Не, връщане от ISR PORTB_int call wait ; Изчакай 16ms comf PORTB,w ; Инверт. PORTB и запиши резултата в W movwf Temp,f ; (W) ? Temp movlw B'11110000' ; 11110000b?W andwf Temp, f ; (w) AND (Temp) ?Temp call Check keys ; Провери броя на натиснатите бутони movf Key_number,w ; (Key_number)=> W btfsc STATUS,Z ; (Key_nimber) = 0 ? goto release ; Да xorlw H'01' ; Не, (w) XOR G l h ? W btfss STATUS,Z ; (w)=0? (Един бутон ли е натиснат ?) goto key_error ; Не, индикация за грешка swapf Temp,w ; Размени тетрадите на Темр movwf PORTB ; (w) , PORTB goto release key_error bcf Out ; RA4=0 (светни VD5) release movlw B'11110000' ; 11110000?W andwf PORTB,w ; (PORTB) AND (w)?w xorlw B'11110000' ; (w) XOR 11110000b?w btfss STATUS,Z ; (w)=0? (отпуснат бутон?) goto release ; Не, провери отново call wait ; Да, изчакай 16ms bsf Out ; RA4=1 (изгаси VD5) end_int movf PORTB,f ; Четене на PORTB bcf INTCON,RBIF ; Нулиране на флага INTF и връщане retfie ; Към главната програма ;-------- Подпрограма “wait”, ; формираща времезадръжка от 16 ms--- Wait movlw D'2' ; 2->w movwf Counter ; (w)->Counter clrf TMR0 ; 00h->TMRO again bcf INTCON.T0IF ; Нулирай бит TOIF loop btfss INTCON.T0IF ; Бит TOIF=1? goto loop ; Не, провери отново decfsz Counter,f ; Да, Counter= (Counter)-1 Counter=0? goto again ; Не, изпълни цикъла отново return ;----------Подпрограма за проверка броя на натиснатите бутони--------- Check_keys clrf Key_number ; 00h?Key_number btfsc Temp,7 ; Temp<7>=1? (натиснат бутон S1?) incf Key_number,f ; Да, Key_number=(Key_nimber)+1 btfsc Temp,6 ; Temp<6>=1? (Натиснат бутон S2?) incf Key_number,f ; Да, Key_number=(key_number)+1 btfsc Temp,5 ; Temp<5>=1? (Натиснат бутон S3?) incf Key_number,f ; Да, Key_number=(key_number)+1 btfsc Temp,4 ; Temp<4>=1? (Натиснат бутон S4?) incf Key_number,f ; Да, Key_number=(key_number)+1 return ;************************************************************************ ; Главна програма ;*********************************************************************** main sleep ; режим SLEEP nop ; Празна информация goto main END ; Директина за край на програмата
|