Ir ao conteúdo
  • Cadastre-se

Problemas com I2c e o pic


Micael77

Posts recomendados

fiz uns testes com o capacitor que você falou e deu certo

agora meu problema é com a comunicacao i2c que me retorna -91

como se na 1 vez que ele faz a comunicacao ele pega o tempo ok

na segunda ele recebe lixo e eu e meu professor ficamos +d 1h olhando e n descobrimos o porque disso

se vocês souberem e me responderem eu agradeço

valeu

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

O problema não parece ser a comunicação, e sim saber o que realmente você está lendo no RTC.

Concentre-se nos endereços de leitura... quem sabe você não está lendo o ano 91.

Outra coisa pode ser o seu compilador ou programa...

Porque ele retorna um numero negativo, enquanto que isto não existe no PCF...

tabpcf8583.gif

tabpcf85832.gif

Link para o comentário
Compartilhar em outros sites

nao nao

eu acho q ele pega o endereço certo

pois eu testei só com o registrador dos segundos

e ele pega certo

mas ainda continua com esse problema

esta acontecendo alguma problema na comunicacao sim

já identifiquei isso

uma vez q o hardware esta certo(agora)

só nao sei o que esta errado

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

ele fica assim agora:

digamos q eu sete a hr 10:35:57(hh:mm:ss)

ele me mostra

10:35:57

-91:-91:-91

10:35:58

-91:-91:-91

10:35:59

-91:-91:-91

10:36:00

-91:-91:-91

Você está finalizando o PCF após cada leitura?

Se não, experimente chamar o i2Cstop após cada leitura correta.

Não esqueca de fazer o start e endereçar quando for ler novamente.

Não entendo de C, por isso não pude analisar.

Pelo que você citou acima ele faz uma leitura correta e outras 3 com valor -91...é isto?

Link para o comentário
Compartilhar em outros sites

nao

ele le uma vez certo e a outra nao, antes ele fazia isso com 3 variaveis

por isso lia 3 vezes errado

eu vou postar uma parte do meu codigo que le os segundos

o programa esta comentado para ficar + fácil de analisar


{
int8 s;//declara uma variavel do tipo int8 - 8 bits

output_float(PCF8583_SCL);//coloca o pino C3 (SCL) em alta impedancia
output_float(PCF8583_SDA);//coloca o pino C4 (SDA) em alta impedancia
PCF8583_init();//inicia a contagem
while(1)//inicio do laço infinito
{

i2c_start();//inicia a comunicacao i2c
i2c_write(PCF8583_WRITE_ADDRESS);//envia o endereço do RTC
i2c_write(PCF8583_SECONDS_REG);//envia o endereço do registrador dos segundos
i2c_start();//reinicia a comunicacao i2c
i2c_write(PCF8583_READ_ADDRESS);//reenvia o endereço do RTC
s = i2c_read(1);//le o registrador setado anteriormente - segundos
i2c_stop();//para a comunicacao i2c

s = bcd2bin(s);//converte os bytes lidos do rtc de BCD para decimal
printf(lcd_putc, "\f%d", s );//escreve valor lido no display
delay_ms(500);//espera 500 milisegundos
}
}
void main()//funcao principal

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Eu quis dizer que ele lê 3 bytes corretos e 3 bytes errados (-91).

Para mim, não adianta postar seu código em C, e ainda mais de um PIC. Eu só programo AVR e 8051 em ASM ou Basic.

A sequência está correta, mas as funções estão corretas?

E a velocidade?

Se tivesse em ASM daria pra analisar toda a sequência dos bits seriais...

edit:Mais um detalhe...

Anted de dar o stop, o microcontrolador não pode enviar o bit ACK (veja no final do timing abaixo). Portanto é uma leitura diferente da leitura normal.

i2cpcfc.gif

Link para o comentário
Compartilhar em outros sites

ele nao pode??

porque nao??

olhando ali parece que ele espera o ack do master, qual é o problema se eu madar o ack??

