Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général en BASIC et PASCAL !

Modérateur : Gérard

La Communication I2C
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#1 Message par cyril13110 » jeu. 28 juil. 2016 14:22

alors je propose un tutorial participatif avec l retour de ceux qui veulent bien partager leurs expérience sur l'utilisation de l'I2C au sens large et global du terme de tel sorte à comprendre le mécanisme de cette communication.
la base ddu tuto pourri se faire sur des puces classic RTC DS1307 ou DS3231 tel que decrit dans le post de Jérémy.
http://www.fantaspic.fr/viewtopic.php?f=32&t=297


avec pourquoi pas étendre la réflexion sur d'autre puce avec com I2C.

A l'origine mon idée était de récupérer l'heure sur un DS1307 pour l’éclairage de mon aquarium.
Je me suis basé sur le code exemple pour faire mes premiers pas afin de tenter de comprendre comment cela fonctionne.
Je ne retrouve pas l'exemple pour le DS1307 de mikrobasic du coup on va partir sur le code exemple du PCF8583:

Code : Tout sélectionner

program RTC_Read

dim seconds
, minutes, hours, _day, _month, year as byte    ' Global date/time variables

'
 Software I2C connections
dim Soft_I2C_Scl  as sbit at RC3_bit
    Soft_I2C_Sda  as sbit at RC4_bit
    Soft_I2C_Scl_Direction as sbit at TRISC3_bit
    Soft_I2C_Sda_Direction as sbit at TRISC4_bit
' End Software I2C connections

'
 Lcd module connections
dim LCD_RS as sbit at LATB4_bit
    LCD_EN as sbit at LATB5_bit
    LCD_D4 as sbit at LATB0_bit
    LCD_D5 as sbit at LATB1_bit
    LCD_D6 as sbit at LATB2_bit
    LCD_D7 as sbit at LATB3_bit
    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D4_Direction as sbit at TRISB0_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D7_Direction as sbit at TRISB3_bit
' End Lcd module connections

'
--------------------- Reads time and date information from RTC (PCF8583)
sub procedure Read_Time()
  Soft_I2C_Start()              ' Issue start signal
  Soft_I2C_Write(0xA0)          '
 Address PCF8583, see PCF8583 datasheet
  Soft_I2C_Write
(2)             ' Start from address 2
  Soft_I2C_Start()              '
 Issue repeated start signal
  Soft_I2C_Write
(0xA1)          ' Address PCF8583 for reading R/W=1
  seconds = Soft_I2C_Read(1)    '
 Read seconds byte
  minutes 
= Soft_I2C_Read(1)    ' Read minutes byte
  hours = Soft_I2C_Read(1)      '
 Read hours byte
  _day 
= Soft_I2C_Read(1)       ' Read year/day byte
  _month = Soft_I2C_Read(0)     '
 Read weekday/month byte}
  Soft_I2C_Stop()               ' Issue stop signal}
end sub

'
-------------------- Formats date and time
sub procedure Transform_Time
() 
  seconds  
=  ((seconds and 0xF0) >> 4)*10 + (seconds and 0x0F)  ' Transform seconds
  minutes  =  ((minutes and 0xF0) >> 4)*10 + (minutes and 0x0F)  '
 Transform months
  hours    
=  ((hours and 0xF0)  >> 4)*10  + (hours and 0x0F)    ' Transform hours
  year     =   (_day and 0xC0) >> 6                              '
 Transform year
  _day      
=  ((_day and 0x30) >> 4)*10    + (_day and 0x0F)    ' Transform day
  _month    =  ((_month and 0x10)  >> 4)*10 + (_month and 0x0F)  '
 Transform month
end sub

'-------------------- Output values to Lcd
sub procedure Display_Time()
  Lcd_Chr(1, 6, (_day / 10)   + 48)    '
 Print tens digit of day variable
  Lcd_Chr
(1, 7, (_day mod 10)   + 48)  ' Print oness digit of day variable
  Lcd_Chr(1, 9, (_month / 10) + 48)    '
 Print tens digit of month variable
  Lcd_Chr
