• Welcome to LusoRobótica - Robótica em Português.
 

I2C Problemas

Started by fiasgardone, 12 de January de 2010, 20:52

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

p0wd3r

então pelos vistos tens tudo bem a nível de hardware! o que me está a fazer confusão é quando dizes que individual funciona, logo parto do princípio que a tua PIC fica presa no código!!!

Como já referi, a nível de código (CSS) não te posso ajudar, o que podes fazer é testar o teu código com LED's, isto é, ligas alguns LED's a portos que tenhas disponíveis e vais tentando "pontos críticos" para saberes se a PIC faz o que programaste.

fiasgardone

Quote from: p0wd3r on 13 de January de 2010, 20:38
então pelos vistos tens tudo bem a nível de hardware! o que me está a fazer confusão é quando dizes que individual funciona, logo parto do princípio que a tua PIC fica presa no código!!!

Como já referi, a nível de código (CSS) não te posso ajudar, o que podes fazer é testar o teu código com LED's, isto é, ligas alguns LED's a portos que tenhas disponíveis e vais tentando "pontos críticos" para saberes se a PIC faz o que programaste.

Caro amigo as pessoas só ajudam no que podem, e fico agradeço por isso!!

Eu penso que que a comunicaçao entre o Pic e os chips nao esta a ser feita da melhor maneira no codigo principal, acho que deve haver algum conflito  no bus de comunicação, mas tambem não estou a  ver onde, os meus conhecimentos tambem não são muitos! eu jà mudifiquei o codgo mais de 20vezes e continua na mesma !

Pode ser que lgem descobra onde esta o erro !
Um abraço


ricardo-reis

eu n te posso ajudar com pics porque não tenho experiência nenhuma com eles, mas acho que n tens nada a perder em postar o código completo desse teu projecto, porque será mais fácil que te ajudem com ele à frente do que simplesmente a especular de onde será o problema.. tens aqui já uns quantos a querer ajudar mas sem código não conseguem fazer mt mais..

fiasgardone

Quote from: ricardo-reis on 13 de January de 2010, 21:42
eu n te posso ajudar com pics porque não tenho experiência nenhuma com eles, mas acho que n tens nada a perder em postar o código completo desse teu projecto, porque será mais fácil que te ajudem com ele à frente do que simplesmente a especular de onde será o problema.. tens aqui já uns quantos a querer ajudar mas sem código não conseguem fazer mt mais..

Amigo reis não ha problema ninhum, e o não poder ajudar è muito normal, por isso eu disse que ponho o codigo e as bibliotecas sem problema! isto que vou postar foi o que fiz eo que pesquisei,vejam se poderem o que esta mal por favor e poder ajudar ,claro!

Um abraço

Primeiro o codigo e depois as bibliotecas !!
codigo
#include <16f877A.h>                                   

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT 
#use delay(clock=4000000)                           
//#use i2c(master,sda=PIN_C4,scl=PIN_C3,FORCE_HW)// pinos de comunicaçao...Pic+DS1307 
#include <RTC_DS1307.c>//libraria do RTC DS1307
#include <kbd4x4ABCD_PROTEUS.c> //libraria do teclado
#include <flex_lcd.c>
#include <DS1631.c>
   
#use standard_io (b)                                         
#use standard_io (a)
#use standard_io(c)                                                 
#use standard_io(D)     

