Bonjour
J'ai mis des led sur le portB pour visualiser les secondes mais je ne les vois
pas s'incrementer .
Code:
LIST p=16F84a ; Définition de processeur
#include <p16F84a.inc> ; Définitions des constantes
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
; '__CONFIG' précise les paramètres encodés dans le processeur au moment de
; la programmation du processeur. Les définitions sont dans le fichier include.
; Voici les valeurs et leurs définitions :
; _CP_ON Code protection ON : impossible de relire
; _CP_OFF Code protection OFF
; _PWRTE_ON Timer reset sur power on en service
; _PWRTE_OFF Timer reset hors-service
; _WDT_ON Watch-dog en service
; _WDT_OFF Watch-dog hors service
; _LP_OSC Oscillateur quartz basse vitesse
; _XT_OSC Oscillateur quartz moyenne vitesse
; _HS_OSC Oscillateur quartz grande vitesse
; _RC_OSC Oscillateur à réseau RC
;*********************************************************************
; DEFINE *
;*********************************************************************
; entrees / sorties
#DEFINE SCL PORTA,0 ; SCL i2c sur RA0
#DEFINE SDA PORTA,1 ; SDA i2c sur RA1
#DEFINE LedR PORTA,4 ; Led erreur I2C sur RB4
#DEFINE L1 PORTB,4 ; led test 1 sur rb0
#DEFINE L2 PORTB,5 ; led test 2 sur rb2
N equ 0C ; i2c
OCTET equ 0D ; i2c
count1 equ 0E ; 1er compteur
count2 equ 0F ; 2e compteur pour la tempo
heures equ 10 ; heures lues dans RTC
minutes equ 11 ; minutes lues dans RTC
secondes equ 12
;**********************************************************************
; DEMARRAGE SUR RESET *
;**********************************************************************
org 0x000 ; Adresse de départ après reset
call init ; Adresse 0: initialiser
goto start ; Debut du prog principal
;*********************************************************************
; INITIALISATIONS *
;*********************************************************************
init
bsf STATUS,RP0 ; aller en bank1
movlw b'0000000' ;
movwf TRISB ; port B en sortie
movlw b'00000000'
movwf TRISA ; port A en sortie
bcf STATUS,RP0 ; aller en bank0
movlw b'00011'
movwf PORTA
clrf PORTB ; ttes les sorties a 0
init_i2c
bsf SDA ; SDA a 1
bsf SCL ; SCL a 1
return
;*********************************************************************
; PROGRAMME PRINCIPAL *
;*********************************************************************
start
call wait0
AAA
call LIRE_RTC ; lit hrs et min sec dans la rtc
movlw secondes
movwf PORTB ; met les secondes sur le portB
call wait0
goto AAA ; reboucle
;************ SOUS PROGRAMMES I2C *****************************
LIRE_RTC ; ici c'est le prog qui lit ( heure et minutes ) la clock RTC
call I2C_START ; bit de start de I2C
movlw B'11010000' ; adresse RTC est 1101000 en mode ecriture
call I2C_EMISSION
call I2C_SLAVE_ACK ; attend ack du esclave RTC
movlw B'00000000' ; on va a l'adresse ram 1 du RTC
call I2C_EMISSION ; c'est l'adresse des SECONDES
call I2C_SLAVE_ACK ; attend ack du esclave RTC
call I2C_STOP
call tempo_5us
call I2C_START
movlw B'11010001' ; adresse RTC est 1101000 en mode lecture
call I2C_EMISSION
call I2C_SLAVE_ACK ; attend ack du esclave RTC
call I2C_RECEPTION ; on recoit les donnees
call I2C_PIC_ACK ; Ack du pic
movwf secondes ; on met w dans secondes
call I2C_RECEPTION ; on recoit les donnees
call I2C_PIC_ACK ; Ack du pic
movwf minutes ; on met w dans minutes
call I2C_RECEPTION ; on recoit les donnees
call I2C_PIC_NACK ; Nack du pic
movwf heures ; on met w dans heures
call I2C_STOP ; bit de stop de I2C
return ; on a lu la clock rtc et mis les valeurs
; heures , minutes , secondes a jour
I2C_START
bsf SCL
bsf SDA ; au repos SDA et SCL a 1
call tempo_5us
bcf SDA ; SDA passe a 0
call tempo_5us
bcf SCL ; SCL passe a 0
call tempo_5us ; >> bus I2C occupé
return
I2C_STOP ; ss prog bit de fin
bcf SCL
bcf SDA
call tempo_5us
bsf SCL ; SCL passe a 1
call tempo_5us
bsf SDA ; SDA passe a 1 >> bus I2C au repos
call tempo_5us
return
I2C_RESTART ; ss prog condition de restart
bsf SDA ;
call tempo_5us
bsf SCL ; SDA et SCL a 1
call tempo_5us
call tempo_5us
bcf SDA ; SDA passe a 0
call tempo_5us
bcf SCL ; SCL passe a 0
call tempo_5us ; >> bus I2C occupé
return
I2C_SLAVE_ACK ; attend acknowledge de l'esclave
bcf SCL ; SCL a 0
call SDA_IN ; SDA en entree
call tempo_5us ; tempo de 11 us
bsf SCL ; SCL a1
call tempo_5us ; tempo de 11 us
btfsc SDA
call NO_ACK
bcf SCL ; SCL a 0
call tempo_5us ; tempo de 11 us
call SDA_OUT ; SDA en sortie
return
I2C_PIC_ACK ; envoye l'acknowledge du pic vers esclave
bcf SCL ; SCL a 0
call SDA_OUT ; SDA en sortie
bcf SDA ; SDA a 0
bsf SCL ; SCL a 1
call tempo_5us ; tempo de 11 us
bcf SCL ; SCL a 0
call tempo_5us ; tempo de 11 us
bsf SDA
return
I2C_PIC_NACK ;
bcf SCL ; SCL a 0
call SDA_OUT ; SDA en sortie
bsf SDA ; SDA a 0
bsf SCL ; SCL a 1
call tempo_5us ; tempo de 11 us
bcf SCL ; SCL a 0
call tempo_5us ; tempo de 11 us
bcf SDA
return
I2C_EMISSION ; envoye donnee du pic vers esclave
movwf OCTET ; w >> OCTET
movlw .8
movwf N ; 8 >> N
call SDA_OUT ; mette SDA en sortie
OUT_BIT
rlf OCTET, F ; decalage a gauche dans carry
btfsc STATUS, C ;
goto OUT_ONE
OUT_ZERO
bcf SDA ; SDA a 0
goto OUT_CONT
OUT_ONE
bsf SDA ; SDA a 1
OUT_CONT
call tempo_5us
bsf SCL ; SCL a 1
call tempo_5us ; tempo de 5 us
bcf SCL
call tempo_5us
decfsz N, F ; decrementer N
goto OUT_BIT
return
I2C_RECEPTION ; recois donnees de l esclave vers le pic
clrf OCTET ; efface octet
movlw d'8'
movwf N ; la donnees sur 8 bits
call SDA_IN ; SDA en entree
call tempo_5us ; tempo de 5 us
IN_BYTE
bsf SCL ; SCL a 1
call tempo_5us
btfsc SDA ; test de SDA
goto IN_ONE ;
IN_ZERO
bcf STATUS,C ; SDA a 0 met la carry a 1 ou a 0
goto IN_CONT ; suivant etat de SDA
IN_ONE
bsf STATUS,C ; SDA a 1
goto IN_CONT
IN_CONT
call tempo_5us
bcf SCL ; SCL a 0
call tempo_5us
rlf OCTET,1 ; decallage a gauche C >> OCTET
call tempo_5us
decfsz N,f ; si N = 0
goto IN_BYTE
call tempo_5us ; tempo de 5 us
movf OCTET,0 ; met octet recu dans w
return
NO_ACK ; si Nack de rtc alors stop i2c
call tempo_5us
bcf LedR ; Led rouge allumée
call tempo500ms
call tempo500ms ; attente 1 sec
bsf LedR ; Led rouge eteinte
goto start ; si erreur bus I2C alors goto start
sleep
SDA_IN ; mettre SDA ( RA1 ) en entree
bsf STATUS,RP0 ; aller en bank1
movlw b'00000010'
movwf TRISA ; port A en sortie
bcf STATUS,RP0 ; aller en bank0
return
SDA_OUT ; mettre SDA ( RA1 ) en sortie
bsf STATUS,RP0 ; aller en bank1
movlw b'00000000'
movwf TRISA ; port A en sortie
bcf STATUS,RP0 ; aller en bank0
return
tempo_5us ; tempo de 11 us pour l' i2c
nop
nop
nop
return
tempo500ms ; temporisation de 500 ms
call wait0
call wait0
call wait0
call wait0
return
wait0 ; Boucles réalisant une tempo élémentaire
movlw .200 ; Charge count1 avec valeur décimale 200
movwf count1
d1 movlw .200 ; Charge count2 avec valeur décimale 200
movwf count2
d2 decfsz count2,1 ; décremente et saute ligne suiv. si zero
goto d2 ; si différent de zero
decfsz count1,1 ; décremente count1 si count2 == zero
goto d1 ; boucle interne si count2 <> zero
return
END ; fin de programme
C'est le début de ta routine de lecture qui me parait bizarre...
D'après la datasheet du DS1307 (figure6 page13) il faut avoir la séquence suivante:
- start
- ecriture adresse esclave (1101000 + rw=0)
- ack esclave
- ecriture adresse pointeur registre (00 pour lire les secondes)
- ack esclave
- Start à nouveau
- écriture adresse esclave (1101000 + rw=1)
- ack esclave
- lecture octet (normalement les secondes)
- Nack du maitre
- stop
normalement ça devrait rouler...
A+
25/03/2012 - 09h34
juju_du_26
Date d'inscription
octobre 2010
Localisation
26 MTLR
Messages
50
Re : pic 16F84A , clock RTC en asm
Merci Schmo
J'ai refais mon test du bus I2C ( rallonger tempo pour le rallentir ) et
leds sur SDA et SCL . Je vois bien passer tous les octets .
Start , Adresse rtc , Adresse , Start , Adresse rct puis les données , Stop .
J'ai fais des tests en lisant les sec , min , et les mois ...
Les données sur le bus sont corrects mais l'affichage sur le portB
est toujours le meme ( 010001000 ) et differents des données du bus.
Le probleme est donc dans la partie reception .
Merci
Code:
I2C_RECEPTION ; recois donnees de l esclave vers le pic
clrf OCTET ; efface octet
movlw d'8'
movwf N ; la donnees sur 8 bits
call SDA_IN ; SDA en entree
call tempo_5us ; tempo de 5 us
IN_BYTE
bsf SCL ; SCL a 1
call tempo_5us
btfsc SDA ; test de SDA
goto IN_ONE ;
IN_ZERO
bcf STATUS,C ; SDA a 0 met la carry a 1 ou a 0
goto IN_CONT ; suivant etat de SDA
IN_ONE
bsf STATUS,C ; SDA a 1
goto IN_CONT
IN_CONT
call tempo_5us
bcf SCL ; SCL a 0
call tempo_5us
rlf OCTET,1 ; decallage a gauche C >> OCTET
call tempo_5us
decfsz N,f ; si N = 0
goto IN_BYTE
call tempo_5us ; tempo de 5 us
movf OCTET,0 ; met octet recu dans w
return
25/03/2012 - 15h01
schmo
Date d'inscription
juillet 2009
Messages
62
Re : pic 16F84A , clock RTC en asm
Salut,
En relisant ton prog, je viens de constater que :
Code:
AAA
call LIRE_RTC ; lit hrs et min sec dans la rtc
movlw secondes
movwf PORTB ; met les secondes sur le portB
call wait0
goto AAA ; reboucle
faute de frappe ou autre??? remplace l'instruction par "MOVF secondes,W" cela changera peut être les choses..
A+
25/03/2012 - 17h11
juju_du_26
Date d'inscription
octobre 2010
Localisation
26 MTLR
Messages
50
Re : pic 16F84A , clock RTC en asm
Salut
Effectivement il y avait bien une erreur sur cette instruction mais ca ne fonctionne toujours pas .
J'ai fais le test suivant :
1 ) En mettant une valeur dans ' secondes ' , et mis 0 dans ' w ' pour etre sure
Cette valeur s'affiche bien sur le portB
Comme ici
Code:
AAA
movlw b'10101010' ; mettre 10101010 dans w
movwf secondes ; mettre w dans secondes
movlw b'00000000' ; mettre 0 dans w
call wait0 ; tempo
movf secondes,0 ; secondes >> w
movwf PORTB ; met les secondes sur le portB
goto AAA
2 ) En lisant la valeur dans la RTC
Rien ne s'affiche . Le portB reste a 00000000
Code:
AAA
call LIRE_RTC ; lit hrs et min dans la rtc
movf secondes,0 ; sec >> w
movwf PORTB ; met les secondes sur le portB
call wait0
goto AAA
Ca signifie qu'en revenant du sous prog LIRE_RTC je n'ai pas
la valeur des secondes dans w , non ?
Merci
Dernière modification par juju_du_26 ; 25/03/2012 à 17h13.
25/03/2012 - 17h50
schmo
Date d'inscription
juillet 2009
Messages
62
Re : pic 16F84A , clock RTC en asm
salut,
Apres simulation de ton prog dans MPLAB, il semblerai que:
- a la fin de I2C_RECEPTION, tu place la valeur lu (qui est dans OCTET) dans Wreg,
- tu appel I2C_PIC_ACK, qui appel SDA_OUT,
- Dans cette routine, tu utilise Wreg --> donc tu a perdu la valeur lue....