2010-09-19 11 views
2

J'essaie d'envoyer des données à une carte SD à partir d'un PIC18f4580, mais le PIC n'envoie pas ce qu'il devrait être.Problèmes USART de transmission sur un PIC

variables globales liées:

unsigned char TXBuffer[128]; //tx buffer 
unsigned char TXCurrentPos = 0x00; //tracks the next byte to be sent 
unsigned char TXEndPos = 0x00; //tracks where new data should be put into the array 

J'ajoute des données à un tampon en utilisant la fonction suivante:

void addToBuffer(char data){ 

    TXBuffer[TXEndPos] = data; 
    TXEndPos++; 
} 

Et mettre les données de la TXBuffer en TXREG avec l'interruption suivante:

else if (PIR1bits.TXIF == 1){ 

    if((TXEndPos - TXCurrentPos) > 0){   // if there is data in the buffer 
     TXREG = TXBuffer[TXCurrentPos];   // send next byte 
     TXCurrentPos++;    // update to the new position 
    } 

En utilisant un oscilloscope, je peux voir que le PIC envoie 0x98, indépendamment de ce que je mets dans le tampon. En fait, je ne mets jamais 0x98 dans le tampon.

Cependant, si je remplace

TXREG = TXBuffer[TXCurrentPos]; 

avec

TXREG = 0x55; 

ou

TXREG = TXCurrentPos; 

puis-je obtenir les résultats escomptés, qui est le PIC enverrez 0x55 à plusieurs reprises, ou le nombre en hausse de 0 respectivement.

Alors, pourquoi le PIC a-t-il du mal à envoyer des données à partir de la matrice, mais à un autre moment, cela va-t-il bien? Je soulignerai que le transfert est géré dans une interruption, parce que j'ai l'impression que c'est la racine de mon problème.

EDIT: Il est un tampon circulaire dans le sens retour à 0 TXEndPos et TXCurrentPos quand ils atteignent 127. je désactive également l'interruption d'émission lorsque TXEndPos - TXCurrentPos == 0, et réactiver lors de l'ajout de données à le tampon. Vraiment, mon code fonctionne complètement comme prévu en ce que si j'ajoute 13 caractères à TXBuffer en main, mon PIC transmettra 13 caractères, puis s'arrêtera. Le problème est qu'ils sont toujours le même (mauvais) caractère - 0x98.

EDIT2: fonctions plus complètes sont ici: http://pastebin.com/MyYz1Qzq

+0

Vous pourriez essayer de poser cette même question sur http://chiphacker.com/, il y a beaucoup d'experts pic là-bas. – SingleNegationElimination

+0

Il est peu probable qu'une carte SD souhaite être contrôlée par un flux série asynchrone généré par un UART. Êtes-vous sûr de ne pas vouloir utiliser SPI à la place? – RBerteig

+0

Il serait probablement plus facile de répondre si vous postez un peu plus du code associé et expliquez un peu plus en détail ce que vous essayez de faire. –

Répondre

2

Peut-être que TXBuffer ne contient pas vraiment les données que vous pensez qu'il fait? Peut-être que vous n'appelez pas addToBuffer ou que vous l'appelez au mauvais moment ou avec le mauvais paramètre?

Vous pouvez essayer quelque chose comme ceci dans votre gestionnaire d'interruption:

TXBuffer[TXCurrentPos] = TXCurrentPos; 
TXREG = TXBuffer[TXCurrentPos]; 
TXCurrentPos++; 

Juste pour vous prouver que vous pouvez lire et écrire à TXBuffer et l'envoyer à l'USART.

Essayez aussi:

TXREG = TXEndPos; 

Pour voir si cela correspond à vos attentes (= la longueur de votre message).

Je suppose qu'il y a un autre code que nous ne voyons pas ici qui s'occupe du démarrage de la transmission. En supposant également que ceci est fait par message avec la position en cours de réinitialisation entre les messages - c'est-à-dire que ceci n'est pas censé être un tampon circulaire.

EDIT: Basé sur le code le plus récemment affiché: Vous n'avez pas besoin de redémarrer l'émetteur en écrivant le premier octet de votre tampon sur TXREG? Ce que je ferais normalement est d'activer l'interruption et d'écrire le premier octet dans le registre de transmission et un coup d'oeil rapide sur la feuille de données semble indiquer que c'est ce que vous devez faire. Une autre chose est que je ne vois toujours pas comment vous assurer un enveloppement de 127 à 0?

Aussi votre principal() semble se terminer brusquement, où l'exécution continue-t-elle une fois la fin principale terminée?

+0

J'ai déjà essayé TXREG = TXEndPos et obtenu le résultat attendu, la longueur de mon message. Essayer d'écrire dans le TXBuffer et ensuite lire depuis le TXBuffer ne fonctionnait pas; J'ai le même personnage que j'ai eu. –

+1

Peut-être que TXBuffer n'est pas mappé à l'emplacement de mémoire approprié. Utilisez-vous le compilateur MPLAB C? Essayez de mettre "#pragma udata TXBuffer" avant la déclaration de TXBuffer. Revoyez également tous les paramètres pour voir s'ils correspondent à votre PIC. Je pense qu'il devrait y avoir un script d'éditeur de liens spécifique à ce PIC. Une autre chose à essayer est de courir dans le simulateur. –

1

Il y a beaucoup de choses que vous ne prenez pas soin de. TXBuffer doit être un tampon circulaire. Une fois que vous avez passé TXEndPos au-delà de 127, vous devez revenir à 0. Même chose pour TXCurrrentPos. Cela affecte également le test pour voir s'il y a quelque chose dans le tampon, le test> 0 n'est pas assez bon. Le conseil générique est available here.

+0

Il ne doit pas * être * un tampon circulaire. Cela dépend de ce que le PO veut faire. En lisant le code, il semble vouloir le configurer pour la transmission d'un seul message <128 octets. –

1

Votre code est incomplet, mais il semble mal en l'état: que se passe-t-il s'il n'y a rien à envoyer? Vous ne semblez pas charger TXREG alors, alors pourquoi tout ce qui serait transmis, que ce soit 0x98 ou autre chose? La manière généralement utilisée lorsque ce type d'architecture de code est utilisée est de désactiver TXIE s'il n'y a rien à envoyer (dans une partie else de la routine IRQ) et de l'activer inconditionnellement à la fin de la addToBuffer fonction (puisque vous savez alors avec certitude qu'il y a au moins un caractère à envoyer).

En outre, vous devez tester TXEndPos et TXCurrentPos pour l'égalité directement, car cela vous permettrait d'utiliser un tampon circulaire très facilement en ajoutant deux opérations modulo.

+0

J'ai pris soin de toutes ces préoccupations. J'ai édité mon post pour les adresser. J'essayais juste de rendre ma question aussi courte que possible et de découper beaucoup de mes commandes pour des choses que je ne pensais pas avoir appliquées à mon problème. : P –