|
|
View previous topic :: View next topic |
Author |
Message |
maxD
Joined: 16 Dec 2013 Posts: 22
|
sending binary values through rs232 using pic 18f2550 |
Posted: Mon Dec 16, 2013 12:42 am |
|
|
Hi guys i'm new to this forum and also beginner to pic c programming...
In these days I'm doing a project using pic18f2550 rs232 communication.
I want to send and receive 8 bit (or 7 think it does not matter).
How can i do this ...putc getc ?
I want to send these binary values without converting them to ascii values
because i have to check them at the end.
putc and getc are working with strings as i know.
Please reply... |
|
|
oxo
Joined: 13 Nov 2012 Posts: 219 Location: France
|
|
Posted: Mon Dec 16, 2013 1:30 am |
|
|
Yes, just use putc and getc. Make sure the UART is set to 8 bits though ! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Mon Dec 16, 2013 2:00 am |
|
|
Let's make a comment.
putc, and getc are not 'working with strings'....
Key is very basic. putc, and getc, just send characters, and will accept anything at all. They will _not_ accept strings (actually in CCS there is a 'shortcut', so they will send constant strings). A 'string' in C, doesn't actually exist as a type (a thing that is often misunderstood). In C, a 'string' is just an array of characters, with a single terminating '0' character (sometimes called NULL).
putc(1);
Just sends the number '1' over the RS232 (not the ASCII character '1').
putc('1');
Sends the ASCII character '1' over the RS232. Not a 'string', the single ASCII character. 0x31.
So:
Code: |
//suitable processor header etc.
void main(void)
{
int n;
char text[10]; //A character array
for (n=10;n<20;n++)
{
putc(n); //just sends binary 0b1010 to 0b10011 one after the other
}
for (n=10;n<20;n++)
{
printf("%02d\n",n); //This sends the ASCII represented numbers '10'
//etc. one after the other
}
for (n=10;n<20;n++)
{
sprintf(text, "%02d\n",n);
//This now generates the same text from above as what is commonly
//called a 'string' in the array 'text'
}
|
So you are starting with a basic 'wrong idea', that putc, and getc, have anything to do with 'strings'.
Best Wishes |
|
|
maxD
Joined: 16 Dec 2013 Posts: 22
|
|
Posted: Mon Dec 16, 2013 8:18 am |
|
|
Thank you so much Ttelmah ..
but i have another question on this
here integer 10 will be converted to b'1010' and send over serial com
but here if i define integer variable as 1010 think it will be converted to binary and send over com
So how can i send binary values as it is.. |
|
|
oxo
Joined: 13 Nov 2012 Posts: 219 Location: France
|
|
Posted: Mon Dec 16, 2013 9:00 am |
|
|
maxD wrote: | Thank you so much Ttelmah ..
but i have another question on this
here integer 10 will be converted to b'1010' and send over serial com
but here if i define integer variable as 1010 think it will be converted to binary and send over com
So how can i send binary values as it is.. |
There is no conversion to ascii when using putc (and getc). So it is simply done like this.
Code: |
int n = 10;
putc(n);
|
|
|
|
maxD
Joined: 16 Dec 2013 Posts: 22
|
|
Posted: Mon Dec 16, 2013 9:16 am |
|
|
thankz oxo
but i want to send binary number as it is.. |
|
|
oxo
Joined: 13 Nov 2012 Posts: 219 Location: France
|
|
Posted: Mon Dec 16, 2013 9:25 am |
|
|
I am confused as to what you mean.
int n = 10 sets n to the binary value 0b00001010
Explain why you think the binary value transmitted by putc() is being "converted". |
|
|
maxD
Joined: 16 Dec 2013 Posts: 22
|
|
Posted: Mon Dec 16, 2013 9:33 am |
|
|
ya
as Ttelmah said if
int a=10;
putc(a) sends b'1010'
but if i define int a=1010//1010 is a binary number i want to send
putc(a) will send binary value equals to integer 1010
that what i meant |
|
|
oxo
Joined: 13 Nov 2012 Posts: 219 Location: France
|
|
Posted: Mon Dec 16, 2013 9:40 am |
|
|
maxD wrote: | ya
as Ttelmah said if
int a=10;
putc(a) sends b'1010' |
Yes, that's correct.
Quote: |
but if i define int a=1010//1010 is a binary number i want to send
putc(a) will send binary value equals to integer 1010
t |
And that is a wrong assumption. If you define
int a= 0b1010;
putc(a) will send binary value of 00001010
It's all much more easy than you are imagining |
|
|
maxD
Joined: 16 Dec 2013 Posts: 22
|
|
Posted: Mon Dec 16, 2013 9:47 am |
|
|
what...
That solved my problem 100%
thank you so much oxo!!! |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Mon Dec 16, 2013 10:20 am |
|
|
maxD wrote: |
but i have another question on this
here integer 10 will be converted to b'1010' and send over serial com
but here if i define integer variable as 1010 think it will be converted to binary and send over com
So how can i send binary values as it is.. |
It can be very confusing... Computers work in binary: they represent everything using just two states, which we call '0' and '1'. We call this a bit. Bits are generally grouped together in eights: a byte. A byte is simply 8 bits. This idea came about in the early sixties, since then most computers have been organised to work with multiples of bytes, often called words: two bytes is 16 bits, four is 32 and so on.
Computers are great at working in binary; it's what they are good at. The problem is that humans aren't so great at it. Also, we want the binary patterns to be used as representations of different things, so we a) Represent the binary patterns in several, more human friendly ways and b) code the binary to represent useful things other than just numbers.
A bits, bytes, and words, can represent anything that we want them to. It was in the early 50's that Alan Turing made the key conceptual leap: that bits can represent not just numbers, but also characters, and indeed the instructions for the computer itself. Today we're comfortable with them representing colours and sound, but that would have seemed way out there in the early years. That leap created the concept of the stored program computer that we are familiar with today.
The contents of a byte, or indeed any length word, can be written in binary, such as (using C's syntax) 0b01000001, which can also be written as 0x41, which is hexadecimal, and is a bit more human friendly. It can also be written as 65, the decimal representation, which is even more human friendly. It also, in ASCII coding, represents the upper case letter 'A'. All are the same bit pattern. All that's changing is how we write it. All can be sent somewhere using the serial comm (UART) as a single, identical, byte. The meaning, is not determined by hardware - its just an eight bit pattern - but by the programmer through the software they write.
Inside the computer there is no need to convert from decimal integer to binary, or from hex to decimal, all are the same. Its just a matter of what meaning we humans want to assign to the bit pattern. Binary, hex and decimal are all the same. Characters too, are just bit patterns.
You can send bytes down a serial line. No trouble. You can send them in forms other computers find easy to deal with, but which humans can't read. Or, if intended for humans, you can convert the values into human readable form.
A byte has two hundred and fifty six different possible states. Each could represent a character (the ASCII code actually has only 128 states, i.e. needs seven bits, and a little over 32 of those are non-printing: they do not represent a readable character. They are things like new line, backspace etc.
To convert the 256 different states, 0 - 255 of a byte requires at least three human readable characters, four is the byte represents a signed value, -128 - 127. Conversion from binary to ASCII like this is simple using repeated division by 10. In C it can be done with something like this code (note this will not work on PIC as its recursive):
Code: |
// Declare an integer and initialise it with decimal 65.
unsigned int8 My_Byte = 65;
// This convert an unsigned byte into its decimal representation in ASCII.
void Print_Unsigned_Byte_As_ASCII_Decimal(unsigned int8 Value)
{
// if the value is more than one digit we divide it by ten and
// call ourselves (that's recursion - won't work in PICs).
if (Value > 9)
{
Print_Unsigned_Byte_As_ASCII_Decimal(Value / 10);
}
// We take the remainder, 0 to 9, and convert it to ASCII by
// adding the code of the ASCII character '0', which happens to
// decimal 48 or hex 0x30.
putc((Value % 10) + '0');
}
...
Print_Unsigned_Byte_As_ASCII_Decimal(My_Byte);
...
|
To convert incoming human readable ASCII coded numbers is even easier, just multiply what you've already got by ten and get the character, subtract the ASCII code for '0' from it and add it to your number. Stop when you don't read a valid digit (i.e. '0' to '9').
The same principles work for any other number base. Conversions to and from hexadecimal are particularly simple as each hex digit is four bits - a nibble, or half a byte.
Its even simpler as C will do it all for you. Printf() and its relatives, will convert a byte, or almost any word, to the ASCII representation of octal, hex or decimal, signed or unsigned:
Code: |
unsigned int8 My_Byte = 65;
// This will print "A, 65, 0x41, o141"
printf("Character: %c, decimal: %d, hex: %X, octal: %o", My_Byte, My_Byte, My_Byte, My_Byte);
|
Printf often won't convert to an ASCII representation of binary, probably as its so human unfriendly. So you have to do that if you really want, which is unlikely. Notice I didn't write won't convert to binary for you, as the value is already binary. It's the ASCII character codes, i.e. something like '0', 'b', '0', '1', '0', '0', '0', '0', '0', '1', that gets 'printed, i.e. sent down the serial line, not the binary value 65, which, if you'll recall, is the ASCII code for the letter 'A'.
This may seem complicated at the moment, but once you've got your head around it it'll all seem simple. The key is to remember these bit patterns can mean almost anything we want them to mean. There are some commonly used codes, such as ASCII, and C will do a lot of the reformatting/conversion for us. |
|
|
maxD
Joined: 16 Dec 2013 Posts: 22
|
|
Posted: Tue Dec 17, 2013 8:08 am |
|
|
thanks a lot RF _DEVELOPER
more problems are coming.
1st one
I am using eusart.
In the case of sending some data to receiver what happens if the receiver
does not ready to receive that data(think he is in another operation when sender sends some data and the baud rates are matched) ?
Will it a be loss of data?
Or else sender won't send data until receiver is ready?
If so how does the sender knows receiver is ready for communication?
2nd
if i want to send start123123r
I write
Code: | char array[13]="start123123r"; //i only want to show you
puts(array); |
at the receiver
Code: | char array[13];
gets(array); |
Is this correct?
If not suggest me way.
How i match the gets and puts to operate in same time ...
Thanks a lot those who are helping me. |
|
|
oxo
Joined: 13 Nov 2012 Posts: 219 Location: France
|
|
Posted: Tue Dec 17, 2013 8:16 am |
|
|
Hi,
I don't have time for a long reply, but you need to look at the example EX_SISR.C
You need to run interrupts and a buffer at the receiver end.
- and to answer your question, the transmitter does not know if the receiver is "ready". It is up to the programmer to be sure the receiver is always ready by having the interrupt driven buffer as in the example. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Tue Dec 17, 2013 12:41 pm |
|
|
comment: oxo is 100% right, study and use the CCS example ex_sisr.c ! I KNOW it'll work 100% on a PIC18F46K22 using both UARTs at 115k200 baud. My 'test' has been going on about a year and has never missed any data.
hth
jay |
|
|
maxD
Joined: 16 Dec 2013 Posts: 22
|
|
Posted: Tue Dec 17, 2013 10:24 pm |
|
|
ya
i got your idea..
I read your example and it uses getc
but if i use gets,
will it get data without losing any of them?
or if i lost data by using gets what should i do?
do i need care about receiver buffer full situation ?
how do i use interrupts with gets function..? |
|
|
|
|
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
|