|
|
View previous topic :: View next topic |
Author |
Message |
nasbyc
Joined: 27 Apr 2009 Posts: 50
|
rs485 communication |
Posted: Thu Nov 01, 2012 8:24 am |
|
|
Hi, I used one of the programs posted in the forum and modified it. I tried with 1 master and 2 slave pic. It worked when I try to send data from master to the slave. The problem is to tell the master the program is complete.
Here is the master program:
Code: |
#include <18F2480.h>
#use delay(clock=20000000)
#fuses hs, nowdt, nolvp, noprotect
#use rs232(baud = 9600, xmit = PIN_C6, rcv = PIN_C7, enable = PIN_A1, Errors, STREAM=COM_A)
#byte RCREG = 0x1A
#include <stdlib.h>
#include <string.h>
#byte portB=6
#byte portC=7
#define RX_SIZE 10 // RS232 buffer for serial reception
#define RCV_OFF() {setup_uart(FALSE);}
int RX_Command_Ready; // TRUE If a receive packet is ready
char RxBuffer[RX_SIZE]; // RS232 serial RX buffer
int Index = 0; // RS232 RX data IN index
#INT_RDA // Interrupt driven RS232 routine
void rs232_isr(void)
{
char temp; // local data storage
temp = fgetc(COM_A); // get rx data
// If we got a '#', then the command is beginning.
if (temp == '#')
{
Index = 0;
RxBuffer[Index] = temp;
Index++;
return;
}
// If we got a 'A', then the command is completed.
if (temp == 65)
{
temp = '\0';
RxBuffer[Index] = temp;
RX_Command_Ready = TRUE;
return;
}
// Save the character to the receive buffer.
RxBuffer[Index]=temp;
// Check for buffer overflow.
if ( Index >= (RX_SIZE - 1) )
Index = 0;
else
Index++;
}
void main()
{
char motor[7] = "#5128A";
char strmotor[3] = "CD";
char status_motor[3];
int8 *motorpointer;
int i,s,iresult;
iresult = 1;
printf("\nProgram started...\r\n");
motorpointer = motor;
for(i=0; i < 7;i++)
{
fputc(*motorpointer,COM_A);
++motorpointer;
}
do{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
//fprintf(COM_A,"\nReady to receive data");
while(RX_Command_Ready == TRUE)
{
disable_interrupts(INT_RDA);
fprintf(COM_A,"\n");
//fprintf(COM_A,"\nData received");
for(s=0;RxBuffer[s]!='\0';s++)
{
fprintf(COM_A,"RxBuffer[%d] = %c \n",s,RxBuffer[s]);
}
status_motor[0] = RxBuffer[1];
status_motor[1] = RxBuffer[2];
status_motor[2] = '\0';
iresult = strcmp(status_motor,strmotor);
fprintf(COM_A,"status_motor = %c%c iresult = %d \n",status_motor[0],status_motor[1],iresult);
if(iresult == 0)
{
fprintf(COM_A,"Next sequence please\n");
RX_Command_Ready = FALSE;
break;
}
else
{
fprintf(COM_A,"WRONG!!!!\n");
}
}
}while(1);
}
|
slave
Code: |
#include <16f88.h>
#fuses HS,PUT,NODEBUG,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,xmit=PIN_B5,rcv=PIN_B2,enable = PIN_A1 ,stream = COM_C)
#include <stdlib.h>
#include <string.h>
#byte portB=6
#byte portC=7
int RX_Command_Ready; // TRUE If a receive packet is ready
#define RX_SIZE 10 // RS232 buffer for serial reception
#define AN0 0X0E
#define RCV_OFF() {setup_uart(FALSE);}
char RxBuffer[RX_SIZE]; // RS232 serial RX buffer
int Index = 0; // RS232 RX data IN index
#INT_RDA // Interrupt driven RS232 routine
void rs232_isr(void)
{
char temp; // local data storage
temp = fgetc(COM_C); // get rx data
// If we got a '#', then the command is beginning.
if (temp == '#')
{
Index = 0;
RxBuffer[Index] = temp;
Index++;
return;
}
// If we got a 'A', then the command is completed.
if (temp == 65)
{
temp = '\0';
RxBuffer[Index] = temp;
RX_Command_Ready = TRUE;
return;
}
// Save the character to the receive buffer.
RxBuffer[Index]=temp;
// Check for buffer overflow.
if ( Index >= (RX_SIZE - 1) )
Index = 0;
else
Index++;
}
#byte RCREG = 0x1A
void clear_usart_receiver(void);void MotorFish_CW(); void MotorFish_CCW(); void MotorFish_Stop (); void RCV_ON(void);
void main(void)
{
int8 strnum1;
unsigned int8 Desired_Angle;
int8 idslave = 5;
char slavenum[2];
char angledata[4];
int s,m;
char motorstatus[5] = "#CDA";
int8 *motorcomplete;
//output_high(PIN_A2);
//delay_ms(1000);
//output_low(PIN_A2);
//delay_ms(1000);
do
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(RX_Command_Ready == TRUE)
{
disable_interrupts(INT_RDA);
fprintf(COM_C,"\n");
for(s=0;RxBuffer[s]!='\0';s++)
{
fprintf(COM_C,"RxBuffer[%d] = %c \n",s,RxBuffer[s]);
}
printf("\n");
slavenum[0] = RxBuffer[1];
slavenum[1] = '\0';
angledata[0] = RxBuffer[2];
angledata[1] = RxBuffer[3];
angledata[2] = RxBuffer[4];
angledata[3] = '\0';
strnum1 = atoi(slavenum);
Desired_Angle = atoi(angledata);
if(strnum1 == idslave)
{
output_high(PIN_A2);
delay_ms(1000);
output_low(PIN_A2);
delay_ms(1000);
motorcomplete = motorstatus;
for(m=0; m < 5;m++)
{
fputc(*motorcomplete,COM_C);//to tell master the prog complete
++motorcomplete;
}
RX_Command_Ready = FALSE;
break;
//enable_interrupts(INT_RDA);
}
}
}while(1);
}
|
the result from master
Code: |
Program started...
#5128A
|
the result from slave
Code: |
RxBuffer[0] = #
RxBuffer[1] = 5
RxBuffer[2] = 1
RxBuffer[3] = 2
RxBuffer[4] = 8
#CDA
|
It can be seen that in master, RX_Command_Ready == TRUE never occurs. So I try to display what data is actually in RxBuffer:
Code: |
Program started...
#5128A
RxBuffer[0] =
RxBuffer[1] =
RxBuffer[2] =
RxBuffer[3] =
RxBuffer[4] =
RxBuffer[5] =
RxBuffer[6] =
RxBuffer[7] =
RxBuffer[8] =
RxBuffer[9] =
RxBuffer[10] =
RxBuffer[11] = #
RxBuffer[12] = 5
RxBuffer[13] = 1
RxBuffer[14] = 2
RxBuffer[15] = 8
RxBuffer[16] = A
RxBuffer[0] =
RxBuffer[1] =
|
So the error is that the master never receive the data send by the slave and RxBuffer is filled with the data send by the master previously. How can I clear the buffer after I send data and make it ready to receive a new data ? |
|
|
nasbyc
Joined: 27 Apr 2009 Posts: 50
|
|
Posted: Fri Nov 02, 2012 4:56 am |
|
|
Anyone?
I tried setup_uart(False) and setup_uart(True) before and after sending data. however no data been sending out. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Fri Nov 02, 2012 5:39 am |
|
|
The buffer _will_ be overwritten as soon as data comes back.
There are several things that are basically 'wrong', but it is also not very obvious what you are doing. Gven your buffer names are the same in the master and the slave, which are you looking at?.
No ERRORS in slave.
Your slave code does send the transmitted data back:
Code: |
for(s=0;RxBuffer[s]!='\0';s++)
{
fprintf(COM_C,"RxBuffer[%d] = %c \n",s,RxBuffer[s]);
}
|
So this data will be in the buffer. It doesn't get there any other way.
Your buffer size in is only 10bytes, but you print 17 bytes.....
You have statements like:
Code: |
#byte portB=6
#byte portC=7
|
Which are fundamentally 'wrong'. These are the addresses for a PIC16, you are using a PIC18.....
You are also mixing using putc to a stream, and and without a stream name. With only one stream these go to the same place.
I'm afraid it is not plain from what you post, what you want to happen, what you think will happen, what is actually happening, etc. etc.. The code is a mess. You have obviously taken part of a routine, and not correctly patched it. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Fri Nov 02, 2012 8:03 am |
|
|
Looking at this again, look at some of the threads about RS485. Ideally you want to disable the RX buffer when you transmit, or the master will receive every byte it sends. You also then want to bias the data output of the receive buffer to +5v, so when the data is being sent, the receive part sees the line as idle. This is done by wiring the two enable pins together, and to the CPU enable pin.
I don't think you are turning the bus round correctly.
Best Wishes |
|
|
nasbyc
Joined: 27 Apr 2009 Posts: 50
|
|
Posted: Fri Nov 02, 2012 10:39 am |
|
|
I'm using max481 as a driver. I also had wired re and de pin together to pic. Is it necessary to turn on /off receiver when transmitting data ? I successfully transmit #1128A from master to slave. I know this because the led attached to the slave on/off accordingly. The problem is when to tell to master that the slave already received the data. So that the master can send another #5127A (for example with same length) to id another slave pic. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Fri Nov 02, 2012 3:16 pm |
|
|
You are turning the receiver off if you operate both RE and DE. But you do need a pull up resistor on the RX input of the PIC, so it doesn't see garbage when the receiver is turned off. Something like 10KR.
Best Wishes |
|
|
|
|
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
|