Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Problema SCL su I2C - PIC16f1789

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Problema SCL su I2C - PIC16f1789

Messaggioda Foto Utentephase » 15 ott 2014, 19:57

Ciao!

Vi volevo chiedere una mano per quanto riguarda la comunicazione su I2C tra un PIC16F1789 e un DS1307...

Il codice che ho scritto (e un po' copiato in giro... :mrgreen: ) è questo:

questa è la libreria i2c.c...
Codice: Seleziona tutto
#include <xc.h>
#include "i2c.h"

void I2CInit(void)
{
   TRISCbits.TRISC3 = 1;   /* SDA (RC4) and SCL (RC3) as input pin */
   TRISCbits.TRISC4 = 1;
   ANSELC = 0;           
   WPUC = 0;
   SSPSTAT = 0x80;         /* Slew rate disabled */
   SSPCON1 = 0x08;         /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
   SSPADD = 0x13;          /* 100Khz @ 8Mhz Fosc */
   SSPCON1bits.SSPEN = 1;
}

void I2CStart()
{
   SSPCON2bits.SEN = 1;    /* Start condition enabled */
   while(SSPCON2bits.SEN); /* AUTOMATICALLY CLEARED BY HARDWARE */
                            /* wait for start condition to finish */
}

void I2CStop()
{
   SSPCON2bits.PEN = 1;    /* Stop condition enabled */
   while(SSPCON2bits.PEN); /* Wait for stop condition to finish */
                            /* PEN automatically cleared by hardware */
}

void I2CRestart()
{
   SSPCON2bits.RSEN = 1;      /* Repeated start enabled */
   while(SSPCON2bits.RSEN);   /* wait for condition to finish */
}

void I2CAck()
{
   SSPCON2bits.ACKDT = 0;     /* Acknowledge data bit, 0 = ACK */
   SSPCON2bits.ACKEN = 1;     /* Ack data enabled */
   while(SSPCON2bits.ACKEN);  /* wait for ack data to send on bus */
}

void I2CNak()
{
   SSPCON2bits.ACKDT = 1;     /* Acknowledge data bit, 1 = NAK */
   SSPCON2bits.ACKEN = 1;     /* Ack data enabled */
   while(SSPCON2bits.ACKEN);  /* wait for ack data to send on bus */
}

void I2CWait()
{
   while ((SSPCON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );
    /* wait for any pending transfer */
}

void I2CSend(unsigned char dat)
{
   SSPBUF = dat;          /* Move data to SSPBUF */
   while(SSPSTATbits.BF); /* wait till complete data is sent from buffer */
   I2CWait();              /* wait for any pending transfer */
}

unsigned char I2CRead(void)
{
   unsigned char temp;
    /* Reception works if transfer is initiated in read mode */
   SSPCON2bits.RCEN = 1;  /* Enable data reception */

   while(SSPSTATbits.BF);    /* wait for buffer full */
   temp = SSPBUF;         /* Read serial buffer and store in temp register */
    I2CWait();              /* wait to check any pending transfer */
   return temp;            /* Return the read data from bus */
}


e questo il programma...
Codice: Seleziona tutto
#include <xc.h>
#include "configuration.h"
#include "i2c.h"

#define _XTAL_FREQ 8000000

void main(void) {

    unsigned char I2CData[] = {0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x00};
   char i;
   
    OSCCON = 0x72;            //8MHz clock

    ANSELA = 0;                 //all dig
   INTCONbits.GIE  = 0;      
   INTCONbits.PEIE = 0;      //dis ext and per interrupt
   
    for(;;){
   
        I2CInit();
       I2CStart();
       I2CSend(0xD0);              //address slave
       I2CSend(0x00);              //address mem
       for (i = 0; i < 8; i++){   
          I2CSend(I2CData[i]);   
       }
       I2CStop();
       I2CStart();
       I2CSend(0xD0);              //address slave
       I2CSend(0x00);              //address mem
       I2CRestart();
       I2CSend(0xD1);              //address slave with write bit
       for (i = 8; i > 0; i--){
          I2CData[i-1] = I2CRead();
          if (i-1)
             I2CAck();
          else
             I2CNak();           //last ack from master
       }
       I2CStop();
    }
}


ed infine il file configuration.h
Codice: Seleziona tutto
#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = ON        // Internal/External Switchover (Internal/External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config VCAPEN = OFF     // Voltage Regulator Capacitor Enable bit (Vcap functionality is disabled on RA6.)
#pragma config PLLEN = ON       // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low Power Brown-Out Reset Enable Bit (Low power brown-out is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)


i collegamenti tra il PIC e l'IC sono questi:


Il problema è che non c'è alcun segnale sul pin SCL (RC3) e quindi il PIC non riesce a leggere il DS1307... Io pensavo ad un problema di priorità sulle funzioni del pin in questione... Però guardando il ds a me sembra di aver configurato tutto correttamente...

:-)

datasheet del PIC
datasheet del DS1307
Avatar utente
Foto Utentephase
50 4
New entry
New entry
 
Messaggi: 82
Iscritto il: 23 apr 2013, 16:28

0
voti

[2] Re: Problema SCL su I2C - PIC16f1789

Messaggioda Foto UtenteWALTERmwp » 17 ott 2014, 15:40

Ciao Foto Utentephase, limitando al momento la risposta al problema che indichi ti suggerirei di verificare se, nell'ambito del tuo codice, il pin SCL viene e rimane configurato come input; stando a quanto si vede, da una superficiale lettura, non sembrerebbe diversamente configurato:
Codice: Seleziona tutto
void I2CInit(void)
{
   TRISCbits.TRISC3 = 1;   /* SDA (RC4) and SCL (RC3) as input pin */
   TRISCbits.TRISC4 = 1;
Lo scrivo per evitare eventuali equivoci ma immagino che tu sappia che la linea SCL, per il Master (ovvero per il tuo microcontrollore), è un output cioè una uscita; tale deve essere proprio per generare il clock di riferimento del bus.
Anche dovessi aver scritto quella che a te pare una ovvietà ti suggerirei di controllare la configurazione.
Non ho letto il codice e comunque presumo che le librerie alle quali ti appoggi prevedano la gestione dell'SCL da parte del modulo periferico.
Facci sapere.

Saluti

p.s.
Questo ...
phase ha scritto:Il problema è che non c'è alcun segnale sul pin SCL (RC3)
... in base a quali riscontri ?
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[3] Re: Problema SCL su I2C - PIC16f1789

Messaggioda Foto Utentephase » 19 ott 2014, 15:03

Da quello che ho capito, dalle note applicative della microchip viene sempre indicato che la linea SCL e SDA devono essere configurate come input, nella nota viene detto

Finally, before selecting any mode, the SCL and SDA pins must be configured to inputs by setting the appropriate TRIS bits. Selecting an mode by set-ting the SSPEN bit (SSPCON1<5>), enables the SCL
and SDA pins to be used as the clock and data lines in mode. A logic "1" written to the respective TRIS bits configure these pins as inputs


Non mi appoggio a librerie della microchip ma tutto quello che sto usando è quello che ho scritto nel primo post, e il programma si basa sulla periferica mssp del micro.

Per osservare il comportamento del pin scl ho usato un oscillospio.
Ultima modifica di Foto UtenteWALTERmwp il 19 ott 2014, 22:02, modificato 1 volta in totale.
Motivazione: Corretto errore di battitura nell'URL
Avatar utente
Foto Utentephase
50 4
New entry
New entry
 
Messaggi: 82
Iscritto il: 23 apr 2013, 16:28

0
voti

[4] Re: Problema SCL su I2C - PIC16f1789

Messaggioda Foto UtenteWALTERmwp » 19 ott 2014, 23:53

Credo d'avere trovato quello che potrebbe essere un errore ...
Codice: Seleziona tutto
SSPCON1 = 0x08;         /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
perché invece dovrebbe essere ...
Codice: Seleziona tutto
SSPCON1 = 0x28;         /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
A pagina 352 del datasheet si trova la conferma di quanto sopra.
Il valore è disallineato rispetto al commento.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[5] Re: Problema SCL su I2C - PIC16f1789

Messaggioda Foto Utentephase » 20 ott 2014, 9:04

Il codice è questo:
Codice: Seleziona tutto
SSPCON1 = 0x08;         /* SSPEN = 1, I2C Master mode, clock = FOSC/(4 * (SSPADD + 1)) */
SSPADD = 0x13;          /* 100Khz @ 8Mhz Fosc */
SSPCON1bits.SSPEN = 1;


hai ragione che il modulo ssp non lo abilito subito... ma due righe dopo lo abilito a parte... ho fatto così per renderlo più immediato, ma equivale a scrivere SSPCON1 = 0x28 :(

Grazie mille comunque per l'aiuto ;-)
Avatar utente
Foto Utentephase
50 4
New entry
New entry
 
Messaggi: 82
Iscritto il: 23 apr 2013, 16:28

0
voti

[6] Re: Problema SCL su I2C - PIC16f1789

Messaggioda Foto UtenteWALTERmwp » 20 ott 2014, 9:33

E' vero, anzi è un fatto e mi era sfuggito.
phase ha scritto:Grazie mille comunque per l'aiuto
... che non ha dato una soluzione.
Come mi è sfuggita questa, potrebbe mancare anche qualcosa di necessario e non ancora rilevato; gli darò ancora un'occhiata.
Per ora, escludendo un errore a livello di configurazione, potrei pensare che:
i) inavvertitamente, per l'SCL, sul micro, ti sei collegato ad un altro pin,
ii) il time keeper che stai utilizzando è difettoso e ti "tiene" agganciato a livello basso il segnale di clock generato dal micro.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
30,2k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 8982
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino


Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite