Je travaille actuellement sur un projet EEPROM I2C utilisant le bit banging pour piloter les lignes SDA et SCL.
Ma fonction de lecture fonctionne bien mais chaque fois que j'écris un octet avec un "1", je relis toujours FF; même si l'octet a été programmé avec autre chose auparavant. Un "0" en tête est parfait. Ce n'est pas ma routine de lecture; comme je peux le voir sur la portée, il retourne FF.
Je cherche des suggestions sur la raison pour laquelle cela pourrait être. Y a-t-il une évidence que je pourrais manquer qui pourrait causer le problème? [Je ne peux pas poster le code - société confidentielle ... :(]
Chaque forme d'onde que je regarde répond exactement aux spécifications. Je suis en train de découpler l'EEPROM. Mes tractions sont de 2,2k donc conformes aux spécifications. Je pointe à environ 500 Hz dans ce prototype. La puce envoie des ACK à chacun de mes octets pour les reconnaître. Mais ça ne marche pas ...
J'utilise une Microchip 24LC256 .
Algorithme d'écriture simplifié pour un octet:
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
Algorithme de lecture simplifié pour un octet:
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
Réponses:
Vous lisez à nouveau les données une fois que l'horloge est basse. Vous devrez faire cela entre faire en sorte que l'horloge soit haute et basse. Une fois que l'horloge est basse, l'esclave est autorisé à changer la ligne de données, pas tant qu'elle est haute.
La lecture devrait donc être comme ceci:
la source
En fin de compte, le problème s'est avéré que j'envoyais par inadvertance une condition STOP dans certaines conditions en raison d'un timing tronqué. J'ai abandonné l'utilisation de l'oscilloscope et sorti l'analyseur logique, et j'ai pu résoudre le problème en 15 minutes car il a mis en évidence l'ARRÊT qui n'aurait pas dû être là. Je choisirai à qui donner la prime en fonction de la réponse la plus utile. Merci pour toutes les solutions.
la source
OK, votre portée prouve que le 1er octet entrant dans le PIC est mauvais, donc ce n'est pas la fonction de lecture PIC.
Avez-vous vérifié que le délai d'écriture est correct du côté réception?
Est-ce que cela échoue dans les deux modes ci-dessous?
La spécification indique que "le bit le plus significatif (MSB) 'b7' est envoyé en premier". Cela coïncide également lorsque b7 = 1 que l'octet entier est lu en FF. Donc, soit il n'est pas écrit et seulement effacé (condition de défaut) lorsque b7 = 1, soit il est mal lu comme FF quel que soit le contenu précédent. Étant donné que chaque écriture est un effacement de large octet avant l'écriture, pourrait-il encore être une mauvaise écriture ou une mauvaise lecture ou le timing du 1er octet est différent.
Suggestion: vérifiez le signal PTC pendant une écriture / lecture pour assurer un fonctionnement normal.
Il est possible d'utiliser une horloge externe pour chronométrer la durée d'un cycle E / W à l'aide de PTC. Avez-vous essayé de l'utiliser?
temps de cycle tE / W
Répond-elle à ces critères?
la source
On dirait que cela pourrait être un couple de choses:
0xFF
. La broche peut être laissée en sortie en conduisant le bus pendant que vous lisez.0xFF
s (et retournera probablement la même chose car il s'agit probablement d'une commande / condition non valide).la source
0xFF
s? Voir aussi mes modifications ci-dessus.J'ai soumis cela en tant que commentaire ci-dessus, mais ma confiance dans la réponse a tranquillement grandi dans les profondeurs de mon esprit, donc je la promeut en réponse.
J'ai un pressentiment fou qu'il s'agit presque certainement d'un bogue logiciel de bas niveau lié à la signature de certaines variables. Dans votre code pour chaque bit, est-ce que vous étendez par inadvertance des signes avec une opération de décalage vers la droite? Si vous êtes alors votre leader vous laissera éventuellement un 0xFF après 7 opérations de quart.
Steven y a fait allusion dans un commentaire, mais avez-vous été témoin du caractère sacré de vos opérations d'écriture sur un osilloscope, ou présumez-vous seulement qu'elles fonctionnent sur la base de la moitié des lectures qui semblent bonnes? Si vous n'avez pas essayé de regarder l'opération d'écriture de la valeur 0xAA, cela peut être une bonne chose à essayer.
Si vous pouvez fournir le code réel de votre boucle interne et les déclarations de variables associées, nous pourrons peut-être détecter un bogue.
la source