10
votes

Écrire des données pour vous inscrire

J'ai l'adresse de la mémoire de certains registres (l'adresse LCDCW1 est en C000).

C codes C: xxx

Je veux juste écrire des données à ce registre. Les codes ont des problèmes, comment le corriger?

thx!


2 commentaires

@Andrey: 8051, Compilateur: ICC8051


Le code tel que ne compilera pas car 0xc000 n'est pas un pointeur, et l'opérateur * nécessite un opérateur de pointeur.


5 Réponses :


0
votes

Je ne sais pas ce que LCDCW1 signifie, mais d'écrire à une adresse constante: xxx

ajuster en fonction (votre registre peut ne pas être intogéré). < / p>


0 commentaires

1
votes

En supposant que le registre a la même taille qu'un long : xxx


3 commentaires

@Mouviciel: Ma solution est tout à fait la même chose, mais il y a une erreur: l'expression du pointeur requise, savez-vous pourquoi?


Les pointeurs à des registres externes doivent être volatile qualifié.


@Martin: La réponse de Naveen donne l'explication: vous devez lancer votre valeur entière à un type de pointeur.



20
votes

Vous pouvez, comme d'autres les suggérons, déclarez un pointeur approprié, c'est-à-dire xxx

note que j'ai ajouté le qualificatif volatile . C'est toujours une bonne idée lors de la lecture ou de l'écriture de registres matériels, car il garantit que chaque accès que vous effectuez dans votre code C apparaît réellement dans le code généré.

Cependant, je préfère généralement écrire des macros comme ceci xxx

puis remplissez-les avec les ASM de GCC appropriés. J'aime mieux que l'utilisation directe des pointeurs parce que:

  • Je pense qu'ils ont mieux lu dans le code, identifiant ce que je fais, lisez un registre, au lieu de vous concentrer sur la façon dont je le fais.
  • Certains registres nécessitent un processus en plusieurs étapes à lire à partir du matériel. Ceci est facilement caché dans les macros de ce style et la majeure partie de mon code fait toujours référence aux registres que je m'intéresse, et non à la manière compliquée que le matériel me fait toucher.
  • Enfin, en utilisant ASM S, je sais exactement comment j'accélère le registre. Parfois, il existe des instructions spéciales ou des espaces d'adresse nécessaires pour accéder à un registre, qui ne peut généralement pas être généré par le compilateur C.
  • Même si vous êtes en désaccord avec la motivation pour l'utilisation de déclarations de l'ASM, je suggérerais toujours d'envelopper vos accès à vos registres dans des macros (ou des fonctions inline) comme celles-ci.

    Dans votre cas, les définitions les plus simples doivent être: xxx


5 commentaires

+1 pour l'utilisation appropriée (et trop souvent négligée) de «volatile».


Voir le commentaire de la planche ci-dessous pour un document intéressant sur la façon dont la plupart des compilateurs échouent à implémenter volatile correctement dans divers cas difficiles.


Utilisez uint32_t etc. au lieu de long .


@CRAIG: tout à fait à droite. J'ai édité la réponse de manière appropriée.


Oui, un blanc d'blanc Atmel est d'accord avec votre mot pour Word, atmel.com/images/doc8075.pdf < / a>, page 9.



1
votes

LCDCW1 est juste une valeur entière. Vous ne pouvez pas faire * à ce sujet. Vous devez le jeter en Integer (ou vous tapez besoin besoin) Pointeur, puis utilisez-le. Par exemple: * (int *) lcdcw1 = 0x31;


1 commentaires

Utilisez uint16_t etc. au lieu de int .



5
votes

1 commentaires

C'est un très bon papier. Sa technique proposée pour faire du travail volatile de manière fiable dans C compilateurs de C est intéressante, mais je pense qu'ils sont pires d'une perspective de lisibilité que de simplifier une paire de macros de fonctions de lecture / écriture pour chaque registre, comme je le suggère dans ma réponse à ce poste. .