|
|
View previous topic :: View next topic |
Author |
Message |
bittersweet
Joined: 23 Apr 2008 Posts: 22
|
problem with int32 type data transmission |
Posted: Thu May 01, 2008 7:41 am |
|
|
hi all;
i want to transmit int32 type data from pic to pic.
there're puts(),putc(),printf() RS232 comments but none of them is suitable.how can transmit and receive int32 type data?
thanks... |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Thu May 01, 2008 8:07 am |
|
|
RS232 only knows bytes. Any other data type must be converted to bytes to go through the UART. Look at make8() and make32(). _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
bittersweet
Joined: 23 Apr 2008 Posts: 22
|
|
Posted: Thu May 01, 2008 2:18 pm |
|
|
Hi again,
I achieved int 32 type data transmission with make8() make32() commands, but I have a new problem. when I transmit int32 type data, changeable values are being received.for ex. i transmit 6000 but i receive 1000.i couldn't synchronize transmitter and receiver.i don't know the length of delay after putc().
here's the codes:
Code: |
// transmitter code:
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)
#use rs232 (baud=2400, xmit=PIN_C6)
unsigned int16 tmrSayac= 0;
unsigned int32 ArabaVarZaman_ms = 0;
unsigned int32 ArabaYokZaman_ms = 0;
unsigned int1 arabaVar = true;
unsigned int arabaSayac = 0;
unsigned int16 KontrolSuresi = 0;
unsigned int32 OrtYokZaman=0;
unsigned int32 OrtVarZaman=0;
unsigned int32 TopVarZaman=0;
unsigned int32 TopYokZaman=0;
void main()
{
delay_ms(20);
enable_interrupts(int_RB);
enable_interrupts(int_timer1);
enable_interrupts(int_timer0);
enable_interrupts(global);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
setup_timer_0(RTCC_internal | RTCC_div_256);
set_timer0(0);
setup_timer_1(T1_internal | T1_div_by_8);
set_timer1(15535);
set_tris_b(0x10);
while(1)
{if (KontrolSuresi>=500)
{
delay_ms(35);
putc(make8(OrtVarZaman,0));
delay_ms(35);
putc(make8(OrtVarZaman,1));
delay_ms(35);
putc(make8(OrtVarZaman,2));
delay_ms(35);
putc(make8(OrtVarZaman,3));
delay_ms(35);
putc(arabaSayac);
delay_ms(35);
}
}
}
#int_RB
void kesmeAltFonk()
{
if(input(pin_b4))
{
arabaVar = true;
arabaSayac++;
ArabaYokZaman_ms = ((tmrSayac * 500) + (get_timer1()*8-15535) / 100); //ms cinsinden toplam geçen zaman
TopYokZaman=ArabaYokZaman_ms+TopYokZaman;
OrtYokZaman=TopYokZaman/arabaSayac;
set_timer1(15535);
tmrSayac = 0;
}
else
{
arabaVar = false;
ArabaVarZaman_ms = ((tmrSayac * 500) + (get_timer1()*8-15535) / 100);
TopVarZaman=ArabaVarZaman_ms+TopVarZaman;
OrtVarZaman=TopVarZaman/arabaSayac;
set_timer1(15535);
tmrSayac = 0;
}
}
#int_timer1
void tmr1Kesme()
{
tmrSayac++;
}
#int_timer0
void tmr0Kesme()
{
KontrolSuresi++;
if(KontrolSuresi>=600)
{
KontrolSuresi=0;
set_timer0(0);
OrtVarZaman=0;
OrtYokZaman=0;
arabaSayac=0;
}
}
|
Code: |
//Receiver code
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay (clock=4000000)
#use rs232 (baud=2400, rcv=PIN_C7)
#include <lcd.c>
unsigned int32 OrtVarZaman;
unsigned int v1;
unsigned int v2;
unsigned int v3;
unsigned int v4;
unsigned int arabasayisi;
void main()
{
delay_ms(20);
enable_interrupts(int_RB);
enable_interrupts(int_timer1);
enable_interrupts(int_timer0);
enable_interrupts(global);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
setup_timer_1(T1_DISABLED);
lcd_init();
while(1)
{
v1=getc();
v2=getc();
v3=getc();
v4=getc();
arabasayisi=getc();
OrtVarZaman=make32(v4,v3,v2,v1);
printf(lcd_putc,"\f OVZ=%ul",OrtVarZaman);
delay_ms(1500);
printf(lcd_putc,"\f Arabasayisi=%u",arabasayisi);
delay_ms(1500);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 01, 2008 2:35 pm |
|
|
See this thread which discusses problems with changing int16 or int32
global variables inside an interrupt service routine, and accessing them
as bytes outside of the interrupt routine. It also has solutions to it.
Follow the links.
http://www.ccsinfo.com/forum/viewtopic.php?t=32668
Code: | #use rs232 (baud=2400, xmit=PIN_C6)
#use rs232 (baud=2400, rcv=PIN_C7) |
These two lines are creating software UARTs. That's not as good as
a hardware UART. If an interrupt occurs in the middle of a byte
(transmitted or received), it will be corrupted.
Change both of those lines to this:
Code: | #use rs232 (baud=2400, xmit=PIN_C6, rcv=PIN_C7, ERRORS) |
Then you will have a hardware UART, that is also protected against
locking up if there is a receiver overrun error. |
|
|
bittersweet
Joined: 23 Apr 2008 Posts: 22
|
|
Posted: Thu May 01, 2008 4:20 pm |
|
|
i tried
Code: |
#use rs232 (baud=2400, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
|
but the problem couldn't been solved...if u can help me, i'll be satisfied... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 01, 2008 4:28 pm |
|
|
But what about this part:
See this thread which discusses problems with changing int16 or int32
global variables inside an interrupt service routine, and accessing them
as bytes outside of the interrupt routine. It also has solutions to it.
Follow the links.
http://www.ccsinfo.com/forum/viewtopic.php?t=32668 |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Thu May 01, 2008 5:28 pm |
|
|
You have a fundamental problem of synchronization. If you start off synchronized and if the receiver processes every character that is sent by the transmitter, then you will stay synchronized. But there is no way to get synchronized if you are ever out of synchronization. And your receiver, the way it is written, cannot keep up with all the data that is being transmitted, because of the LCD stuff, so it will always lose synchronization.
Why do you have delay_ms(35); after every character in the transmitter? The receiver is perfectly capable of receiving 5 bytes at full speed, the way you have written the receiver code. If you want to have a delay, put a single delay after all 5 bytes have been sent. That is when your receiver takes more time. Currently there is a 70 msec. total delay between the last byte of one packet and the first byte of the next packet. This is clearly not long enough if you want to allow the receiver to receive everything. Your receiver code has at least 3000 msec. of delay that I can see. During that time, your transmitter has sent many many packets that you have missed. It is no wonder that you are losing synchronization.
Here is what I suggest: You can keep the transmitter the way it is, except you can eliminate the unnecessary delay_ms(35), and just put a single delay_ms(80) after the last byte. Your are going to miss lots of data in the receiver. That is just the way it goes. But after the receiver processes a packet, it should re-acquire synchronization by reading bytes and measuring the time between bytes received. Throw away all bytes you receive until you find two bytes that are more than 60 msec. apart. Then take the second of those two bytes as v1 and keep going from there.
Robert Scott
Real-Time Specialties |
|
|
bittersweet
Joined: 23 Apr 2008 Posts: 22
|
|
Posted: Fri May 02, 2008 2:13 am |
|
|
first, i eliminated delay_ms(35) and put a single delay_ms(80) after sending 5 bytes...but the problem is still going on.also, i couldn't understand
Quote: |
Throw away all bytes you receive until you find two bytes that are more than 60 msec. apart. Then take the second of those two bytes as v1 and keep going from there.
|
when i simulate the program,i sent OVZ=4000 and ArabaSayisi=1.
but i received first OVZ=2440 and ArabaSayisi=1, then OVZ=256 and ArabaSayisi=192...i have to see only one OVZ and ArabaSayisi... |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Fri May 02, 2008 9:00 am |
|
|
bittersweet wrote: | .. i couldn't understand
Quote: |
Throw away all bytes you receive until you find two bytes that are more than 60 msec. apart. Then take the second of those two bytes as v1 and keep going from there.
|
|
If you want to re-acquire synchronization after missing a lot of characters, then you have to detect that 80 msec. pause somehow. You must use a timer or some other means to measure the time between the arrival of characters at the receiver. Then you will know when you are seeing the 80 msec. gap, and then you can start receiving the next 5-byte packet.
Again, by the time your receiver is ready to read another 5 bytes, many many bytes have already come and have been ignored because you weren't reading while you were writing to the LCD. So the next byte that the receiver reads is probably not going to be the beginning of a 5-byte packet. That is why you need to discard characters in the receiver code until you find the first character of a 5-byte packet, and the only way to do that is by measuring timing, unless you totally re-define how you are sending data so that each packet starts with a unique byte that cannot appear anywhere in the data.
Robert Scott
Real-Time Specialties |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri May 02, 2008 9:07 am |
|
|
For example the NEMA strings that most GPS units send always start with $, and that is the only place $ is used. So the receiving software can start by throwing away characters until it finds the $ and then it knows it is at the start of a new GPS message. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
|
|
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
|