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:

Tela com o escravo respondendo com erro:

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.