Atualmente, estou trabalhando em um projeto I2C EEPROM, usando bit-banging para conduzir as linhas SDA e SCL.
Minha função de leitura funciona bem, mas sempre que escrevo qualquer byte com um "1" inicial, sempre leio FF de volta; mesmo que o byte tenha sido programado com outra coisa antes. O "0" inicial é perfeito. Não é minha rotina de leitura; como posso ver no escopo, ele retorna FF.
Estou procurando sugestões sobre por que isso pode ser. Existe algum óbvio que eu possa perder que possa causar o problema? [Não consigo postar o código - empresa confidencial ... :(]
Cada forma de onda que eu olho atende exatamente às especificações. Estou dissociando a EEPROM. Meus pull ups são 2.2k, portanto, dentro das especificações. Estou com clock de cerca de 500 Hz neste protótipo. O chip está enviando ACKs para cada um dos meus bytes para reconhecê-los. Mas isso simplesmente não funciona ...
Estou usando um Microchip 24LC256 .
Algoritmo de escrita simplificado para um byte:
wait
SDA low
SCL low
wait
for each bit
if bit is set: SDA high
if bit is unset: SDA low
wait
SCL high
wait
wait
SCL low
wait
wait
SDA high
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status
Algoritmo de leitura simplificado para um byte:
wait
SCL low
SDA high
for each bit (8 bits)
SCL high
wait
wait
SCL low
wait
check and store received bit
wait
do a NACK or ACK depending on if it is the last byte
Respostas:
Você está lendo os dados depois que o relógio está baixo novamente. Você terá que fazer isso entre aumentar o relógio e diminuí-lo. Depois que o relógio está baixo, o escravo pode alterar a linha de dados, não enquanto estiver alto.
Portanto, a leitura deve ser assim:
fonte
O problema no final acabou sendo que eu estava inadvertidamente enviando uma condição de STOP sob algumas condições devido a um tempo mutilado. Desisti de usar o escopo e saí do analisador lógico, e consegui resolver o problema em 15 minutos, pois destacava a PARADA que não deveria estar lá. Vou escolher a quem dar a recompensa com base na resposta mais útil. Obrigado por todas as soluções.
fonte
OK, seu escopo prova que o primeiro byte que chega ao PIC é ruim, portanto não é a função de leitura do PIC.
Você verificou que o tempo de gravação está bom no final do recebimento?
Isso falha nos dois modos abaixo?
A especificação mostra "O bit mais significativo (MSB) 'b7' é enviado primeiro" Isso também é coincidente quando b7 = 1 que todo o byte é lido como FF. Portanto, ele não é gravado e apenas é apagado (condição de falha) quando b7 = 1, ou lê incorretamente como FF, independentemente do conteúdo anterior. Como toda gravação é apagada em bytes antes da gravação, ainda pode ser uma gravação ruim ou uma leitura ruim ou o tempo do 1º byte é diferente.
Sugestão: Verifique o sinal PTC durante uma gravação / leitura para garantir a operação normal.
Existe a opção de usar um relógio externo para cronometrar a duração de um ciclo E / W usando PTC. Você já tentou usar isso?
tempo de ciclo tE / W
Passa neste critério?
fonte
Parece que pode haver algumas coisas:
0xFF
. O pino pode ser deixado como uma saída dirigindo o ônibus enquanto você o lê.0xFF
s (e provavelmente retornará o mesmo, provavelmente uma condição / comando inválido).fonte
0xFF
s? Veja minhas edições acima também.Enviei isso como um comentário acima, mas minha confiança na resposta tem crescido silenciosamente nos recônditos profundos da minha mente, por isso estou promovendo isso para uma resposta.
Eu tenho um palpite maluco de que este é quase certamente um bug de software de baixo nível relacionado à assinatura de algumas variáveis. No seu código para cada bit, você inadvertidamente estende o sinal com uma operação shift right? Se você é o líder, o deixará com um 0xFF após 7 operações de turno.
Steven fez alusão a isso em um comentário, mas você testemunhou a santidade de suas operações de gravação em um osciloscópio ou apenas presume que elas funcionam com base em metade das costas de leitura com boa aparência? Se você ainda não tentou examinar a operação de gravação do valor 0xAA, pode ser uma boa coisa para tentar.
Se você puder fornecer o código real do seu loop interno e as declarações de variáveis associadas, poderemos detectar um bug.
fonte