Como usar I2C do 18F4550 com C18 ???

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Como usar I2C do 18F4550 com C18 ???

Mensagempor Andre_Cruz » 13 Mar 2012 01:00

Estou tentando comunicar um 18F4550 com um DS1307 usando a biblioteca do compilador C18 para comunicação I2C.
Na internet tem vários exemplos mas num vai nem com bomba, alguém já implementou comunicação I2C no pic 18 pra dar uma luz ?
Estou simulando no proteus, amanhã vou montar no protoboard e conferir com osciloscópio.
Andre_Cruz
Word
 
Mensagens: 559
Registrado em: 03 Jan 2009 14:06

Mensagempor marcelo campos » 13 Mar 2012 09:11

Andre_Cruz:

trabalhar com o DS1307 tem 2 "pegadinhas do malandro":
- você obrigatoriamente tem que instalar a bateria ou aterrar o pino dele de bat senão, só de birra ele não te responde nada.
- O C18 tem um problema: ele não manda um byte de ack então você tem que explicitamente mandar um Acki2C após ler um byte.
Na nossa página tem dois exemplos pro C18 com 4520 mas é simples portar pro 4550 que está usando. Veja no link na parte de downloads o arquivo MultiPicInstall.exe e instale ele que tem os exemplos: http://www.smartradio.com.br/loja-pic/index.php?id=27

qualquer coisa poste aí

abraço

marcelo
marcelo campos
Word
 
Mensagens: 648
Registrado em: 08 Ago 2009 08:37

Mensagempor Andre_Cruz » 13 Mar 2012 11:10

Marcelo,

