|
|
View previous topic :: View next topic |
Author |
Message |
guest Guest
|
struct problem |
Posted: Sat Feb 07, 2004 5:27 pm |
|
|
Hello!
I want to write 4 bytes to a struct. I know that the compiler creates "1 byte packets". But I have no idea why the following doesn't give the right result:
the struct:
Code: |
struct _s_mp3_header { //4 bytes //http://www.id3.org/mp3frame.html
unsigned Sync1 :8;
unsigned Sync2 :4; //SyncWord (12 bit)
unsigned Id :1; //MPEG Version (1bit): 0=MPEG-2 and 1=MPEG-1
unsigned Layer :2; //MPEG Layer (2bit): 00=not def., 01=LayerIII, 10=LayerII, 11=LayerI
unsigned Protection :1; //Protection Bit (1bit): Die genaue Funktionsweise ist noch nicht dokumentiert
unsigned Bitrate :4; //Bitrate (4 bit)
unsigned SampleFreq :2; //Samplingfrequenz (2 bit)
unsigned Padding :1; //Padding Bit (1 bit): gibt an ob alle anderen Bits genutzt werden, oder ob ungebrauchte Bits aufgefüllt werden sollen
unsigned Private :1;
unsigned Mode :2; //Mode (2 bit): gibt an ob das MP3 File Stereo, Mono oder Joint-Stereo ist
unsigned ModeExt :2; //Mode Extention (2 bit) nur wenn in Joint-Stereo codiert wird, gibt Frequenzbänder an
unsigned Copyright :1; //Copyright (1 bit) wenn dieses Bit gesetzt ist ist die Datei urheberrechtlich geschützt
unsigned OrigHome :1;
unsigned Emphasis :2; //Emphasis (2 bit) zur Rauschunterdrückung, hebt leise Frequenzen an
};
|
Code: |
struct _s_mp3_header h;
word i, tmp;
byte bh, bl;
bh = 0x12;
bl = 0x34;
//swap(bl);
*(&h) = bh;
*(&h+1) = bl;
bh = 0x56;
bl = 0x78;
//swap(bh);
//swap(bl);
*(&h+2) = bh;
*(&h+3) = bl;
printf("\n\rh:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
printf("\n\rSync:0x%4lX", ((word)h.Sync1<<4) | h.Sync2);
printf("\n\rId:%X", h.Id);
printf("\n\rLayer:%X", h.Layer);
printf("\n\rProtection:%X", h.Protection);
printf("\n\rBitrate:%X", h.Bitrate);
printf("\n\rSampleFreq:%X", h.SampleFreq);
printf("\n\rPadding:%X", h.Padding);
printf("\n\rPrivate:%X", h.Private);
printf("\n\rMode:%X", h.Mode);
printf("\n\rModeExt:%X", h.ModeExt);
printf("\n\rCopyright:%X", h.Copyright);
printf("\n\rOrigHome:%X", h.OrigHome);
printf("\n\rEmphasis:%X", h.Emphasis);
|
The output is:
h:12345678
Sync:0x0124
Id:01
Layer:01
Protection:00
Bitrate:06
SampleFreq:01
Padding:01
Private:00
Mode:00
ModeExt:02
Copyright:01
OrigHome:01
Emphasis:01
it should be in the same order as in the structure:
Sync:0x0123
...etc
Thanx for some hints :-)
Matthias |
|
|
guest Guest
|
|
Posted: Sat Feb 07, 2004 5:29 pm |
|
|
sorry i forgot:
using PCH 3.181
and PICLF452 |
|
|
Guest Guest
|
An empirical approach |
Posted: Sat Feb 07, 2004 7:28 pm |
|
|
I don't know the answer, but you might try this approach to figuring out where the compiler is putting the elements of the structure. That might lead you to the way it organizes it.
Code: | struct _s_mp3_header h;
void clear_struct(void)
{
byte b;
b = 0;
*(&h) = b;
*(&h+1) = b;
*(&h+2) = b;
*(&h+3) = b;
}
main()
{
clear_struct();
printf("\r\nh:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
// for each element of the structure, put in a value and check where it goes
h.Sync1 = 0x0123;
printf("\r\nh:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
}
|
|
|
|
Guest Guest
|
Compiler builds from the LSB |
Posted: Sun Feb 08, 2004 10:45 am |
|
|
I played with this a bit. It looks like the CCS compiler builds bit fields into structures starting from the least significant bit. (Now that I've typed all this, somebody will point out where in the documentation it says this.) So, where you might expect
Code: | struct s {
unsigned s :4;
unsigned i :1;
unsigned l :2;
unsigned p :1;
} |
to give you a byte like (ssssillp) it actually gives you (pllissss). The bits stay in order. So
gives you (00001011).
Here's the result I got, and the code I used.
Code: | #include <18f452.h>
#device ICD=TRUE
#device adc=10
#use delay(clock=20000000)
#fuses NOWDT, HS, PUT, NOLVP
#use rs232(baud=57600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
struct _s_mp3_header {
unsigned Sync1 :8;
unsigned Sync2 :4;
unsigned Id :1;
unsigned Layer :2;
unsigned Protection :1;
unsigned Bitrate :4;
unsigned SampleFreq :2;
unsigned Padding :1;
unsigned Private :1;
unsigned Mode :2;
unsigned ModeExt :2;
unsigned Copyright :1;
unsigned OrigHome :1;
unsigned Emphasis :2;
};
struct _s_mp3_header h;
void clear_struct(void)
{
byte b;
b = 0;
*(&h) = b;
*(&h+1) = b;
*(&h+2) = b;
*(&h+3) = b;
}
main()
{
clear_struct();
printf("\r\nClear h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
h.Sync1 = 0x23;
h.Sync2 = 0x01;
printf("\r\nSync h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Id = 1;
printf("\r\nId h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Layer = 3;
printf("\r\nLayer h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Protection = 1;
printf("\r\nProtection h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Bitrate = 15;
printf("\r\nBitrate h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.SampleFreq = 3;
printf("\r\nSampleFreq h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Padding = 1;
printf("\r\nPadding h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Private = 1;
printf("\r\nPrivate h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Mode = 3;
printf("\r\nMode h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.ModeExt = 3;
printf("\r\nModeExt h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Copyright = 3;
printf("\r\nCopyright h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.OrigHome = 1;
printf("\r\nOrigHome h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
clear_struct();
h.Emphasis = 3;
printf("\r\nEmphasis h:%X%X%X%X", *(&h), *(&h+1), *(&h+2), *(&h+3));
while (TRUE)
{
}
}
|
Code: | Clear h:00000000
Sync h:23010000
Id h:00100000
Layer h:00600000
Protection h:00800000
Bitrate h:00000F00
SampleFreq h:00003000
Padding h:00004000
Private h:00008000
Mode h:00000003
ModeExt h:0000000C
Copyright h:00000010
OrigHome h:00000020
Emphasis h:000000C0 |
|
|
|
Guest Guest
|
Oops. I forgot something. |
Posted: Sun Feb 08, 2004 10:51 am |
|
|
Since I think your structure is arranged from MSB to LSB instead of the CCS way, I think you may need to rearrange your structure like this:
Code: | struct _s_mp3_header {
unsigned Emphasis :2;
unsigned OrigHome :1;
unsigned Copyright :1;
unsigned ModeExt :2;
unsigned Mode :2;
unsigned Private :1;
unsigned Padding :1;
unsigned SampleFreq :2;
unsigned Bitrate :4;
unsigned Protection :1;
unsigned Layer :2;
unsigned Id :1;
unsigned Sync2 :4;
unsigned Sync1 :8;
};
|
|
|
|
guest Guest
|
no thats not right |
Posted: Sun Feb 08, 2004 11:16 am |
|
|
Hello!
Thanks for your help. I knew that there can be such a problem, but i was a little bit confuesed...
Can i configure this anywhere?
it should be arranged like this:
Code: |
struct _s_mp3_header {
unsigned Sync1:8;
unsigned Protection :1;
unsigned Layer :2;
unsigned Id :1;
unsigned Sync2 :4;
unsigned Private :1;
unsigned Padding :1;
unsigned SampleFreq :2;
unsigned Bitrate :4;
unsigned Emphasis :2;
unsigned OrigHome :1;
unsigned Copyright :1;
unsigned ModeExt :2;
unsigned Mode :2;
};
|
It seems that only the bit alignment is changes, not the byte-blocks in the structure. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|