|
|
View previous topic :: View next topic |
Author |
Message |
funmix
Joined: 27 Mar 2007 Posts: 33
|
PIC to PIC via 232 |
Posted: Tue Mar 27, 2007 11:26 am |
|
|
Hi all,
I am new in ccs. I am trying to communicate between two PICs with UART.
So, the problem i would like to:
1. PIC master send a character 't'
2. Slave receive the character 't'; blink 1 time the Port B_1 LED.
3. Slave will send back character 's' to master once they finish blinking.
4. master check the character 's', if 's' is received, blink master PORT B_1 LED.
master.c
Code: |
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
#define BAUD_RATE 19200
#define FREQ_OSC 20000000
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//RB_1 -- Purple
//RB_2 -- Yellow
#byte PIR1 = 0x0c
#byte SPBRG = 0x99
#byte RCSTA = 0x18
#byte TXREG = 0x19
#byte RCREG = 0x1A
#byte TXSTA = 0x98
#bit TXIF = PIR1.4
#bit RCIF = PIR1.5
#bit CREN = RCSTA.4
#include <stdio.h>
//---------------------------------------
//Receive data interrupt
//------------------------------------
//------------------------
// Wait for the hardware UART's transmitter
// to become ready and then send the specified
// character.
void my_putc(char c)
{
while(!TXIF);
TXREG = c;
}
//------------------------
// Wait for character to be available from the
// hardware UART's receiver and then return it.
// If there is an overrun error, then clear it.
char my_getc(void)
{
int temp;
int retval;
while(!RCIF);
temp = RCSTA;
retval = RCREG;
if(bit_test(temp, 1))
{
CREN = 0;
CREN = 1;
}
return(retval);
}
//-------------------------
void init_uart(void)
{
SPBRG = (FREQ_OSC / (BAUD_RATE * 16)) -1;
TXSTA = 0x26;
RCSTA = 0x90;
}
#int_rda
void rda_isr(void)
{
char c;
c = my_getc();
if(c=='s')
{
output_high(PIN_B1);
delay_ms(5000);
output_low(PIN_B1);
delay_ms(5000);
}
//if(c=='r')
//{
//output_high(PIN_B2);
//delay_ms(5000);
//output_low(PIN_B2);
//delay_ms(5000);
//}
}
//================================
void main()
{
init_uart();
my_putc('t');
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1);
}
|
slave.c
Code: |
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <stdio.h>
#include <slave_send.c>
//======================================slave
void main()
{
int i;char rec;
output_low(PIN_B1);
output_low(PIN_B2);
while(1)
{
wait_master(rec);
check_char(rec);
putc('s');
wait_master(rec);
check_char(rec);
//putc('r');
//wait_master(rec);
//check_char(rec);
}
}
|
slave_send.c
Code: |
void wait_master(char rec)
{
if (kbhit())
{
rec=getc();
}
}
void check_char(char rec)
{
if(rec=='t')
{
output_high(PIN_B1);//RB_1 -- Orange
delay_ms(5000);
output_low(PIN_B1);
delay_ms(5000);
}
//if(rec=='y')
//{
//output_high(PIN_B2);//RB_1 -- Orange
//delay_ms(5000);
//output_low(PIN_B2);
//delay_ms(5000);
}
}
|
For your information, my hardware connection got no problem. As i tested sending and echo a character with PC to PIC. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 27, 2007 11:51 am |
|
|
There are several things in your code that need to be improved.
For example, you have a #use rs232() statement, but then you
substitute your own functions for all the CCS functions. Why ?
In the routine below, you duplicate the functionality of getc(). The CCS
getc() function already waits for kbhit. It's part of the function.
Code: | void wait_master(char rec)
{
if (kbhit())
{
rec=getc();
}
} |
In other words, your function above could be replaced by this single
line of code:
There's another problem with your routine above. You have these
two lines of code in your program, where it's clear that you expect
wait_master() to update the 'rec' value. But it won't do that.
Code: | wait_master(rec);
check_char(rec); |
To get a value back from a function you need to return it (at least, that's
the easiest way to do it). You need to re-write the wait_master()
function so it returns a value. This is done with a 'return' statement.
Then your code would look like this:
Code: |
rec = wait_master();
check_char(rec);
|
Or, the better way is to get rid of the wait_master() function completely,
as I said above, and do this:
Code: | rec = getc();
check_char(rec); |
Your code might have other problems. But at least these things should
be fixed. |
|
|
funmix
Joined: 27 Mar 2007 Posts: 33
|
|
Posted: Tue Mar 27, 2007 8:58 pm |
|
|
here is my modified
master.c
Code: |
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
#define BAUD_RATE 19200
#define FREQ_OSC 20000000
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//RB_1 -- Purple
//RB_2 -- Yellow
#byte PIR1 = 0x0c
#byte SPBRG = 0x99
#byte RCSTA = 0x18
#byte TXREG = 0x19
#byte RCREG = 0x1A
#byte TXSTA = 0x98
#bit TXIF = PIR1.4
#bit RCIF = PIR1.5
#bit CREN = RCSTA.4
#include <stdio.h>
#include <master_check.c>
//-------------------------
void init_uart(void)
{
SPBRG = (FREQ_OSC / (BAUD_RATE * 16)) -1;
TXSTA = 0x26;
RCSTA = 0x90;
}
//================================
void main()
{
char rec;
init_uart();
putc('t');
delay_ms(6000);
rec=getc();
check_char();
putc('y');
delay_ms(6000);
rec=getc();
check_char();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1);
}
|
master_send.c
Code: |
void check_char(void)
{
char rec;
if(rec=='r')
{
output_high(PIN_B1);//RB_1 -- Orange
delay_ms(5000);
output_low(PIN_B1);
delay_ms(5000);
}
if(rec=='s')
{
output_high(PIN_B2);//RB_1 -- Orange
delay_ms(5000);
output_low(PIN_B2);
delay_ms(5000);
}
}
|
slave.c
Code: |
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <stdio.h>
#include <slave_send.c>
//======================================slave
void main()
{
int i;char rec;
output_low(PIN_B1);
output_low(PIN_B2);
while(1)
{
rec=getc();
check_char();
delay_ms(6000);
putc('s');
rec=getc();
check_char();
putc('r');
delay_ms(6000);
}
}
|
slave_send.c
Code: |
void check_char(void)
{
char rec;
if(rec=='t')
{
output_high(PIN_B1);//RB_1 -- Orange
delay_ms(5000);
output_low(PIN_B1);
delay_ms(5000);
}
if(rec=='y')
{
output_high(PIN_B2);//RB_1 -- Orange
delay_ms(5000);
output_low(PIN_B2);
delay_ms(5000);
}
}
|
I am just doing vice-versa communication. I could not figure out why my code doesn't give me correct result.
Kindly please help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 27, 2007 9:10 pm |
|
|
Quote: | #include <18F4520.h>
#byte PIR1 = 0x0c
#byte SPBRG = 0x99
#byte RCSTA = 0x18
#byte TXREG = 0x19
#byte RCREG = 0x1A
#byte TXSTA = 0x98
#bit TXIF = PIR1.4
#bit RCIF = PIR1.5
#bit CREN = RCSTA
//-------------------------
void init_uart(void)
{
SPBRG = (FREQ_OSC / (BAUD_RATE * 16)) -1;
TXSTA = 0x26;
RCSTA = 0x90;
}
|
This demonstrates a very good reason why you should not use your
own routines. All of the register addresses listed above are for the
16F series PICs. The 18F series have different addresses.
I suggest that you use the CCS library code. Use the #use rs232()
statement, and use the built-in CCS UART functions. Most of your
problems will then go away. |
|
|
funmix
Joined: 27 Mar 2007 Posts: 33
|
|
Posted: Tue Mar 27, 2007 11:01 pm |
|
|
Thanks for advice. Another things is, how to interrupt once the master microcontroller receive data from slave? |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
|
|
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
|