module I²C pic16f876 et DS1307
Répondre à la discussion
Affichage des résultats 1 à 4 sur 4

module I²C pic16f876 et DS1307



  1. #1
    sekyo7

    Smile module I²C pic16f876 et DS1307


    ------

    Bonjour,
    Je voudrais réaliser une horloge/calendrier avec un pic16F876 câblé en maître et un DS1307 esclave avec le mode I²C. Je programme en assembleur et je fais la simulation sous proteus 7. Voici le schéma de mon horloge (QUARTZ de 4MHz utilisé).

    Nom : schema.png
Affichages : 426
Taille : 15,0 Ko

    Voici mon programme :
    Code:
    ;*****************************************************************************
    ;   Réalisation d'une montre lcd contrôlée par un PIC16876					 * 
    ;                                                                            *
    ;*****************************************************************************
    ;                                                                            *
    ;    NOM: montrelcd                                                          *
    ;    Date: 06/11/2013                                                        *
    ;    Version: 1.0                                                            *
    ;    Circuit: Proteus                                                        *
    ;    Auteur: Traoré Sékou                                                    *
    ;                                                                            *
    ;*****************************************************************************
    ;                                                                            *
    ;    Fichier requis: P16F876.inc                                             *
    ;                    lcd_4b.inc                                              *
    ;                                                                            *
    ;                                                                            *
    ;*****************************************************************************
    ;                                                                            *
    ;    Notes: Affichage lcd 4 bits                                             *
    ;                                                                            *
    ;                                                                            *
    ;                                                                            *
    ;                                                                            *
    ;*****************************************************************************
    
    
    	LIST      p=16F876            ; Définition de processeur
    	#include <p16F876.inc>        ; fichier include
    	#include <lcd_4b.inc>		  ; fichier include afficheur lcd
    
    	__CONFIG   _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC 
    
    ;_CP_OFF		Pas de protection
    ;_DEBUG_OFF		RB6 et RB7 en utilisation normale
    ;_WRT_ENABLE_OFF	Le programme ne peut pas écrire dans la flash
    ;_CPD_OFF               Mémoire EEprom déprotégée
    ;_LVP_OFF		RB3 en utilisation normale
    ; _BODEN_ON		Reset tension en service
    ;_PWRTE_ON		Démarrage temporisé
    ;_WDT_OFF		Watchdog hors service
    ;_HS_OSC		Oscillateur haute vitesse (4Mhz<F<20Mhz)
    
    ;*****************************************************************************
    ;                               ASSIGNATIONS SYSTEME                         *
    ;*****************************************************************************
    
    ; REGISTRE OPTION_REG (configuration)
    ; -----------------------------------
    OPTIONVAL	EQU	B'10000000'
    			; RBPU     b7 : 1= Résistance rappel +5V hors service
    
    ; REGISTRE INTCON (contrôle interruptions standard)
    ; -------------------------------------------------
    INTCONVAL	EQU	B'00000000'
    
    ; REGISTRE PIE1 (contrôle interruptions périphériques)
    ; ----------------------------------------------------
    PIE1VAL		EQU	B'00000000'
    
    ; REGISTRE ADCON1 (ANALOGIQUE/DIGITAL)
    ; ------------------------------------
    ADCON1VAL	EQU	B'00000110' ; PORTA en mode digital
    
    ; DIRECTION DES PORTS I/O
    ; -----------------------
    
    DIRPORTA	EQU	B'00000000'	; Direction PORTA 
    DIRPORTB	EQU	B'00000001'	; Direction PORTB
    DIRPORTC	EQU	B'11111111'	; Port RC3/SCL et RC4/SDA en entrée
    
    
    ;*****************************************************************************
    ;                                  DEFINE                                    *
    ;*****************************************************************************
    
    ; exemple
    ; -------
    #DEFINE LCD_RS	PORTB,1		; Broche RS de l'afficheur LCD reliée a la pin RB1
    
    #DEFINE LCD_RW	PORTB,2		; Broche RW de l'afficheur LCD reliée a la pin RB2
    
    #DEFINE LCD_E	PORTB,3		; Broche E de l'afficheur LCD reliée a la pin RB3
    
    #DEFINE LCD_DATA PORTB		; LCD: Port ou est branche le bus de donnee ( bits 4 à 7 ) MSB IMPERATIF
    
    #DEFINE carry STATUS,C		; define carry
    
    ;*****************************************************************************
    ;                             MACRO                                          *
    ;*****************************************************************************
    
    			; Changement de banques
    			; ----------------------
    
    BANK0	macro				; passer en banque0
    		bcf	STATUS,RP0
    		bcf	STATUS,RP1
    	endm
    
    BANK1	macro				; passer en banque1
    		bsf	STATUS,RP0
    		bcf	STATUS,RP1
    	endm
    
    BANK2	macro				; passer en banque2
    		bcf	STATUS,RP0
    		bsf	STATUS,RP1
    	endm
    
    BANK3	macro				; passer en banque3
    		bsf	STATUS,RP0
    		bsf	STATUS,RP1
    	endm
    
    ;*****************************************************************************
    ;                      VARIABLES ZONE COMMUNE                                *
    ;*****************************************************************************
    
    ; Zone de 16 bytes
    ; ----------------
    
    	CBLOCK 0x70		; Début de la zone (0x70 à 0x7F)
    	w_temp : 1		; Sauvegarde registre W
    	status_temp : 1		; sauvegarde registre STATUS
    	FSR_temp : 1		; sauvegarde FSR (si indirect en interrupt)
    	PCLATH_temp : 1		; sauvegarde PCLATH (si prog>2K)
    
    ;variable fichier lcd_b4.asm
    ;---------------------------
    	LCD_mode_set : 1    ;
    	LCD_disp_cont : 1   ;
    	DATA_TMP : 1		;
    	J : 1 				;
    	LCD_curs_disp_shift : 1 ;
    	LCD_func_set : 1 	;
    	DATA_SWAP : 1		;
    	PORT_SAVE : 1       ;
    
    ;variable tempo q4mhz 
    ;--------------------
    	temp1 : 1;
    	temp2 : 2;
    	temp3 : 1;
    
    	ENDC
    
    ;*****************************************************************************
    ;                        VARIABLES BANQUE 1                                  *
    ;*****************************************************************************
    
    ; Zone de 80 bytes
    ; ----------------
    
    	CBLOCK	0xA0		; Début de la zone (0xA0 à 0xEF)
    	secondes : 1		;
    	minutes : 1			;
    	heures : 1			;
    	jour : 1 			;
    	mois : 1			;
    	annee : 1			;
    	cmpt1 : 1			; variable compteur pour read
    
    	endc			; Fin de la zone                        
    
    
    ;*****************************************************************************
    ;                      DEMARRAGE SUR RESET                                   *
    ;*****************************************************************************
    
    	org 0x000 		; Adresse de départ après reset
    	
      	goto    init		; Initialiser
    
    
    
    ; ////////////////////////////////////////////////////////////////////////////
    
    ;                           P R O G R A M M E
    
    ; ////////////////////////////////////////////////////////////////////////////
    
    ;*****************************************************************************
    ;                          INITIALISATIONS                                   *
    ;*****************************************************************************
    init
    
    			; initialisation PORTS (banque 0 et 1)
    			; ------------------------------------
    	BANK0			; sélectionner banque0
    	clrf	PORTA		; Sorties PORTA à 0
    	clrf	PORTB		; sorties PORTB à 0
    
    	bsf	STATUS,RP0	; passer en banque1
    	movlw	ADCON1VAL	; PORTA en mode digital/analogique
    	movwf	ADCON1		; écriture dans contrôle A/D
    	movlw	DIRPORTA	; Direction PORTA
    	movwf	TRISA		; écriture dans registre direction
    	movlw	DIRPORTB	; Direction PORTB
    	movwf	TRISB		; écriture dans registre direction
    	movlw	DIRPORTC	; Direction PORTC
    	movwf	TRISC		; écriture dans registre direction
    
    			; Registre d'options (banque 1)
    			; -----------------------------
    	movlw	OPTIONVAL	; charger masque
    	movwf	OPTION_REG	; initialiser registre option
    
    			; registres interruptions (banque 1)
    			; ----------------------------------
    	movlw	INTCONVAL	; charger valeur registre interruption
    	movwf	INTCON		; initialiser interruptions
    	movlw	PIE1VAL		; Initialiser registre 
    	movwf	PIE1		; interruptions périphériques 1
    
    	;--------------------------------------------------------
    	;			CONFIGURATION MODULE MSSP					*
    	;--------------------------------------------------------	
    
    			; SSPSTAT
    			;--------
    	
    	BANK1 	; passer en banque 1
    	movlw B'10000000' ; 
    	movwf SSPSTAT ; b7 : SMP = 1 (100 kHz)
    					; b6 : CKE = 0 (pour bus I²C)
    
    			; SSPADD
    			;-------
    	movlw D'9' ; Quartz de 4Mhz et fréquence de 100 kHz pour le I²C maître 
    			; SSPADD = (4 000 0000 /(4*100 000))-1 = 9
    	movwf SSPADD ; Le PIC va donc travailler en I²C à la frequence de 100kHz (fréquence de travail du DS1307)
    
    			; SSPCON
    			;-------
    	BANKSEL SSPCON; passer en banque 0
    	movlw	B'00101000' ; b5 : SSPEN = 1 mettre le module MSSP en service
    					; b3 à b0 SSMPx = 1000 mode I²C maître : fréquence déterminée par le registre SSPADD 
    	movwf SSPCON;
    	
    			; autoriser interruptions (banque 0)
    			; ----------------------------------
    	
    	goto	start		; programme principal
    
    	#include <lcd_4b.asm>		  ; Inclusion des fonctions utilisées pour l'affichage LCD
    
    	#include <q4mhz.asm>		  ; inclusion des fonctions de temporisations LCD
    
    
    ;*****************************************************************************
    ;					SOUS-ROUTINE MODULE I²C MAITRE							 *
    ;*****************************************************************************
    I2C_idle
    	BANKSEL SSPSTAT ; passer en banque 1
    I2C_idle2
    	clrwdt			; effacer watchdog
    	btfsc SSPSTAT,R_W			; tester si émission en cours
    	goto I2C_idle2				; oui, attendre
    I2C_idle3
    	clrwdt			; effacer watchdog
    	movf SSPCON2,w  ; charger registre SSPCON2
    	andlw 0x1F		; conserver ACKEN,RCEN,PEN,RSEN,et SEN
    	btfss  STATUS,Z  ; tester si tous à zero (aucune opération en cours)
    	goto I2C_idle3  ; non, attendre
    	bcf STATUS,RP0  ; repasser en banque 0
    	return			; rien en cours on peut sortir
    	 
    
    I2C_start
    	call I2C_idle ; on attend que le bus I2C soit libre
    	BANKSEL SSPCON2 ; passage en banque 1
    	bsf SSPCON2,SEN ; SEN = 1 (lancement d'une opération start)
    	bcf STATUS,RP0  ; retour en banque 0
    	return 			; 
    	
    I2C_write
    	call I2C_idle ; on attend que le bus I2C soit prêt
    	movwf SSPBUF  ;
    	return
    
    I2C_ACK_slave_to_master
    	call I2C_idle ; on attend que le bus I2C soit prêt
    	BANK1		 	; passage en banque 1
    I2C_ACK_slave_to_master0
    	btfsc SSPCON2,ACKSTAT ; tester bit ACKSTAT
    	goto  I2C_ACK_slave_to_master0 ; bit ACKSTAT = 1 acknowledge pas encore reçu
    	bcf STATUS,RP0	; retour en banque 0
    	return
    
    I2C_Repeated_Start
    	call I2C_idle ; on attend que le bus I2C soit libre
    	BANK1		; passer en banque 1
    	bsf SSPCON2,RSEN ; RSEN = 1 (lancement d'une opération Repeated Start Condition)
    	bcf STATUS,RP0 ;
    	return
    
    I2C_read
    	call I2C_idle ; on attend que le bus I2C soit libre
    	BANK1 ;
    	bsf SSPCON2,RCEN ; on lance la réception
    I2C_read2
    	btfsc SSPCON2,RCEN ; on teste si la reception est terminer (RCEN = 0)
    	goto I2C_read2 ; non, on attend
    	bcf STATUS,RP0 ; réception terminée on passe en banque 0
    	movf SSPBUF,w ; copie de la valeur reçue dans w
    	return
    
    I2C_ACK_master_to_slave
    	call I2C_idle ; on attend que le bus I2C soit prêt
    	BANK1		 	; passage en banque 1
    	bcf SSPCON2,ACKDT ; préparation de l'envoi d'un acknowledge
    	bsf SSPCON2,ACKEN ; ACKEN = 1 (lancement d'une opération acknowledge)
    	bcf STATUS,RP0	; passage en banque 
    	return
    
    ; Not Acknowledge (maître vers esclave)
    ;--------------------------------------
    
    I2C_NOACK
    	call I2C_idle ; on attend que le bus I2C soit prêt
    	BANK1		 ; passage en banque 1
    	bsf SSPCON2,ACKDT ; preparation de l'envoi d'un not acknowledge
    	bsf SSPCON2,ACKEN ; lancement de l'opération not acknowledge
    	bcf STATUS,RP0 ; retour en banque 0
    	return
    
    I2C_stop 
     	call I2C_idle ; on attend que le bus I2C soit prêt
    	BANK1 ; passage en banque 1
    	bsf	SSPCON2,PEN ; lancement d'une opération stop
    	bcf STATUS,RP0  ; retour en banque 0
    	return
    
    ;*****************************************************************************
    ;                      PROGRAMME PRINCIPAL                                   *
    ;*****************************************************************************
    
    start
    
    	clrwdt			; effacer watch dog
    	
    	call I2C_start    ; envoyer start condition
    	
    	movlw B'11010000' ; 8 bits à ecrire (7 bits d'adresse + bit 0 Write)
    	call I2C_write	   ;
    	call I2C_ACK_slave_to_master ; attendre acknowledge du DS1307
    	
    	movlw B'00000000' ; envoyer l'adresse des secondes
    	call I2C_write	  ; au DS1307
    	call I2C_ACK_slave_to_master ; attendre acknowledge DS1307
    
    	call I2C_Repeated_Start ; envoyer un repeated start condition
    
    	movlw B'11010001'	; envoyer adresse DS1307 (7 bits de poids fort) + bit 0 = Read
    	call I2C_write		;
    	call I2C_ACK_slave_to_master ; attendre acknowledge DS1307
    
    	movlw	0xA0		;	
    	movwf	FSR			; charger première adresse variable banque 1 (secondes) dans FSR
    	bsf STATUS,RP0		; passer en banque 1 (sortie d'un call, donc on était en banque 0)
    	movlw .6			; charger 6 dans cmpt1
    	movwf	cmpt1		; en effet on a 6 lectures à faire (s,min,h,jour,mois,annee)
    
    lecture
    	call I2C_ACK_master_to_slave ;  lire valeur envoyée au pic
    	call I2C_read		; et mettre le contenu dans w
    	movwf INDF			; envoyer la valeur lue dans la variable dont l'adresse se situe dans FSR
    	incf FSR,f			; passer à la variable suivante
    
    	decfsz	cmpt1,f		; decrementer compteur 1
    	goto lecture		; non, pas 0 donc aller à la variable suivante
    	
    	call I2C_NOACK		; toutes les valeurs ont été lues donc arrêter lecture
    	call I2C_stop		; 
    
    	
    loop
    	clrwdt			; effacer watch dog
    	goto loop		; boucler
    
    
    
    
    	END 			; directive fin de programme
    Voilà vous l’avez sans doute deviné, mon programme ne fonctionne pas, j’ai pas d’erreur a la compilation mais j’ai l’impression que l’adresse du DS1307 n’est pas convenablement transmise par le pic16F876 et donc le DS1307 n’envoit jamais de acknowledge et donc mon programme reste bloquer a cette étape. Je ne trouve pourtant pas d’erreur dans mon programme donc je souhaiterais avoir votre aide, merci d’avance pour vos réponses.

    -----

  2. #2
    paulfjujo

    Re : module I²C pic16f876 et DS1307

    bonjour,


    Comment fais-tu pour verifier le fonctionnement du DS1307 ?
    Pourquoi s'embarasser dans un premier temps du watchdog ?
    il me semble que tu as oublié le jour de la semaine (JS) dans ta reservation d'adresse ram .
    donc 7 items .
    Si le DS1307 est bien initiailsé , il doit sortir un signal de 1hz sur sa broche SQWOUT.
    Il faut aussi la presence de VBAT 3V sur la pin Vbatterie ou mettre celle ci au 0V.



    Code:
    ; Zone de 80 bytes
    ; ----------------
    
    	CBLOCK	0xA0		; Début de la zone (0xA0 à 0xEF)
    	secondes : 1		;
    	minutes : 1			;
    	heures : 1			;
    	js :1                         ; jour de la semaine
            jour : 1 			;
    	mois : 1			;
    	annee : 1			;
    	cmpt1 : 1			; variable compteur pour read
    
    	endc			; Fin de la zone

  3. #3
    sekyo7

    Re : module I²C pic16f876 et DS1307

    Tout d'abord merci pour votre réponse ^^, pour la variable manquante c'est vrai je l'avais oubliée. J'ai mis des clrwdt mais j'ai désactivé le watchdog (j'avais utiliser le watchdog pour voir où se plantais mon programme) et avec le I2C debugger de proteus j'ai cru voir que l'adresse n'étais pas correctement envoyée au DS1307. Je ne suis pas vraiment sûr puisque c'était par hasard que j'ai pu voir le I2C debugger et que j'ai gribouiller un peu mais ça m'a semblé logique.

  4. #4
    sekyo7

    Re : module I²C pic16f876 et DS1307

    Ah j'oubliais avec l'ajout de la masse ou du +3V sur VBAT je n'obtiens toujours rien...

  5. A voir en vidéo sur Futura

Discussions similaires

  1. PWM et pic16f876
    Par prince02 dans le forum Électronique
    Réponses: 19
    Dernier message: 04/03/2009, 15h08
  2. pb CAN du PIC16f876
    Par invite0b61f2e8 dans le forum Électronique
    Réponses: 11
    Dernier message: 11/05/2008, 21h16
  3. comment relier un pic16f876 a un lcd module 162f
    Par invitecec8a619 dans le forum Électronique
    Réponses: 4
    Dernier message: 16/01/2008, 20h52
  4. PIC16F876 en I2C
    Par invite2977d557 dans le forum Électronique
    Réponses: 3
    Dernier message: 16/09/2007, 15h38
  5. PIC16F876
    Par inviteaaaccd27 dans le forum Électronique
    Réponses: 1
    Dernier message: 04/02/2004, 12h56
Découvrez nos comparatifs produits sur l'informatique et les technologies.