(1,10, (_month mod 10) + 48)  ' Print oness digit of month variable
  Lcd_Chr(1, 15, year        + 48)     '
 Print year vaiable + 8 (start from year 2008)

  Lcd_Chr(2, 6, (hours / 10)   + 48)   ' Print tens digit of hours variable
  Lcd_Chr(2, 7, (hours mod 10)   + 48) '
 Print oness digit of hours variable
  Lcd_Chr
(2, 9, (minutes / 10) + 48)   ' Print tens digit of minutes variable
  Lcd_Chr(2,10, (minutes mod 10) + 48) '
 Print oness digit of minutes variable
  Lcd_Chr
(2,12, (seconds / 10) + 48)   ' Print tens digit of seconds variable
  Lcd_Chr(2,13, (seconds mod 10) + 48) '
 Print oness digit of seconds variable
end sub

'------------------ Performs project-wide init
sub procedure Init_Main()

  TRISB = 0
  LATB = 0xFF
  TRISB = 0xFF
  ANSELB = 0                '
 Configure AN pins as digital I/O
  ANSELC 
= 0

  Soft_I2C_Init
()           ' Initialize Soft I2C communication
  
  Lcd_Init()                '
 Initialize Lcd
  Lcd_Cmd
(_LCD_CLEAR)       ' Clear Lcd display
  Lcd_Cmd(_LCD_CURSOR_OFF)  '
 Turn cursor off
  
  Lcd_Out
(1,1,"Date:")      ' Prepare and output static text on Lcd
  Lcd_Chr(1,8,".")
  Lcd_Chr(1,11,".")
  Lcd_Chr(1,16,".")
  Lcd_Out(2,1,"Time:")
  Lcd_Chr(2,8,":")
  Lcd_Chr(2,11,":")
  Lcd_Out(1,12,"201")       '
 start from year 2010
end sub

'----------------- Main sub procedure
main:
  Delay_ms(500)
   
  Init_Main()             '
 Perform initialization

  while TRUE              
' Endless loop
    Read_Time()           '
 Read time from RTC(PCF8583)
    Transform_Time()      ' Format date and time
    Display_Time()        '
 Prepare and display on Lcd
  wend
end


l'ensemble du code est trés simple donc autant s'interesser directement sur la fonction qui gère la com I2C
datasheet du PCF8583:

pas de surprise au debut il faut initialiser -- normal

Code : Tout sélectionner


  Soft_I2C_Start
()              ' Issue start signal


 vue que c'est du reseau bon ok il faut adrésser mais snif sur cette puce il ny a que 2 adresse de possible du coup comment on fait si on a plus de 2 puces à connecter sur le reseau?
-->  Slave addresses: A1h or A3h for reading, A0h or A2h for writing (exttrait DS page 1 ) -  mais quesqu'il se passe si a la place de A0 je rentre A2?
 

Code : Tout sélectionner

 Soft_I2C_Write(0xA0)          ' Address PCF8583, see PCF8583 datasheet


 page 8 il y a le descriptif du registre du coup ok pour l'adresse2 de debut mais comment la puce c'est quil faut démarer à cette adresse?
 
 

Code : Tout sélectionner

Soft_I2C_Write(2)             ' Start from address 2

 la je plante pourquoi refaire un 2nd start? quel en est l'utilité? dans la librairie il y a une fonction I2C_repeated_start le descriptif est plutot obscure et pas d'exemple est dispo est ce que c'est la meme utilité?
  

Code : Tout sélectionner

Soft_I2C_Start()              ' Issue repeated start signal

alors la je ne trouve vraiment pas d'infoo sur ce registre ormi ca:
  --> Slave addresses: A1h or A3h for reading, A0h or A2h for writing (exttrait DS page 1 )  - mais quesqu'il se passe si a la place de A1 je rentre A3?
 

Code : Tout sélectionner

 Soft_I2C_Write(0xA1)          ' Address PCF8583 for reading R/W=1


et la ca se complique car je ne comprend pas comment on peut dire à la puce qu'il faut quelle envoie les variables de secondes à mois, est ce que c'est parcequ'il y a le paramétre d’acquittement qui est renseigné?
  

