4 votos

Error conexión RTC DS1307 con PIC32

Yo soy la interconexión DS1307 RTC con PIC32MX795F512L. Estoy usando I2C1 para DS1307 RTC y, a continuación, utilizando UART2 a enviar el RTC valor a la terminal. He escrito el código, pero no sé por qué no estoy recibiendo datos.

En mi código que estoy utilizando

OpenI2C2 to open the i2c channel.
StartI2C2() to start the communication
StopI2C2() to stop the communication
MasterWriteI2C() to write the data
MasterReadI2C() to read the data

Estos están incluidos en el plib.h archivo.

CÓDIGO actualizado:

OpenI2C2(I2C_EN, 163); // I2C channel Configuration

StartI2C2();            
IdleI2C2();             
n = MasterWriteI2C2(0xD0);  //device address
IdleI2C2();              
MasterWriteI2C2(0x07);      
IdleI2C2();
MasterWriteI2C2(0x00);
IdleI2C2();
StopI2C2();

StartI2C2();            
IdleI2C2();             
MasterWriteI2C2(0xD0);  
IdleI2C2(); 
MasterWriteI2C2(0x01);
IdleI2C2(); 
MasterWriteI2C2(0b00010011);
IdleI2C2(); 
StopI2C2();


StartI2C2();
IdleI2C2();
MasterWriteI2C2(0xD0);
IdleI2C2();
MasterWriteI2C2(0x01);
IdleI2C2();
StopI2C2();

StartI2C2();
IdleI2C2();
MasterWriteI2C2(0xD1);
IdleI2C2();
**res = MasterReadI2C2();**
IdleI2C2();
NotAckI2C2();
IdleI2C2();
StopI2C2();

Yo estoy usando el 163 ((33000000/2/100000)-2)como BRG valor para la comunicación I2C. Yo soy la depuración del código y puede ver todos los valores en I2C registros son correctos, pero en res = MasterReadI2C2(), nada se muestra en I2C2RCV registro que contiene el valor recibido y aún nada, demostrando en la res variable. También he utilizado una variable n para comprobar si los valores son en realidad la transmisión o no. Recibí 0x00 como el valor de n y de acuerdo con el documento, 0 significa que la transmisión exitosa.

No sé dónde me estoy perdiendo el punto.

1voto

Oka Puntos 761
  1. Basado en la hoja de datos:

El Bit 7 del Registro 0 es el reloj halt (CH) bits. Cuando este bit se establece en a 1, el oscilador está deshabilitado. Cuando se retiran a 0, el oscilador está habilitado

Así que cuando se establece segunda, asegúrese de que el bit 7 (CH) es de 0. Y establezca el bit 7 (CH) a cero cada vez que el IC se está encendiendo.

  1. Intente agregar pequeño retraso (10ms) antes de I2C inicio y después de I2C parar.
  2. Intenta establecer un registro a la vez.
  3. Ajustar la resistencia pull-up, trate de cambiar a 1.5 k/1.8 k Ohm

He trabajado este RTC con ATMega128 y CodeVisionAVR Este código funciona:

rtc_init(0,1,0); // output pin for debugging

delay_ms(10);
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_write( (data_rtc[10]-48)*16 + (data_rtc[11]-48));      //second
i2c_stop();

delay_ms(10);
i2c_start();
i2c_write(0xD0);
i2c_write(0x01);
i2c_write( (data_rtc[8]-48)*16 + (data_rtc[9]-48));        // minutes
i2c_stop();

delay_ms(10);
i2c_start();
i2c_write(0xD0);
i2c_write(0x02);
i2c_write( (data_rtc[6]-48)*16 + (data_rtc[7]-48));        // hour
i2c_stop();

delay_ms(10);   
i2c_start();
i2c_write(0xD0);
i2c_write(0x04);
i2c_write( (data_rtc[4]-48)*16 + (data_rtc[5]-48));        // day
i2c_stop(); 

delay_ms(10);   
i2c_start();
i2c_write(0xD0);
i2c_write(0x05);
i2c_write( (data_rtc[2]-48)*16 + (data_rtc[3]-48));        // month
i2c_stop();

delay_ms(10);   
i2c_start();
i2c_write(0xD0);
i2c_write(0x06);
i2c_write( (data_rtc[0]-48)*16 + (data_rtc[1]-48));        // year
i2c_stop();

delay_ms(10); 
rtc_init(0,1,0);

1voto

Konstantin Puntos 64

Usando las bibliotecas heredadas de Microchip PLIB para I2C, es necesario sondear manualmente para que el autobús a ser inactivo después de cada operación. A continuación se muestra un ejemplo:

La función de IdleI2C2() es simplemente la siguiente:

