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/
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.