|
|
View previous topic :: View next topic |
Author |
Message |
Andrew83
Joined: 16 Sep 2008 Posts: 51
|
Handling strings - the newcomer to CCS c way :) |
Posted: Sat Jan 10, 2009 6:20 am |
|
|
Hello 2 all !
By the following code, i am trying to read a character from serial port, translate this character into binary form and store the result in a string.
Parameters : PIC18f452 @ 10 MHz and using CCS C compiler version 4.057.
The code looks like this :
Code: |
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <string.h>
void main()
{
char c,i,temp[1],buffer[8];
while(1)
{
c=getc();
for(i = 0; i < 8; i++)
{
if(c & 0x80)
{
sprintf(temp,"%c",'1');
}
else
{
sprintf(temp,"%c",'0');
}
strcpy(buffer,temp);
c <<= 1;
}
printf("%s /n/r",buffer);
}
|
So ..... i am getting the character from serial port by using the "getc()" function. Next, i'm doing a bitwise AND (http://en.wikipedia.org/wiki/Bitwise_operation#AND) of the character with the hex number 0x08 (binary representation :10000000). If the current bit is a "1"or a "0", i'm copying the value into a temporary buffer wich is a 1 character long. Then the result of the "IF" statement, is copyed into a larger string, 8 characters wide.
So, for a 0x02, i have to get 00000010.
Instead, i'm getting an endless string of zeroes.
WHERE IS MY MISTAKE ??
Thank you very much for your time ! |
|
|
Andrew83
Joined: 16 Sep 2008 Posts: 51
|
|
Posted: Sat Jan 10, 2009 6:34 am |
|
|
Hmmm...i will try to use the "strcat()" function instead of the "strcpy()".
Let's see what happens ! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Jan 10, 2009 6:39 am |
|
|
First of all, in C a string is always terminated by a null character. So when declaring your variables you have to add 1 extra character to the desired length.
Change: Code: | char c,i,temp[1],buffer[8]; | to: Code: | char c,i,temp[2],buffer[9]; |
A second problem is that you copy the temporary string to the output buffer inside the loop and hereby overwrite the existing data. What is missing is a mechanism to 'shift' the destination output 1 character in every loop iteration.
Change: Code: | strcpy(buffer,temp); | to: Code: | strcpy(&buffer[i],temp); |
Note that the sprintf function is causing some overhead. Your program would be smaller and easier to read when you optimize the sprintf function 'away'. I leave this as an exercise to the poster. |
|
|
Andrew83
Joined: 16 Sep 2008 Posts: 51
|
|
Posted: Sat Jan 10, 2009 6:42 am |
|
|
Thank you very much ckielstra ! Thank you for the quick answer ! |
|
|
Andrew83
Joined: 16 Sep 2008 Posts: 51
|
|
Posted: Sat Jan 10, 2009 7:34 am |
|
|
So...here is the code without using the "sprintf()" function!
ckielstra rules !! Thank you again 4 opening my eyes to the real solution of the problem !
Code: |
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <string.h>
void main()
{
char c,d,i,temp[2],buffer[9];
while(1)
{
c=getc();
for(i = 0; i < 8; i++)
{
if(c & 0x80)
{
d='1';
}
else
{
d='0';
}
c <<= 1;
strcpy(&buffer[i],&d);
}
printf("%s \n\r",buffer);
}
}
|
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Jan 10, 2009 7:38 am |
|
|
Hi Andrew,
Your implementation is close to what I had in mind, except for 1 problem, your variable 'd' is not a string so you can not use strcpy.
change: Code: | strcpy(&buffer[i],&d); | to: and then after the loop add a terminating zero to the buffer: |
|
|
Andrew83
Joined: 16 Sep 2008 Posts: 51
|
|
Posted: Sat Jan 10, 2009 7:42 am |
|
|
Hmmm ...you ar right ...however, the program works just fine ! I think a type conversion is happening here ...it's worth further investigation!
Ok ...let's see: if i write the following program, i tink it's an equivalent to the strcpy() function:
Code: |
void main()
{
char str1[] = "Copy a string.";
char str2[15];
int i;
for (i=0; str1[i]; i++)
str2[i] = str1[i];
str2[i] = 0;
printf("The content of str2: %s\n", str2);
while(1);
} |
So this program represent exactly what you sugested
Am i right ? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Jan 10, 2009 8:51 am |
|
|
Quote: | Hmmm ...you ar right ...however, the program works just fine ! I think a type conversion is happening here ...it's worth further investigation! | No conversion is done. You are just being lucky the memory location directly after the variable 'd' contains a zero. This is random behaviour and can not be relied on.
Yes, your program is equivalent to the strcpy function but there is no need to write your own implementation. The compiler supplied version suffices and is way more optimized.
Here is the complete code as I suggested: Code: | #include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
void main()
{
char c,d,i,buffer[9];
while(1)
{
c = getc();
for(i = 0; i < 8; i++)
{
if (c & 0x80)
{
d = '1';
}
else
{
d = '0';
}
c <<= 1;
buffer[i] = d;
}
buffer[8] = 0; // terminate string
printf("%s \n\r", buffer);
}
} |
|
|
|
Guest
|
|
Posted: Sat Jan 10, 2009 9:17 am |
|
|
Ok ! Thank you very very much !! |
|
|
|
|
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
|