e eu já andei dando uma olhada em codigos do avr nao é estão diferente assim

eu consegui entender os codigos dele numa boa, ai já n sei é o case de eu ser programador mesmo (faço ciencias da computacao) ou sei lá

acho que estamos chegando em algum lugar^^

obrigado por inquanto

------------------------------------------------------------------------------------------

EDIT: mudando a funcao i2c_read() para i2c_read(0) ele nao envia o ack

ele parou de mostar o -91 mas a contagem nao esta mais certa

estou usando resistores de pull up de 10k e o capacitor trimmer de 22pF

e o clock aquele que já tinhamos comentado antes, vou fazer uma analise aqui e ver o que é

o brigado +1 vez

-----------------------------------------------------------------------------------------

EDIT 2: Resolvido!!!!!!!!!!!

o capacitor estava com mal contato por isso contava fora, agora esta funcionando certo

tenho que te agradecer agora se n fosse a sua ajuda esse treco aqui nao ia funcionar de jeito nenhum, muito obrigado mesmo

tudo por causa que o PIC estava mandando o ack na ultima leitura dai ele se perdia, mas agora esta ok

e obrigado de novo

VLWWWWWWWWWWWWW

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Fico feliz...

Eu já apanhei com este ack também quando fiz essa rotina em ASM para 8051.

você tinha perguntado porque?

Se der o ACK, ele incrementa o endereço para uma próxima leitura sem precisar mandar o controle e endereço novamente.

Se não enviar o ACK, ele se prepara para receber o STOP.

Link para o comentário
Compartilhar em outros sites

hmmm

agora entendi hehe

me diz uma coisa ae

você sabe trabalhar com a atmel24c64??

é uma eeprom preciso gravar nelaos dados recebidos do pcf8583 + um valor digitado

eu preciso mandar um endereço tb?

ela se auto incrementa?

eu mando so os dados?

como eu faço?

e obrigado +1 vez salvou minha pele hehe

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Sim... já trabalhei até com AT24C512.

O método é o mesmo. Está tudo nos datasheets.

Basta analisar a sequencia no gráfico de timing, como fiz no post acima. O protocolo é o mesmo. para leitura, pode indicar somente o endereço inicial e ir lendo em sequência...

Para gravação, tem um número limitado em sequência, pois funciona por páginação.

Eu só uso o modo randômico mesmo.. um byte de cada vez.

Link para o comentário
Compartilhar em outros sites

é que eu preciso gravar o seguinte

a hora lida do rtc + o numero de uma moto

então seria a moto + hr + min + seg + sentesimode segundos

seriam 5 dados em sequencia sem apagar o que já esta gravado

pode me dar uma ideia de como fazer?

e +1 coisa eu preciso converter os dados para bcd para a memoria tb ou n?

obrigado de novo

Link para o comentário
Compartilhar em outros sites

Bom nesse caso voce pode usar a gravação em modo sequencial, ou seja manda start bit, byte de comando, horas,ack,min,ack,sec,ack,cent, ack, ack, numero da moto, ack,e stop bit, no proprio datasheet da memoria tem esse modo de gravação, seria bem simples de ler o dado depois, ja que cada leitura estaria em sequencia.

abs.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Sou obrigado a pedir que consulte novamente o datasheet. Não faz sentido ficar colocando aqui tudo que está lá. Se pegar uma eeprom 24cxx, um PCF85xx ou qualquer outro CI que tenha comunicação I2C, verá que ele precisa deste primeiro byte, que eu chamo de identificador do dispositivo. Ele serve justamente para o dispositivo saber que o MASTER está ''falando'' com ele, e se é leitura ou escrita.

No caso de ligar 4 memórias iguais na mesma linha, este byte também selecionará só aquela cujo endereço estiver setado pelos pinos A0, A1 e A2 (veja datasheet da 24C02, por exemplo).

Veja a imagem abaixo e imagine a bagunça que seria se cada dispositivo não tivesse o seu byte de comando próprio...

