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 sur le langage C !

Modérateur : Jérémy

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#11 Message par paulfjujo » jeu. 21 janv. 2021 12:38

bonjour à tous ,

Temps-x a écrit :Bonsoir Jérémy, paulfjujo, et tout le forum,

paulfjujo a écrit :Source du message j'attends Temps_X et le STAFF ASM ...pour une demo I2C Hardware.


:sifflotte: Mode I²C Bit bang, c'est la solution....

A causse de ce Pic :mad: Je suis obligé de reprendre les cours du chapitre 2 sur I²C de Monsieur Bigonoff :-)

S'il pouvait nous venir en aide, et nous donner un coup de main, ça serait sympa, et un grand honneur pour le Forum.

==> A+



ça marche OK en SOFTW I2C ( donc bit bang ), mais je pense que les cours de bigonoff ne seront d'aucun secours
vu le changement hardware coté I2C de ce PIC .

Eventuellement, voir le code généré en asm de la compilation MPLABX XC8 , version OK en I2C Hardware ?
ça promet aussi pour les 18F27Q10 et Q43 !!!

j'ai recupéré la note microchip
sample code from TB3159,
[url=sample code from TB3159,
http://ww1.microchip.com/downloads/en/A ... 03159B.pdf]http://ww1.microchip.com/downloads/en/AppNotes/TB3159-I2C-with-Hardware-Protocol-Acceleration-on-8-Bit-PIC-90003159B.pdf[/url]

Code : Tout sélectionner


Target MCU
: PIC18F46K42 on Xpress dev board, programmed via hex-file drag-and-drop. 
I2C Master on MSSP1
, pins RC3 (SCL) and RC4 (SDA), I2C Slave on MSSP2, pins RB1 (SCL) and RB2 (SDA),
 with the slave using MCC generated code. MCC generated code

    RC3PPS 
= 0x21;   //RC3->I2C1:SCL1;    
    I2C1SCLPPS = 0x13;   //RC3->I2C1:SCL1;    
    RC4PPS = 0x22;   //RC4->I2C1:SDA1;    
    I2C1SDAPPS = 0x14;   //RC4->I2C1:SDA1;    
   
    RB1PPS 
= 0x23;   //RB1->I2C2:SCL2;    
    I2C2SCLPPS = 0x09;   //RB1->I2C2:SCL2;    
    RB2PPS = 0x24;   //RB2->I2C2:SDA2;    
    I2C2SDAPPS = 0x0A;   //RB2->I2C2:SDA2; 


void I2C2_Initialize(void)
{
    
        
// ADR 64; 
        I2C2ADR0 = 0x40;
        // ADR 64; 
        I2C2ADR1 = 0x80;
        // ADR 0; 
        I2C2ADR2 = 0x00;
        // ADR 0; 
        I2C2ADR3 = 0x00;
        // TXU 0; CSD Clock Stretching enabled; ACKT 0; RXO 0; ACKDT Acknowledge; ACKSTAT ACK received; ACKCNT Acknowledge; 
        I2C2CON1 = 0x00;
        // ABD enabled; GCEN disabled; ACNT disabled; SDAHT 30 ns hold time; BFRET 8 I2C Clock pulses; FME enabled; 
        I2C2CON2 = 0x28;
        // CLK MFINTOSC; 
        I2C2CLK = 0x03;
        // CNT 255; 
        I2C2CNT = 0xFF;
        // CSTR clock stretching; S Cleared by hardware after Start; MODE four 7-bit address; EN disabled; RSEN disabled; 
        I2C2CON0 = 0x10;
    
    
    PIR5bits
.I2C2RXIF=0;
    PIR5bits.I2C2TXIF=0;
    PIR6bits.I2C2EIF=0;
    I2C2ERRbits.NACKIF=0;
    PIR6bits.I2C2IF=0;
    I2C2PIRbits.PCIF=0;
    I2C2PIRbits.ADRIF=0;
    
    PIE5bits
.I2C2RXIE=1;//enable I2C RX interrupt
    PIE5bits.I2C2TXIE=1;//enable I2C TX interrupt
    PIE6bits.I2C2EIE=1;//enable I2C error interrupt
    I2C2ERRbits.NACKIE=1;//enable I2C error interrupt for NACK
    PIE6bits.I2C2IE=1;//enable I2C  interrupt
    I2C2PIEbits.PCIE=1;//enable I2C interrupt for stop condition
    I2C2PIEbits.ADRIE=1;//enable I2C interrupt for I2C address match condition
    
    I2C2PIR 
= 0;//    ;Clear all the error flags
    I2C2ERR = 0;
    
}
Aide toi, le ciel ou FantasPic t'aidera

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2618
Enregistré en : juillet 2016
Localisation : Terre

#12 Message par Temps-x » jeu. 21 janv. 2021 19:27

Bonsoir paulfjujo, et tout le forum,

paulfjujo a écrit :Source du message Eventuellement, voir le code généré en asm de la compilation MPLABX XC8


:roll: J'y ai pensé.... :sad: mais il faut trouver un désassembleur pour ce pic, et là je crois que c'est pas possible :cry:

paulfjujo a écrit :Source du message j'ai récupéré la note microchip


Je vais tenté de la lire.... tout en anglais :furieux:

:sifflotte: y a pu cas faire....

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#13 Message par paulfjujo » ven. 22 janv. 2021 10:54

bonjour Temps-X , et à tous

le traitement I2C hardware , un peu plus détaillé avec ce fichier joint , issu du MCC
I2c1_master.i
il n'y a que 27000 lignes !!!!

le nombre d'interruptions pouvant y être attachées .. de quoi avoir la migraine, non ?

Code : Tout sélectionner

static inline void I2C1_MasterDisableIrq(void)
{
PIE3bits.I2C1IE 0;
PIE3bits.I2C1EIE 0;
PIE2bits.I2C1RXIE 0;
PIE3bits.I2C1TXIE 0;
I2C1PIEbits.SCIE 0;
I2C1PIEbits.PCIE 0;
I2C1PIEbits.CNTIE 0;
I2C1PIEbits.ACKTIE 0;
I2C1PIEbits.RSCIE 0;
I2C1ERRbits.BCLIE 0;
I2C1ERRbits.BTOIE 0;
I2C1ERRbits.NACKIE 0;


i2c_simple_master_Interface2.zip
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#14 Message par satinas » ven. 22 janv. 2021 11:03

Bonjour à tous

J'ai regardé ce fameux nouvel i2c et fait un test avec un oled, juste l'envoi d'une commande, pour recevoir des ACK, et vérifier que ça marche.
Le module I2C est plus performant qu'avant, il est capable de déclencher automatiquement l'envoi des Start, Stop, et de l'adresse. Il permet ainsi de mieux respecter les normes I2C.

Le bit I2CxSTAT0.BFRE indique l'état du bus, s'il est à 1, le bus est libre.
L'adresse de l'esclave est envoyée automatiquement depuis le registre I2CxADB1 qui doit contenir 0b'aaaaaaac' (c = 0 write ou 1 read).
Le registre I2CxCNT contient le nombre d'octets à envoyer ou recevoir, cela permet d'envoyer automatiquementle le Stop.
Si le bit I2CxCON2.ADB est mis à 1, le Start est déclenché automatiquement, sinon on l'envoie en passant le bit I2CxCON0bits.S à 1.

Pour envoyer un ou plusieurs octets data en I2C adresse 7 bits :
On place l'adresse de l'esclave 0baaaaaaa0 dans I2CxADB1
On place le nombre d'octets data dans I2CxCNT.
On attend que le bus soit libre, en scrutant I2CxSTAT0.BFRE, il doit être à 1.
On copie les octets un par un dans I2CxTXB, après avoir attendu que le bit I2CxSTAT1bits.TXBE est bien passé à 1.
Avec ADB=1, cela génère automatiquement le Start, j'ai essayé mais problème, à voir.
Avec ADB=0, on envoie le Start avec I2CxCON0bits.S, là ça marche.
Le Stop est déclenché après le dernier octet data.

J'ai perdu des heures à cause de ce glorieux passage du datasheet. Il fallait tout lire, et pas s'arrêter au mot inputs, parce qu'en input y a rien qui sort des pins :) The user must configure these pins as open-drain inputs. This is done by clearing the appropriate TRIS bits and setting the appropriate and ODCON bits.

Code : Tout sélectionner

// 18F27K42 i2c sur C3 scl et C4 sda

#define _XTAL_FREQ  32000000            // FOSC = 32MHz
#define I2C_ADDR    0x78                // 0x3C<<1

//--------------------------------------------------------------------------------------------
void main(void)
//--------------------------------------------------------------------------------------------
{
  unsigned char buff[2];
  buff[0] = 0x80; buff[1] = 0xaf;

  OSCCON1 = 0x60; OSCFRQ = 0x06;        // FOSC = 32MHz
  ANSELA  = ANSELB = ANSELC = 0x00;     // pins numériques

  I2cInit();

  while (1) {
    I2cSendBuffer(buff, sizeof(buff));
    __delay_ms(100);
  } 


//--------------------------------------------------------------------------------------------
void I2cInit(void)
//--------------------------------------------------------------------------------------------
{
  RC3PPS     = 0x21;      // i2c1, scl -> C3
  I2C1SCLPPS = 0x13;      // i2c1, scl <- C3
  RC4PPS     = 0x22;      // i2c1, sda -> C4
  I2C1SDAPPS = 0x14;      // i2c1, sda <- C4
  WPUC       = 0x18;      // C3 et C4 pull-up
  ODCONC     = 0x18;      // C3 et C4 open drain
  TRISCbits.TRISC3 = 0;   // C3 output
  TRISCbits.TRISC4 = 0;   // C4 output

  I2C1CLK    = 0x03;      // i2c1, 100kHz
  I2C1CON0   = 0x04;      // i2c1, master 7 bits
  I2C1CON1   = 0x80;      // i2c1, envoi NAK sur dernier octet attendu
  I2C1CON2   = 0x00;      // i2c1, envoi Start non auto, SDAHT 300ns hold time, BFRET 8 i2c clock pulses
  I2C1ADB1   = I2C_ADDR;  // i2c1, 2 * adresse esclave
  I2C1CON0bits.EN = 1;    // i2c1 on
}

//--------------------------------------------------------------------------------------------
void I2cSendByte(unsigned char b)
//--------------------------------------------------------------------------------------------
{
  I2C1CNT = 1;                    // on envoie un seul octet data
  while (!I2C1STAT0bits.BFRE) { } // attente bus libre
  I2C1CON0bits.S = 1;             // envoi Start
  while (I2C1CON0bits.S) { }      // attente fin Start
  I2C1TXB = b;                    // envoi adresse, data, Stop
  while (I2C1STAT0bits.MMA) { }   // attente fin Stop
}

//--------------------------------------------------------------------------------------------
void I2cSendBuffer(unsigned char *b, unsigned char n)
//--------------------------------------------------------------------------------------------
{
  I2C1CNT = n;                    // on envoie n octets data
  while (!I2C1STAT0bits.BFRE) { } // attente bus libre
  I2C1CON0bits.S = 1;             // envoi Start
  while (I2C1CON0bits.S) { }      // attente fin Start
  while (n--) {                   // envoi adresse, n data, Stop
    while (!I2C1STAT1bits.TXBE) { }
    I2C1TXB = *b++;
  }
  while (I2C1STAT0bits.MMA) { }   // attente fin Stop
}

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#15 Message par paulfjujo » sam. 23 janv. 2021 10:08

bonjour Satinas,

Merci ! pour ton aide,

Avec MikroC I2C1 Hardware ,c'est OK avec la RTC DS3231 , ecriture et lecture OK ,
mais c'est avec l'OLED que ça ne va plus, malgré une init identique des parametres ,
pourtant la presence de l'OLED sur le bus est bien vue en 0x3C ( adresse device en 7 bits avec I2C hw MikroC)...

j'ai essayé d'adapter ton test exemple, en MikroC .. qui ne contient pas certains bits accessible via MPLAB
non definis dans le fichier definition du directory \Defs\ PIC18F27K42.C de mikroC
d'où l'usage de sbit..

il se compile bien ..mais
Dans ton exemple de programme, comment vois-tu que l'OLED est vu ?
ou est-ce en connectant un analyser logique ?
est-ce quil bloque avec une adresse Device inconnue ?



Code : Tout sélectionner

#define _XTAL_FREQ  FOSC 32000000       // FOSC = 32MHz
#define I2C_ADDR    0x78                // 0x3C<<1

// REGISTER 33-1: I2CxCON0: I2C CONTROL REGISTER 0
// EN RSEN S CSTR MDR MODE [2:0]

 
sbit Led_Rouge at LATA.B4;
 
sbit I2C1CON0_EN  at I2C1CON0.B7;      //absolute 0x3D73; 1 = Enables the I2C module
 
sbit I2C1CON0_S   at I2C1CON0.B5;
 
sbit I2C1STAT0_BFRE  at I2C1STAT0.B7;              //  absolute 0x3D77;
 
sbit I2C1STAT0_MMA   at I2C1STAT0.B5;
 
sbit I2C1STAT1_TXBE at I2C1STAT1.B5//absolute 0x3D78;

 
 
unsigned char buff[2];

  
//--------------------------------------------------------------------------------------------
void I2C1_Init(void)
//--------------------------------------------------------------------------------------------
{
  
TRISC.B3 0;   // C3 output
  
TRISC.B4 0;   // C4 output
  
WPUC       0x18;      // C3 et C4 pull-up
  
ODCONC     0x18;      // C3 et C4 open drain
  
RC3PPS     0x21;      // i2c1, scl -> C3
  
I2C1SCLPPS 0x13;      // i2c1, scl <- C3
  
RC4PPS     0x22;      // i2c1, sda -> C4
  
I2C1SDAPPS 0x14;      // i2c1, sda <- C4

  
I2C1CLK    0x03;      // i2c1, 100kHz
  
I2C1CON0   0x04;      // i2c1, master 7 bits
  
I2C1CON1   0x80;      // i2c1, envoi NAK sur dernier octet attendu
  
I2C1CON2   0x00;      // i2c1, envoi Start non auto, SDAHT 300ns hold time, BFRET 8 i2c clock pulses
  
I2C1ADB1   I2C_ADDR;  // i2c1, 2 * adresse esclave
  
I2C1CON0_EN 1;    // i2c1 on

}



//--------------------------------------------------------------------------------------------
void I2cSendByte(unsigned char b)
//--------------------------------------------------------------------------------------------
{
  
I2C1CNT 1;                    // on envoie un seul octet data
  
while (!I2C1STAT0_BFRE) { } // attente bus libre             absolute 0x3D77;
  
I2C1CON0_S 1;             // envoi Start
  
while (I2C1CON0_S) { }      // attente fin Start
  
I2C1TXB b;                    // envoi adresse, data, Stop
  
while (I2C1STAT0_MMA) { }   // attente fin Stop
}

//--------------------------------------------------------------------------------------------
void I2cSendBuffer(unsigned char *bunsigned char n)
//--------------------------------------------------------------------------------------------
{
  
I2C1CNT n;                    // on envoie n octets data
  
while (!I2C1STAT0_BFRE) { } // attente bus libre
  
I2C1CON0_S 1;             // envoi Start
  
while (I2C1CON0_S) { }      // attente fin Start
  
while (n--) {                   // envoi adresse, n data, Stop
    
while (!I2C1STAT1_TXBE) { }
    
I2C1TXB = *b++;
  }
  while (
I2C1STAT0_MMA) { }   // attente fin Stop
}




//--------------------------------------------------------------------------------------------
void main(void)
//--------------------------------------------------------------------------------------------
{

  
buff[0] = 0x80
  
buff[1] = 0xaf;

  
OSCCON1 0x60
  
OSCFRQ 0x06;        // FOSC = 32MHz
  
ANSELA  ANSELB ANSELC 0x00;     // pins numériques

  
I2C1_Init();

  while (
1) {
    
I2cSendBuffer(buffsizeof(buff));
    
Delay_ms(100);
  }
}
 
Aide toi, le ciel ou FantasPic t'aidera

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#16 Message par satinas » sam. 23 janv. 2021 10:21

Bonjour Paul,
C'est l'Oled qui envoie des ACK. Sinon la transmission avorte juste après l'envoi de l'adresse non acquittée. Il bloque pas, il fait le Stop juste après l'adresse. Dans le test la commande envoyée est SLEEP_OFF (0x80 0xAF sauf erreur). J'ai aussi essayé d'envoyer un buffer de 5 octets, pas de problème. J'ai fait le minimum syndical, le module I2C est très riche, comme tu l'a déjà précisé, il est très fourni en paramétrage et en interruptions.

Oui je démarre toujours le spi et l'i2c oscillo à mémoire allumé. C'est ainsi que j'ai trouvé et vérifié le test de bit pour attendre la fin du Stop, parce comme ça bufférise pas mal, les fonctions d'envoi se termineraient bien avant la fin de la transmission complète. cela peut être voulu pour gagner du temps, sans poser de problème car le prochain envoi commencera par attendre que le bus soit libre. Il faudrait alors déplacer la ligne "I2C1CNT = n" après le test bus libre.
Si tu veux que je regarde ton programme MikroC il faudrait qu'il rentre dans la version de démo. Je peux voir ce que cela donne avec xc8, n'ayant pas trop envie de replonger dans mon ancienne bibliothèque Oled.

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#17 Message par paulfjujo » sam. 23 janv. 2021 19:18

bonsoir,

Version allégée pour test I2C1 Hardw et OLED
à noter que rien que la lib PPS prend 1568 bytes

je doute que le programme puisse tenir dans les 2K de la version libre MikroC
je le mets neamoins

compilation conditionelle avec le #define UART et Interrupts

//#define With_Interrupts (sans traitement IT)
// #define With_UART1
// avec UART1 (et lib UART)
//Used RAM (bytes): 327 (4%) Free RAM (bytes): 7843 (96%)
//Used ROM (bytes): 6821 (5%) Free ROM (bytes): 124251 (95%)
// sans UART1 (ni lib UART)
// Used RAM (bytes): 223 (3%) Free RAM (bytes): 7947 (97%)
// Used ROM (bytes): 4988 (4%) Free ROM (bytes): 126084 (96%) <--4988 bytes rom dont1578 bytes rien que pour le PPS mapping!


avec UART :
(0.000)
(2.032) Test presence device(s) sur le bus I2C1
(0.135)
(0.026) Device(s) trouvés sur le bus
(0.000) Device #1 at @3C
(0.000) Device #2 at @57
(0.041) Device #3 at @68
(0.000)
(0.545) OLED CLS
(1.282) Affiche lettres A B C ...Q
(0.023) Write_Char_At(X en pixel (0 à 127), ligne Y (0 à 3),code ascii char)

voit bien le LCD OLED et module RTC connecté aussi sur le bus

_18F27K42_UART1_ADC1_Mini_Oled_et_RTC_I2C_Hardw_20x10mm_allegge_2021.zip


Capture_debut_Init_Oled_I2C1_Hardw.jpg
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#18 Message par satinas » sam. 23 janv. 2021 21:12

Comment je fais pour programmer le pic avec un un hex MikroC ?
Essai avec IPE sur PicKit3, il affiche "The target circuit may require more power than the debug tool can provide. An external power supply might be necessary. Connection Failed"
Pas trouvé où désactiver l'alim par PicKit3.

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#19 Message par paulfjujo » sam. 23 janv. 2021 21:21

voir ici pour le 18F27Q10
la demarche est la meme ..
decocher la case dans power setting
mot de passe "microchip" pour le "advanced mode"
Aide toi, le ciel ou FantasPic t'aidera

Test mini OLED SSD1306 20x10mm 128x32 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#20 Message par satinas » dim. 24 janv. 2021 08:46

Bonjour à tous.

Merci Paul, maintenant j'arrive à programmer avec IPE 5.45 et le PicKit3 Microchip.

Voici un programme xc8 MpLabX qui remplit un écran Oled 64x128.
Cela peut intéresser Temps-x car entre C et ASM il y a pas trop de différence.
18F27K42_Oled_i2c_xc8.X.c.zip

Et converti en MikroC, en ne cochant aucune bibliothèque. Ca marche :)
Par contre avec IPE il faut resélectionner le fichier HEX avant chaque programmation, il ne détecte pas qu'il a pu être modifié, il doit y a voir un autre réglage quelques part. On dirait aussi qu'il est en retard d'une version du fichier HEX, étrange.
J'ai fait quelques essais avec les bibliothèques MikroC, pas concluants, faut faire simple.
18F27K42_Oled.zip

PS Il y a eu plusieurs versions des zip, prendre les dernières.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 49 invités