void main()//Funçao principal
{
  BYTE sec;
  BYTE min;
  BYTE hrs;                                                                         
  BYTE day;
  BYTE month;
  BYTE yr;
  BYTE dow;

     float value; 
 
lcd_init();                                     
    delay_ms(50);
           init_temp();                                             

   
        ds1307_init();
          delay_ms(50);

            lcd_putc("\f Relogio Calendario");
             delay_ms(500); 
                 
                                         ds1307_set_date_time(10,10,10,0,10,10,00); 
     while(1)
  {                                                                                       
   
   delay_ms(1000);                                                                       
   
    ds1307_get_date(day,month,yr,dow);                                                   
    ds1307_get_time(hrs,min,sec);
     
    printf(lcd_Putc,"\f \%02d/\%02d/\%02d\r\n",day,month,yr);
    printf(lcd_Putc," %02d:\%02d:\%02d", hrs,min,sec);
                                                                                                                               
   value = (float)read_full_temp();   
       value /= 100.0;                                                                     
       value=(value-32)/1.8;
       lcd_gotoxy(15,1);                   
      printf(lcd_putc,"temp.%03.1f", value);                           
      delay_ms(100);                                                                   
       
}
  }   

DS1307


///                               DS1307.C                                   ///
///                     Driver for Real Time Clock                           ///

#define DAL_SCL PIN_C3                 
#define DAL_SDA PIN_C4
#use i2c(master, sda=DAL_SDA, scl=DAL_SCL)
BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
   BYTE seconds = 0;

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_start();
   i2c_write(0xD1);      // RD from RTC
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
   i2c_stop();
   seconds &= 0x7F;

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_write(bin2bcd(seconds));     // Start oscillator with current "seconds value
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x07);      // Control Register
   i2c_write(0x01);     // Disable squarewave output pin
   i2c_stop();     

}

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();                                             
  i2c_write(0xD0);            // I2C write address
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));      // REG 0
  i2c_write(bin2bcd(min));      // REG 1
  i2c_write(bin2bcd(hr));      // REG 2
  i2c_write(bin2bcd(dow));      // REG 3
  i2c_write(bin2bcd(day));      // REG 4
  i2c_write(bin2bcd(mth));      // REG 5
  i2c_write(bin2bcd(year));      // REG 6
  i2c_write(0x01);            // REG 7 - Disable squarewave output pin
  i2c_stop();
}
                                   
void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);            // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(0xD1);
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
  year = bcd2bin(i2c_read(0));            // REG 6
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}


ds1631




////   Library for a Dallas 1631 Temperature chip                       ////
////                                                                    ////




#define read_temp    read_full_temp // for backwards compatability

#use i2c(master, sda=DAL_SDA, scl=DAL_SCL)
                                             
                                             
void temp_config(BYTE data) {
                                   
   i2c_start();                                 
   i2c_write(0x92);
   i2c_write(0xac);             
   i2c_write(data);                     
   i2c_stop();
}
           

void init_temp() {
   output_high(DAL_SDA);
   output_high(DAL_SCL);             
   i2c_start();
   i2c_write(0x92);
   i2c_write(0x51);
   i2c_stop();
   temp_config(0xc);
}


signed long read_full_temp() {  // Returns hundreths of degrees F (-67 to 257)
   long datal; //long datal;
   signed long datah, data;
 

   i2c_start();
   i2c_write(0x92);                                                                             
   i2c_write(0xaa);
   i2c_start();
   i2c_write(0x93);                                                           
   datah=i2c_read();                                                       
   datal=i2c_read(0);
   i2c_stop();

   data = datah * 100;
   data += (datal << 8) / 655;   
   data=data*9;
   data = (data / 5) + 3200;

   return(data);
} 

TigPT

#19
Olá,

Pode ser um pouco descontextoalizado pois não tive tempo para ler toda a sequência do tópico contudo gostaria de deixar referencia para uma lib de i2c por software que estou de momento a fazer para arm e que embora ainda esteja em fase crua, pode já ajudar por comparação a encontrar alguma anomalia.

O ficheiro vai sendo actualizado conforme vou desenvolvendo sobre ele, assim em vez de o transcrever deixo antes um link para o ficheiro em si.

http://code.google.com/p/lpc210x/source/browse/trunk/libs/i2c.c

Qualquer questão mais concreta ou se suspeitar onde possa estar a anomalia, vá comunicando que tentarei ajudar.

