hi
can somebody say me how to make word of 16 bits with two char 8 bits?
example:
char1= 01010101
char2= 00001111
how to make so that
word =0101010100001111 ??
thank you
hi
can somebody say me how to make word of 16 bits with two char 8 bits?
example:
char1= 01010101
char2= 00001111
how to make so that
word =0101010100001111 ??
thank you
Try this:
char1 = 0x55;
char2 = 0x0F;
word a;
a = char1;
a = a << 8;
a = a | char2;
Michael
I’d do something like this:
char * Foo = &word;
*Foo = char1;
Foo++;
*Foo = char2;
This is clearly the wrong way of doing it:NleahciM:
I’d do something like this:char * Foo = &word;
*Foo = char1;
Foo++;
*Foo = char2;
unclear
non endianness-safe, therefore not portable
probably not even efficient
Stick with mifi’s advice.
I'd expect it to be faster, or at least the same speed, actually. Clearly, you have not done much assembly programming. There is nothing unclear about the code, if you know anything about C programming. Clearly, he is asking for an ARM processor, so who cares if it isn't portable to other systems? Clearly, you really don't have a clue what you're talking about.bertrik:
This is clearly the wrong way of doing it:NleahciM:
I’d do something like this:char * Foo = &word;
*Foo = char1;
Foo++;
*Foo = char2;
unclear
non endianness-safe, therefore not portable
probably not even efficient
Stick with mifi’s advice.
Does that clear things up for you?
I must agree with bertrik and mifi. If your goal is to produce a 16-bit quantity in the CPU’s native byte order, use bit shifts — ( hi << 8 ) | ( lo ). The compiler will usually optimize that expression perfectly well.
Using pointer manipulation also forces the value to be stored in RAM. If you’re using a cpu with plenty of registers (like the ARM) then it’s going to be more efficient to use a technique which allows the compiler to keep the value in registers.
It is doubtful to me that the compiler can recognize that all you're doing is copying the chars into the word, so it cannot optimize as well as is possible.wiml:
I must agree with bertrik and mifi. If your goal is to produce a 16-bit quantity in the CPU’s native byte order, use bit shifts — ( hi << 8 ) | ( lo ). The compiler will usually optimize that expression perfectly well.Using pointer manipulation also forces the value to be stored in RAM. If you’re using a cpu with plenty of registers (like the ARM) then it’s going to be more efficient to use a technique which allows the compiler to keep the value in registers.
If your variable is so short lived that it will only exist in a register than yes your way is better.
/me raises hand. One more vote for Bertrik/Mifi
The purpose of writing C is to write portable code (if yours isn’t, you should reconsider your strategy). Even among ARMs, there are endian differences, some even allow their endianness to be changed during runtime.
Compiling both examples using gcc 4.1 with -O3, I get the following:
00000000 <lala_mem>:
0: e24dd008 sub sp, sp, #8 ; 0x8
4: e5cd0006 strb r0, [sp, #6]
8: e5cd1007 strb r1, [sp, #7]
c: e1dd00f6 ldrsh r0, [sp, #6]
10: e28dd008 add sp, sp, #8 ; 0x8
14: e12fff1e bx lr
00000018 <lala_shift>:
18: e1811400 orr r1, r1, r0, lsl #8
1c: e1a01801 mov r1, r1, lsl #16
20: e1a00841 mov r0, r1, asr #16
24: e12fff1e bx lr
Guess it’s obvious which one is going to perform faster under all circumstances?
Regards
Dominic
Ummmm... Maybe that's your purpose in using C. I use it to write clean and efficient code and to speed up dev time.Dominic:
The purpose of writing C is to write portable code (if yours isn’t, you should reconsider your strategy).
I’m unsure what you’re trying to show with the assembly code.
Clean code is portable, as it makes no assumptions about implementation details. Using memory operations for the purpose of putting to 8-bit quantities into a 16-bit quantity isn’t efficient.
What I want to show with the assembly is:
that a) the compiler is very well capable of optimizing the shifting C code presented by mifi and that b) it’s going to be faster than using the pointer method you presented.
For example on an ARM7 (LPC, SAM7) lala_mem uses two stores (each 2 cycles) and one load (another 3 cycles), while lala_shift uses three data processing instructions (each 1 cycle).
Regards,
Dominic
hello
thank you very much for your assistance,
it was to me very useful.
finally I use:
a = char1;
a = a << 8;
a = a | char2 or a=a+cah2 it is the same but takes more time to do it;
but I still have a small question,
im using SPI to send data to LCD, it works fine whene i m sending a string but not when im sendint an integer!!??
is there a solution to convert integer to string ?( itoa() is not included in stdlib for ARM)
the essential of my code is:
void lcd_data(char c)
{
spi(0x05); //E =1, RW =0 ,RS=1
spi(c); //sent byte
valid(); // on shift reg
spi(0x00); //clear E
spi(c);
valid();
}
void print (char *car)
{
int i=0;
while(*car != ‘\0’)
{
lcd_data(*car);
car++;
i++;
if(i==16)
{
lcd_comm(0xc0);
for(i=0;i<5;i++)
{
lcd_data(’ ');
}
}
}
}
main()
{
spi_init();
lcd_init();
print(" hello olimex");// ------> work fine
}
I wants to pass in parameter integers to print them on lcd
How about using printf? Here’s a nice light-weight implementation: http://www.menie.org/georges/embedded/index.html#printf
It only needs a putchar implementation. Your lcd_data function already looks very much like putchar, so this should not be too much of a change.
Printf allows you to easily format strings, like
printf("Temperature = %2d deg", temp);
where temp is a variable containing the temperature.
The %2d is a special code that tells printf to take ‘temp’ and format is as a signed decimal integer that requires at least 2 character positions (possibly more if temp > 99, or < 0).
Example output (for temp =25)
Temperature = 25 deg
thank you
it is exactly what I wants, the only problem : by using this function the size of the code increases considerably but its works fine.
now I have a table of two dimensions where i stock integer parameters I also have a variable I wants to traverse the table to post my parameters and to modify them if need .
when posting the values are false!!
and when I modify them , at the reset of becomes again like front!!
an idea??
static int para[5][10] = { 1,1,30,100, 100, 10, 10, 10, 1, 1,
2,1,20,150, 120, 10, 10, 10, 0,1,
3,1,20,200, 140, 10, 10, 10, 0, 1,
4,1,20,250, 150, 10, 10, 10, 0, 0,
5,1,20,300, 160, 10, 10, 10, 0, 0};
modif (int n , int m)
{
int val;
val = para[n][m];----------------??
while(1)
{
if (!(IOPIN0 & (1<<plus)))
{
mili(500);//wait
val++;---------------------?? my problem
sprintf (buf, “%d”, m+1);
sprintf (buf1, “%d”, val);
home();//lcd commande
out2para ( mess,buf,buf1);// mess is string
}
if (!(IOPIN0 & (1<<moins)))
{
mili(500);
if (val >0)
{
**val–; **
sprintf (buf, “%d”, m+1);
sprintf (buf1, “%d”, val);
home();
affiche2para ( mess,buf,buf1);
}
}
if (!(IOPIN0 & (1<<valide)))
{
mili(500);
para[n][m]=val;// to save the new value in para[n][m]
home();
affiche(" fin de config");
goto rep3;
}
}
rep3:
}
it is a memory problem??
Are you sure you’re linking the light-weight version (and not the gcc version)?
With my settings, the printf module takes just over one kilobyte of ARM code.
i don’t know :oops: im using keil µvision without changing anything!
the code without aprintf and stdio.h takes 3.2kbyte
and with takes 4.6 kbyte