|
|
View previous topic :: View next topic |
Author |
Message |
mahdi70
Joined: 05 Jan 2016 Posts: 44
|
long_data uart---solved |
Posted: Tue Jan 05, 2016 1:36 am |
|
|
hi buddies
i want to send and receive int16 over 2 pic uart with 9 bit long data..but i dont know how to do it..the getc() is normal as a 8 bit receive...but for sending 16 bit i can not use putc...pls help...thanks
Last edited by mahdi70 on Thu Jan 07, 2016 1:39 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Jan 05, 2016 1:58 am |
|
|
Lets take a deep breath.
Your question is not very clear. You talk about 16bit, and 9bit?.
The PIC UART cannot send 16bit data. Nor can most other async UART's. The 'longer' the data in async comms, the more accurate the clocks at each end have to be. With 8bit, using 3* sampling in the received data, the maximum allowable timing error is about 4%, so async comms rarely uses data much longer than this. There are though old 'specialist' systems using much longer data (things like 56bit), but these never became standard. Neither the PC UART, or the PIC UART can handle such data.
Now, you could (for instance), use 9bit transmission, and use the 9th bit as a flag to say 'this is the top byte'. Then use make8, to get each of the two bytes, and simply send these one after the other.
Putc, and getc, will both accept and return 'long' data (int16). You have to set the option 'LONG_DATA' in the #use RS232 setup.
Set this, and then getc, returns an int16, and putc expects an int16, each containing the 9bit data. |
|
|
mahdi70
Joined: 05 Jan 2016 Posts: 44
|
|
Posted: Tue Jan 05, 2016 2:21 am |
|
|
Ttelmah wrote: | Lets take a deep breath.
Your question is not very clear. You talk about 16bit, and 9bit?.
The PIC UART cannot send 16bit data. Nor can most other async UART's. The 'longer' the data in async comms, the more accurate the clocks at each end have to be. With 8bit, using 3* sampling in the received data, the maximum allowable timing error is about 4%, so async comms rarely uses data much longer than this. There are though old 'specialist' systems using much longer data (things like 56bit), but these never became standard. Neither the PC UART, or the PIC UART can handle such data.
Now, you could (for instance), use 9bit transmission, and use the 9th bit as a flag to say 'this is the top byte'. Then use make8, to get each of the two bytes, and simply send these one after the other.
Putc, and getc, will both accept and return 'long' data (int16). You have to set the option 'LONG_DATA' in the #use RS232 setup.
Set this, and then getc, returns an int16, and putc expects an int16, each containing the 9bit data. |
tnx for reply...for example i want to transmit a=2000.
unsigned int16 a=2000;
unsigned int8 a1=0,a2=0;
a1=make8(a,1);
a2=make8(a.0);
putc(a1);
putc(a2);
this is right? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Tue Jan 05, 2016 2:43 am |
|
|
Potentially yes.
Problem is, how it the receive end going to know where it is in the data?.
Since you are using all 256 possible values, you can't use any value as a flag to say 'this is the start' or 'this is the end' of the data. If anything gets lost/missed the code can never recover. This is where 9bit then comes in.
For instance:
Code: |
#use rs232(UART1, BAUD=9600, BITS=9, LONG_DATA)
//Then
unsigned int16 a=2000; //0x07D0
putc((int16)(make8(a,1) | 0x100)); //sets bit 8
putc((int16)(make8(a,0));
|
This will then send the 9bit data 0x107 and then the 9bit data 0xD0.
Then your receive code can use an int16 to hold the data, and if bit 8 is set, on the received data, 'know' that this is the MSB. Potentially it can then recover if it was expecting the LSB at this point.....
You need to always remember serial links can be 'good', but are never 'perfect'....
This is also why it is common not to send 'raw' data. If instead you send as hex, you can use a comma as a separator between values, and a line feed to mark the end of the data.
printf("%04lx\n",a);
sends the text 07DA<LF>
Which is much easier to work with.... |
|
|
mahdi70
Joined: 05 Jan 2016 Posts: 44
|
|
Posted: Tue Jan 05, 2016 3:39 am |
|
|
Ttelmah wrote: | Potentially yes.
Problem is, how it the receive end going to know where it is in the data?.
Since you are using all 256 possible values, you can't use any value as a flag to say 'this is the start' or 'this is the end' of the data. If anything gets lost/missed the code can never recover. This is where 9bit then comes in.
For instance:
Code: |
#use rs232(UART1, BAUD=9600, BITS=9, LONG_DATA)
//Then
unsigned int16 a=2000; //0x07D0
putc((int16)(make8(a,1) | 0x100)); //sets bit 8
putc((int16)(make8(a,0));
|
This will then send the 9bit data 0x107 and then the 9bit data 0xD0.
Then your receive code can use an int16 to hold the data, and if bit 8 is set, on the received data, 'know' that this is the MSB. Potentially it can then recover if it was expecting the LSB at this point.....
You need to always remember serial links can be 'good', but are never 'perfect'....
This is also why it is common not to send 'raw' data. If instead you send as hex, you can use a comma as a separator between values, and a line feed to mark the end of the data.
printf("%04lx\n",a);
sends the text 07DA<LF>
Which is much easier to work with.... |
tnx..im beginner in c lang...i dont know how write receiving part code....can i request an example from receiving part?I'm a little confused |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Jan 05, 2016 4:34 am |
|
|
mahdi70 wrote: | tnx..im beginner in c lang...i dont know how write receiving part code....can i request an example from receiving part?I'm a little confused |
There are code examples provided with the compiler, and 'C' functions available to convert from ASCII.
The other great advantage of using ASCII is you can see what's happening on a PC used as a terminal.
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Tue Jan 05, 2016 8:40 am |
|
|
As Mr T points out the PICs hardware UART is an 8 bit device which is the 'standard' these days, so as he shows you'll need to send 2 8 bit data to transfer your 16 bits of information. This is possibly the easiest way to do it as it use built in compiler functions however there is another way.
You could use a 'software' UART. This is in fact what CCS does when you use I/O pins that are not attached to the internal hardware UART peripheral. A software UART does allow for 'non-standard' data lengths typially found in 'specialist' systems as Mr T writes.
One I did almost 30 years ago was 352 bits in length Using a simple R-C clock I could get 15 miles(one way) communication.When the units were upgraded to xtal clocks I got 22 miles with zero faults.
As you're 'new' to PICs, C and the 'micro' World I do recommend Mr T's method unless you require a 'hackerproof' form of data transfer.
Jay |
|
|
mahdi70
Joined: 05 Jan 2016 Posts: 44
|
|
Posted: Tue Jan 05, 2016 10:56 am |
|
|
Ttelmah wrote: |
This will then send the 9bit data 0x107 and then the 9bit data 0xD0.
Then your receive code can use an int16 to hold the data, and if bit 8 is set, on the received data, 'know' that this is the MSB. Potentially it can then recover if it was expecting the LSB at this point.....
|
tnx for help me.....
Code: |
unsigned int16 data=0;
unsigned int8 a1=0,a2=0;
#INT_RDA
void rda_isr(void)
{
a1=getc();
a2=getc();
data=make16(a1,a2);
}
|
this is my code but above you mention if gets lost/missed the code not recover...my problem is how to set flag bit 9th to determine the start byte from end byte?
Sorry for the questions too much |
|
|
mahdi70
Joined: 05 Jan 2016 Posts: 44
|
|
Posted: Tue Jan 05, 2016 11:00 am |
|
|
Mike Walne wrote: | mahdi70 wrote: | tnx..im beginner in c lang...i dont know how write receiving part code....can i request an example from receiving part?I'm a little confused |
There are code examples provided with the compiler, and 'C' functions available to convert from ASCII.
The other great advantage of using ASCII is you can see what's happening on a PC used as a terminal.
Mike |
tnx for reply but now my problem is how to set bit 9th to separate start byte from end byte |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Tue Jan 05, 2016 1:37 pm |
|
|
from Mr T's code...
Code: | putc((int16)(make8(a,1) | 0x100)); //sets bit 8 |
0x100 is 0000 0001 0000 0000 in binary
That does set the 9th bit, which is really the 8th bit if you 'think like a computer' as computers always start at bit0.
Jay |
|
|
mahdi70
Joined: 05 Jan 2016 Posts: 44
|
|
Posted: Thu Jan 07, 2016 1:39 am |
|
|
temtronic wrote: | from Mr T's code...
putc((int16)(make8(a,1) | 0x100)); //sets bit 8
0x100 is 0000 0001 0000 0000 in binary
That does set the 9th bit, which is really the 8th bit if you 'think like a computer' as computers always start at bit0.
Jay |
solved........thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Jan 07, 2016 2:09 am |
|
|
temtronic wrote: | from Mr T's code...
putc((int16)(make8(a,1) | 0x100)); //sets bit 8
0x100 is 0000 0001 0000 0000 in binary
That does set the 9th bit, which is really the 8th bit if you 'think like a computer' as computers always start at bit0.
Jay |
I suspect I always think 'like a computer'. Backwards, upside down, forget the wrong things, and remember all sorts of rubbish.... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9228 Location: Greensville,Ontario
|
|
Posted: Thu Jan 07, 2016 6:36 am |
|
|
re: Backwards, upside down, forget the wrong things, and remember all sorts of rubbish..
Those are Windows attributes !!!
There's only 2 things we need...
1) PIC datasheets
2) CCS C manual
OK, a 3rd
To READ the manuals !!
Jay |
|
|
|
|
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
|