; ;******************************************************************** LIST P = 16C84 LIST F = INHX8M __config H'3F1A' ; CP : off,PWRTE : on, WDT : off, HS OSC INCLUDE "PIC84JW.H" ; ; Lecture de codes de télécommandes IR ;********************************************************************* ; ; PRÉSENTATION DU PROGRAMME ; ; Ce programme tourne sur un PIC16C84. ; ; Description de la carte ; ; AFFICHAGE ; L'affichage se fait sur 4 afficheurs LED 7 segments sous la forme : ; ; ( 88:88 ) ; ; Les mêmes segments des 4 afficheurs sont tous reliés entre eux et sont ; connectés au port B (a=RB1 ; b=RB2 ; c=RB3 ; d=RB4 ; e=RB5 ; f=RB6 ; g=RB7); ; ; Les ":" sont réalisés par les virgules des 2 afficheurs du milieu (celui de ; droite est retourné) qui sont connectées au bit 0 du port B. ; ; Les afficheurs sont de type anode commune (HPDSP7511) et leurs anode est ; connectée au port A (digit0=RA3 ; digit1=RA2 ; digit2=RA1 ; digit3=RA0). ; ; ; INTERRUPTEURS ; Les 12 lignes d'entrée/sortie étant utilisées, il faut effectuer un ; multiplexage pour pouvoir insérer les interrupteurs ; cela est réalisé ; sur le port B (SW1=RB1 ; SW2 = RB2 ; SW3 =RB3); il faut donc que le ; programme commute ces lignes en entrée pour pouvoir analyser l'état des ; interrupteurs. ; SW1 : ; SW2 : ; SW2 : ; ; ; PRINCIPE : ;ATTENTE : à l'initialisation, on vérifie que le senseur IR est inactif ; (RA4 = 1); on se place alors dans l'attente d'un front descendant de ; RA4 (indiquant un signal) tout en effectuant un cycle d'affichage. ; ;CRENEAU : une fois celui-ci repéré (RA4=0), on lit le contenu du timer ; (inutile au premier passage) et on le réinitialise à une valeur ; supérieure au temps le plus long attendu; ainsi, en cas de débordement ; on retourne à la phase ATTENTE. ; ;DUREE : au passage de RA4 à 1, on lit le compteur, ce qui nous donne la ; marque de la télécommande émettrice; aussitôt après, on réinitialise le ; timer à une valeur supérieure au temps le plus long à mesurer pour le ; code considéré (même considération que précédemment). ; ; ; On boucle ainsi jusqu'à avoir lu tous les bits du code ; ; ; Résumé temporel des codes de commande : ; ; B&O : 0,2 ms de créneau suivi de 5ms ("0") ou 7 ms ("1") ; Thomson TV : 0,5 ms de créneau suivi de 5ms ("0") ou 8 ms ("1") ; Thomson VCR : 0,5 ms de créneau suivi de 2ms ("0") ou 4,5 ms ("1") ; Philips : le signal carré de période 1,78 ms de phase 180° ("0") ou 0° ("1") ; ; ; L'oscillateur à quartz utilisé génère une fréquence de 1,8432 MHz, cela ; donne une fréquence interne de 460,8 kHz (T= 2,17 µs); une prédivision ; par 16 du timer donne un cycle maximal de comptage de 8,888 ms. ; ; On en déduit les valeurs initiales à donner au timer : ; ; Mesure du créneau : 0,2 ms = 5,76*34,72 µs soit N = 5 ; 0,5 ms = 14,40*34,72 µs soit N = 14 ; 0,85 ms = 24,48*34,72 µs soit N = 24 ; On peut définir comme butée (1 ms) : N = 28 ; ; Mesure de la durée : 2 ms = 57,6*34,72 µs soit N = 57 ; 4,5 ms = 129,6*34,72 µs soit N = 129 ; 5 ms = 144,0*34,72 µs soit N = 143 ; 7 ms = 201,6*34,72 µs soit N = 201 ; 8 ms = 230,4*34,72 µs soit N = 230 ; On peut définir comme butée (8,88 ms) : N = 255 ; ;************************** Déclarations ************************* ; ; Programme : remote.ASM ; Date de Révision : Février 96 ;************************** Déclarations ************************* ; ; ;PORT_A equ H'05' ; anodes communes des afficheurs 7 segments ;PORT_B equ H'06' ; segments et virgules des afficheurs et interrupteurs ; ZEROT equ H'81' UN equ H'F3' DEUX equ H'49' TROIS equ H'61' QUATRE equ H'33' CINQ equ H'25' SIX equ H'05' ; Table des segments (PORT_B) SEPT equ H'F1' HUIT equ H'01' NEUF equ H'31' A_HEX equ H'11' B_HEX equ H'07' C_HEX equ H'8D' D_HEX equ H'43' E_HEX equ H'0D' F_HEX equ H'1D' BLANC equ H'FF' VIDE equ H'7F' ; variables pour le comptage C_INIT equ D'230' ; butée de la mesure de créneau ( 255-28 : 1 ms) C02ms equ D'232' ; mesure de créneau 0,2 ms : 1110 xxxx C05ms equ D'241' ; mesure de créneau 0,5 ms : 1111 0xxx C085ms equ D'251' ; mesure de créneau 0,85 ms : 1111 10xx D_INIT equ D'0' ; butée de la mesure de durée (8,88 ms) D2ms equ D'57' ; mesure de durée 2 ms : 0011 xxxx D45ms equ D'129' ; mesure de durée 4,5 ms : 1000 xxxx D5ms equ D'143' ; mesure de durée 5 ms : 1000 xxxx D7ms equ D'201' ; mesure de durée 7 ms : 1100 xxxx D8ms equ D'230' ; mesure de durée 8 ms : 1110 xxxx AFF_OFF equ B'00000000' SWITCH equ B'00001110' ; Sélection des interrupteurs ; ; VARIABLES org RAM affiche res 1 ; quel afficheur raffraîchir ? digit0 res 1 ; Digit des minutes (à droite) digit1 res 1 ; Digit des dizaines de minutes digit2 res 1 ; Digit des heures digit3 res 1 ; Digit des dizaines de heure marque res 1 ; type de code (marque) result res 1 ; variable temporaire var res 1 ; variable temporaire duree res 1 ; stockage de la durée curseur res 1 ; stockage de la position code res 1 ; code reçu final res 1 ; code reçu m_final res 1 ; longueur du code maxbits res 1 ; longueur du code count res 1 ; Variable de comptage count2 res 1 ; 2ème variable de comptage ; ;******************************************************************************** ; ; Initialisation des ports et effacement de l'affichage ; ORG PIC84 GOTO START org RETOUR_INT movlw B'10000000' ; INTCON : GIE=1 ; EEIE=0 ; TOIE=0 ; INTE=0; flags à 0 movwf INTCON ; Positionnement des int et des flags movfw maxbits subwf curseur,0 bnz ERREUR ; a-t'on comptabilisé tous les bits (et pas plus !) movlw 2 subwf marque,0 skpnz ; est-ce THOMSON, alors on complémente comf code,1 clrc rlf code,0 ; on enregistre le bit movwf final movfw marque movwf m_final ; on enregistre la marque ERREUR ; il y a erreur dans les comptes goto MAIN RETFIE START BSF STATUS,RP0 ; Passage au banc mémoire 1 movlw B'00000011' ; T0CS=0 ; T0SE=x ; PSA=0 ; PS[2:0]=3 movwf OPT ; Règlage du timer RTCC (1:16) sur horloge interne movlw B'10000000' ; INTCON : GIE=1 ; EEIE=0 ; TOIE=0 ; INTE=0; flags à 0 movwf INTCON ; Positionnement des int et des flags movlw B'10000' movwf TRISA ; Tous les bits du port A en sortie (sauf RA4) clrf TRISB ; Tous les bits du port B en sortie BCF STATUS,RP0 ; Retour au banc mémoire 0 movlw BLANC movwf PORT_B ; On n'affiche rien movlw H'0F' movwf count ; ; initialize variables clrf code ; on initialise le code à 0 clrf curseur ; on place le curseur à 0 clrf affiche ; on initialise l'afficheur (rien) clrf marque ; on initialise la marque clrf m_final ; on initialise la marque clrf final ; on efface le code final clrf digit0 ; on efface le digit0 clrf final ; on efface le digit0 clrf digit1 ; on efface le digit1 clrf digit2 ; on efface le digit2 clrf digit3 ; on efface le digit3 MAIN clrf curseur btfss PORT_A,4 goto INIT ; RA4 est à 0, on démarre decfsz count,1 ; on n'affiche qu'un coup sur 256 goto MAIN CALL AFFICHAGE ; on lance l'affichage goto MAIN INIT clrf marque ; on initialise la marque CRENEAU ; RA4 est passé à 0, on mesure bsf INTCON,T0IE ; on valide le timer movlw C_INIT call SUB_TIMER MESURE_DE_DUREE movlw 4 movwf duree ; durée initiale à 0 NEXT_D ; première durée rlf result,1 ; on décale decfsz duree,1 ; 8 ms:0 ; 7 ms:1 ; 5 ms:2 ; 2 ms:3 bc NEXT_D ; si carry, on cherche le suivant WAIT_1 btfsc PORT_A,4 ; on attend que RA4 repasse à 1 goto DUREE ; RA4 est à 1, on poursuit goto WAIT_1 DUREE bsf INTCON,T0IE ; on valide le timer movlw D_INIT call SUB_TIMER ; btfsc marque,0 ; goto CHOIX MESURE_DE_CRENEAU movlw 4 movwf var ; marque initiale à 0 rlf result,1 ; on décale rlf result,1 ; on décale rlf result,1 ; on décale NEXT rlf result,1 ; on décale decfsz var,1 ; Philips : 1 ; Thomson : 2 ; B&O : 3 bc NEXT ; si carry, on cherche le suivant movlw 1 subwf var,0 bc VERIF movlw 1 movwf var VERIF clrw subwf marque,0 bz M_INIT movfw var subwf marque,0 bnz MAIN M_INIT movfw var movwf marque CHOIX B_et_O movlw 3 ; télécommande B&O subwf marque,0 ; codes : duree=2 -->"0" ; duree=1 -->"1" bnz THOMSON ; movf curseur,1 ; bnz DECODAGE_PWM movlw D'8' movwf maxbits goto DECODAGE_PWM THOMSON movlw 2 ; télécommande THOMSON subwf marque,0 ; codes : duree=2 -->"0" ; duree=1 -->"1" bnz PHILIPS ; movf curseur,1 ; bnz DECODAGE_PWM movlw D'13' movwf maxbits goto DECODAGE_PWM PHILIPS movlw 1 ; télécommande PHILIPS subwf marque,0 ; codes : duree=2 -->"0" ; duree=1 -->"1" bnz MAIN ; movf curseur,1 ; bnz SUITE movlw D'13' movwf maxbits goto MAIN ;******************************************************************************** DECODAGE_PWM ; décodage PWM : B&O et THOMSON clrc btfsc duree,0 ; duree = 1 ? setc ; oui alors "1" rlf code,1 ; on enregistre le bit incfsz curseur,1 ; on a tous les bits ? goto WAIT_2 ; non, alors on boucle goto MAIN WAIT_2 bsf INTCON,T0IE ; on valide le timer btfss PORT_A,4 ; on attend que RA4 repasse à 0 goto CRENEAU ; RA4 est à 0, on poursuit goto WAIT_2 ;******************************************************************************** AFFICHAGE movlw H'FF' movwf count clrf digit0 clrf digit1 movfw final andlw H'0F' call RENVOI_CODE ; Recherche du code dans la table des segments movwf digit0 swapf final,0 andlw H'0F' call RENVOI_CODE ; Recherche du code dans la table des segments movwf digit1 movfw m_final andlw H'0F' call RENVOI_CODE ; Recherche du code dans la table des segments movwf digit3 ; le digit3 donne le code de la marque AFFICHE_7SEG btfsc affiche,0 goto AFF0 btfsc affiche,1 goto AFF1 btfsc affiche,2 goto AFF2 btfsc affiche,3 goto AFF3 movlw 1 movwf affiche return AFF0 movfw digit0 ; on digit0 place dans w movwf PORT_B ; on envoie w vers les afficheurs (Port B) movlw 8 ; Cycle d'affichage du digit concerné movwf PORT_A ; Validation de l'affichage movlw 2 movwf affiche return AFF1 movfw digit1 ; on digit1 place dans w movwf PORT_B ; on envoie w vers les afficheurs (Port B) movlw 4 ; Cycle d'affichage du digit concerné movwf PORT_A ; Validation de l'affichage movwf affiche return AFF2 movlw VIDE ; on digit1 place dans w movwf PORT_B ; on envoie w vers les afficheurs (Port B) movlw 2 ; Cycle d'affichage du digit concerné movwf PORT_A ; Validation de l'affichage movlw 8 movwf affiche return AFF3 movfw digit3 ; on digit1 place dans w movwf PORT_B ; on envoie w vers les afficheurs (Port B) movlw 1 ; Cycle d'affichage du digit concerné movwf PORT_A ; Validation de l'affichage movwf affiche return ;******************************************************************************** SUB_TIMER movwf var ; mot de commande --> var movfw RTCC ; RTCC --> w movwf result movfw var ; tampon --> w movwf RTCC ; initialisation du timer return ;******************************************************************************** RENVOI_CODE addwf PC,1 retlw ZEROT retlw UN retlw DEUX retlw TROIS retlw QUATRE retlw CINQ retlw SIX retlw SEPT retlw HUIT retlw NEUF retlw A_HEX retlw B_HEX retlw C_HEX retlw D_HEX retlw E_HEX retlw F_HEX END