Code : Tout sélectionner

  seconds = Soft_I2C_Read[b](1)[/b]    ' Read seconds byte
  minutes = Soft_I2C_Read[b](1)[/b]    '
 Read minutes byte
  hours 
= Soft_I2C_Read[b](1)[/b]      ' Read hours byte
  _day = Soft_I2C_Read[b](1)[/b]       '
 Read year/day byte
  _month 
= Soft_I2C_Read[b](0)[/b]     ' Read weekday/month byte}


bon la ok pas trés difficile on comprend que ca veux dire que c'est fini  :langue: 
 

Code : Tout sélectionner

 Soft_I2C_Stop()               ' Issue stop signal}
end sub


du coup est ce que quelqu'un pourrai démystifier tous cela? afin que les personnes qui ne maitrise pas ce protocole puisse enfin savoir pourquoi c'est comme ca et pas autrement.

La Communication I2C
Gérard
Avatar de l’utilisateur
Expert
Expert
Messages : 1640
Âge : 65
Enregistré en : septembre 2015
Localisation : Alsace - Haut-Rhin

#2 Message par Gérard » jeu. 28 juil. 2016 16:17

Code : Tout sélectionner


SUB PROCEDURE INIT_I2C_RTC

    I2C1_START
()
    I2C1_WR(RTC_WR)                              'ADRESSE RTC
    I2C1_WR(14)                                  '
ADRESSE A ECRIRE
    I2C1_WR
(64)                                  'DONNEE A ECRIRE
    I2C1_WR(0)                                   '
DONNEE A ECRIRE
    I2C1_REPEATED_START
()
    I2C1_WR(RTC_WR)
    I2C1_WR(2)                                   'OCTET DES HEURES
    I2C1_REPEATED_START()
    I2C1_WR(RTC_RD)
    RTC_TMP = I2C1_RD(0)                         '
LECTURE OCTET H DANS RTC_TMP
    I2C1_STOP
()                                  '(0) --> NACK

    IF RTC_TMP.6 = 1 THEN                        '
COMPTAGE 24h
        RTC_TMP.6 
= 0
    END IF

    I2C1_START
()
    I2C1_WR(RTC_WR)
    I2C1_WR(2)                                   'ADRESSE OCTET DES HEURES
    I2C1_WR(RTC_TMP)
    I2C1_STOP()

END SUB



Code : Tout sélectionner


SUB PROCEDURE LECTURE_RTC

    I2C1_START
()
    I2C1_WR(RTC_WR)                              'adresse RTC + WR
    I2C1_WR(MINUTES)                             '
adresse minutes
    I2C1_REPEATED_START
()
    I2C1_WR(RTC_RD)                              'adresse RTC + RD
    FOR I = 1 TO 5
        DATA_RTC[I] = I2C1_RD(1)                 '
--> ACK
    NEXT I
    DATA_RTC
[6] = I2C1_RD(0)                     '0 --> NACK
    I2C1_STOP()

    MN_RTC     = DATA_RTC [1]
    H_RTC      = DATA_RTC [2]
    JOUR_RTC   = DATA_RTC [3]
    DATE_RTC   = DATA_RTC [4]
    MOIS_RTC   = DATA_RTC [5]
    ANNEE_RTC  = DATA_RTC [6]

END SUB



Code : Tout sélectionner

'DECLARATIONS
    CONST    RTC_WR  = %11010000
    CONST    RTC_RD  = %11010001
    
    DIM      DATA_RTC      AS BYTE [7]


Dans cette partie de programme, je n'ai pas lu les secondes, je n'en avais pas besoin.
J'espère que ça aidera.

EDIT : il s'agit de la DS3231.
Le 18/04/19 je suis devenu papy de jumeaux, le 01/09/23 une petite cousine des jumeaux est née.

La Communication I2C
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » jeu. 28 juil. 2016 17:09

Bonjour à tous,

 ! Message de modération :
cyril13110 j'ai modérer ta proposition de tutoriel, partant du principe qu'un tutoriel est fait pour expliquer les choses et non pour chercher des réponses.


Dans l'idéal et dans ce post je te propose de chercher toutes les infos dont tu as besoin, pour ensuite faire un tutoriel.