______________
Estive a ler na diagonal e encontrei 2 starts sem stops pelo meio, acho que não deve de dar bom resultado:
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_start();


Estou também a fazer lib para o DS1621, pelo que deixo o link:
http://code.google.com/p/lpc210x/source/browse/trunk/libs/DS1621.c

Volto a referir, estes ficheiros não estão ainda totalmente testados.

tr3s

Creio que aqueles dois start estão bem, o datasheet fala nisso se não me engano.

FiasGardone, já não me recordo bem dos datasheets destes dois módulos, mas verifica bem em que modo de funcionamento os estás a programar. Certifica-te bem com o datasheet que estás a enviar os comandos correctos para funcionarem num bus com mais dispositivos.
Sugiro ainda que faças um delay_ms entre os dois inits na Main e ainda entre as duas leituras que fazes seguidas ao RTC (este último é só um "just-in-case").

Caso ainda não o tenhas feito... Dá uma olhada nestes dois tópicos, lê tudo com atenção e vê também o código:
Real Time Clock DS1307 (RTC)
Termómetro / Termo-estato DS1620
Tr3s
Daniel Gonçalves

fiasgardone

Boa noite Pessoal!!

Agradeço desde ja o vosso apoio!

Daniel fiz todas as alteraçõs que indicou no seu post acima e nao resultou,perece incrivel mas està na mesma, depois tentei fazer mais modificações como fazer as inicializações dentro do ciclo(WHILE) e nada!
de tanta  experiencia que fiz atè que ficou torado um 16F877A e o DS1307,devido a eu ter tirado o regulador 7805 e não me lembrei mais de que o tinha tirado depois liguei a fonte que è de 12V quando me deparei ja tinha ido a vida!
Vi os tópicos que me aconselhou e bastantes interessante pena eu não perceber tudo ( desculpem mas tenho que falar verdade) e se tornou para mim não muito claro !!

A coisa que mais me chateia è funcionar separado e não e não os dois no mesmo Bus! embora o Ds1631 è um pouco lento a actualizar a temperatura !

Quanto aos comandos eu penso que esta tudo bem eu vi o data  e quanto aos comando esta como manda os data!
Pessoal se algem tiver mais alguma ideia para resolver isto agradeço!
Um abraço

Njay

Tenta descobrir qual dos chips (ou se os 2) está a interferir. Faz um programa que ora lê de um chip ora lê do outro, mas em que só se carregares numa tecla do terminal é que ele avança para o teste de um chip para o outro. Aí podes em várias experiências deixar os 2 chips, tirar um enquanto acedes ao outro e vice-versa, para tentar perceber se é um dos chips que interfere quando se acede ao outro ou vice-versa ou se ambos interferem um com o outro.

fiasgardone

Boa noite pessoal
Depois de tudo o apoio que me deram eu não podia dexar de dizer que o problema foi resolvido, e o erro esta realmente na comunicação ente o PIC e o DS1631 e o ds1307, oe seja eu estava a configurar mal os pinos do PIC
Desde jà agradeço mais o grande apoio que me foi dado!
Espero voltar
Um abraço

p0wd3r

Quote from: fiasgardone on 02 de February de 2010, 21:57
Boa noite pessoal
Depois de tudo o apoio que me deram eu não podia dexar de dizer que o problema foi resolvido, e o erro esta realmente na comunicação ente o PIC e o DS1631 e o ds1307, oe seja eu estava a configurar mal os pinos do PIC
Desde jà agradeço mais o grande apoio que me foi dado!
Espero voltar
Um abraço

Por vezes são coisas tão simples que até passam ao lado. Ainda bem que resolveste. Abc.

fiasgardone

Quote from: p0wd3r on 03 de February de 2010, 13:03

Por vezes são coisas tão simples que até passam ao lado. Ainda bem que resolveste. Abc.

È verdade ,razão para a proxima vez estar mais atento!

Um abraço