2012-02-05 5 views
2

J'ai une question très élémentaire. Cependant, quoi que j'ai essayé, je ne pouvais pas réussir à implémenter cela.PIC C18: Lecture de bits d'un octet

I ont un registre à décalage (74LS164) connecté à PIC18F2550 avec la configuration du matériel suivant:

// Data pin 
#define SCLCD_DATA   LATBbits.LATB7 
#define SCLCD_DATA_TRIS  TRISBbits.TRISB7 

// Clock pin 
#define SCLCD_CLOCK   LATBbits.LATB6 
#define SCLCD_CLOCK_TRIS TRISBbits.TRISB6 

LED sont connectées aux broches de sortie de 74LS164 pour afficher son état. J'ai une variable de 8 bits déclarée comme unsigned char. Je veux envoyer les bits de cette variable au registre à décalage. Le registre à décalage possède des bascules internes dont les sorties sont nommées Q0-Q7. Le premier bit envoyé se charge dans Q0, lorsque vous envoyez un deuxième bit, le précédent Q0 passe à Q1 et le nouveau bit envoyé à Q0, et cela continue ainsi lorsque vous envoyez les bits suivants. Lorsque l'envoi est terminé, LSB de la variable est censé être sur le Q0 du registre à décalage, et MSB sera sur Q7.

Mon code est comme celui-ci (La langue est C18):

void SCLCD_SendSerialBits(unsigned char unRegister) 
{ 
    // ucRegister is always passed as 0b10101010 for test 
    for (i=0; i<8; i++) 
    { 
     SCLCD_CLOCK = 0; 
     SCLCD_DATA = ((ucRegister & 0b10000000) == 0b10000000) ? 1 : 0; 
     ucRegister = ucRegister << 1; 
     SCLCD_CLOCK = 1; 
    } 
} 

Le code ne fonctionne pas au-dessus que je veux. Lorsque je l'exécute, tous les voyants s'allument, comme si j'avais chargé 0b11111111 dans la variable ucRegister.

Cependant, celui qui suit fonctionne très bien:

void SCLCD_SendSerialBits(void) 
{ 
    SCLCD_CLOCK = 0; SCLCD_DATA = 1;  SCLCD_CLOCK = 1; 
    SCLCD_CLOCK = 0; SCLCD_DATA = 0;  SCLCD_CLOCK = 1; 
    SCLCD_CLOCK = 0; SCLCD_DATA = 1;  SCLCD_CLOCK = 1; 
    SCLCD_CLOCK = 0; SCLCD_DATA = 0;  SCLCD_CLOCK = 1; 
    SCLCD_CLOCK = 0; SCLCD_DATA = 1;  SCLCD_CLOCK = 1; 
    SCLCD_CLOCK = 0; SCLCD_DATA = 0;  SCLCD_CLOCK = 1; 
    SCLCD_CLOCK = 0; SCLCD_DATA = 1;  SCLCD_CLOCK = 1; 
    SCLCD_CLOCK = 0; SCLCD_DATA = 0;  SCLCD_CLOCK = 1; 
} 

Quel est le problème avec mon code? Je pense que l'erreur est le plus susceptible d'être sur la ligne SCLCD_DATA = ((ucRegister & 0b10000000) == 0b10000000) ? 1 : 0;, mais peu importe combien je regarde, il me semble parfaitement OK. Quel est le problème avec mon code?

Toute aide sera appréciée.

+0

Exécutez le code via le simulateur MBLAB et les bits s'allument et s'éteignent comme prévu. Je vous suggère de faire la même chose pour confirmer que la version de votre compilateur génère une instruction qui activera les sorties comme prévu. Si le compilateur génère du code défectueux, je passerais au dernier relier de compliant. Si le simulateur fonctionne bien alors quelque chose de plus sinistre continue. Cela pourrait-il être des problèmes de synchronisation? Votre code qui fonctionne va synchroniser le serveur de sauvegarde plus rapidement que le code qui ne fonctionne pas. Cependant, je pense que merci le code plus rapide échouerait avant le plus lent. – user957902

Répondre

2

Votre code semble devoir fonctionner. Je voudrais écrire comme ça pour être plus lisible et plus efficace (en supposant que votre système a un levier de vitesses de canon):

for (i=7; i>=0; i--) 
{ 
    SCLCD_CLOCK = 0; 
    SCLCD_DATA = ((ucRegister >> i) & 1); 
    SCLCD_CLOCK = 1; 
} 

Pour les systèmes sans décalage à barillet, une variante de votre code

unsigned char ucMask = 0x80; 

    for (i=0; i<8; i++) 
    { 
     SCLCD_CLOCK = 0; 
     SCLCD_DATA = (ucRegister & ucMask) ? 1:0; 
     ucMask >>= 1; 
     SCLCD_CLOCK = 1; 
    } 

Si mon Le premier ou le deuxième exemple fonctionne, alors il semble que le compilateur ne gère pas les valeurs constantes ou ne les compare pas correctement dans votre code d'origine.

0

Peut-être juste une faute de frappe, mais votre paramètre est unRegister pas ucRegister. Est-il possible que ucRegister est un global qui est 0b11111111?