Programme pour le PIC16F84 utilisant le TIMER PCF8583 et les EEPROM 24LC65:
Système de pointage industrie. Lecture du timer et affichage de l'heure en continu, création d'une trame de 2 octets (info de pointage recu par carte a puce), écriture des 2 octets en EEPROM, Gestion du changement d'EEPROM si l'une est pleine, gestion de coupure (en cas de coupure de courant, on repren l'écriture en EEPROM à la dérnière adresse accédée+1).
Source / Exemple :
;==========================================================
; Fichier : EEPROM.asm
; Auteur : Frédéric
; fonction: Programme pour le PIC16F84 utilisant le TIMER PCF8583 et les EEPROM 24LC65
; lecture du timer, création de la trame de 2 octets, écriture de 2 octets
; en EEPROM, Gestion du changement d'EEPROM si l'une est pleine, gestion de
; coupure (en cas de coupure de courant, on repren l'écriture en EEPROM à la
; dérnière adresse accédé+1)
;==========================================================
; HEADER ===========================================
include P16F84.INC
processor 16f84
radix dec
__config _XT_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF
; DATA =============================================
; Constantes pour l'afficheur
RS_lcd equ 0 ; bit 0 du port A
RW_lcd equ 1 ; bit 1 du port A
E_lcd equ 2 ; bit 2 du port A
D4_lcd equ 0 ; bit 0 du port B
D5_lcd equ 1 ; bit 1 du port B
D6_lcd equ 2 ; bit 2 du port B
D7_lcd equ 3 ; bit 3 du port B
BUSY_lcd equ 3 ; bit 3 du port B
Saut_Ligne equ 0C0h
CARTE equ 05h
Inser_Card equ 0
Bad_Card equ 8
End_Card equ 17
Reinser_Card equ 25
Card equ 35
; Variables
Compteur equ 13h
Var1 equ 0Ch
Var2 equ 0Dh
Var3 equ 0Eh
Var4 equ 0Fh
Val1 equ 35h
Tampon1 equ 41h
Tampon2 equ 42h
Tampon3 equ 43h
id1 equ 00h
id2 equ 01h
code1 equ "B"
code2 equ "F"
acqui_b equ 15
Com_buf equ 38h
Valeur1 equ 39h
Valeur2 equ 3Ah
Val_Tempo equ 3Bh
Calcul equ 3Ch
Parite equ 3Dh
Oct_Envoi equ 3Eh
Parite_recu equ 3Fh
Compteur2 equ 40h
; sur le bus interne I2C
SDA equ 4 ; bit 4 du port A
SCL equ 3 ; bit 3 du port A
Wr_ROM4 equ 10101000b ; EEPROM IC4 en écriture
Wr_ROM5 equ 10101010b ; EEPROM IC5 en écriture
Rd_ROM4 equ 10101001b ; EEPROM IC4 en lecture
Rd_ROM5 equ 10101011b ; EEPROM IC5 en lecture
Wr_TIMER equ 10100000b ; Horloge IC8 en écriture
Rd_TIMER equ 10100001b ; Horloge IC8 en lecture
Rom_Courante_Read equ 26h
Rom_Courante_Write equ 32h
Adr_High equ 28h
Adr_Low equ 27h
Num_Rom equ 30h
Change_Flag equ 31h
I2C_Send equ 14h
I2C_Receive equ 15h
Seconde equ 20h
Minute equ 21h
Heure equ 22h
Jour_Week equ 29h
S1 equ 23h
S2 equ 24h
S3 equ 25h
EE_Send equ 33h
EE_Receive equ 34h
goto Debut
;=========================================================================================
PutString
;Affichage de chaines de caractères
;w contient le numero de la chaine à afficher
movwf Var2 ; numero de la chaine de caractère
call CHAR_TABLE ; appelle du tableau du caractère
movwf Var3 ; le nombre de caractère à afficher -> Var3
BOUCLE_CHAR
incf Var2 ; Var2+1: ofsset de deplacement du PCL
movf Var2,w ; Var2 -> w
call CHAR_TABLE ; w contient le caractère à afficher
call PutChar ; affiche le caractère
decfsz Var3 ; Var3-1: Nombre de caractère à afficher
goto BOUCLE_CHAR
CHAR_TABLE
addwf PCL ; ajoute un offset à PCL (Program Counter)
; ainsi le PCL saute jusqu'au caractère
; à afficher
retlw 7 ;nombre de caratère du mot
retlw "I" ;retour avec 1 caractère dans w
retlw "n"
retlw "s"
retlw "e"
retlw "r"
retlw "e"
retlw "z"
retlw 7
retlw "M"
retlw "a"
retlw "u"
retlw "v"
retlw "a"
retlw "i"
retlw "s"
retlw "e"
retlw 7
retlw "T"
retlw "e"
retlw "r"
retlw "m"
retlw "i"
retlw "n"
retlw "e"
retlw 9 ;nombre de caratère du mot
retlw "R"
retlw "e"
retlw "i" ;retour avec 1 caractère dans w
retlw "n"
retlw "s"
retlw "e"
retlw "r"
retlw "e"
retlw "z"
retlw 6
retlw " "
retlw "c"
retlw "a"
retlw "r"
retlw "t"
retlw "e"
; CODE ===============================================
Debut
movlw 057h
option ; active les pull-up interne
call Init_Aff
clrf Change_Flag
MOVLW 00h
tris PORTA ;portA<3:4> en sortie
BSF PORTA,SDA
BSF PORTA,SCL
movlw 10
call Tp_xx ;temporisation
refaire
Main_Lp
movlw 00h
call MoveCursor
call ReadHeure ; lire heure et minute
call ReadJour ; lire jour
call Aff_heure ; afficher heure et jour
movlw "-"
call PutChar
movf Jour_Week,w
call PutHex
call MakeTrame ; créer la trame
movlw 40h
call MoveCursor
movf Jour_Week,w
call PutHex
movf Minute,w
call PutHex
call ecriture
call PORTB_IN ; Port B en entrée
movlw 0ffh
movwf Var1
; Suite du programme
movlw 19
call TEMPO ; tempo 100us
goto Main_Lp ; boucle principale
;=========================================================================================
ecriture
MOVLW 00h
tris PORTA ;portA<3:4> en sortie
BSF PORTA,SDA
BSF PORTA,SCL
movlw 0efh
call Tp_xx
movlw id1
movwf EE_Send
call EEWrite ;écrire la trame en EEPROM
movlw 010h
call Tp_xx
movlw id2
movwf EE_Send
call EEWrite ;écrire la trame en EEPROM
movlw 010h
call Tp_xx
movf Jour_Week,w
movwf EE_Send
call EEWrite ;écrire la trame en EEPROM
movlw 010h
call Tp_xx
movf Minute,w
movwf EE_Send
call EEWrite ;écrire la trame en EEPROM
movlw 010h
call Tp_xx
movlw 00h
call MoveCursor
return
;=========================================================================================
; Lecture de +ieurs octets dans le TIMER
ReadHeure
call I2CStart ; bit de START
movlw Wr_TIMER ; TIMER en écriture
call I2CSendByte
call I2CWaitAck ; Attente d'un ACKnowledge
movlw 02h ; word address des secondes
call I2CSendByte
call I2CWaitAck
call I2CStartLoad ; Start spécial lecture
movlw Rd_TIMER ; TIMER en lecture
call I2CSendByte
call I2CWaitAck ; Attente d'un ACKnowledge
call I2CReceiveByte ; reception Seconde
movf I2C_Receive,w
movwf Seconde
call I2CSendAck ; envoyer ACK
call I2CReceiveByte ; reception Minute
movf I2C_Receive,w
movwf Minute
call I2CSendAck ; envoyer ACK
call I2CReceiveByte ; reception Heure
movf I2C_Receive,w
movwf Heure
call Wait_10 ; tempo de 10µs car pas d'ACKnowledge
call I2CStop ; bit de STOP
return
;=========================================================================================
ReadJour
call I2CStart ; bit de START
movlw Wr_TIMER ; TIMER en écriture
call I2CSendByte
call I2CWaitAck ; Attente d'un ACKnowledge
movlw 06h ; word address des jours
call I2CSendByte
call I2CWaitAck
call I2CStartLoad ; Start spécial lecture
movlw Rd_TIMER ; TIMER en lecture
call I2CSendByte
call I2CWaitAck ; Attente d'un ACKnowledge
call I2CReceiveByte ; reception Seconde
movf I2C_Receive,w
movwf Jour_Week
call Wait_10 ; tempo de 10µs car pas d'ACKnowledge
call I2CStop ; bit de STOP
rrf Jour_Week
rrf Jour_Week
rrf Jour_Week
rrf Jour_Week
rrf Jour_Week ; ici Jour<0:2> contient jour de la semaine
movf Jour_Week,w
andlw b'00000111'
movwf Jour_Week
incf Jour_Week
return
;=========================================================================================
;NOUVEAU MAKE_TRAME JOUR|HEURE|MINUTE sur 2 octets
MakeTrame
rlf Jour_Week
rlf Jour_Week
rlf Jour_Week
rlf Jour_Week
rlf Jour_Week
Movf Jour_Week,w
andlw b'11100000'
movwf Jour_Week ; Jour_Week=b'JJJ00000'
btfsc Heure,5 ;test de la carry
bsf Jour_Week,4
btfsc Heure,4 ;test de la carry
bsf Jour_Week,3
btfsc Heure,3 ;test de la carry
bsf Jour_Week,2
btfsc Heure,2 ;test de la carry
bsf Jour_Week,1
btfsc Heure,1 ;test de la carry
bsf Jour_Week,0
Movf Minute,w
andlw b'01111111'
movwf Minute ; Jour_Week=b'JJJ00000'
btfsc Heure,0 ;test de la carry
bsf Minute,7
; Jour_Week=b'JJJHHHHH'
; et Minute= b'HMMMMMMM'
return
;=========================================================================================
Aff_heure
movlw 00h
tris PORTA ; PORTA en sortie
movf Heure,w
call PutHex ; affiche heure
movlw ":"
call PutChar
movf Minute,w
call PutHex
movlw ":"
call PutChar
movf Seconde,w
;movf Jour_Week,w
call PutHex ; affiche le caractere reçu
return
;=========================================================================================
; Ecrit 2 octets dans l'EEPROM
EEWrite
call EELoadParam
movlw 45h
call MoveCursor
movf Adr_High,w
call PutHex
movf Adr_Low,w
call PutHex
movlw "-"
call PutChar
movf Num_Rom,w
call PutHex
call EELoadAdress ;récuperer adresse read et write
;movlw Wr_ROM5
;movwf Rom_Courante_Write
;movlw Rd_ROM5
;movwf Rom_Courante_Read
call I2CStart ; bit de start
movf Rom_Courante_Write,w ; ROM en écriture
call I2CSendByte
call I2CWaitAck
movf Adr_High,w
call I2CSendByte
call I2CWaitAck
movf Adr_Low,w
call I2CSendByte
call I2CWaitAck
movf EE_Send,w
call I2CSendByte
call I2CWaitAck
call I2CStop
call Tp_05 ; Tempo d'écriture (5ms)
incf Adr_Low
btfsc STATUS,Z
bsf Change_Flag,0
btfsc Change_Flag,0
goto Change_Adr
call EESaveParam
return
Change_Adr
movf Adr_High,w
sublw 1Fh
btfsc STATUS,Z
goto Change_EE
incf Adr_High
clrf Change_Flag
call EESaveParam
return
Change_EE
call Change_EEPROM
clrf Change_Flag
call EESaveParam
return
;=========================================================================================
EESaveParam
movlw 00h
movwf EEADR
movf Adr_Low,w
movwf EEDATA
call ECRITURE
movlw 01h
movwf EEADR
movf Adr_High,w
movwf EEDATA
call ECRITURE
movlw 02h
movwf EEADR
movf Num_Rom,w
movwf EEDATA
call ECRITURE
return
;=========================================================================================
EELoadParam
bcf STATUS,RP0
movlw 00h
movwf EEADR
call LECTURE
movwf Adr_Low
movlw 01h
movwf EEADR
call LECTURE
movwf Adr_High
movlw 02h
movwf EEADR
call LECTURE
movwf Num_Rom
return
;=========================================================================================
;Ecriture d'un octet en eeprom du PIC
ECRITURE
bsf STATUS,RP0
bsf EECON1,WREN
bcf EECON1,EEIF
movlw 0x55
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1,WR
attend_ecriture
btfss EECON1,4
goto attend_ecriture
bcf STATUS,RP0
return
;=========================================================================================
;Lecture d'un octet en EEPROM du PIC
LECTURE
bsf STATUS,RP0
bsf EECON1,RD
bcf STATUS,RP0
movf EEDATA,w
return
;=========================================================================================
; Lis 1 octets dans L'EEPROM
EERead
; lecture en random read de l'EEPROM
call I2CStart ; bit de START
movlw Wr_ROM4 ; ROM4 en écriture
call I2CSendByte
call I2CWaitAck ; Attente d'un ACKnowledge
movlw 01h
call I2CSendByte
call I2CWaitAck
movlw 20h
call I2CSendByte
call I2CWaitAck
call I2CStartLoad ; Start spécial lecture
movlw Rd_ROM4 ; ROM en lecture
call I2CSendByte
call I2CWaitAck ; Attente d'un ACKnowledge
call I2CReceiveByte
movf EE_Receive,w
movwf S1
call Wait_10 ; tempo de 10µs car pas d'ACKnowledge
call I2CStop ; bit de STOP
return
;=========================================================================================
; Fonction envoyant un bit de START pour l'I2C interne
I2CStartLoad
bsf PORTA,SDA
call Wait_04
bsf PORTA,SCL ; préparation pour bit de start
call Wait_04
I2CStart call Wait_06
bcf PORTA,SDA
call Wait_06
bcf PORTA,SCL
call Wait_04
return
;=========================================================================================
; Fonction envoyant un bit de STOP
I2CStop bcf PORTA,SDA ; préparation pour bit de stop
call Wait_06
bsf PORTA,SCL
call Wait_06
bsf PORTA,SDA
call Wait_04
return
;=========================================================================================
; Fonction qui attend l'acquittement d'une EEPROM
I2CWaitAck BSF PORTA,SDA
movlw 10h
tris PORTA ; mise de SDA en lecture
call Wait_04
bsf PORTA,SCL ; impulsion d'horloge
call Wait_04
bcl_ack btfsc PORTA,SDA
goto bcl_ack ; recommence si SDA=1
bcf PORTA,SCL
call Wait_04
Fin_ack movlw 0
tris PORTA ; mise de SDA en écriture
call Wait_04
return
;=========================================================================================
; Fonction qui envoie l'acquittement vers une EEPROM
I2CSendAck
bcf PORTA,SDA
call Wait_04
bsf PORTA,SCL ; impulsion d'horloge
call Wait_04
bcf PORTA,SCL
call Wait_04
return
;=========================================================================================
; Fonction qui envoie un octet sur le bus I2C pour les EEPROM
; W doit contenir la données à envoyer
;
I2CSendByte
movwf I2C_Send
movlw 8
movwf Var1 ; compteur de bits
bcl_env rlf I2C_Send
btfss STATUS,C
goto C0_env ; si Carry=0
C1_env nop ; si Carry=1
bsf PORTA,SDA
goto st_env
C0_env bcf PORTA,SDA
goto st_env
st_env bsf PORTA,SCL ; impulsion d'horloge
call Wait_04
bcf PORTA,SCL
decfsz Var1
goto bcl_env
rlf I2C_Send ; repositionnement du buffer I2C
bsf PORTA,SDA ; préparation de l'ACKownledge
return
;=========================================================================================
;Fonction qui reçoit un octet venant de l'EEPROM
I2CReceiveByte
movlw 10h
tris PORTA ; mise de SDA en lecture
clrf I2C_Receive
movlw 8
movwf Var1 ; compteur de bits
bcl_rcp call Wait_04
bsf PORTA,SCL ; impulsion d'horloge
call Wait_04
btfss PORTA,SDA
goto SD0_rcp ; si SDA=0
SD1_rcp nop ; si SDA=1
bsf STATUS,C
goto st_rcp
SD0_rcp bcf STATUS,C
goto st_rcp
st_rcp bcf PORTA,SCL
rlf I2C_Receive
decfsz Var1
goto bcl_rcp
movlw 0
tris PORTA ; mise de SDA en écriture
call Wait_04
return
;=========================================================================================
Change_EEPROM
movf Num_Rom,w
sublw 01h
btfss STATUS,Z
goto INC_EEPROM
goto EEPROM_PLEINE
INC_EEPROM
incf Num_Rom
call EELoadAdress
clrf Adr_High
clrf Adr_Low
return
EEPROM_PLEINE
movlw Saut_Ligne
call SendCmd
movlw "p"
call PutChar
movlw "l"
call PutChar
movlw "e"
call PutChar
movlw "i"
call PutChar
movlw "n"
call PutChar
movlw "e"
call PutChar
Boucle_Pleine
goto Boucle_Pleine
;=========================================================================================
; permet de récuperer les adresses courantes des EEPROMs
; d'après la variable Num_Rom
EELoadAdress
movf Num_Rom,w
sublw 00h
btfsc STATUS,Z
goto ROM1
movf Num_Rom,w
sublw 01h
btfsc STATUS,Z
goto ROM2
return
ROM1
movlw Wr_ROM4
movwf Rom_Courante_Write
movlw Rd_ROM4
movwf Rom_Courante_Read
;clrf Adr_High
;clrf Adr_Low
return
ROM2
movlw Wr_ROM5
movwf Rom_Courante_Write
movlw Rd_ROM5
movwf Rom_Courante_Read
;clrf Adr_High
;clrf Adr_Low
return
;=========================================================================================
; tempo en µs
Wait_10 goto Wait_08
Wait_08 goto Wait_06
Wait_06 goto Wait_04
Wait_04 return
;=========================================================================================
;Envoie à l'afficheur 1 caractère ou une commande
PutChar
bsf PORTA,RS_lcd ; RS=1 pour affichage d'1 char
SendCmd
movwf Var1 ; w-> Var1
bcf PORTA,RW_lcd ; RW=0 mise en ecriture de commandes
movlw 0F0h ; 1110000 b0,b1,b2 et b3 = outpout
tris PORTB ; mise en ecriture du PORTB
swapf Var1,w
movwf PORTB ; w->PORTB
call ACT_ENABLE
movf Var1,w ; Var1 -> w
AFF_INI
movwf PORTB
call ACT_ENABLE
bcf PORTA,RS_lcd ; RS=0
movlw 0Fh ; changement 0FFh
tris PORTB ; mise en entréé du PORTB
bsf PORTA,RW_lcd ; mise en lecture de l'afficheur
bsf PORTA,E_lcd
Boucle1
btfsc PORTB,BUSY_lcd
goto Boucle1 ;attente que BUSY_lcd=0
bcf PORTA,E_lcd ;lecture de COUNTER<high>
bsf PORTA,E_lcd
bcf PORTA,E_lcd ;lecture de COUNTER<low>
bcf PORTA,RW_lcd
;movlw b'00000000'
;TRIS PORTB
return
;=========================================================================================
ACT_ENABLE
bsf PORTA,E_lcd ; active Enable
bcf PORTA,E_lcd ; desactive Enable
return
;=========================================================================================
Init_Aff
movlw 010h ;10h pour 16ms
call Tp_xx ;temporisation de 16ms
movlw 018h
tris PORTA ;bits a0,a1,a2 en sorties
movwf PORTA ;mise a 0 des sorties PORTA
movlw 0F0h
tris PORTB ;bits b0,b1,b2,b3 en sorties
movlw 0F2h ;Positionne l'interface en 4 bits
movwf PORTB
call ACT_ENABLE
movlw 05h
call Tp_xx ;temporisation de 5ms
call ACT_ENABLE
movlw 01h
call Tp_xx ;temporisation de 1ms
call ACT_ENABLE
movlw 02h
call AFF_INI
movlw 028h
call SendCmd ;4 bits, 2 lignes
movlw 0Ch
call SendCmd ;Display On, Curseur Off
movlw 01h
call SendCmd ;Display Clear
movlw 06h
call SendCmd ;Mode incremente
return
;=========================================================================================
;Routine d'affichage de caractère en HEXA
;Affiche 1 octet en HEXA soit 2 caractères
PutHex
movwf Var2
swapf Var2,w
call Aff_H2
movf Var2,w
Aff_H2 andlw 0Fh
addlw 06h
movwf Var3
addlw 02Ah
btfsc Var3,4
addlw 07h
goto PutChar
return
;=========================================================================================
MoveCursor
;w contient l'adresse de destination du curseur
;change la position du curseur
;exemple: mettre le curseur en position
;4Fh=01001111 il faut envoyer
;11001111
MOVWF Var4
BSF Var4,7
MOVF Var4,0
CALL SendCmd
RETURN
;=========================================================================================
;Temporisations
Tp_05 movlw 05 ; tempo 5ms
goto Tp_xx
Tp_125 movlw 07Dh
Tp_xx
movwf Var1
tp1
movlw 0CCh ; 3.2768Mhz/0CCh, 4Mhz/0F9h
movwf Var2
tp2
nop
decfsz Var2
goto tp2
decfsz Var1
goto tp1
return
;=========================================================================================
;=========================================================================================
;=========================================================================================
PORTB_IN
movlw 0FFh
tris PORTB
movwf PORTB
return
;=========================================================================================
;temporisation: avant appel mettre le nombre de fois que l'on veut faire la boucle dans w
;Val_Tempo* 5micro secondes + 5µs
TEMPO:
movwf Var2
nop
tempo:
DECFSZ Var2,1
GOTO inst
nop
RETURN
inst:
GOTO tempo
;fin de temporisation
;=========================================================================================
Cart_Insere
call SYNCHRO
call CODE_ENTRE
call ID_EMPLOYE
call HORAIRE
movlw 40h
call MoveCursor
movlw End_Card
call PutString
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
call PORTB_IN
atten_desinsertion
btfss PORTB,4
goto atten_desinsertion
call ecriture
goto Main_Lp
;=========================================================================================
SYNCHRO
; Une carte a été insérée
; Procédure de synchronisation
; Emission du premier bit de synchronisation
movlw 12
call Tp_xx ; tempo 12ms de démarrage
movlw 11011111b ; bit CARTE en sortie
tris PORTB
bcf PORTB,CARTE ; bit à 0
movlw 9
call TEMPO ; tempo 50us
bsf PORTB,CARTE ; bit à 1
; reception du bit de synchronisation 2
call PORTB_IN ; port B en entrée
clrf Var1
Attend_bit2
btfss PORTB,CARTE
goto Bit2_ok ; le bit à 0 est détecté
decfsz Var1
goto Attend_bit2
; erreur pas de bit détecté
movlw 40h
call MoveCursor
movlw Reinser_Card
call PutString ; Affiche erreur, correspond carte mal insere
movlw Card
call PutString ; Affiche erreur, correspond carte mal insere
call PORTB_IN
att_des
btfss PORTB,4
goto att_des
goto refaire
Bit2_ok
; Emission du dernier bit(3eme) de synchro
movlw 19
call TEMPO ; tempo 100us
movlw 11011111b ; bit CARTE en sortie
tris PORTB
bcf PORTB,CARTE ; bit à 0
movlw 9
call TEMPO ; tempo 50us
bsf PORTB,CARTE ; bit à 1
return
;-------fin init
;=========================================================================================
; ss prog de control du code de l'entreprise
CODE_ENTRE
movlw 3
movwf Var2
Recep_code1
clrf Val1
; Reception du premier octet
call RECEP
btfsc STATUS,Z
goto Suite_code1 ; Si pas d'erreur continu
call AFF_ERREUR ; à tester 3 fois ??
goto Main_Lp
; Emission de l'octet
Suite_code1
movwf Valeur1 ; mémorise la premier valeur
; controle du premier code entreprise
movlw code1
subwf Com_buf,w
btfsc STATUS,Z
goto code1_bon
bsf Val1,0 ; code mauvais
code1_bon
; Reception du deuxième octet
call RECEP
btfsc STATUS,Z
goto Suite_code2 ; Si pas d'erreur continu
call AFF_ERREUR ; à tester 3 fois ??
goto Main_Lp
Suite_code2
movwf Valeur2 ; mémorise la deuxième valeur
; controle du deuxieme code entreprise
movlw code2
subwf Com_buf,w
btfsc STATUS,Z
goto code2_bon
bsf Val1,0
code2_bon
movlw 17
call TEMPO ; permet d'avoir 100µs entre dernier reception et envoi
btfss Val1,0
goto trans_code_ok
clrw
call ENVOI
decfsz Compteur2
goto Recep_code1
movlw 40h
call MoveCursor
movlw Bad_Card
call PutString ; mauvaise carte
movlw Card
call PutString ; Affiche erreur, correspond carte mal insere
call PORTB_IN
att_desi
btfss PORTB,4
goto att_desi
goto Main_Lp
trans_code_ok
movlw acqui_b
call ENVOI
return
; fin sous prog de CODE
;=========================================================================================
; sous prog de reception de l'id de l'employe
ID_EMPLOYE
; reception du premier octet de l'ID
movlw 3
movwf Compteur2 ; variable pour boucle de reception en cas d'erreur
Recep_id1
clrf Val1
; Reception du premier octet
call RECEP
btfsc STATUS,Z
goto Suite_id1
call AFF_ERREUR
goto Main_Lp
Suite_id1
movwf id1 ; mémorise la premier valeur
call CONTROL ; valeur recu se trouve toujours dans Com_buf
btfsc STATUS,Z
goto id1_bon
bsf Val1,0
id1_bon
; entre chaque reception il ya 75 µs
; Reception du deuxième octet du code
call RECEP
btfsc STATUS,Z
goto Suite_id2
call AFF_ERREUR
Suite_id2
movwf id2 ; mémorise la deuxième valeur
call CONTROL
btfsc STATUS,Z
goto id2_bon
bsf Val1,0
id2_bon
movlw 1
call TEMPO ; permettra d'avoir 100µs avant emission
btfss Val1,0 ; si 0 erreur
goto trans_id_ok
clrw
call ENVOI
decfsz Compteur2
goto Recep_id1
call AFF_ERREUR
trans_id_ok
movlw acqui_b
call ENVOI
return
; fin sous prog de reception de l'id
;=========================================================================================
HORAIRE
movlw 3
movwf Compteur2 ; variable pour boucle de reception en cas d'erreur
env_horaire
movf Jour_Week,w
movwf Oct_Envoi
call Cal_Parite
movlw 7
call TEMPO
movf Oct_Envoi,w
call ENVOI
movlw 7
call TEMPO
movf Minute,w
movwf Oct_Envoi
call Cal_Parite
movf Oct_Envoi,w
call ENVOI
CALL RECEP
movlw acqui_b
subwf Com_buf,w
btfsc STATUS,Z
return
decfsz Compteur2
goto env_horaire
goto Main_Lp ; SI ON ARRIVE LA C'EST QUE LA CARTE N'A PAS BIEN RECU
; LES HORAIRES
;=========================================================================================
; Reception d'un octet en provenance de la carte avec recep du bit de parite
RECEP
call PORTB_IN ; Port B en entree
clrf Tampon1
Wait_start
btfss PORTB,CARTE
goto Start_ok ; Détection du bit de start 0
decfsz Tampon1
goto Wait_start ; pas de bit 0
; pas de bit de start pendant 256*5 µs
bcf STATUS,Z
return ; fin sur erreur
Start_ok
movlw 3
call TEMPO ;
nop
nop
nop
clrf Com_buf ; mise a zero du buffer reception
movlw 8
movwf Tampon1 ; positionnement boucle principale
Bcl_recep
btfsc PORTB,CARTE
goto Bit_un_recu
; bit zero recu
bcf STATUS,C
goto Suite_Rcp
Bit_un_recu
bsf STATUS,C
nop
Suite_Rcp
rrf Com_buf ; bit poids faible recu en premier
movlw 1
call TEMPO
NOP
decfsz Tampon1
goto Bcl_recep
; reception bit parite
btfsc PORTB,CARTE
goto par_un
bcf STATUS,C
goto sauv_par
par_un
bsf STATUS,C
nop
sauv_par
clrf Parite_recu
rlf Parite_recu ; bit 0 de parite recu
movlw 1
call TEMPO
NOP
nop
Rcp_Fin
movf Com_buf,w
bsf STATUS,Z
return ; fin reception complete
;=========================================================================================
; Emission d'un octet vers la carte, avec envoi du bit de parite
ENVOI
movwf Tampon3 ; sauvegarde de l'octet a emettre
call PORTB_IN ; port B en entree
movlw 11011111b ; bit CARTE en sortie
tris PORTB
bcf PORTB,CARTE ; bit de start
movlw 8
movwf Tampon1 ; init nb de bits
movlw 2
call TEMPO
Bcl_emission
rrf Tampon3
btfsc STATUS,C
goto Emt_1
nop
bcf PORTB,CARTE
goto Attente1
Emt_1
bsf PORTB,CARTE
goto Attente1
Attente1
movlw 1
call TEMPO
decfsz Tampon1
goto Bcl_emission
; emission bit de parite
rrf Parite
btfsc STATUS,C
goto parite_un
nop
bcf PORTB,CARTE
goto attent_2
parite_un
bsf PORTB,CARTE
goto attent_2
attent_2
goto attent_3
attent_3
movlw 1
call TEMPO ; temps global 20us
nop
nop
; bit de stop
bsf PORTB,CARTE ; remise sortie a 1
return
;=========================================================================================
AFF_ERREUR
movlw 40h
call MoveCursor
movlw Reinser_Card
call PutString
movlw Card
call PutString ; Affiche erreur, correspond carte mal insere
call PORTB_IN
attdesi
btfss PORTB,4
goto attdesi
movlw 47h
call MoveCursor
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
movlw " "
call PutChar
goto Main_Lp
;=========================================================================================
;sous programme de calcul de parite
Cal_Parite:
MOVLW 8
MOVWF Calcul
clrf Parite
comptage:
BTFSC Oct_Envoi,7
INCF Parite,1
RLF Oct_Envoi,1
DECFSZ Calcul,1
goto comptage
test:
BTFSc Parite,0 ; parite paire si 0
GOTO impaire
clrf Parite
bsf Parite,0
rlf Oct_Envoi,1 ; valeur a envoye remise dans variable
RETURN
impaire:
clrf Parite ; parite impaire
RLF Oct_Envoi,1 ; valeur a envoye remise correctement dans Oct_Envo
RETURN
;fin de ssprg de Parite
;=========================================================================================
; sous programme de controle reception de trame grace bit parite
CONTROL:
movf Com_buf,w ; oct recu
movwf Oct_Envoi
call Cal_Parite
movf Parite,w
subwf Parite_recu,w
RETURN
; fin ss prg de controle de parite
;=========================================================================================
FIN
Dernier fill 3FFFh,(400h-Dernier)
END
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.