Bonjour,
Je viens vous exposer un problème de bus sur lequel je plante depuis bientôt 3 jours...
J'ai branché sur un 16F876 une DS1307 via I2C (jusque là, rien d'extravagant) SCL SDA sur les pins ad-hoc des deux côtés, 4MHz pour le pic, quartz RTC connecté, pin Vbat au GND, 5V etc etc
N'ayant jamais utilisé l'I2C je charge le datasheet Microchip et je suis la procédure classique, voici le source (c'est un peu en vrac j'en suis au début du projet):
;------------ Programme ---------------
; Titre : CdR
; Date de départ : 31 Mai 2006
; Date de version alpha : 01 Juin 2006 (test RS232)
; Date de version bêta :
; Date de version release :
; Auteur : B.Marien
; PIC utilisé : PIC 16F876/16F876A
; Base de fréquence externe à 4Mhz XT
;
;***** PIC16F876 ****************************** ******************** ****
;
; MCLR/Vpp -- 1 28 -- RB7/PGD
; RA0/AN0 -- 2 27 -- RB6/PGC
; RA1/AN1 -- 3 26 --> RB5
; RA2/AN2/Vref-/CVref -- 4 25 -- RB4
; RA3/AN3/Vref+ -- 5 24 <-- RB3/PGM
; RA4/T0CKI/C1OUT -- 6 23 -- RB2
; RA5/AN4/SS/C2OUT -- 7 22 -- RB1
; - Vss --> 8 21 -- RB0/INT
; OSC1/CLKI --> 9 20 <-- Vdd +
; OSC2/CLKO <-- 10 19 <-- Vss -
; RC0/T1OSO/T1CKI -- 11 18 -- RC7/RX/DT
; RC1/T1OSI/CCP2 -- 12 17 -- RC6/TX/CK
; RC2/CCP1 -- 13 16 -- RC5/SDO
; RC3/SCK/SCL -- 14 15 -- RC4/SDI/SDA
;
; RB3 = LVP
; RB5 = sortie test
;***************************** ******************** *********************
;----------------- Directive d' assemblage pour MPLAB -----------------
LIST P=16F876 ;Device
#INCLUDE P16F876.INC ;Fichier invoqué contenant les infos du proc
;***** Pattern de configuration
; CP -- DEBUG WRT1 WRT0 CPD LVP BOREN -- -- PWRTE WDTE FOSC1 FOSC0
;bit 13 12 11 10 9 8 7 6 5 4 3 2 1 0
; 1 1 1 1 1 1 1 0 1 1 0 0 0 1(3FB1)
;
; CP = 1 Code protection off
; -- 1 /!\ Mettre à 1 les bits non utilisés /!\
; DEBUG = 1 In-Circuit debugger disabled, RB6 RB7 free
; WRT1/0 = 11 No code protection
; CPD = 1 No EEPROM protection
; LVP = 1 Low Voltage Programming enabled, RB3 no more free I/O
; BOREN = 0 No brown-out
; -- 1
; -- 1
; PWRTE = 0 Power-up timer enabled
; WDTE = 0 WDT disabled
; FOSC1/0 = 01 XT
__CONFIG 0x3FB1 ;Word de configuration (watchdog...)
ERRORLEVEL -302 ;Suppression des erreurs de Bank
;---------------------- Définition des macros ----------------------
Bank0 macro
BCF STATUS,RP0
BCF STATUS,RP1
endm
Bank1 macro
BSF STATUS,RP0
BCF STATUS,RP1
endm
Bank2 macro
BCF STATUS,RP0
BSF STATUS,RP1
endm
Bank3 macro
BSF STATUS,RP0
BSF STATUS,RP1
endm
;-------------------- Définition des constantes --------------------
;Initialisation I2C
#define RTC_ADD_IN B'11010000' ;Control Byte d'écriture vers DS1307
#define RTC_ADD_OUT B'11010001' ;Control Byte de lecture vers DS1307
#define RTC_BAUD D'100' ;Baud en Kbps
#define FOSC D'4000' ;Oscillateur en KHz
;Initialisation RS232
#define carry STATUS,C ;Flag décimal
#define zero STATUS,Z ;Flag de résultat nul
#define _receivedcar flag,0 ;Alias de flag, bit indicateur de réception
#define CT_TEST PORTB,5 ;Sortie BLINK
;--------------------- Définition des variables --------------------
; ORG 0x20
i EQU 0x20 ;Variable de division
j EQU 0x21 ;Variable de division
k EQU 0x22 ;Variable de division
XTEMPO EQU 0x23 ;Registre temporaire du multiplicateur de temporisation 0,25s
saveW EQU 0x24 ;\
savesta EQU 0x25 ; >Sauvegarde de registres pour rétablissement après interruption
saveFSR EQU 0x26 ;/
flag EQU 0x27
caractere EQU 0x28
compteur EQU 0x29
SECONDS EQU 0x2A
MINUTES EQU 0x2B
HOURS EQU 0X2C
CONTROL EQU 0X2D
;-------------------- Init des ports A, B et C ----------------------
ORG 0 ;Point de départ du code
GOTO init
org 4
GOTO interrupt ;Interruption
init:
Bank0 ;Passage en Bank0
CLRF PORTA ;\
CLRF PORTB ; >Clear Data Latches
CLRF PORTC ;/
Bank1
CLRF TRISA ; A en sortie
CLRF TRISB ; B en sortie
MOVLW B'10011000' ; RC7 en entrée ( RX ) / RC6 en sortie ( TX ) / RC3 en entrée (SCL) / RC4 en entrée (SDA)
MOVWF TRISC
; GOTO debut ;On saute l'I2C pour la simulation
;Init I2C en Master Mode 100KHz
Bank0
MOVLW B'00101000' ;SSPEN pour valider l'I2C, SSPMx pour Master Mode
MOVWF SSPCON ;Config établie dans le registre correspondant
Bank1
MOVLW B'10000000' ;Slew Rate configuré pour le 100KHz
MOVWF SSPSTAT
MOVLW (FOSC / (4 * RTC_BAUD)) -1 ;Calcul SPADD pour obtenir le paramètre menant à 100KHz, soit SSPADD = 9
MOVWF SSPADD
;Phase d'initialisation de la RTC
Bank1
BSF SSPCON2,SEN ;Signal START
CALL WaitMSSP ;On attend la fin de l'opération, attention fonction en Bank0
MOVLW RTC_ADD_IN ;Adresse RTC en mode écriture
CALL Send_I2C_Byte ;On envoit W vers la RTC, attention fonction en Bank0
CALL WaitMSSP ;On attend la fin de l'opération, attention fonction en Bank0
MOVLW 0x00 ;Première adresse de la RTC
CALL Send_I2C_Byte ;On envoit W vers la RTC, attention fonction en Bank0
CALL WaitMSSP ;On attend la fin de l'opération, attention fonction en Bank0
Bank1
BSF SSPCON2,PEN ;Signal STOP
CALL WaitMSSP ;On attend la fin de l'opération, attention fonction en Bank0
******
j'initialise mes options_reg intcon après pour ne pas gêner tant que ça ne marche pas
Donc je saute un peu de code qui est un simple blinker et une sortie uart pour voir si le prog tourne encore...
******
;---------------------- Fonctions invoquées ------------------------
;Retardateur I2C
WaitMSSP:
Bank0
BTFSS PIR1,SSPIF ;On vérifie le flag de fin d'opération
GOTO $-1 ;Pas encore fini
BCF PIR1,SSPIF ;RAZ du flag de fin d'opération
RETLW 0 ;Retour
;Fontion d'envoi sur l'I2C
Send_I2C_Byte:
Bank0
MOVWF SSPBUF ;On envoit le contenu de W dans le Buffer I2C
RETLW 0 ;Retour
[...]
Blabla les autres fonctions
[...]
End
Oui mais non car mon prog bloque au premier WaitMSSP donc sur SSPIF qui ne se met jamais à 1.
Quand je regarde au voltmètre mes SCL et mes SDA ils restent collés à 0V :/
Le buff me semble donc occupé alors que la RTC est le seul périph connecté!
Je vous serai reconnaissant de me sortir de la crise de nerf qui me guette avant ce week end
-----