;********************************************************************** ; ; NOM: Clavier_L298.asm ; Date: 09/06/2001 ; Version: V1.1 ; Circuit: Clavier 5 touches, platine: PIC_CDE.edb ; avec platine Moteur Pas à Pas MPAP_1.edb ; à base de l297 et L298 ; Auteur: ACQUIER Bernard ; ;********************************************************************** ; * ; Fichier requis: P16F84.inc * ; * ;********************************************************************** ;Notes: PIC 16F84 gérant un clavier 5 touches et envoi ; selon l'appui, une commande montée / descente (Touche UP, DOWN ) ; ou une impulsion montée puis descente, entrée externe (sur RA4) ; prévu pour perçage de circuits imprimées, ; avec la carte moteur pas à pas à base de L297 et L298. ; La carte est programmable In Situ. ; principe: On garde une IRQ Timer (toutes les 2 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. ; Selon l'appui (Touche UP, DOWN ), on génère le signal RST, SENS et CLK ; en pas entier (FULL\). ; Si touche RA4 (impulsion), on a un cycle de qq pas UP et autant DOWN. ;********************************************************************** 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 * ;********************************************************************* OPTIONVAL4 EQU b'00000010' ; Valeur registre option ; Résistance pull-up ON ; Interrupt flanc descendant RB0 ; Préscaler timer à 8 toutes les 4ms OPTIONVAL16 EQU b'00000100' ; Préscaler timer à 32 toutes les 16ms OPTIONVAL8 EQU b'00000011' ; Préscaler timer à 16 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 VRAI EQU 0xFF ; Condition requise FAUX EQU 0x00 ; Condition non requise 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_IMPULSION ETAT,1 ; Test Impulsion Montée puis descente. #DEFINE ETAT_IMP_M ETAT,2 ; =1 si montée #DEFINE ETAT_RELAX ETAT,3 ; =1 signifie fin de cycle impulsion ; donc interdiction de recommencer un cycle clavier. ; ; ***** 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 ; ; ***** 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 ; ;********************************************************************* ; 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 ETAT : 1 ; Indique au PP qu'une IRQ a eu lieu ; et qu'il faut la traiter. Ou bien que le PIC doit envoyer ; une impulsion Montée puis descente. 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: Test des actions UP ou DOWn CMPT_IMPULS : 1 ; Compteur de créneau. OPTION_R : 1 ; Pour différents prescaler. 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 de vient 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 OPTIONVAL4 ; 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 ;********************************************************************* ; 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 ; ; Sommes nous en Mode Impulsion? ; BTFSC ETAT_IMPULSION ; Mode Impulsion? GOTO Mode_Impuls ; donc oui ; ; 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 GOTO TRAIT_T ; Traitement Appui Touche INCF CMPT,F ; Compteur Appui. MOVLW A'o' ; 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,5 ; 2ms*32 passages = 64ms ? GOTO PP ; et réattend une IRQ Affich BSF LED1 ; Traitement OK DECF CMPT_A,F ; Afin de toujours rester allumer ; pendant la durée d'appui Verf_U MOVLW A'u' ; Touche UP appuyée? XORWF L_BOX,W ; afin de vérifier l'égalité BTFSS STATUS,Z ; oui? GOTO Verf_D GOTO Cde_Up Verf_D MOVLW A'd' ; Touche UP appuyée? XORWF L_BOX,W ; afin de vérifier l'égalité BTFSS STATUS,Z ; oui? GOTO Verf_OK GOTO Cde_Down Verf_OK MOVLW A'o' ; Touche UP appuyée? XORWF L_BOX,W ; afin de vérifier l'égalité BTFSS STATUS,Z ; oui? GOTO PP ; On laisse la led allumée pour dire ; qu'un appui a été fait et c'est tout! BSF ETAT_IMPULSION ; On ne s'occupera plus du clavier ; par la suite. Une montée puis une descente. BSF ETAT_IMP_M ; D'abord, une montée... CLRF CMPT_IMPULS ; pas nécessaire, mais, bon... GOTO PP Erreur CLRF ETAT ; On efface vraiment tous les Flags. BCF LED1 CLRF CMPT_A CLRF CMPT GOTO PP Mode_Impuls BTFSC ETAT_RELAX ; Fin de cycle impulsion? GOTO Wait_Touch ; Non et on attend la fin de tout appui. Mode_MD BTFSS ETAT_IMP_M ; mode montée? GOTO Descente ; Non Monte INCF CMPT_IMPULS,F ;pour compter le nbre de pas BTFSS CMPT_IMPULS,6 ; 128 Pas/2 car DEMI => 64 ? GOTO Cde_Up BCF ETAT_IMP_M ; On s'impose donc une descente maintenant. GOTO PP Descente DECF CMPT_IMPULS,F ;pour compter le nbre de pas BTFSS STATUS,Z ; Arrivée à 0? GOTO Cde_Down ; Non BSF ETAT_RELAX ; Nous sommes en fin de cycle. GOTO PP Cde_Up BCF SENS BSF DEMI ; Pas en Half, c'est plus doux BSF RST ; On actionne le Moteur BTFSC CLK ; Que vaut l'horloge, état Bas? GOTO Impuls_L ; On le mettra à l'état bas BSF CLK GOTO PP Cde_Down BSF SENS BSF DEMI ; Pas en Half, c'est plus doux BSF RST ; On actionne le Moteur BTFSC CLK ; Que vaut l'horloge, état Bas? GOTO Impuls_L ; On le mettra à l'état bas BSF CLK GOTO PP Impuls_L BCF CLK GOTO PP Wait_Touch MOVLW 0xF1 ; Touche libérée? XORWF CLAVIER,W ; afin de vérifier l'égalité BTFSS STATUS,Z ; oui? GOTO PP ; Non et on attend GOTO Erreur ; On remet tout à 0, ; mais il n'y a pas d'erreur END ; directive fin de programme