;********************************************************************** ; ; NOM: Clavier0.asm ; Date: 02/06/2001 ; Version: V1.0 ; Circuit: Clavier 5 touches, platine: PIC_CDE.edb ; Auteur: ACQUIER Bernard ; ;********************************************************************** ; * ; Fichier requis: P16F84.inc * ; * ;********************************************************************** ;Notes: PIC 16F84 gérant un clavier 5 touches et envoi selon la version ; une commande par la RS485 ou par un connecteur pilotant ; une carte moteur pas à pas à base de L297 et L298. ; Elle accepte aussi une entrée externe (sur RA4) ; La carte est programmable In Situ. ; principe: On garde une IRQ Timer (toutes les 8 ms) qui scanne le ; clavier. Dans le Prog Principal, on lit et traite le clavier, c.a.d. ; que la touche est valide si l'appui est resté stable pendant 80ms. ; Sinon, on dévalide de suite. ;********************************************************************** LIST p=16F84 ; Définition de processeur #include ; Définitions des constantes __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ; '__CONFIG' précise les paramètres encodés dans le processeur au moment de ; la programmation du processeur. Les définitions sont dans le fichier include. ; Voici les valeurs et leurs définitions : ; _CP_ON Code protection ON : impossible de relire ; _CP_OFF Code protection OFF ; _PWRTE_ON Timer reset sur power on en service ; _PWRTE_OFF Timer reset hors-service ; _WDT_ON Watch-dog en service ; _WDT_OFF Watch-dog hors service ; _LP_OSC Oscillateur quartz basse vitesse ; _XT_OSC Oscillateur quartz moyenne vitesse ; _HS_OSC Oscillateur quartz grande vitesse ; _RC_OSC Oscillateur à réseau RC ;********************************************************************* ; ASSIGNATIONS * ;********************************************************************* OPTIONVAL EQU b'00000100' ; Valeur registre option ; Résistance pull-up ON ; Interrupt flanc descendant RB0 ; Préscaler timer à 32 toutes les 8ms INTERMASK EQU b'10100000' ; Masque d'interruption ; Interruptions sur TOIE TOIE EQU 5 TOIF EQU 2 GIE EQU 7 RBIE EQU 3 C_PORTA EQU b'00010000' ; A0 à A3 en sorties ; A4 en entrée (Config PORTA) ;A0 = Sens...A1 = Clk...A2 = Rst...A3 = 1/2Pas... ;A4 = OK ou validation Commande C_PORTB EQU b'11110001' ; B0, B4 à B7 en entrées (Config PORTB) ;B0 = RX...B1 = TX...B2 = CTRL Half Duplex...B3 = EXTerne ;B4 = RIGHT...B5 = DOWN...B6 = LEFT...B7 = UP ;********************************************************************* ; DEFINE * ;********************************************************************* ; #DEFINE IRQ_TE INTCON,TOIE ;Afin de valider IRQ Timer TMR0 #DEFINE IRQ_TF INTCON,TOIF ;Flag IRQ Timer TMR0 #DEFINE IRQ_BE INTCON,RBIE ;Afin de valider IRQ changement etat port B #DEFINE IRQ_BF INTCON,RBIF ;Flag IRQ changement etat port B #DEFINE IRQ_G INTCON,GIE ; IRQ Général ; ; ***** Flag d'évolution ***** ; #DEFINE ETAT_IRQ_TIMER ETAT,0 ;LSB #DEFINE ETAT_IRQ_ENVOI ETAT,1 ;Indique qu'un octet a déjà été envoyé ; ; ***** ENTREES ***** ; #DEFINE RIGHT CLAVIER,4 ; Touche DROITE #DEFINE LEFT CLAVIER,6 ; Touche GAUCHE #DEFINE UP CLAVIER,7 ; Touche HAUT #DEFINE DOWN CLAVIER,5 ; Touche BAS #DEFINE OK CLAVIER,0 ; Touche OK ou Validation Commande #DEFINE VAL_R VALID,0 ; Touche Relâchée #DEFINE VAL_A VALID,1 ; Touche Appuyée(1 seule à la fois) ; ; ***** SORTIES ***** ; #DEFINE SENS PORTA,0 ; Touche Sens pour carte Moteur PàP #DEFINE CLK PORTA,1 ; Touche Horloge pour carte Moteur PàP #DEFINE RST PORTA,2 ; Touche Reset pour carte Moteur PàP #DEFINE DEMI PORTA,3 ; Touche 1/2 Pas pour carte Moteur PàP #DEFINE LED1 PORTB,3 ; LED de sortie RB3 ; ; ***** Port Série ***** ; #DEFINE CTRL PORTB,2 ; Controle le sens du dialogue ; Emission ou réception (par défaut). ; Pour RX et TX, confère Include série #DEFINE TX PORTB,1 ; Sortie RB1 ; ;********************************************************************* ; MACRO * ;********************************************************************* BANK0 macro bcf STATUS , RP0 ; passer banque0 endm BANK1 macro bsf STATUS , RP0 ; passer banque1 endm ; ; #Include ; Macro Lecture / Ecriture EEPROM ; et eventuellement ses paramètres ; à mettre pdt sa programmation ;********************************************************************* ; DECLARATIONS DE VARIABLES * ;********************************************************************* ; CBLOCK 0x00C ; début de la zone variables w_temp :1 ; Sauvegarde du registre W status_temp : 1 ; Sauvegarde du registre STATUS VALID : 1 ; Validation d'appui ETAT : 1 ; Indique au PP qu'une IRQ a eu lieu ; et qu'il faut la traiter. CLAVIER : 1 ; Code Touche Appuyée (une seule autorisée) CMPT_A : 1 ; Compteur d'Appui (max =10) CMPT : 1 ; Compteur d'Appui simultanée L_BOX : 1 ; Letter Box: code à envoyer par RS485 ENDC ; Fin de la zone ;********************************************************************** ; DEMARRAGE SUR RESET * ;********************************************************************** org 0x000 ; Adresse de départ après reset goto init ; Adresse 0: initialiser ;********************************************************************** ; ROUTINE INTERRUPTION * ;********************************************************************** ;sauvegarder registres ;--------------------- IRQ org 0x004 ; adresse d'interruption movwf w_temp ; sauver registre W swapf STATUS,w ; swap status avec résultat dans w movwf status_temp ; sauver status swappé ; ; switch vers différentes interrupts ; inverser ordre pour modifier priorités ;---------------------------------------- ; ; Traiter interrupt timer toutes les 8ms ; BCF IRQ_TF ; effacer flag interrupt timer BSF ETAT_IRQ_TIMER ; signalement de passage IRQ MOVF PORTB,W ; lecture tout le clavier ANDLW 0xF0 ; Masquage de PB0 à PB3 MOVWF CLAVIER ; stockage SWAPF PORTA,W ; RA4 devient RA0 ANDLW 0x01 ; Masquage pour ne garder que RA4 IORWF CLAVIER,F ; Ou pour avoir les 5 touches... ;Donc CLAVIER à la config des 5 touches qui seront traités par le ; PP ou Programme Principal. ;restaurer registres ;------------------- restoreg; swapf status_temp,w ; swap ancien status, résultat dans w movwf STATUS ; restaurer status swapf w_temp,f ; Inversion L et H de l'ancien W ; sans modifier Z swapf w_temp,w ; Réinversion de L et H dans W ; W restauré sans modifier status retfie ; return from interrupt ;********************************************************************* ; INITIALISATIONS * ;********************************************************************* init BANK0 CLRF INTCON ; aucune interruptions autorisées clrf PORTA ; Sorties portA à 0 clrf PORTB ; sorties portB à 0 BANK1 ; passer banque1 movlw OPTIONVAL ; charger masque movwf OPTION_REG ; initialiser registre option MOVLW C_PORTA ; E / S PORTA MOVWF TRISA ; MOVLW C_PORTB ; E / S PORTB MOVWF TRISB ; ; Effacer RAM ; ------------ movlw 0x0c ; initialisation pointeur movwf FSR ; pointeur d'adressage indirect init1 clrf INDF ; effacer ram incf FSR,f ; pointer sur suivant btfss FSR,6 ; tester si fin zone atteinte (>=40) goto init1 ; non, boucler btfss FSR,4 ; tester si fin zone atteinte (>=50) goto init1 ; non, boucler BANK0 ; passer banque0 movlw INTERMASK ; masque interruption movwf INTCON ; charger interrupt control ; ; Le port série 485 doit être initialisé BCF CTRL ; reception par défaut. BSF TX ; pour ne pas déformer le premier caractère. ;********************************************************************* ; PROGRAMME PRINCIPAL * ;********************************************************************* PP BTFSS ETAT_IRQ_TIMER ; Y a t'il eu une IRQ Timer? GOTO PP ; Non, boucler BCF ETAT_IRQ_TIMER ; Pour ne pas reboucler ; ; On va donc tester le clavier. ; NEXT_R BTFSC RIGHT ; Test 1er Appui GOTO NEXT_L ; Autre Touche? INCF CMPT,F ; Compteur Appui. MOVLW A'R' ; Lettre Droite minuscule MOVWF L_BOX ; dans la boite aux lettres NEXT_L BTFSC LEFT ; Test 2ème Appui GOTO NEXT_U ; Autre Touche? INCF CMPT,F ; Compteur Appui. MOVLW A'L' ; Lettre Gauche minuscule MOVWF L_BOX ; dans la boite aux lettres NEXT_U BTFSC UP ; Test 3ème Appui GOTO NEXT_D ; Autre Touche? INCF CMPT,F ; Compteur Appui. MOVLW A'U' ; Lettre Haut minuscule MOVWF L_BOX ; dans la boite aux lettres NEXT_D BTFSC DOWN ; Test 4ème Appui GOTO NEXT_O ; Traitement Appui Touche INCF CMPT,F ; Compteur Appui. MOVLW A'D' ; Lettre Bas minuscule MOVWF L_BOX ; dans la boite aux lettres NEXT_O BTFSC OK ; Test 4ème Appui qui est STOP GOTO TRAIT_T ; Traitement Appui Touche INCF CMPT,F ; Compteur Appui. MOVLW A'S' ; Lettre Bas minuscule MOVWF L_BOX ; dans la boite aux lettres TRAIT_T MOVLW 1 ; comme 1 appui XORWF CMPT,W ; afin de vérifier l'égalité BTFSS STATUS,Z ; Plus d'une touche appuyée? GOTO Erreur ; Soit Aucun Appui, soit plein... APPUI CLRF CMPT ; Pour le prochain scanning INCF CMPT_A,F BTFSS CMPT_A,3 ; 8ms*8 passages = 64ms ? GOTO PP ; et réattend une IRQ Affich BTFSC ETAT_IRQ_ENVOI ; a t'on déjà envoyé un octet sur RS 485? GOTO PP ; et oui, donc on a rien à faire BSF LED1 ; Traitement OK BSF CTRL ; pour valider l'écriture sur le circuit RS485 DECF CMPT_A,F ; Afin de toujours rester allumer ; pendant la durée d'appui ; BCF IRQ_TE ; On interdit l'IRQ TMR0 ; MOVF L_BOX,w MOVWF XmtReg ; pour la liaison série CALL ENVOI BCF CTRL ; pour arréter l'écriture sur le circuit RS485 ; BSF ETAT_IRQ_ENVOI ; Il faudra dévalider la touche puis la revalider ; pour réenvoyer le même octet. BSF IRQ_TE ; On réautorise l'IRQ TMR0 ; GOTO PP Erreur CLRF CMPT_A CLRF CMPT CLRF VALID BCF LED1 BCF ETAT_IRQ_ENVOI ; Il faudra dévalider la touche puis la revalider GOTO PP #Include END ; directive fin de programme