Problema SCL su I2C - PIC16f1789
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...
) è questo:
questa è la libreria i2c.c...
e questo il programma...
ed infine il file configuration.h
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
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...
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
