A quoi ca sert?:
Prix de revient: ordre d'idée: à partir de 60F environ (10Euros).
Quelques images des codes de
differentes telecommandes (relevés à l'oscilloscope): (Base de
temps: 2ms/division)
Ci dessus, le code d'une telecommande Philips. (Touche pour augmenter le volume). Ce code
est du type RC-5
Ci dessus le code d'une telecommande Kenwood. (Touche pour augmenter le volume). Ce code
est du type REC-80.
Ci dessus le code d'une telecommande Technics. (Touche pour augmenter le volume). Ce code
est du type REC-80, mais il est bien plus long en terme de nombre de bits que le
precedent; ce qui fait qu'on ne peut pas memoriser 4 touches dans la memoire du PIC, mais
seulement 2 si on a ce type de telecommande.
Vous l'aurez remarqué, il existe deux normes de codage, (RC-5 et REC80), mais en plus le
codage differe en terme de vitesse et de nombre de bits entre chaque telecommande. Ceci ne
rend pas la memorisation du code facile, car il faut non seulement memoriser tous les
bits, mais en plus il faut memoriser la vitesse d'emission.
Comme si ca ne suffisait pas, il y a une porteuse à environ 40kHz lorsque la telecommande
emet un niveau haut (voir image ci dessus). Cette porteuse permet au recepteur d'éviter
les parasites dus aux néons, .... Le probleme, c'est qu'il faut recreer cette porteuse
avec le PIC pour que le recepeur réagisse!
Schéma:
Voici le schema relativement simple de la telecommande:
Description du schema de gauche à droite:
~ On a tout d'abord la partie receptrice avec une diode infra rouge branchée sur un
darlington PNP (T1+T2) pour amplifier fortement en courant. Le tout va sur une entrée
trigger du PIC (patte 3)
~ On trouve ensuite la partie emission, avec T4 qui est commandée par la patte 6 du PIC.
T4 sert à recreer le code en lui meme. T5 quant à lui sert à recreer la porteuse. Il
est commandé par la patte 7 du PIC.
nb: je ne sais pas s'il fallait faire comme ca pour recreer la porteuse, mais l'essentiel
c'est que ca marche!
~ A droite du PIC, on trouve deux LED pour indiquer les differents etats de la
telecommande (programmation, ...).
~ Le fait qu'il n'y ait pas de resistance de rappel pour les interrupteurs n'est pas une
erreur de ma part! En effet elles sont deja incluses dans le PIC, il suffit de les
activer.
Principe de fonctionnement:
Voici le principe que j'utilise pour memoriser le code sans erreur:
Quelques explications. Tout d'abord, on fait rechercher au PIC la durée minimale d'un etat (On mesure T et on le divise par 2). Ensuite, il "suffit" d'utiliser les interruptions du PIC, et d'interrompre l'execution du programme toutes les T/2 secondes pour memoriser l'etat de la LED receptrice (niveau haut ou bas).
Pour eviter les decalages entre l'horloge du PIC et l'horloge de la telecommande; je resynchronise l'horloge du PIC à chaque changement d'etat de la LED receptrice (Fleche violete). D'autre part, la durée avant interruption du programme lorsqu'il y a changement d'etat est T/4 (au lieu de T/2); ceci pour etre environ au milieu de l'etat a memoriser lorsqu'il y a interruption.
Matériel nécessaire:
Un fer a souder, de la soudure, du matériel pour graver les plaques, et
de préférence une insoleuse et une bonne imprimante.
PIC | PIC16F84A-04 (environ 40F soit 6.1Euros) |
R1 | 560 kOhm |
R2 | 100 Ohm |
R3, R5, R6, R7 | 1 kOhm |
R4 | 39 Ohm |
C1 | 100 µF |
C2 | 100 nF |
C3, C4 | 15 à 33 pF |
D1 | Photo diode receptrice (dans le cas d'un boitier parallelepipedique,
l'angle cassé sur le dessus de la LED indique la cathode) A priori a peu pres tous les modeles peuvent convenir; j'ai récupéré la mienne dans une television. Attention tout de meme de ne pas prendre un photo transistor, ca ne se branche pas pareil. |
D2 | Diode emetrice infra rouge 5mm quelconque. Vous pouvez eventuellement en mettre 2 (voir typon), pour augmenter la portée, mais dans ce cas il faut baisser la valeur de R4 (par exemple 15 Ohm ou moins). |
D3, D4 | LED 5mm |
T1, T2 | BC327-25 ou BC557B ou BC558B ou BC559B |
T3 | BC327 de preference (a cause du courant assez important qui circule dans D2). eve,tuellement BC557 |
T4 | BC337 de preference (a cause du courant assez important qui circule dans D2). eventuellement BC547 |
I1 à I6 | Interrupteurs poussoir miniatures à 4 pattes (voir la photo). Il faut imperativement qu'ils aient 4 pattes, car ces pattes sont reliées 2 à 2 à l'interieur de l'interrupteur et servent de strap de temps en temps. |
Q1 | Quartz 4MHz pour faire fonctionner le PIC |
S1 à S4 | Straps (morceaux de fil) |
Description:
Réalisation:
Essais et mode d'emploi:
Le programme (voir plus haut pour le
telecharger)
;Police: TERMINAL ;___________________________________________________ ;|Enregistreur de code de telecommandes Infra Rouge| ;___________________________________________________ ;Recepteur/Emmeteur Infra Rouges. ;Copyright Xavier IZARD: xizard@enib.fr, xizard@chez.com, http://move.to/xi ;Ca marche, il y a maintenant quatre boutons, branches sur PORTB4 a PORTB7 ;Il y a un bouton Enregistrement branche sur portA,0 (resistance au plus) ;Le PIC est maintenant capable de reconnaitre le type de code tout seul, ;en mesurant la largeur des impulsions. Pour cela mettre PORTA1 au niveau bas. (resistance au plus) ;Pour enregistrer un code, appuyer sur le bonton enregistre, puis sur la touche a enregistrer. ;pour resituer un code, appuyer simplement sur la touche correpondante ;(pour effacer tous les codes, appuyer sur la touche enregistrement avant d'alimenter le PIC) ;La LED receptrice est branchee sur un darlington PNP sur le PORTA,4 (entree trigger) ;LA LED emmetrice est branchee sur le PORTB,0 ;Une LED indicatrice est branchee sur le PORTB,1 ;La porteuse sort de PORTB,2, va sur un PNP qui va au plus de la LED ;interruptions a utiliser: (donne a titre indicatif, le PIC les detectes tout seul) ;telecommandes Philips, Grundig, ... (code RC-5): echant=D'38' et echantd=D'140' ;telecommandes Kenwood, Goldstar, ... (code REC-80): echant=D'124' et echantd=D'180' ;Le programme a ete teste avec plein de telecommandes, de plein de marque differentes. ;Il a fonctionnne dans tous les cas. ;marques testees: Philips, Kenwood, JVC, Goldstar, Grundig, Akai, Technics, Panasonic. ;Pour les telecommandes Technics et Panasonic, et peut etre d'autres, enlevez le point virgule ;dans la ligne "#DEFINE Panasonic" (attention vous n'aurez plus que 2 memoire, en effet le code de ces telecommandes ;est tres long, et ne tient pas sur 16bits comme c'est le cas pour les autres codes) ;#DEFINE Panasonic list p=16f84,f=inhx8m __config B'11111111110001' #include "p16f84a.inc" preced equ H'0C' W_temp equ H'0D' ST_temp equ H'0E' index equ H'0F' echant equ H'10' ;"durée" minimale d'un etat (haut ou bas) echantd equ H'11' ;"durée" correpondant d'un "demi etat" mini equ H'12' ;variable temporaire transferée dans echant temp1 equ H'13' org H'00' goto Debut ;_________________________________________________________________________________________________________ ;|On vient ici lorsqu'il y a interruption (permet d'enregistrer et de recreer le code a la bonne vitesse)| ;_________________________________________________________________________________________________________ org H'04' ; le programme s'execute a partir d'ici lorsqu'il y a interruption movwf W_temp ; On sauvegarde W et STATUS pour pouvoir les restituer intacts swapf STATUS,0 ; apres le traitement de l'interruption. movwf ST_temp ; On utilise un swap pour ne pas modifier le contenu de STATUS (C,DC,Z) bcf STATUS,RP0 ; pour le cas ou il y aurait interruption lorsqu'on est dans la page mem 1 btfss PORTA,0 ; Est-on en mode enregistrement? call Enr_code ; Oui alors on va au label Enr_code btfsc PORTA,0 ; Est on en mode resitution du code? call Rest_code ; Oui alors on va au label Rest_code bcf INTCON,T0IF ; On annule l'interruption swapf ST_temp,0 ; On remet STATUS dans le bon sens movwf STATUS ; Et on le resitue movf echant,0 ; On reinitialise TMR0 avec la valeur contenue dans echant movwf TMR0 ; (enchant contient la duree minimale d'un etat haut ou bas) swapf W_temp,1 ; swapf W_temp,0 ; On a restitue W sans modifier le contenu de STATUS retfie ; On revient a l'endroit ou le programm s'est interrompu. ;______________________ ;|Configuration du PIC| ;______________________ Debut bsf STATUS,RP0 ; On passe dans la zone memoire numero 1 movlw B'00000001' ; movwf OPTION_REG ; Predivision par 4 (incrementation de TMR0 toutes les 4micorsecondes) movlw B'00010000' ; movwf TRISA ; bit a 1 => patte en entree; bit a 0 => patte en sortie movlw B'11111100' ; movwf TRISB ; bit a 1 => patte en entree; bit a 0 => patte en sortie bcf STATUS,RP0 ; On passe dans la zone memoire numero 0 movlw D'124' ; echant est charge avec une valeur par defaut, mais il est conseille de movwf echant ; refaire le reglage automatique pour chaque telecommande. Il suffit de ; mettre PORTA1 au niveau bas et d'appuyer sur plein de touches de la ; telecommande en attendant l'extinction de la LED Menu bcf PORTB,0 ; On remet a zero la sortie PORTB0 (LED d'emmission) bsf PORTB,1 ; Pour eviter de consommer inutilement (transistor PNP) bcf PORTA,0 ; Led indicatrice de mode (enregistrement ou lecture) movf echantd,0 ; On va charger TMR0 avec une valeur calculee a partir de echant: movwf TMR0 ; echantd = echant - 8 + (255 - echant) / 2 clrf index ; index contient le bit en cours de traitement. movlw H'FF' ; movwf echantd ; Tout ceci permet de calculer la valeur de echantd a partir de echant: movf echant,0 ; echantd = echant - 8 + (255 - echant) / 2 subwf echantd,1 ; On cree un interruption plus rapidement lors d'un changement d'etat bcf STATUS,C ; de la LED receptrice rrf echantd,1 ; Division de echantd par 2 movf echant,0 ; addwf echantd,1 ; movlw D'008' ; subwf echantd,1 ; bsf index,7 ; ;__________________________________ ;|On attend l'appui sur une touche| ;__________________________________ Menu1 bcf PORTA,1 ; On eteint la LED indicatrice clrf EEADR ; 0 -> EEADR: contient l'adresse a laquelle on va ecrire dans l'EEPROM btfss PORTB,4 ; as t'on appuye sur la touche 0 goto Boucle4 ; Oui alors on va au label Boucle 4 (on va restituer le code correspondant) #IFDEF Panasonic clrf EEADR #ELSE movlw H'10' ; sinon on continue movwf EEADR ; H'10' -> EEADR: contient l'adresse a laquelle on va ecrire dans l'EEPROM #ENDIF btfss PORTB,5 ; as t'on appuye sur la touche 1 ? goto Boucle4 ; Oui alors on va on va restituer le code correspondant a la touche 1 movlw H'20' ; sinon on continue movwf EEADR ; H'20' -> EEADR: contient l'adresse a laquelle on va ecrire dans l'EEPROM btfss PORTB,6 ; as t'on appuye sur la touche 2 ? goto Boucle4 ; Oui alors on va on va restituer le code correspondant a la touche 2 #IFDEF Panasonic movlw H'20' #ELSE movlw H'30' ; sinon on continue #ENDIF movwf EEADR ; H'30' -> EEADR: contient l'adresse a laquelle on va ecrire dans l'EEPROM btfss PORTB,7 ; as t'on appuye sur la touche 3 ? goto Boucle4 ; Oui alors on va on va restituer le code correspondant a la touche 3 btfss PORTB,3 ; Appuye t'on sur la touche echantillonage goto Echantillonage ; Oui alors on va au label echantillonage (recherche de la duree mini ; d'un etat haut ou bas. a faire une fois par telecommande) btfsc PORTB,2 ; Veut-on enregistrer une nouvelle touche? goto Menu1 ; Non alors on revient au label Menu1 movlw H'30' ; H'30' -> FSR. FSR est un pointeur sur la RAM. Il contient l'adresse d'une movwf FSR ; case memoire de la RAM. On recupere le contenu de cette case memoire dans ; la variable INDF. ;____________________________________________________________ ;|On efface une partie de la RAM avant d'enregistrer le code| ;____________________________________________________________ Efface_RAM clrf INDF ; incf FSR,1 ; Va permettre d'effacer le contenu de la RAM entre les adresse H'30' movlw H'50' ; et H'4F'. Cette zone de memoire servira a stocker provisoirement le subwf FSR,0 ; code de la telecommande. (On ne peux pas stocker directement le code btfss STATUS,Z ; de la telecommande dans l'EEPROM, car le temps d'ecriture est trop long) goto Efface_RAM ; movlw H'30' ; On recharge FSR avec la valeur H'30' movwf FSR ; ;__________________________________________________________________ ;|On attend de savoir quelle touche l'utilisateur veut enregistrer| ;__________________________________________________________________ Menu2 clrf EEADR ; btfss PORTB,4 ; goto Boucle1 ; #IFDEF Panasonic clrf EEADR #ELSE movlw H'10' ; movwf EEADR ; #ENDIF btfss PORTB,5 ; goto Boucle1 ; movlw H'20' ; On regarde quelle touche on veut enregister, et on charge l'adresse movwf EEADR ; de l'EEPROM en consequence. btfss PORTB,6 ; goto Boucle1 ; #IFDEF Panasonic movlw H'20' #ELSE movlw H'30' ; #ENDIF movwf EEADR ; btfss PORTB,7 ; goto Boucle1 ; goto Menu2 ; ;__________________________________________________ ;|On attend que la telecommande commence a emettre| ;__________________________________________________ Boucle1 btfss PORTA,4 ; On attent que la telecommande commence a emmetre. goto Boucle1 bsf PORTA,1 ; On indique a l'utilisateur que l'enregistrement debute movf PORTA,0 ; preced va contenir la valeur precedente de PORTA (pour pouvoir movwf preced ; detecter les changements d'etat) movlw B'10100000' ; On va autoriser les interruptions dues au Timer0 movwf INTCON ; (interruption chaque fois que TMR0 passe de H'FF' a H'00' ;_________________________________________________________________________________________________________ ;|C'est l'enregistement du code. A chaque interruption l'etat de la LED emettrice est stocke dans un bit | ;|de la RAM. L'horloge du PIC est resynchronisee sur l'horloge de la telecommande a chaque changement | ;|d'etat de cette derniere | ;_________________________________________________________________________________________________________ Boucle2 movf preced,0 ; On compare la valeur actuelle de PORTA avec la valeur precedente. subwf PORTA,0 ; S'il y a changement d'etat de la led receprtrice, alors on va btfss STATUS,Z ; resynchroniser les interruptions sur le front. call Init_timer0 ; ; btfss PORTA,4 ; ; bcf PORTB,0 ; La sortie PORTB0 recopie ce que le PIC recoit sur PORTA4 ; btfsc PORTA,4 ; (enlever les point virgule pour verifier le bon fonctionnement a l'oscillo) ; bsf PORTB,0 ; movf PORTA,0 ; movwf preced ; On transfert PORTA dans preced movlw H'50' ; On regarde si l'enregistrement n'est pas finit (memoire pleine) subwf FSR,0 ; btfss STATUS,Z ; goto Boucle2 ; Si l'enregistrement est finit, on ne retourne pas au label Boucle2 bcf INTCON,GIE ; On desactive les interruptions movlw H'30' ; On recharge le pointeur sur la RAM: FSR avec la valeur movwf FSR ; du debut ;_________________________________________________________________________________________________________ ;|On transfert maintenant le contenu de la RAM dans l'EEPROM (On ne peut pas ecrire directement dans | ;|l'EEPROM, car le temps d'ecriture est trop long (4ms mini). | ;_________________________________________________________________________________________________________ Boucle3 movf INDF,0 ; On recupere le contenu de la RAM a l'adresse FSR. movwf EEDATA ; On met ce contenu dans EEDATA call Ecriture ; et on va l'ecrire dans l'EEPROM #IFNDEF Panasonic movlw H'0E' ; subwf EEADR,0 ; btfsc STATUS,Z ; goto Type_code ; #ENDIF movlw H'1E' ; subwf EEADR,0 ; btfsc STATUS,Z ; On regarde si EEADR a atteint sa valeur finale (4 cas possibles), au goto Type_code ; quel cas, on arrete d'enregisterer #IFNDEF Panasonic movlw H'2E' ; subwf EEADR,0 ; btfsc STATUS,Z ; goto Type_code ; #ENDIF movlw H'3E' ; subwf EEADR,0 ; btfsc STATUS,Z ; goto Type_code ; incf FSR,1 ; Sinon on incremente la valeur du pointeur sur la RAM incf EEADR,1 ; et on incremente la valeur de l'adresse de l'EEPROM goto Boucle3 ; Et on va recommencer un cycle d'ecriture ;___________________________________________________________________________________________ ;|Dans le dernier octet concernant une touche, on enregistre la vitesse d'execution du code| ;___________________________________________________________________________________________ Type_code incf EEADR,1 ; On incremente une derniere fois EEADR movf echant,0 ; On va ecrire dans la derniere case memoire concernant une touche movwf EEDATA ; la valeur de echant, c'est a dire la "duree" minimale d'un etat call Ecriture ; (haut ou bas) bcf PORTA,1 ; On indique a l'utilisateur que l'enregistrement est finit goto Menu ; On revient au label Menu ;______________________________________________________________________ ;|A partir d'ici, ca concerne la restitution du code (partie emission)| ;______________________________________________________________________ Boucle4 bcf PORTB,0 ; On eteint la LED d'emission bsf PORTA,0 ; Pour indiquer qu'on est en mode restitution #IFDEF Panasonic movlw H'1F' #ELSE movlw H'0F' ; #ENDIF addwf EEADR,1 ; On va aller lire dans l'EEPROM (tout a la fin du code d'une touche) bsf STATUS,RP0 ; la duree minimale d'un etat pour pouvoir regler les interruptions bsf EECON1,RD ; correctement, et ainsi resituer le code a la bonne vitesse bcf STATUS,RP0 ; movf EEDATA,0 ; movwf echant ; #IFDEF Panasonic movlw H'1F' #ELSE movlw H'0F' ; #ENDIF subwf EEADR,1 ; clrf preced ; preced va cette fois ci contenir le nombre d'octet qu'on a lu dans l'EEPROM clrf index ; index contient la valeur du bit en cours de lecture bsf index,7 ; On commence par le bit le plus a gauche movf echant,0 ; movwf TMR0 ; on transfert la valeur de echant de TMR0 movlw B'10100000' ; movwf INTCON ; On reactive les interruptions bsf PORTB,0 ; On allume la LED emmetrice (le code commence forcement par un "1" Boucle5 #IFDEF Panasonic movlw D'31' #ELSE movlw D'15' ; #ENDIF subwf preced,0 ; On regarde si on n'a pas restitue toutes les valeurs (15 octets au max) btfsc STATUS,Z ; goto Fin ; Si c'est le cas, on va au label Fin nop ; nop ; Pour retarder un peu le PIC, en fait ca sert à restituer la porteuse a nop ; peu pres a bonne frequence (38kHz environ) nop ; btfsc PORTB,1 ; goto Reset_PORTB2 ; Permet de faire changer d'etat PORTB2 a une frequence d'environ 38kHz bsf PORTB,1 ; (pour recreer la porteuse) goto Boucle5 ; on retourne au label Boucle5 pour continuer a resituer le code Reset_PORTB2 bcf PORTB,1 ; Sous programme pour faire changer d'etat PORTB2 a 38kHz environ goto Boucle5 ; ;________________________________________________________________________________________________ ;|Sous programme appele pour mesurer la duree minimale d'un etat haut ou bas de la LED emettrice| ;________________________________________________________________________________________________ Echantillonage movlw D'100' ; On initialise la variable temporaire temp1 a la valeur 100 pour faire movwf temp1 ; cent mesures bsf STATUS,RP0 ; Zone memoire numero 1 movlw B'00000010' ; movwf OPTION_REG ; predivision par 8 (incrementation de TMR0 toutes les 8 microsecondes) bcf STATUS,RP0 ; On revient dans la zone memoire numero 0 bsf PORTA,1 ; On allume la LED indicatrice movlw H'FF' ; On initialise mini a la plus grande valeur possible movwf mini ; mini contiendra la "duree" minimale d'un etat (haut ou bas) de la LED receptrice Ech0 bcf PORTA,0 ; On eteint l'autre LED indicatrice bcf INTCON,GIE ; On desactive les interruptions btfsc PORTA,4 ; On attend que la led receptrice soit au niveau bas goto Ech0 Ech1 btfss PORTA,4 ; On attend que la LED receptrice soit au niveau haut goto Ech1 ; (les quelques lignes precedentes permettent de detecter un front montant) clrf TMR0 ; 0 -> TMR0 bsf PORTA,0 ; On alume l'autre LED indicatrice movlw B'10100000' ; movwf INTCON ; On reactive les interruptions. Ech2 movlw D'250' ; On s'arrange pour qu'il n'y ait jamais interruption subwf TMR0,0 ; En fait TMR0 va uniquement nous servir a mesurer la "duree" d'un etat btfsc STATUS,C ; goto Ech0 ; Dans le cas ou TMR0 depasse D'250', on revient à Ech0 btfsc PORTA,4 ; goto Ech2 ; On revient au label Ech2 tant que l'entree de la led receptrice n'est pas a "0" Ech3 movlw D'250' ; subwf TMR0,0 ; btfsc STATUS,C ; Idem que precedemment, mais avec un niveau haut pour l'entree de la goto Ech0 ; receptrice. ; Encore une fois, ces quelques lignes nous ont permis de detecter un btfss PORTA,4 ; front montant goto Ech3 ; bcf INTCON,GIE ; On desactive les interruptions movf TMR0,0 ; subwf mini,0 ; On compare la valeur de TMR0 avec la valeur minimale prise par cette variable btfss STATUS,C ; Si la valeur de TMR0 < mini, alors on va l'enregistrer goto Fin_ech ; Sinon on va au label Fin_ech movf TMR0,0 ; movwf mini ; TMR0 -> mini sublw H'FF' ; addlw D'006' ; 6 Par ce que ca marchait mieux movwf echant ; 255 - mini + 6 -> echant ; ainsi on pourra charger TMR0 directement avec la valeur de echant Fin_ech decfsz temp1,1 ; As t-on fait 100 echantillonages? goto Ech0 ; Non alors on continue bcf PORTA,1 ; On eteint la LED indicatrice pour dire que l'echantillonage est finit bsf STATUS,RP0 ; movlw B'00000001' ; movwf OPTION_REG ; On remet la predivision par 4 bcf STATUS,RP0 ; goto Menu ; On revient au menu avec la bonne valeur dans echant Init_timer0 movf echantd,0 ; echantd (comme echantillonage de depart) -> TMR0 movwf TMR0 ; return ; ;____________________________________________________ ;|Sous programme concerant la retransmission du code| ;____________________________________________________ Rest_code ; btfsc PORTB,1 ; etait cense rendre la porteuse 38kHz plus reguliere ; goto Reset2_PORTB2 ; Il s'est avere que c'est ce qui empechait le bon fonctionnement ; bsf PORTB,1 ; sur une chaine Goldstar. En cas de pb essayez d'enlever les ; du debut Rest_code2 bcf STATUS,C ; Permet d'eviter l'apparution de "1" lors de la rotation (rrf) rrf index,1 ; on decale tout vers la droite. (traitement du bit suivant) btfss STATUS,C ; on regarde si on n'a pas fait un tour complet goto Fin_rest_code ; non alors on saute quelques lignes clrf index ; bsf index,7 ; sinon on reinitialise index a B'10000000' incf EEADR,1 ; On incremente EEADR pour changer l'octet en cours de traitement incf preced,1 ; On incremente la variable preced qui contient le nb d'octets traites Fin_rest_code bsf STATUS,RP0 ; bsf EECON1,RD ; On lit le contenu de l'EEPROM a l'adresse EEADR. Ce contenu est mis bcf STATUS,RP0 ; dans EEDATA movf index,0 ; Et logique avec index pour recuperer uniquement le bit qui nous interesse andwf EEDATA,1 ; Par exemple index = B'00010000' et EEDATA = B'10000111' alors EEDATA = 0 movf EEDATA,1 ; btfsc STATUS,Z ; On regarde si EEDATA est nul, dans ce cas on eteint la LED emmetrice goto Eteint ; bsf PORTB,0 ; sinon on l'allume return Eteint bcf PORTB,0 return Reset2_PORTB2 bcf PORTB,1 ; sert a faire changer d'etat PORTB2 goto Rest_code2 ; ;_________________________________________________________ ;|Sous programme en rapport avec l'enregistrement du code| ;_________________________________________________________ Enr_code btfss PORTA,4 ; La LED receptrice est-elle a "1" goto Suite_Enr_code ; Non alors on laisse le bit correpondant de la RAM a "0" (RAM prealablement effacee) movf index,0 ; On met index dans W iorwf INDF,1 ; On fait un OU logique entre index et le contenude la RAM a l'adresse FSR ; ceci permet de garder le contenu de INDF intact, et de ne mettre a "1" ; que le bit qui nous interesse, c'est a dire celui d'index Suite_Enr_code bcf STATUS,C ; Permet d'eviter l'apparution de "1" lors de la rotation (rrf) rrf index,1 ; deplacement de tous les bits d'un cran vers la droite btfss STATUS,C ; On regarde si on a fait un tour complet. return ; Sinon on revient clrf index ; Si oui: bsf index,7 ; On reinitialise index a B'10000000' incf FSR,1 ; On incremente FSR pour memoriser dans l'octet suivant de la RAM return ;___________________________________________________ ;|Sous programme pour ecrire dans la memoire EEPROM| ;___________________________________________________ Ecriture bsf STATUS,RP0 ; on passe dans la zone memoire numero 1 clrf EECON1 ; remise a zero des eventuelles erreurs bsf EECON1,WREN ; on autorise l'ecriture movlw H'55' ; movwf EECON2 ; securite de microchip pour eviter les ecritures movlw H'AA' ; intempestives. movwf EECON2 ; bsf EECON1,WR ; on ecrit pour de bon Fin_ecriture btfsc EECON1,WR ; goto Fin_ecriture ; on attend que l'operation d'ecriture soit finie (de l'ordre de la ms, bcf STATUS,RP0 ; contre une micro seconde pour un cycle d'horloge) return Fin bcf INTCON,GIE ; On desactive les interruptions goto Menu ; On revient au label Menu ;___________________________________________________________ ;|Permet d'ecrire des donnees dans la memoire EEPROM du PIC| ;___________________________________________________________ org H'210F' ;Adresse = H'2100' + Adresse de l'EEPROM a laquelle on veut ecrire de D'124' ;Permet d'eviter un blocage du PIC lors de la premiere utilisation si on appuie sur une touche non programmee org H'211F' de D'124' org H'212F' de D'124' org H'213F' de D'124' end |
Remarques:
pour tout renseignement, question, commentaire, ... n'hesitez pas a
écrire à xizard@enib.fr
Attention je ne suis en aucun cas responsable des dommages corporels ou
matériels que pourrait causer le montage.