Para testes iniciais estou usando o I2C Debugger do proteus, testei seu código no 18F4520 e funciona perfeitamente.
Fiz apenas para teste a configuração da comunicação I2C, Start, escrita e Stop e funciona, o mesmo código em meu programa usando o 18F4550 não funciona :( !

Assim que eu conseguir fazer funfar no proteus vou montar na pratica e seguirei suas dicas.

A única diferença que notei na parte de MSSP entre o 18F4520 e o 18F4550 é que o 18F4520 usa o PORTC como I/O ou com o MSSP, já o 18F4550 os pinos do MSSP são no PORTB e compartilhados com mais periféricos.

Muito obrigado !
Andre_Cruz
Word
 
Mensagens: 559
Registrado em: 03 Jan 2009 14:06

Mensagempor marcelo campos » 13 Mar 2012 11:34

Por algum motivo que desconheço e até hoje não entendi a mchp usou a spi e i2c no 4550 em pinos diferentes do restante da família 18F...

Tem um outro detalhe que é mais ou menos pegadinha da i2C: exitem dispositivos que trabalham a 100Khz e outros 400Khz de velocidade de barramento/clock e o ds1307 e da categoria 1, 100KHz.

Não sei se o Proteus chega à este nível na efeiciência da emulação também de não aceitar devido ao clk mais alto que o dispositivo slave aceita. Todo caso é bem comum colocarmos o 4550 com clock alto e consequentemente spi/ i2c junto.

abraço, boa sorte aí;
marcelo campos
Word
 
Mensagens: 648
Registrado em: 08 Ago 2009 08:37

Mensagempor Andre_Cruz » 13 Mar 2012 12:16

Marcelo,

Estou configurando:
Código: Selecionar todos
//Bit PBADEN = 0; RB0,RB1,RB2,RB3 e RB4 configurado como I/O

CloseADC();
INTCON = 0b10000000;//PULL UPS DESLIGADOS

OpenI2C(MASTER,SLEW_OFF);   
SSPADD= 49;     
TRISB = 0b00000011;//RB0 E RB1 PINOS DO I2C COMO ENTRADA          


Para enviar um dado pela linha I2C:
Código: Selecionar todos
StartI2C();
WriteI2C(33);
StopI2C();
Delay10KTCYx(100);


A luta continua rsrsrss
Andre_Cruz
Word
 
Mensagens: 559
Registrado em: 03 Jan 2009 14:06

Mensagempor marcelo campos » 13 Mar 2012 13:50

esta é biblioteca pra trabalhar com o C18 / Ds1307 que tem no exemplo do link
Código: Selecionar todos


unsigned char horas, minuto, segundo;
unsigned char dia, mes, ano, semana;

extern void delay_ms(unsigned char milisegundos);

unsigned char rtc_zerado (void)
{
     unsigned char zerado;

     StartI2C ();           //Inicializa a comunicação I2C
     WriteI2C(0xD0);        //Comando de Escrita para o RTC
     WriteI2C(0x00);        //Endereço 00 início da leitura
     RestartI2C () ;        //Reinicializa a comunicação I2C, procedimento obrigatório
     WriteI2C(0xD1);        //Comando para a leitura do RTC    
     zerado = ReadI2C ();   //Faz a leitura do endereço 01
     StopI2C ();            //Finaliza a comunicação I2C
     return zerado;
}

void Inicializa_DS1307()
{
     segundo = 0x11;
     
     StartI2C ();           //Inicializa a comunicação I2C
     WriteI2C (0xD0);     //Comando de Escrita para o RTC
     WriteI2C (0x00);     //Endereço onde será inicializada a programação do relógio,
     WriteI2C (segundo);  //endereço dos segundos.
     WriteI2C (0x47);     //Inicia com 47 em minutos
     WriteI2C (0x07);     //Inicia com 7 em horas
     WriteI2C (0x00);     //Inicia com Domingo
     WriteI2C (0x23);     //Inicia com o dia 23
     WriteI2C (0x02);     //Inicia com o mês 02
     WriteI2C (0x02);     //Inicia com o ano 2002
     WriteI2C (0x80);     //CONTROL REGISTER: desliga saída e força saída à nível 1 ->
                          // -> está ligado no B7 se ativado interfere com gravação ICSP
                       
     StopI2C ();          //Finaliza a comunicação I2C

     delay_ms(1);
     
     StartI2C ();         //Inicializa a comunicação I2C
     WriteI2C (0xD0);   //Comando de Escrita para o RTC
     WriteI2C (0x00);   //Endereço onde será feita a programação
     WriteI2C (segundo & 0x7F);     //  Faz segundos = 0 e CH = 0, inicializando o oscilador
     StopI2C ();        //Finaliza a comunicação I2C

}   //~

void Acerta_Hora(void)
{
   
     StartI2C ();          // Inicializa a comunicação I2C
     WriteI2C (0xD0);        // Comando de Escrita para o RTC
     WriteI2C (0x00);        // Endereço onde será inicializada a programação do relógio,
     WriteI2C (segundo);     // endereço dos segundos.
     WriteI2C (minuto);     // Inicia com 47 em minutos
     WriteI2C (horas);        // Inicia com 7 em horas
     WriteI2C (semana);     // Inicia com Domingo
     WriteI2C (dia);        // Inicia com o dia 23
     WriteI2C (mes);        // Inicia com o mês 02
     WriteI2C (ano);        // Inicia com o ano 2002
     WriteI2C (0x80);        // CONTROL REGISTER: desliga saída e força saída à nível 1 ->
                             // -> está ligado no B7 se ativado interfere com gravação ICSP
                       
     StopI2C ();             // Finaliza a comunicação I2C

     delay_ms(1);
     
     StartI2C ();            // Inicializa a comunicação I2C
     WriteI2C (0xD0);      // Comando de Escrita para o RTC
     WriteI2C (0x00);      // Endereço onde será feita a programação
     WriteI2C (segundo & 0x7F);        // Faz segundos = 0 e CH = 0, inicializando o oscilador
     StopI2C ();           // Finaliza a comunicação I2C

}

void le_rtc(void)           //rotina de leitura do DS1307
{
     StartI2C ();           //Inicializa a comunicação I2C
     WriteI2C (0xD0);          //Comando de Escrita para o RTC
     WriteI2C (0x00);          //Endereço 00 início da leitura
     RestartI2C () ;          //I2C_Repeated_Start();  //Reinicializa a comunicação I2C, procedimento obrigatório
     WriteI2C (0xD1);          //Comando para a leitura do RTC
      
     segundo = ReadI2C ();   //Faz a leitura do endereço 01
    AckI2C () ;
     minuto = ReadI2C ();    //Faz a leitura do endereço 02
    AckI2C () ;
     horas = ReadI2C ();     //Faz a leitura do endereço 03
    AckI2C () ;
     semana = ReadI2C ();    //Faz a leitura do endereço 04
    AckI2C () ;
     dia = ReadI2C ();       //Faz a leitura do endereço 05
    AckI2C () ;
     mes = ReadI2C ();       //Faz a leitura do endereço 06
    AckI2C () ;
     ano = ReadI2C ();       //Faz a leitura do endereço 07
    NotAckI2C ();
     StopI2C ();            // Finaliza a comunicação I2C
}

void Le_RAM_Rtc(void)        // rotina de leitura do DS1307
{
     StartI2C ();           //Inicializa a comunicação I2C
     WriteI2C (0xD0);          //Comando de Escrita para o RTC
     WriteI2C (0x00);          //Endereço 00 início da leitura
     RestartI2C () ;          //I2C_Repeated_Start();  //Reinicializa a comunicação I2C, procedimento obrigatório
     WriteI2C (0xD1);          //Comando para a leitura do RTC
      
     segundo = ReadI2C ();   //Faz a leitura do endereço 01
    AckI2C () ;
     minuto = ReadI2C ();    //Faz a leitura do endereço 02
    AckI2C () ;
     horas = ReadI2C ();     //Faz a leitura do endereço 03
    AckI2C () ;
     semana = ReadI2C ();    //Faz a leitura do endereço 04
    AckI2C () ;
     dia = ReadI2C ();       //Faz a leitura do endereço 05
    AckI2C () ;
     mes = ReadI2C ();       //Faz a leitura do endereço 06
    AckI2C () ;
     ano = ReadI2C ();       //Faz a leitura do endereço 07
    NotAckI2C ();
     StopI2C ();            //Finaliza a comunicação I2C
}
marcelo campos
Word
 
Mensagens: 648
Registrado em: 08 Ago 2009 08:37

Mensagempor Andre_Cruz » 13 Mar 2012 14:02

Marcelo, eu vi essa biblioteca do DS1307 com o C18.
O meu problema é na comunicação I2C quando escrevo na linha I2C como no código que mandei, no I2C Debugger eu vejo o START vários ? ? ? ? e o STOP eu não consigo enviar corretamente o dado pela I2C.
Acho que agora consegui explicar meu "pobrema".
Andre_Cruz
Word
 
Mensagens: 559
Registrado em: 03 Jan 2009 14:06

Mensagempor Andre_Cruz » 15 Mar 2012 14:50

A luta continua rsrsrsrss
Como não tive sucesso com o 18F4550 migrei pro 18F4620 que consegui conversar com o DS1307 no proteus.
Andre_Cruz
Word
 
Mensagens: 559
Registrado em: 03 Jan 2009 14:06


Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x