|
|
View previous topic :: View next topic |
Author |
Message |
flint
Joined: 05 Jun 2010 Posts: 24 Location: Nigeria
|
problem communicating between PIC18f4455 and PIC18f2550 |
Posted: Sun Dec 25, 2011 3:44 pm |
|
|
Hi everyone, please I tried communicating between PIC's. I simulated it and it worked but real hardware, when built on a breadboard doesn't work. Any help would be appreciated. Thanks.
Here's the code for the transmitter:
Code: |
#include <18F4455.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
//#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
//#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#use delay(clock=20000000)
#use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7,stream=Data)
char Dat='a', Det='b';
Void Transmit() // Transmit data
{
delay_ms(10);
fprintf(Data,"%c%c\r",Dat,Det); // Transmit Data frame
delay_ms(10); //delay
}
main()
{
do {
transmit();
}While(1);
}
|
Here's the code for the receiver:
Code: |
#include <18F2550.h>
#device ADC=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES PUT //No Power Up Timer
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=20000000)
#use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7)
long timeout;
char dataX[2];
void main()
{
while(1)
{
timeout=0;
while(!kbhit()&&(++timeout<50000)) //1/2 second
delay_us(10);
timeout++;
if(kbhit())
{
gets(dataX);
printf("%c%c\r",dataX[0],dataX[1]);
}
if(dataX[0]=='a')
{
output_high(PIN_C2);
}else{output_low(PIN_C2);}
}
} |
Last edited by flint on Mon Dec 26, 2011 2:19 pm; edited 3 times in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19559
|
|
Posted: Mon Dec 26, 2011 4:06 am |
|
|
First comment - size of dataX....
You are sending two data characters, but the receiver if asked to store a 'string', needs space for the terminating \0 as well, and also if there is any data corruption, there could be even more characters received.
You need to increase the size of dataX, and also consider some way of stopping if the string gets too large (look at input.c, where there is a replacement for gets, that allows you to limit the maximum string length).
Second, add 'ERRORS' to your RS232 definitions. This _must_ be present when using the hardware UART, unless _you_ handle overrun and framing errors yourself. Without this the receiving UART can get hung.
Third, your timeout code won't work. Remember unless you use brackets, only the line after the while gets executed, so the timeout increment never happens...
Then remember that if a timeout has taken place, the string will contain what was in it last time. Consider clearing dataX[0] before waiting, if you want the pin to reflect that a timeout has happened.
Best Wishes |
|
|
flint
Joined: 05 Jun 2010 Posts: 24 Location: Nigeria
|
|
Posted: Mon Dec 26, 2011 12:18 pm |
|
|
Ttelmah wrote: | First comment - size of dataX....
You are sending two data characters, but the receiver if asked to store a 'string', needs space for the terminating \0 as well, and also if there is any data corruption, there could be even more characters received.
You need to increase the size of dataX, and also consider some way of stopping if the string gets too large (look at input.c, where there is a replacement for gets, that allows you to limit the maximum string length).
Second, add 'ERRORS' to your RS232 definitions. This _must_ be present when using the hardware UART, unless _you_ handle overrun and framing errors yourself. Without this the receiving UART can get hung.
Third, your timeout code won't work. Remember unless you use brackets, only the line after the while gets executed, so the timeout increment never happens...
Then remember that if a timeout has taken place, the string will contain what was in it last time. Consider clearing dataX[0] before waiting, if you want the pin to reflect that a timeout has happened.
Best Wishes | Hi thanks for your prompt reply, have applied your first and second observations before posting this problem, yet it didn't work( it works on simulation). Could you please shed more light on how I can add "ERRORS" to the UART? It would be appreciated. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 26, 2011 12:26 pm |
|
|
Quote: |
Could you please shed more light on how I can add "ERRORS" to the UART?
|
Download the CCS manual. Look in the #use rs232() section. It explains
all the parameters, including the ERRORS parameter.
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf |
|
|
flint
Joined: 05 Jun 2010 Posts: 24 Location: Nigeria
|
|
Posted: Mon Dec 26, 2011 1:29 pm |
|
|
flint wrote: | Ttelmah wrote: | First comment - size of dataX....
You are sending two data characters, but the receiver if asked to store a 'string', needs space for the terminating \0 as well, and also if there is any data corruption, there could be even more characters received.
You need to increase the size of dataX, and also consider some way of stopping if the string gets too large (look at input.c, where there is a replacement for gets, that allows you to limit the maximum string length).
Second, add 'ERRORS' to your RS232 definitions. This _must_ be present when using the hardware UART, unless _you_ handle overrun and framing errors yourself. Without this the receiving UART can get hung.
Third, your timeout code won't work. Remember unless you use brackets, only the line after the while gets executed, so the timeout increment never happens...
Then remember that if a timeout has taken place, the string will contain what was in it last time. Consider clearing dataX[0] before waiting, if you want the pin to reflect that a timeout has happened.
Best Wishes | Hi thanks for your prompt reply, have applied your first and second observations before posting this problem, yet it didn't work( it works on simulation). Could you please shed more light on how I can add "ERRORS" to the UART? It would be appreciated. |
please how can i load the proteus image of the hardware so that it could be scrutinized to check were am missing it? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9250 Location: Greensville,Ontario
|
|
Posted: Mon Dec 26, 2011 1:36 pm |
|
|
quickly..
you save the image on a 3rd party image website, then in the message here embed the 'link' to the image.. |
|
|
flint
Joined: 05 Jun 2010 Posts: 24 Location: Nigeria
|
|
Posted: Mon Dec 26, 2011 5:47 pm |
|
|
Ttelmah wrote: | First comment - size of dataX....
You are sending two data characters, but the receiver if asked to store a 'string', needs space for the terminating \0 as well, and also if there is any data corruption, there could be even more characters received.
You need to increase the size of dataX, and also consider some way of stopping if the string gets too large (look at input.c, where there is a replacement for gets, that allows you to limit the maximum string length).
Second, add 'ERRORS' to your RS232 definitions. This _must_ be present when using the hardware UART, unless _you_ handle overrun and framing errors yourself. Without this the receiving UART can get hung.
Third, your timeout code won't work. Remember unless you use brackets, only the line after the while gets executed, so the timeout increment never happens...
Then remember that if a timeout has taken place, the string will contain what was in it last time. Consider clearing dataX[0] before waiting, if you want the pin to reflect that a timeout has happened.
Best Wishes |
Have applied all your observations, yet its not working. I used wires to connect the TX and RX pins of the sender (PIC18f4455) directly to the RX and TX pins of the receiver (PIC18f2550) respectively. Really need help urgently. Thanks.
code for Transmitter Code: |
#include <18F4455.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
//#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
//#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
//#use fixed_io(c_outputs=pin_C6) //speeds up port use
#use delay(clock=20000000)
#use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7,stream=Data)
char Dat='a', Det='b';
Void Transmit() // Transmit data
{
delay_ms(10);
fprintf(Data,"%c%c\r",Dat,Det); // Transmit Data frame to PIC18f2550
delay_ms(10); //delay
}
main()
{
while(1)
{
transmit();
}
}
|
Reciever
Code: |
#include <18F2550.h>
#device ADC=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES PUT //No Power Up Timer
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=20000000)
#use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7,stream=data)
char dataX[20];
int1 timeout_error;
void main()
{
while(1)
{
long timeout;
timeout_error=FALSE;
timeout=0;
while(!kbhit(data)&&(++timeout<20000)) // wait for char or timeout
{
delay_us(1);
timeout++;
}
if(kbhit(data))
{
gets(dataX);
}
else
{
timeout_error=TRUE;
}
printf("%c%c\r",dataX[0],dataX[1]);
if(dataX[0]=='a')
{
output_high(PIN_C0); // turn on LED connected to pin C0
}
else
{
output_low(PIN_C0); // turn off LED
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 26, 2011 6:32 pm |
|
|
Quote: | Have applied all your observations
|
Wrong. You still don't have ERRORS in the #use rs232() statements.
Quote: | I used wires to connect the TX and RX pins
|
Do you also have a ground connection between the two boards (or the
two PICs) ? You need one. |
|
|
flint
Joined: 05 Jun 2010 Posts: 24 Location: Nigeria
|
|
Posted: Mon Dec 26, 2011 6:38 pm |
|
|
PCM programmer wrote: | Quote: | Have applied all your observations
|
Wrong. You still don't have ERRORS in the #use rs232() statements.
Quote: | I used wires to connect the TX and RX pins
|
Do you also have a ground connection between the two boards (or the
two PICs) ? You need one. |
the two boards share a common VCC and GROUND. please i would appreciate it if you can edit the code and repost it, or send a working code. thanks |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Tue Dec 27, 2011 9:00 am |
|
|
Hi,
Until you've got the basic communications working between your boards, your code is way too complicated! On the transmit side, just send a single character repeatedly with a short delay between transmissions. On the receive side, grab the character with fgetc, and then use fputc to send it out to your PC so that you can see what is actually being received. Get rid of all the array stuff, and the character processing. Once you've got that working, you can expand the code to send multiple characters, process the received characters, etc.
One note, I basically never use the gets function. It's much safer to use getc and read the characters in one-by-one. The gets function will wait endlessly for the null terminator at the end of a string, and if it does not arrive, your code will hang! This function should only be used if you are absolutely sure you'll always be receiving a complete string!
The only way you are going to learn anything is to solve these problems yourself, the solution has been complete laid out for you, but you've got to do the work!
John |
|
|
flint
Joined: 05 Jun 2010 Posts: 24 Location: Nigeria
|
|
Posted: Sat Jan 14, 2012 7:41 pm |
|
|
ezflyr wrote: | Hi,
Until you've got the basic communications working between your boards, your code is way too complicated! On the transmit side, just send a single character repeatedly with a short delay between transmissions. On the receive side, grab the character with fgetc, and then use fputc to send it out to your PC so that you can see what is actually being received. Get rid of all the array stuff, and the character processing. Once you've got that working, you can expand the code to send multiple characters, process the received characters, etc.
One note, I basically never use the gets function. It's much safer to use getc and read the characters in one-by-one. The gets function will wait endlessly for the null terminator at the end of a string, and if it does not arrive, your code will hang! This function should only be used if you are absolutely sure you'll always be receiving a complete string!
The only way you are going to learn anything is to solve these problems yourself, the solution has been complete laid out for you, but you've got to do the work!
John |
Thanks everyone, i reduced the code to light just a single led, and its working fine, also, i included the "errors" in the uart. would work my way up!
You're appreciated. Big thanks to you all. |
|
|
|
|
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
|