Pic 16f84 - timer pcf8583 - eeprom 24lc65, communication i2c et afficheur lcd ltn211

Contenu du snippet

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

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.