Esta línea simplemente es comprobar cualquier bit que significa que el periférico está ocupado, (por ejemplo, un principio activo o condición de parada, actualmente registra datos, etcetera.

0voto

Alex Baum Puntos 1

Mirando el código, no veo nada más que mal, pero si nos fijamos en el DS1307 hoja de datos, página 13, se especifica que para hacer una lectura de datos desde una ubicación específica de escribir la dirección, la ubicación en el DS1307 registros, a continuación, iniciar un "arranque Repetido" de rutina, enviar la dirección de nuevo, luego de leer los datos. Se puede leer en un multibyte ráfaga, de forma secuencial, o de un solo byte y, a continuación, enviar una PARADA y empezar el proceso de nuevo en otro registro de ubicación.

Hace poco fui encontrando un intento de comunicación entre maestro y esclavo PIC sin éxito, y yo tenía un DS1307 por ahí, así que me batida de código. Afortunadamente, para i2c.h, no más de un bit golpeando. El código está escrito para el PIC18F8722, pero usted debe encontrar que algo similar va a trabajar para usted:

#include <pic18f8722.h>
            #include <i2c.h>
            #include <spi.h>
            #include <delays.h>
            #include "LCD.h"
            #include "SerComm.h"

            #pragma config OSC = HSPLL
            #pragma config WDT = OFF
            #pragma config FCMEN = OFF

            #define newline 0x0A
            #define carriageReturn 0x0D

            void initialize(void);
            unsigned char x;
            unsigned char seconds = 0x00;
            unsigned char minutes = 0x36;
            unsigned char hours = 0x48;
            unsigned char days = 0x03;
            unsigned char date = 0x17;
            unsigned char month = 0x08;
            unsigned char year = 0x15;
            unsigned char hyear, lyear, hmonth, lmonth, hdate, ldate, hdays, ldays, hhours, lhours, hminutes, lminutes, hseconds, lseconds;
            unsigned char time[7];

            void main(void)
            {
                lcdInit();
                initialize();
                CloseI2C2();

                OpenI2C2(MASTER, SLEW_OFF);

                IdleI2C2();
                StartI2C2();
                WriteI2C2(0xD0);
                WriteI2C2(0x00);
                WriteI2C2(seconds);
                WriteI2C2(minutes);
                WriteI2C2(hours);
                WriteI2C2(days);
                WriteI2C2(date);
                WriteI2C2(month);
                WriteI2C2(year);
                StopI2C2();

                while(1)
                {
                IdleI2C2();
                StartI2C2();
                WriteI2C2(0xD0);
                WriteI2C2(0x00);
                RestartI2C2();
                WriteI2C2(0xD1);
                for(x = 0; x < 6; x++)
                {
                   time[x] = ReadI2C2();
                   AckI2C2();
                }
                time[6] = ReadI2C2();
                NotAckI2C2();
                StopI2C2();

                hyear = ((time[6] & 0xF0) >> 4) + 0x30;
                lyear = (time[6] & 0x0F) + 0x30;
                hmonth = ((time[5] & 0xF0) >> 4) + 0x30;
                lmonth = (time[5] & 0x0F) + 0x30;
                hdate = ((time[4] & 0xF0) >> 4) + 0x30;
                ldate = (time[4] & 0x0F) + 0x30;
                hdays = ((time[3] & 0xF0) >> 4) + 0x30;
                ldays = (time[3] & 0x0F) + 0x30;
                hhours = ((time[2] & 0x10) >> 4) + 0x30;
                lhours = (time[2] & 0x0F) + 0x30;
                hminutes = ((time[1] & 0xF0) >> 4) + 0x30;
                lminutes = (time[1] & 0x0F) + 0x30;
                hseconds = ((time[0] & 0xF0) >> 4) + 0x30;
                lseconds = (time[0] & 0x0F) + 0x30;



                lcdGoTo(0x00);
                lcdWriteString("Time: ");
                lcdChar(hhours);
                lcdChar(lhours);
                lcdChar(':');
                lcdChar(hminutes);
                lcdChar(lminutes);
                lcdChar(':');
                lcdChar(hseconds);
                lcdChar(lseconds);
                SerTx(hhours);
                SerTx(lhours);
                SerTx(':');
                SerTx(hminutes);
                SerTx(lminutes);
                SerTx(':');
                SerTx(hseconds);
                SerTx(lseconds);
                SerTx(newline);
                SerTx(carriageReturn);
                }

            }

            void initialize(void)
            {
                TRISAbits.RA2=0; // Chip select pin for the SPI port expander;

                TRISDbits.RD5 = 1;  //Set the ports of the I2C bus;
                TRISDbits.RD6 = 0;

                SSP2STAT = 0x80;    //Disable the slew rate control;
                SSP2CON1 = 0x28;    //Enable the Serial Port, Set the mode to: Master Mode, clock = Fosc/(4*(SSP1ADD + 1);
                SSP2CON2 = 0x00;    //No bits to set here;

                SSP2ADD = 0x59;     //Set to 100 kHz at 40 MHz clock;

                TXSTA1 = 0x24;      //Set serial communication to High Speed, TX enabled, 8 bit mode;
                RCSTA1 = 0x90;      //Enable the serial port, Enable the Receiver;
                BAUDCON1 = 0x00;    //;

                SPBRG1 = 42;        //57600 kBaud;
            }

Por favor, no ser demasiado duro en el código. Espero que esto ayude.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X