Lire un octet de l'UART sur AVR en C

Bonjour,

Je suis en train de concevoir un footcontroller MIDI avec un AtMega644. Pour cela, j'utilise l'UART du microcontr=F4leur. Pour l'envoi des messages MIDI, c'est OK mais pour la lecture, =E7a se corse un peu.

Dans un premier temps, j'ai besoin de d=E9tecter si un message de Program Change est re=E7u sur le canal 0, soit le code 0xC0, mais comme le bit de poids fort est envoy=E9 en premier, je re=E7ois 0x03 et c'est donc cette valeur que je dois lire.

Y-a-t-il un moyen de contourner =E7a simplement ? J'ai pens=E9 =E9crire un algo de pile LIFO mais =E7a me parait un peu lourd pour =E7a.

Merci, Lo=EFc

Reply to
difool
Loading thread data ...

Bizarre ce truc, normalement les UART envoient et recoivent les octets avec les bits dans le bon sens, c'est standard ? Tu ne peux pas param=E9trer cela directement sur l' UART ?

Sinon (si j'ai bien compris) soit 'R' l'octet recu [ 76543210 ] soit 'S' l'octet voulu [ 01234567 ]

// inversion de l'ordre des bits

for( i=3D8; i--; R >>=3D 1 ) S =3D (S

Reply to
Jean-Christophe

Le 27/11/2009 13:38, Jean-Christophe a écrit :

C'est ce que je pensais aussi mais visiblement non, à moins que j'ai oublié quelque chose, c'est aussi un peu le but de mon post ;)

J'ai regardé dans le datasheet du 644 et j'ai rien vu à ce propos.

Merci pour ton bout de code, c'est un peu ce que je pensais faire aussi mais si quelqu'un voit l'éventuel problème ou a une meilleure solution, je suis preneur.

Reply to
=?ISO-8859-1?Q?GRENON_Lo=EFc?=

"difool" a écrit dans le message de news: snipped-for-privacy@l13g2000yqb.googlegroups.com...

pa bien compris, a l'emission c'est dans le bon ordre, et a la reception c'est inversé ?

quoi qu'il en soit, si tu veux détecter 0xC0 et que tu recoit 0x03, il suffit de tester sur 0X03

#ifdef INVERSE #define PROGRAM_CHANGE 0x03 #else #define PROGRAM_CHANGE 0xCO #endif

comme cela, tu definis INVERSE ou pas, et tu n'as pas a modifier ton code

Reply to
jlp

Desolé JC, J'ai répondu un peu tard sur ta proposition d'essai de logiciel de schema ( voir sur le fil ferrite)

--

Alain
Reply to
alain denis

On Nov 27, 3:06=A0pm, "alain denis"

ma

Ok, j'ai post=E9 un link vers le ZIP sur le fil "ferrite".

Reply to
Jean-Christophe

On Nov 27, 2:29=A0pm, "jlp"

Salut JL,

Pour pinaller : ca ne marchera pas !

0xCO !=3D 0xC0

;-)

Reply to
Jean-Christophe

Le 27/11/2009 14:29, jlp a écrit :

Pour l'émission, je sais pas trop car pour le moment, j'utilise des fonctions de la librairie de mikroelectronica (en mikroC, donc) pour l'émission et celle pour la réception ne me plait pas (ça n'a pas l'air d'utiliser les interruptions). Comme c'est une librairie proprio, je sais pas comment ça marche ...

Oui mais ça c'était qu'un exemple, pour la suite (je vais avoir des valeurs codées sur les 8 bits à récupérer), c'est nettement moins pratique ;)

Par contre, l'idée du #define, ça me plait. Ça me parait moins lourd d'écrire les 128 #define en inversant les valeurs à la main plutôt que « retourner » chaque octet reçu.

Reply to
=?ISO-8859-1?Q?GRENON_Lo=EFc?=

"difool" a écrit dans le message de news: snipped-for-privacy@l13g2000yqb.googlegroups.com... Bonjour,

Je suis en train de concevoir un footcontroller MIDI avec un AtMega644. Pour cela, j'utilise l'UART du microcontrôleur. Pour l'envoi des messages MIDI, c'est OK mais pour la lecture, ça se corse un peu.

Dans un premier temps, j'ai besoin de détecter si un message de Program Change est reçu sur le canal 0, soit le code 0xC0, mais comme le bit de poids fort est envoyé en premier, je reçois 0x03 et c'est donc cette valeur que je dois lire.

Y-a-t-il un moyen de contourner ça simplement ? J'ai pensé écrire un algo de pile LIFO mais ça me parait un peu lourd pour ça. =========== Le c avr dispose je crois des fonctions de manipulation de bit comme "bit_set() bit_clear) et bit_test " Une petite fonction "basique" comme celle-ci retournera facilement l'ordre des bits