i2cphil.gif

tem muito material na net, basta procurar por ''I2C'' no google.

http://jeronimomachado.vilabol.uol.com.br/I2C.htm

http://www.esacademy.com/faq/i2c/

http://en.wikipedia.org/wiki/I%C2%B2C

etc...etc

Link para o comentário
Compartilhar em outros sites

O byte de comando é constituido pelo

START - CODIGO DO COMPONENTE (FIXO) - A2 -A1 - A0 - R/W

atente se somente ao codigo do componente, que tem no datasheet, isso serve pra saber qual slave do I2C voce está interfaceando, ou seja nunca um RTC tera o mesmo codigo que uma memoria, mas dois RTC terão iguais codigos, ai então voce deve enderaçar A2,A1 e/ou A0 para não teres conflito na linha SDA.

duvidas pergunte!

EDIT.: Po soschip postou junto comigo de novo kkkkk

abs.

Link para o comentário
Compartilhar em outros sites

entendi beleza

só eu tenho +1 duvida e é a ultima

pois eu já consegui fazer o meu circuito conversar com a memoria numa boa

se eu quiser mandar um dado de 16bits para a memoria

como eu faço?

e depois na hr de ler?

precisa fazer uma conversao?

+1 vez obrigado por tudo mesmo

vocês me ajudaram bastante

Obrigado

Link para o comentário
Compartilhar em outros sites

Bom se quiseres enviar um dado de 16 bits, é fácil ( e lógico) envie dois bytes, a diferença é que metade da informação estará em uma posição e metade em outra!

na hora de ler leia as duas posições em guarde em dois registradores (ja que cada um tem 8 bits)

atribua nomes para facilitar a identificação do dado, exemplo se vais ller uma temperatura de 16 bits, voce pode chamar a variavel de TempHigh e TempLow.

duvidas ja sabe!

abs.

off.: pois é estou na flor da idade soschip (ainda sou um brotinho kkkkk)

Link para o comentário
Compartilhar em outros sites

Junte os dois registradores (na ordem em que foram gravados) e trate - os (intreprete os dados) em um registrador por vez, sugestão tente trabalhar com 8 bits ( a menos que a aplicação seja critica) pois ficar tratando dois registradores complementares exige muito esforço computacional!

abs.

Link para o comentário
Compartilhar em outros sites

e eu nao posso usar variaveis normais para fazer esse trabalho??

eu preciso gravar o numero das motos, e esse numero deve ir até pelo menos 999

sendo que uma variaves de 8 bits armazena apenas até 255 é 1/4 do que eu preciso

então usando uma variavel de 16bits meu problema seria sanado

porém temos a complicacao da gravacao na memoria..

você poderia colocar um exemplo em C de como fazer isso?

eu seria muito grato

obrigado +1 vez

Link para o comentário
Compartilhar em outros sites

Bom por ser em C o negocio é mais fácil, use uma variavel int mesmo para armazenar os valores, na hora de escrever na eeprom, converta esse valor pra binário e separe - o em dois valores de no maximo 8 bits, e grave na eeprom, na leitura voce extrai esses dois bytes e refaz a conversão pra decimal, e repoe em uma unica variavle, o caso de usar duas variaveis é justamente pra resolvero porblema de escrita e leitura da eeprom!

abs.

Link para o comentário
Compartilhar em outros sites

acho que entendi

mas voce teria um exemplo para me mostrar?

se nao tiver eu me viro depois

mas ajudaria

graças a ajuda de vocês meu projeto já esta quase pronto ^^

já le o tempo, quando o sensor dispara, você digita o numero da moto e ele move para a memoria (estou gravando os numeros até 255 mesmo enquanto está em teste)

e depois eu vou e mando para o pc que recebe todos os valores pelo hyperterminal por enquanto, + tarde eu irei fazer um driver para fazer a comunicacao e colocar tudo na hr

mas a principio 90% do serviço está pronto

graças a ajuda de vocês

obrigado de novo

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...