Clé dallas + i2c (24c32)

Contenu du snippet

Ce programme est déstiné a être inséré dans un pic ou un microcontroleur. il gère 2 protocoles : celui des clés dallas (iButton) et du protocole I2C pour utiliser une mémoire EEPROM 24C32.
Il est donc nécessaire de réaliser un système électronique, si vous désirez obtenir la doc technic envoyez-moi un mail ou aller sur :
http://www.webfractales.com/projets/

Source / Exemple :


/********************************************************************************

  • *
  • Lecteur-Enregistreur Dallas *
  • *
  • The "Lecteur-Enregistreur Dallas" is a read/write interface of Dallas keys. *
  • See the documentations for more explainations. *
  • *
  • Copyright (C) 2003-2005 Julien MICHOT *
  • *
  • Contact : m.i.t.c.h@free.fr - http://www.webfractales.com/ *
  • *
  • This program is free software; you can redistribute it and/or *
  • modify it under the terms of the GNU General Public License *
  • as published by the Free Software Foundation; either version 2 *
  • of the License, or (at your option) any later version. *
  • *
  • This program is distributed in the hope that it will be useful, *
  • but WITHOUT ANY WARRANTY; without even the implied warranty of *
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  • GNU General Public License for more details. *
  • *
  • You should have received a copy of the GNU General Public License *
  • along with this program; if not, write to the Free Software *
  • Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  • *
  • *
  • *
                                                                                                                                                                • /
; Programme réalisé par Julien Michot - MiTcH ; Pour le projet de réalisation de 2ème année ; Lecteur-Enregistreur Dallas ; zone de d,finition des ,quivalences (equ) OctMemEcrire equ 10100000b OctMemLire equ 10100001b ; zone de d,finition des variables adressables au niveau du bit (bit) Cle bit P3.2 Enreg bit P1.4 Supp bit P1.5 SDA bit P2.3 SCL bit P2.4 Led_OK bit P1.0 Led_Err bit P1.1 Led_Enreg bit P1.2 Led_Supp bit P1.3 ; d,but de la zone de m,moire de donn,es en RAM interne (ds) dseg at 30h ; avant : 30 cle1 ds 8 ; clé lue cle2 ds 8 ; clé contenue dans la mémoire etat ds 1 ; flag d'état (10101010=OK) erreur ds 1 ; non utilisé adrs ds 2 ; adresse dans la mémoire adrs_temp ds 2 TEMPS ds 1 ; variable utilisée pour la temporisation ; fin de la zone de m,moire de donn,es en RAM interne ; d,but de la zone de m,moire de programme en EPROM cseg at 0 ; zone des vecteurs d'interruptions org 0 ljmp main ; zone de constantes (db) org 30h ; avant : 30 ; zone de sous programmes ;-----------------------Fonction de dialogue avec la clé----------------------- ; initialisation des entrées-sories Init: mov adrs,#0 mov adrs+1,#0 lcall Effacer_cle setb Cle setb SDA setb SCL clr Led_Err clr Led_Supp clr Led_Enreg clr Led_OK mov etat,#0 mov erreur,#0 mov IE,#00000000b ret ;cette fonction envoie un '1' à la clé Ecrire_1: clr Cle mov TEMPS,#3 lcall Tempo setb Cle mov TEMPS,#80 lcall Tempo ret ;cette fonction envoie un '0' à la clé Ecrire_0: clr Cle mov TEMPS,#50 lcall Tempo setb Cle mov TEMPS,#20 lcall Tempo ret ;reset la clé, permet de redemander les octets à la clé Reset: Clr Cle mov TEMPS,#255 lcall Tempo mov TEMPS,#140 lcall Tempo setb Cle mov TEMPS,#15 lcall Tempo clr Cle mov TEMPS,#80 lcall Tempo setb Cle mov TEMPS,#170 lcall Tempo ret ;Effacer les 8 octets de la variable cle1 Effacer_cle: mov cle1,#00000000b mov cle1+1,#00000000b mov cle1+2,#00000000b mov cle1+3,#00000000b mov cle1+4,#00000000b mov cle1+5,#00000000b mov cle1+6,#00000000b mov cle1+7,#00000000b ret ;Fonction tres importante ;elle permet de réaliser une temporisation de 128us max ;le temps de tempo est dans la variable TEMPS Tempo: djnz TEMPS,Tempo ret ;----------------------Fonction de dialogue avec la mémoire--------------------- ;Signal de début de transmission de la mémoire Start: clr SDA mov TEMPS,#2 lcall Tempo lcall Front_D ret ;Signal de fin de transmission de la mémoire Stop: clr SCL mov TEMPS,#2 lcall Tempo clr SDA mov TEMPS,#2 lcall Tempo lcall Front_M setb SDA ret ;Cette fonction Acknowledge signifie " un autre octet va etre transmit" ACK: mov TEMPS,#2 lcall Tempo clr SDA lcall Front_M lcall Front_D setb SDA mov TEMPS,#2 lcall Tempo ret ;prevenir la mémoire qu'aucun octet ne va etre transmit NOACK: mov TEMPS,#2 lcall Tempo setb SDA lcall Front_M lcall Front_D ret ;réaliser un front montant pour la mémoire Front_M: clr SCL mov TEMPS,#2 lcall Tempo setb SCL mov TEMPS,#2 lcall Tempo ret ;réaliser un front descendant pour la mémoire Front_D: setb SCL mov TEMPS,#2 lcall Tempo clr SCL mov TEMPS,#2 lcall Tempo ret ;faire une impulsion Impulsion: lcall Front_M lcall Front_D ret ;tester si la mémoire à reçu et compris ce que l'on a demander Test_ACK: lcall Front_M jb SDA,Erreur_Mem;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; lcall Front_D ret ;Gestion des erreurs Erreur: lcall LED_ERR lcall Attente_LED lcall Init lcall Attente_Fin ljmp main ret Erreur_Mem:;;;;;;;;;;;;;;;;;;;;;;TESTER SI C LA MEMOIRE;;;;;;;;;;;; lcall LED_ERR lcall LED_OK lcall Attente_LED lcall Init lcall Attente_Fin ljmp main ret ;Cette fonction ecrit les 8 octets de la clé dans la mémoire, ;à l'adresse contenue dans les 2 octets de adrs Ecrire_Mem: ; lcall Tester_Mem_Dispo ;attendre que la mémoire soit prête lcall Start ;envoyer le premier octet mov A,#OctMemEcrire mov B,#8 ecrire_suite: RLC A mov SDA ,C lcall Impulsion djnz B,ecrire_suite setb SDA lcall Test_ACK ;mettre dans la pile kles 8 octets de la clé et de son adresse push cle1+7 push cle1+6 push cle1+5 push cle1+4 push cle1+3 push cle1+2 push cle1+1 push cle1 push adrs push adrs+1 ;ecrire les 10 octets (2-adresse + 8-clé) mov R2,#10 ecrire_suite1: pop A mov R3,#8 ecrire_suite2: RLC A mov SDA ,C lcall Impulsion djnz R3,ecrire_suite2 lcall Test_ACK djnz R2,ecrire_suite1 lcall Stop ; mov P1,#01010000b ret ;Cette fonction lit les 8 octets contenus dans la mémoire, ;à l'adresse contenue dans les 2 octets de adrs Lecture_Mem: ; lcall Tester_Mem_Dispo ;attendre que la mémoire soit prête ;pour lire les octets à une adresse il faut tout d'abord ecrire ;dans la mémoire l'adresse à laquelle nous voulons lire lcall Start ;envoyer le premier octet mov A,#OctMemEcrire mov B,#8 lecture_suite: RLC A mov SDA ,C lcall Impulsion djnz B,lecture_suite setb SDA lcall Test_ACK ; mettre les adresses dans la pile push adrs push adrs+1 ;ecriture des 2 octets de l'adresse mov R2,#2 lecture_suite1: pop A mov R3,#8 lecture_suite2: RLC A mov SDA ,C lcall Impulsion djnz R3,lecture_suite2 lcall Test_ACK djnz R2,lecture_suite1 lcall Stop ;La lecture en elle-meme : lcall Start mov A,#OctMemLire mov B,#8 lecture_suite8: RLC A mov SDA ,C lcall Impulsion djnz B,lecture_suite8 setb SDA lcall Test_ACK ;mov P1,#11000000b ; lecture des 8 octets mov R2,#8 lecture_suite3: mov R3,#8 lecture_suite4: lcall Front_M mov C,SDA lcall Front_D RLC A djnz R3,lecture_suite4 push A ;mettre dans la pile cjne R2,#1, lecture_suite5 lcall NOACK ljmp lecture_suite6 lecture_suite5: lcall ACK lecture_suite6: djnz R2,lecture_suite3 lcall Stop ;restitution dans le registre nø2 pop cle2+7 pop cle2+6 pop cle2+5 pop cle2+4 pop cle2+3 pop cle2+2 pop cle2+1 pop cle2 ; mov P1,#10100000b ; mov P1,cle2 ret ;teste si la mémoire est prête pour être utilisée Tester_Mem_Dispo: lcall Start mov A,#OctMemLire mov B,#8 Dispo_suite: RLC A mov SDA ,C lcall Impulsion djnz B,Dispo_suite setb SDA lcall Front_M jnb SDA,fin_dispo lcall Front_D lcall Stop mov TEMPS,#50 lcall Tempo ljmp Tester_Mem_Dispo ;ne sort que si la mémoire à répondu fin_dispo: lcall Front_D lcall Stop mov B,#255 lcall Tempo ; mov P1,#10100110b mov etat,#1 ret ;Reset la mémoire et écrit l'octet 11111111b signifiant la fin des codes Reset_Mem: ; lcall Tester_Mem_Dispo lcall Init mov A,#9 Reset_Mem_suite1: lcall Front_M setb SDA lcall Front_D djnz A,Reset_Mem_suite1 lcall Start lcall Effacer_cle mov adrs,#0 mov adrs+1,#0 mov cle1,#11111111b mov cle1+1,#00000000b ; mov TEMPS,#10 ; lcall Tempo lcall Ecrire_Mem mov etat,#10101010b ret ;--------------Fonction gérant l'enregistrement et la suppression--------------- ;Enregistrer les 8 octets de la clé dans la mémoire Enregistrer: lcall Tester_cle mov A,etat cjne A,#10101010b,save_suite ;cle d,j. enregistr,e, ou vient d'^tre enregistr,e ljmp fin_save_err save_suite: lcall Trouver_espace ; espace libre : état -> 00000000b ;fin (1111111)->00001111b mov A,etat cjne A,#00000000b,save_suite3 ; lcall Tester_Mem_Dispo lcall Ecrire_Mem ljmp fin_save save_suite3: cjne A,#00001111b,fin_save_err ; lcall Tester_Mem_Dispo lcall Ecrire_Mem mov A,adrs add A,#8 mov adrs,A cjne A,#00000000b,save_suite2 INC adrs+1 save_suite4: mov A,adrs+1 cjne A,#00010000b,save_suite2 ljmp fin_save save_suite2: lcall Effacer_cle mov cle1,#11111111b ; lcall Tester_Mem_Dispo lcall Ecrire_Mem ljmp fin_save fin_save_err: ;erreurs mov etat,#0 ljmp fin_fin_save fin_save: ;c bon mov etat,#10101010b fin_fin_save: ret ;Supprimer les 8 octets de la mémoire Supprimer: mov adrs,#0 mov adrs+1,#0 mov A,#0 lcall Tester_cle mov A,etat cjne A,#10101010b,fin_supp_err lcall Effacer_cle lcall Tester_Mem_Dispo ; lcall Ecrire_Mem ljmp fin_supp fin_supp_err: mov etat,#01010000b ljmp fin_fin_supp fin_supp: mov etat,#10101010b fin_fin_supp: ;lcall Reset_Mem ret ;tester si la clé est enregistrée dans la mémoire Tester_cle: mov etat,#00001111b mov A,#0 clr C mov adrs,#0 mov adrs+1,#0 ljmp Tester_cle_suite2 Tester_cle_suite1: mov A,adrs add A,#8 mov adrs,A cjne A,#00000000b,Tester_cle_suite2 inc adrs+1 Tester_cle_suite4: mov A,adrs+1 cjne A,#00010000b,Tester_cle_suite2 ljmp fin_fin_mem Tester_cle_suite2: lcall Tester_Mem_Dispo ; lcall Lecture_Mem mov R0,cle2 cjne R0,#11111111b,Tester_cle_suite3 ljmp fin_fin_mem Tester_cle_suite3: mov A,cle1+1 cjne A,cle2+1,Tester_cle_suite1 mov A,cle1+2 cjne A,cle2+2,Tester_cle_suite1 mov A,cle1+3 cjne A,cle2+3,Tester_cle_suite1 mov A,cle1+4 cjne A,cle2+4,Tester_cle_suite1 mov A,cle1+5 cjne A,cle2+5,Tester_cle_suite1 mov A,cle1+6 cjne A,cle2+6,Tester_cle_suite1 mov A,cle1+7 cjne A,cle2+7,Tester_cle_suite1 ;ici le code est bon mov etat,#10101010b ljmp fin_tester_cle fin_fin_mem: mov etat,#00001111b ; mov etat,adrs fin_tester_cle: ;si connue adrs-> son adr dans la mem ;si non connue adrs -> adr de la derniSre place o- il n'y a rien ! ; cl, connue -> 10101010b ;fin (1111111)->00001111b ret ;tester si la clé est enregistrée dans la mémoire Trouver_espace: mov adrs,#0 mov adrs+1,#0 ljmp Trouver_esp_suite2 Trouver_esp_suite1: mov A,adrs add A,#8 mov adrs,A cjne A,#00000000b,Trouver_esp_suite4 INC adrs+1 Trouver_esp_suite4: mov A,adrs+1 cjne A,#00010000b,Trouver_esp_suite2 ljmp fin_fin_mem_1 Trouver_esp_suite2: ; lcall Tester_Mem_Dispo lcall Lecture_Mem mov R0,cle2 cjne R0,#11111111b,Trouver_esp_suite3 ljmp fin_fin_mem_0 Trouver_esp_suite3: cjne R0,#00000000b,Trouver_esp_suite1 mov etat,#00000000b ljmp fin_Trouver_espace fin_fin_mem_0: mov etat,#00001111b ljmp fin_Trouver_espace fin_fin_mem_1: mov etat,#11111111b fin_Trouver_espace: ; espace libre : état -> 00000000b ;fin (1111111)->00001111b ret ; FONCTIONS D'AFFICHAGE LED_OK: mov A,etat clr Led_OK cjne A,#10101010b,fin_led1 setb Led_OK ljmp fin_fin_led1 fin_led1: setb Led_Err fin_fin_led1: ret LED_ENREG: mov A,etat clr Led_Enreg cjne A,#10101010b,fin_led2 setb Led_Enreg fin_led2: ret LED_SUPP: mov A,etat clr Led_Supp cjne A,#10101010b,fin_led3 setb Led_Supp fin_led3: ret LED_ERR: setb Led_Err fin_led4: ret Attente_LED: mov R0,#5 fin_tt1: mov A,#250 fin_tt2: mov TEMPS,#250 lcall Tempo djnz A,fin_tt2 djnz R0,fin_tt1 ret Attente_Fin: mov R0,#5 fin_t1: mov A,#250 fin_t2: mov TEMPS,#250 lcall Tempo djnz A,fin_t2 djnz R0,fin_t1 ret ;;;;;fonction servant à tester les différentes fonctions;;;;;;;;; ;Fonction_tester: ; mov adrs,#0 ; mov adrs+1,#0 ; ; ljmp fct_suite2 ;fct_suite1: ;inc adrs ; mov A,adrs ; add A,#1 ; mov adrs,A ;fct_suite2: ; ; lcall Lecture_Mem ;mov p1,adrs ; mov P1,cle2 ;mov p1,adrs ; lcall Attente_LED ; lcall Attente_Fin ;fct_b: ; jb lec,fct_fin ; jnb tester,fct_b ; ljmp fct_suite1 ;fct_fin: ; lcall Attente_LED ; lcall Init ; lcall Attente_Fin ;ret ;-------------------------------------MAIN----------------------------------- ; d,but du programme principal main: lecture: lcall Reset lcall Ecrire_1 lcall Ecrire_1 lcall Ecrire_0 lcall Ecrire_0 lcall Ecrire_1 lcall Ecrire_1 lcall Ecrire_0 lcall Ecrire_0 mov TEMPS,#90 lcall Tempo ;lecture des octets de la clé mov A,#0 mov R0,#8 boucle0: mov R1,#8 boucle1: clr Cle nop setb Cle nop nop mov C,Cle RRC A cjne R1,#1,suite1 push A mov A,#0 suite1: mov TEMPS,#20 lcall Tempo djnz R1,boucle1 djnz R0,boucle0 ; RESTITUTION pop cle1+7 ;CRC pop cle1+6 pop cle1+5 pop cle1+4 pop cle1+3 pop cle1+2 pop cle1+1 pop cle1 ;CF mov P1,#00110000b mov A,cle1 cjne A,#00000001b,fin_p ;ici il n'y a pas de clé boucle4: ;une clé a été lue mov P1,#00010000b jnb Enreg,test_supp jnb Supp,do_enreg ljmp do_reset test_supp: jnb Supp,test_cle ljmp do_supp test_cle: lcall Tester_cle lcall LED_OK ljmp fin_p do_reset: lcall Reset_Mem lcall LED_ENREG lcall LED_SUPP ljmp fin_p do_enreg: lcall Enregistrer lcall LED_ENREG ljmp fin_p do_supp: lcall Supprimer lcall LED_SUPP fin_p: lcall Attente_LED lcall Init lcall Attente_Fin ljmp main ; fin du programme principal ;asmex1 ; retour au moniteur, ligne à supprimer pour l'EPROM ; fin de la zone de m,moire de programme en EPROM

Conclusion :


Ce code a été réalisé dans le cadre de l'IUT de Tours en info et élec...
Voilà la version finale.

Bien d'autres porgrammes : http://www.webfractales.com/projets/

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.