Je serais vraiment ravi de publier un de tes tutos, même tout simple, mais il faut qu'il réponde à quelques critères. Je te propose de commencer par une application à base de ton module !

Inspire toi de mon tuto sur le DS1307 par exemple.

Voici un lien direct sur la librairie MikroBasic pour RTC avec DS1307 : lien vers la librairie ( il faut être inscrit).

Vers le site : Libstock

ce module n'est vraiment pas sorcier, je suis certain que tu va réussir à t'en tirer, et le forum est la pour t'aider !

merci de ta compréhension
C'est en faisant des erreurs, que l'on apprend le mieux !!!

La Communication I2C
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#4 Message par cyril13110 » jeu. 28 juil. 2016 18:59

Ok pas de probleme jeremy, je le ferais avec plaisir le tuto dès que jai compris le principe :-D

La Communication I2C
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#5 Message par cyril13110 » ven. 29 juil. 2016 08:40

bonjour,
hier j'ai fouillé mes tiroirs et je n’ai pas retrouvé mon DS1307, par contre je suis tombé sur un DS3231 à souder.
Du coup je vais faire mes test avec.
Me reste plus a comprendre et trouver la différence pour l'adressage pour la com.....
Mais je pense qu'avec l'aide de Gérard ca devrait le faire.....

La Communication I2C
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#6 Message par cyril13110 » ven. 29 juil. 2016 13:32

du coup je vais commencer avec une question général de débutant sur l'I2C.
D’après le code de Gérard, le DS3231 a une adresse de $D0.
D’après les datasheet il est possible d'aligner pas mal de composant sur le réseau I2C (de mémoire 127),, mais comment faire si par exemple je veux rajouter une puce quelconque, par exemple un can sur I2C, et que ce dernier comporte la même adresse de démarrage? c'est à dire $D0.

La Communication I2C
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#7 Message par Jérémy » ven. 29 juil. 2016 13:38

Tu ne pourras pas ....... .

Mais les fabricants ne sont pas si vils que ca. Il est en général possible de changer l'adresse des composants . Soit lors d'une initialisation, pour les plus sophistiqués , soit par des straps qu'on soude ou soude pour former une adresse I2C , généralement 2 ou 3 straps max , le reste est figé.

j'avoue qu'il convient quand même de regarder dans le cas ou beaucoup d'appareil I2C sont associés !

Tu as la Data-sheet de la DS3231 ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

La Communication I2C
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#8 Message par cyril13110 » ven. 29 juil. 2016 14:10

oui je l'ai trouvé, je l'ai dl a la maison.
mais pour exemple le DS3231 apparemment il n'est pas possible de lui changer l'adresse.
Il faut que je regarde comment le souder car c'est un cms, si je peut le mettre sur une plaque a pastille ca pourra aller vite si non je ne sais pas comment je vais faire, a moins que je soude directement les fils sur le composant à la bourin........
Je soir je regarde ca...

La Communication I2C
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#9 Message par Jérémy » ven. 29 juil. 2016 14:14

oui je l'ai trouvé, je l'ai dl a la maison.

:-D c'était pour que tu me la file ! :langue:

Il faut que je regarde comment le souder car c'est un cms

En quel format le CMS ?

Cadeaux pour toi : http://www.head-fi.org/t/89714/make-you ... k-warnings
C'est en faisant des erreurs, que l'on apprend le mieux !!!

La Communication I2C
cyril13110
Confirmé
Confirmé
Messages : 721
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#10 Message par cyril13110 » ven. 29 juil. 2016 15:24

c'est un soic 16 broches (j'avais pris ca lors de ma découverte des demande d'échantillon chez les divers fondeurs de silicium), mais ca se trouve je peux directement y aller pastille par pastille car les pattes on l'air bien ecarté.
pour la datasheet voila le lien:
https://datasheets.maximintegrated.com/en/ds/DS3231.pdf

ca a l'air pas mal le lien que tu as donnée meme is j'avoue que je nai pas tous compris a 100% :langue: :langue:


Retourner vers « Langage BASIC & PASCAL »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité