|
|
View previous topic :: View next topic |
Author |
Message |
bestbuylvr
Joined: 31 Jan 2007 Posts: 27 Location: Pittsburgh, PA
|
Serial communications between two PIC's |
Posted: Mon Mar 26, 2007 12:38 pm |
|
|
I have a bit of really simple code I wrote up here trying to just make 2 PIC's talk back and forth to each other. I never really got to making any indicators (LED's) on the master 1st PIC because I can't really get the second to read the data sent from the first. I will post the code of both, and if anyone has any suggestions, I would appreciate any help.
PIC 1:
Code: | #include <18f452.h>
#include <protoalone_1.h>
#include <utility_1.c>
#include <stdlib.h>
#include <INPUT.C>
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
main(){
while(1){
int a, b;
delay_ms(2000);
a=5;
printf("%d", a);
delay_ms(5);
b = get_int();
delay_ms(10000);
}
}
|
PIC 2:
Code: | #include <18f4520.h>
#include <protoalone_1.h>
#include <utility_1.c>
#include <stdlib.h>
#include <INPUT.C>
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
main(){
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
output_bit(PIN_D0,0);
output_bit(PIN_D1,0);
delay_ms(200);
output_bit(PIN_D0,1);
output_bit(PIN_D1,1);
delay_ms(200);
while(TRUE){
int a, b;
a = get_int();
if (a==5) {
output_bit(PIN_D1,1);
output_bit(PIN_D0,0);
}
else {
output_bit(PIN_D0,0);
output_bit(PIN_D1,0);
}
delay_ms(5);
printf("%d", a);
delay_ms(10000);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 26, 2007 1:14 pm |
|
|
Look at the source code for the get_int() function. It's in this file:
c:\program files\picc\drivers\input.c
get_int() calls the get_string() function. That function is looking for
a carriage return character to indicate the end of the string.
You're not sending one with your printf() statements. You need
to add \n after the %d, to do this.
Another thing is that you have these huge delays in your loops.
Also, you have two PICs that are not synchronized to each other.
So one of them could be in the middle of a huge 10 second delay
while the other one is sending characters. The UART's receive fifo
is only 2 characters deep. If it's full and 3rd character comes in,
then the UART will detect an "overrun error" and it will lock up.
To clear this situation automatically, you should add the ERRORS
parameter to your #use rs232() statements. (This only works
with a hardware UART). You should add ERRORS to all your
programs. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Mon Mar 26, 2007 1:20 pm |
|
|
You are declaring your variables, a & b, inside of your while() loop. Don't do this. Declare them at the top of your main() if you want them to be Local variables or declare them close to the top of the file if you want them to be Global variables.
I would use the #int_RA interrupt to receive the character. I would use the interrupt to catch the character, stuff it in a variable and then check that variable in the main() body. There are multiple examples of RS232 communications throughout the forum.
Ronald |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 26, 2007 1:29 pm |
|
|
You mean #int_rda. |
|
|
bestbuylvr
Joined: 31 Jan 2007 Posts: 27 Location: Pittsburgh, PA
|
|
Posted: Mon Mar 26, 2007 2:16 pm |
|
|
Thank you guys for the help, I got the serial to work using the carriage return and declaring the variables in the right spot (dumb mistake, thank you) and I will try using the interrupt on it shortly. Again, thank you for your help, and hopefully I won't need too much more help with this one. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Mon Mar 26, 2007 4:09 pm |
|
|
Quote: | You mean #int_rda. |
Yah, that one. I think the 'd' must have fallen off my keyboard this morning but it's back now. |
|
|
bestbuylvr
Joined: 31 Jan 2007 Posts: 27 Location: Pittsburgh, PA
|
|
Posted: Wed Mar 28, 2007 6:54 am |
|
|
OK, so I programmed the interrupt as you sugested and moved the variable declarations. I now have the following programs written trying to talk serially. I am only trying for one way at the moment, and when I send the number 5, I get the response as if I am sending something else (a red LED). When I use the get_int function in the interrupt, I get a green LED, which is what happens when a=5, but I get nothing if the wrong value is detected. I assume the "BYTE a" line gets the incoming number, correct?
Here is code 1 sending the value 5:
Code: | #include <18f452.h>
#include <protoalone_1.h>
#include <utility_1.c>
#include <stdlib.h>
#include <INPUT.C>
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
main(){
int8 a, b;
delay_ms(2000);
while(1){
a=5;
printf("%d\n\r", a);
delay_ms(5);
}
} |
Here is code 2 recieving the value and using the intterupt:
Code: | #include <18f452.h>
#include <protoalone_1.h>
#include <utility_1.c>
#include <stdlib.h>
#include <INPUT.C>
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)
#INT_RDA
void rda_interrupt () {
BYTE a;
// a = get_int(); //WORKS WITH CORRECT VALUE INPUT ONLY
if (a==5) {
output_bit(PIN_D1,1);
output_bit(PIN_D0,0);
}
else if (a!=5) {
output_bit(PIN_D1,0);
output_bit(PIN_D0,1);
}
else {
output_bit(PIN_D0,0);
output_bit(PIN_D1,0);
}
}
void main () {
int a, b;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
output_bit(PIN_D0,0);
output_bit(PIN_D1,0);
delay_ms(200);
output_bit(PIN_D0,1);
output_bit(PIN_D1,1);
delay_ms(200);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
while(TRUE){
printf("%d \n\r", a);
delay_ms(100);
delay_ms(100);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 28, 2007 12:24 pm |
|
|
Quote: | printf("%d\n\r", a); |
You're sending a linefeed and a carriage return. get_int() calls the
get_string() function. get_string() is looking for a carriage return to
end the line. Change the code to this:
|
|
|
bestbuylvr
Joined: 31 Jan 2007 Posts: 27 Location: Pittsburgh, PA
|
|
Posted: Thu Mar 29, 2007 7:35 am |
|
|
Thank you for clearing that up, the program now works as it was intended. I now am trying to use an RF transmitter over the serial connection between the PIC's and the program is interrupting on the garbage interference and getting stuck. I programmed the kbhit() function into the program, but am still not having any luck. Is there by any chance a function that only reads an int directly before a \r is recieved? If not, do you know any other way to get around this? Thanks you for helping. Here is the code I am using now in the second PIC, the first remains the same:
Code: | #include <18f452.h>
#include <protoalone_1.h>
#include <utility_1.c>
#include <stdlib.h>
#include <INPUT.C>
#use rs232(baud=2400,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)
#define KEYHIT_DELAY 500 // in milliseconds
char timed_get_int() {
long timeout;
int retval;
timeout=0;
while(!kbhit() && (++timeout< (KEYHIT_DELAY*100)))
delay_us(10);
if(kbhit())
retval = get_int();
else
retval = 0;
return(retval);
}
#INT_RDA
void rda_interrupt () {
BYTE a;
a = timed_get_int(); //WORKS WITH CORRECT VALUE INPUT ONLY
if (a==5) {
output_bit(PIN_D1,1);
output_bit(PIN_D0,0);
}
else if (a!=5) {
output_bit(PIN_D1,0);
output_bit(PIN_D0,1);
}
else {
output_bit(PIN_D0,0);
output_bit(PIN_D1,0);
}
}
void main () {
int a, b;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
output_bit(PIN_D0,0);
output_bit(PIN_D1,0);
delay_ms(200);
output_bit(PIN_D0,1);
output_bit(PIN_D1,1);
delay_ms(200);
delay_ms(1000);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
while(TRUE){
printf("%d \n\r", a);
delay_ms(100);
delay_ms(100);
}
}
|
|
|
|
|
|
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
|