2010-04-05 2 views
3

J'ai un microcontrôleur d'échantillonnage de nombreux ADC, et l'envoi des mesures sur une radio à un très faible débit, et la bande passante devient un problème.Manière efficace de créer/décompresser de grands champs de bits dans C?

Actuellement, chaque ADC ne nous donne que 10 bits de données, et il est stocké dans un entier de 16 bits. Existe-t-il un moyen facile de les emballer de manière déterministe, de sorte que la première mesure soit au bit 0, la seconde au bit 10, la troisième au bit 20, etc.?

Pour aggraver les choses, le microcontrôleur est peu endian, et je n'ai aucun contrôle sur l'endianness de l'ordinateur de l'autre côté.

EDIT: Jusqu'à présent, j'aime @ réponse de MSN le meilleur, mais je vais répondre aux commentaires

@EvilTeach: Je ne sais pas si le motif binaire exact serait utile, ou comment pour mieux le formater avec du texte seulement, mais je vais y réfléchir.

@Jonathan Leffler: Idéalement, je placerais 8 valeurs de 10 bits dans 10 octets de 8 bits. Si cela rend le traitement plus facile, je me contenterais de 3 valeurs dans 4 octets ou 6 valeurs dans 8 octets (bien que les 2 soient équivalents à moi, même quantité de bits gaspillés)

+0

Je pense qu'il serait utile, pour montrer un diagramme de votre modèle de bits entrants, et les résultats souhaités. – EvilTeach

+1

Les «champs de bits» et «portabilité» vont rarement ensemble dans la même phrase d'une manière positive; les champs de bits ne sont pas portables. Essayez-vous d'intégrer des valeurs de 3 x 10 bits dans un entier de 32 bits ou de 6 x 10 bits dans un entier de 64 bits, ou essayez-vous d'être contigu sur des plages de mémoire plus longues? –

Répondre

3

Vous pouvez utiliser des champs de bits, mais le commande dans les mots de la machine ne se définit pas:

cela dit, il ressemblerait à quelque chose comme:

struct adc_data { 
unsigned first :10; 
unsigned second :10; 
unsigned third :10; 
}; 

EDIT: Correction, grâce à Jonathan.

+0

Sûrement cela ressemblerait plus à '' struct {unsigned first: 10; seconde non signée: 10; tiers non signé: 10; } adc_data; ''? Vous ne voulez pas affecter 1 bit et 9 bits non affectés; vous voulez que trois ensembles de 10 bits soient assignés, n'est-ce pas - ou ne pose pas la question? –

+0

Vous avez raison. J'ai mal compris la question. –

4

Utilisez les bits 0 et 31 pour déterminer l'endianness et le pack 3 valeurs de 10 bits au milieu. Une méthode simple pour tester l'endianness correspondant consiste à définir les bits 0 à 0 et 31 à 1. À l'extrémité réceptrice, si le bit 0 est égal à 1, affirment que le bit 31 est 0 et inversent l'endianness. Sinon, si le bit 0 est égal à 0, affirmez que le bit 31 est 1 et extrayez les 3 valeurs.

0

La chose la plus simple à faire à propos de l'endianité est de simplement en choisir une pour votre transmission. Pour emballer les bits dans le flux de transmission, utilisez un accumulateur (d'au moins 17 bits dans votre cas) dans lequel vous décalez 10 bits à la fois et gardez une trace du nombre de bits qui s'y trouvent. Quand vous transmettez un octet, vous retirez un octet de l'accumulateur, soustrayez 8 de votre compte, et déplacez l'accumulateur de 8. J'utilise ici "transmettre" sans serrer, vous le stockez probablement dans un tampon pour une transmission ultérieure. Par exemple, si la transmission est peu endian, vous déplacez vos 10 bits en haut de l'acccumator (dans ses bits MS), et tirez vos octets par le bas. Par exemple: pour deux valeurs a et b:

Accumulator  Count 
(MS to LS bit) 
aaaaaaaaaa  10  After storing a 
aa    2  After sending first byte 
bbbbbbbbbbaa 12  After storing b 
bbbb   4  After sending second byte 

La réception est une opération similaire de déballage.

Questions connexes