Página 1 de 1

18F4620 conversando pela I2C com DS1307 e PIC16F876A

MensagemEnviado: 15 Mar 2012 16:45
por Andre_Cruz
A luta continua rsrsrsrss
Como não tive sucesso com o 18F4550 migrei pro 18F4620 que consegui conversar com o DS1307 no proteus.
Mas na minha linha I2C tenho dois dispositivos escravos, o DS1307 e um PIC 16F876A testei cada rotina de comunicação separadamente e funciona, mas quando uso apenas o DS1307 e o PIC escravo apenas o DS responde o PIC escravo não responde os comandos do PIC master.
Segue o código que estou usando:

Mestre (18F4620)
Código:
Código: Selecionar todos
#include<timers.h>                                             //BIBLIOTECA PARA USAR AS FUNÇÕES DE TIMERS
#include<pwm.h>                                                //BIBLIOTECA PARA USAR AS FUNÇÕES DE PWM
#include<i2c.h>

#pragma config OSC = HS


#pragma config WDT = OFF                                        //Desabilita o Watchdog Timer (WDT).
#pragma config PWRT = ON                                       //Habilita o Power-up Timer (PWRT).
//#pragma config BOR = OFF                                           //Brown-out Reset (BOR) habilitado somente no hardware.
#pragma config BORV = 3                                        //Voltagem do BOR é 4,33V.
#pragma config PBADEN = OFF                                       //RB0,1,2,3 e 4 configurado como I/O digital.
#pragma config LVP = OFF                                       //Desabilita o Low Voltage Program.
#pragma config MCLRE = OFF
#pragma config DEBUG = ON

#define   Fosc 20                                                //DEFINE A FREQUÊNCIA DO OSCILADOR PRINCIPAL COMO 20MHz
                                                       

void main () {
   TRISA = 0;
   TRISB = 0;                     
   TRISC = 0b00011000;                         
   TRISD = 0;
   TRISE = 0;         
         
   PORTA = 0;
   PORTB = 0;
   PORTC = 0;
   PORTD = 0; 
   PORTE = 0;                                             
                   
   CloseADC();
   OpenI2C(MASTER,SLEW_OFF);
   SSPADD = 49;                               

   while(1) {
      Delay10KTCYx(100);
//CONVERSA COM O DS1307 E PEDE O SEGUNDO ATUAL                                       
      StartI2C();
      WriteI2C(0xD0);                                     
      IdleI2C();
      WriteI2C(0);
      StopI2C();

      StartI2C();
      WriteI2C(0xD1);
      PORTB = ReadI2C();
      StopI2C();

      StartI2C();
      WriteI2C(0xB1);                                    //ENVIA ENDEREÇO DO ESCRAVO
      PORTA = ReadI2C();
      StopI2C();

   }     
}


Escravo (16F876A)
Código:
Código: Selecionar todos
#include <pic.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "delay.c"
#include "lcd.c"
#include "config_cpu.c"

#define ENDERECO   0xB1    //ENDEREÇO DO PIC ESCRAVO


   __CONFIG (0x1F72);

/*
OSCILADOR HS
WACTH DOG TIMER DESLIGADO
POWER UP TIMER LIGADO
PROGRAMAÇÃO EM BAIXA TENSÃO DESLIGADO
E2PROM DESPROTEGIDA
FLASH DESPROTEGIDA
*/

void interrupt isr () {

   //RECEBEU ALGUM DADO PELA LINHA I2C
   if(PIR1,SSPIF){
      PIR1,SSPIF = 0;                                          //LIMPA FLAG DA INT. DO MODULO MSSP       
      if((SSPSTAT,START)&&(SSPSTAT,ACKDT)){ //SSPSTAT,BF
         RB5^=1;
      //if(SSPCON,SSPOV){
         
      }       
      //MESTRE PEDIU ALGUM DADO   
      //ESPERA RECEBER
      while(SSPSTAT,BF);
      SSPCON,WCOL = 0;
      SSPBUF = 0xAC;
      SSPCON,CKP = 1;   
   }
}



void main () {
   config_cpu();                                                //Configura os periféricos

   GIE = 1;                                                      //Habilita as interrupções
   TRISA = 0;
   TRISB = 0;   
   TRISC = 0b00011000;                                       //PINOS DA COMUNICAÇÃO I2C COMO ENTRADA
   
//CONFIGURA A COMUNICAÇÃO I2C
   SSPSTAT = 0b10000000;                           
                                                      //BIT7-> MODO DE TRANSMISSÃO PADRÃO (100K A 1M)       

   SSPCON = 0b00111110;                                     
                                                      //BIT5-> HABILITA COMUNICAÇÃO, PINOS Ñ SÃO MAIS USADOS
                                                      //BIT4-> HABILITA CLOCK
                                                      //BITS3,0-> MODO ESCRAVO 7 BITS E INTERRUPÇÃO LIGADAS
                                                 
   
   SSPADD = ENDERECO;                                    //ENDEREÇO DO PIC ESCRAVO                                                                                                         

   SSPCON2,SEN = 0;
   PIE1,SSPIE = 1;                                          //HABILITA INT DO MODULO MSSP
   PIE1,SSPIF = 0;
   INTCON,PEIE = 1;
   while(1);
}


Esquemático no proteus:
Imagem

Tela com o escravo respondendo com erro:
Imagem


Alguém pode dar uma "luizzzzz" ??
Coloquei o pullup do proteus, que li aqui no fórum que pode causar anomalias na simulação da I2C mas não vi diferença do resistor de 10k que estava usando.

MensagemEnviado: 18 Mar 2012 13:59
por Andre_Cruz
Pessuarr !

Consegui fazer funcionar um PIC16F876A como mestre e um 16F876A e um DS1307 como Escravos !
Não sei por qual motivo todo evento na linha da I2C o PIC Escravo reconhece como no endereço dele e ferra com a comunicação !
O que na prática não acontece.

Obrigado a todos que leram esse tópico.

MensagemEnviado: 18 Mar 2012 15:40
por mastk
Olha, falo de cabeca, mas as vezes se perde um bit na I2C, um erro de FRAME, e ai, niguem mais que esta no barramento consegue fazer mais nada, ate o mestre, resetar a linha.

MensagemEnviado: 18 Mar 2012 20:13
por Andre_Cruz
mastk,

Olha, falo de cabeca, mas as vezes se perde um bit na I2C, um erro de FRAME, e ai, niguem mais que esta no barramento consegue fazer mais nada, ate o mestre, resetar a linha.


No programa de teste o PIC Mestre enviava para o PIC Escravo o Start, Endereço + Bit de leitura, os 8 pulsos de clock (para ler o dado do Escravo) o Nack e Stop.
Enviando esta sequência a cada 250mS no Proteus recebe o endereço do Escravo algumas vezes na primeira vez que envio esta sequência e retorna o dado corretamente, mas depois na próxima vezes que envia a sequência ele não recebe o endereço do Escravo corretamente e então o Escravo retorna Nack sempre.

Dessa forma o Mestre esta sempre resetando a linha I2C não esta ?

Testei o mesmo código que da erro no Proteus, na prática funciona, vai entender !