int inverse (int x) { int y=0; for(i=0;i

Reply to
maioré

"Jean-Christophe" a écrit dans le message de news: snipped-for-privacy@b2g2000yqi.googlegroups.com... On Nov 27, 2:29 pm, "jlp"

Salut JL,

Pour pinaller : ca ne marchera pas !

0xCO != 0xC0

;-)

j'ai eu du mal a conprendre, mais ca y est, j'ai changé de lunettes !

Reply to
jlp

"GRENON Loïc" a écrit dans le message de news:

4b0ff6ba$0$941$ snipped-for-privacy@news.orange.fr...

de toute facon, ca ne coute rien, tu seras toujours obligé de comparer d'une maniere ou d'une autre. soit if (TrucRecu == 0x03) { ....

soit if (TrucRecu == PROGRAM_CHANGE) { ....

ce qui est bien plus lisible, et bien plus facile a modifier, car il suffit de changer le #define.

dans un switch c'est encore plus flagrant. switch (TrucRecu){ case PROGRAM_CHANGE: machin(); break;

case VELOCITY: chose(); break

default: Rien();

et ainsi de suite

si l'uart peut etre programmé pour inverser les bits, tu n'as rien a retoucher dans le code

Reply to
jlp

difool, le 27/11/2009 a écrit :

C'est étonnant. Êtes-vous certain par exemple ne n'avoir fait qu'une ou deux manips par hasard erronnées qui vous ont amené à penser à cette inversion ? Si votre flux MIDI est standard, et c'est plus que certainement le cas, alors il y aurait un binz dans l'UART du µ-contrôleur. Il devrait alors logiquement y avoir un truc, soit hard, une possibilité d'inverser le décalage, soit soft, une inversion de l'ordre des bits en une instruction.

Je ne connais pas Atmel, ni les possibilité de l'AtMega644. Mais sur 8 bits, une table de lookup est souvent une bonne solution. Elle n'occupe en définitive que 256 octets(*), à diminuer de l'occupation *réelle* du code généré par votre code d'inversion de l'ordre des bits. Et niveau vitesse, sécurité et maintenabilité, c'est quand même autre chose. Bien entendu, vous pouvez vous faire un bout de C ou mieux du langage de script que vous aimez pour générer le morceau du source qui déclare la table.

(*) Peut-être 512, en 256 words ?

--
Pierre Maurette
Reply to
Pierre Maurette

On Nov 27, 4:56=A0pm, GRENON Lo=EFc

d

que =AB

Ecrire 128 (ou 256 ?) lignes de #define est un peu lourd =E0 =E9crire, sans compter les risques de fautes de frappe qui am=E8nent des bugs, =E0 moins de g=E9n=E9rer les #define automatiquement avec un petit soft.

Mais c'est sur que c'est le boulot du pr=E9processeur, et qu'au runtime le traitement sera plus rapide ! ... je persiste =E0 trouver louche ces retournements de bits, il doit y avoir une couille quelque part ...

Reply to
Jean-Christophe

On Nov 27, 4:56=A0pm, GRENON Lo=EFc

Tu peux bidouiller pour tester le header PROGRAM_CHANGE, mais ce sera la meme chose pour chaque octet de la trame, ainsi que pour toutes les donn=E9es recues par l' UART. Je suis presque certain que c'est un probl=E8me de config.

D'ailleurs, s'il y a un bit de parit=E9, celui-ci sera mal plac=E9 et les octets recus devraient etre rejet=E9s au moins =E0 50 %.

Reply to
Jean-Christophe

Jean-Christophe, le 27/11/2009 a écrit :

Si mes souvenirs de plus de 25 ans - la MIDI 1.0 n'était pas vieille - sont exact, il n'y a pas de bit de parité. Il y a un start et un stop encadrant 8 bits.

J'ai vérifié dans Google, et effectivement et contrairement à ce que je pensais, en MIDI le MSB est balancé en premier, en rs232 c'est le LSB. Je ne m'en souvenais pas parce que je codais à l'époque en dur (tempo logicielles sur un Apple ][) ou avec du 6850. J'imagine que le 6850 permettait de positionner le bit-boutisme ?

Donc changement de processeur (c'est peut-être le plus raisonnable) ou table de look-up.

--
Pierre Maurette
Reply to
Pierre Maurette

"Jean-Christophe" a écrit dans le message de news: snipped-for-privacy@z41g2000yqz.googlegroups.com...

Mais c'est sur que c'est le boulot du préprocesseur,

oui

non, ce n'est pas une question de runtime. en C un #define, c'est du traitement de texte pur et dur. ca ne coute rien en temps µp

.>je persiste à trouver louche ces retournements

je suis d'accord avec toi, mais il y a une grosse confusion entre rs232, liaison serie (pourquoi pas rs 422 ?), midi (qui est optocouplé), nombre de bits emis, octet lu sur l'uart et .........

Reply to
jlp

jlp a tapoté du bout de ses petites papattes :

Le Midi est une liaison série tout à fait orthodoxe. On utilisait d'ailleurs des Usart standards au début des 80s. Seule la vitesse (31k250 bauds), assez peu standard, peut géner. La sortie est pilotée par un collecteur ouvert (l'autre fil va sur une pull-up), l'entrée est donc un opto-coupleur. Donc bien penser que la polarité est inversée par rapport à une rs-232, ça peut donner l'illusion - si on regarde au scope une boucle de test qui compte - que le comptage se fait dans le mauvais sens.

--
LeLapin
Reply to
LeLapin

On Nov 28, 8:04=A0am, LeLapin

Oui mais cela ne r=E9soud pas le cas expos=E9 par Difool : L'inversion de polarit=E9 ne ferait que compl=E9menter les valeurs logiques des bits, mais conserverait leur ordre MSB/LSB dans un octet. Par exemple, une inversion de polarit=E9 de 0x03 donne 0xFC, tandis-qu'un renversement de l'ordre des bits donne 0xC0.

Reply to
Jean-Christophe

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.