|
|
View previous topic :: View next topic |
Author |
Message |
PaoloMuchetti
Joined: 12 Apr 2007 Posts: 2
|
Problem with Asynchronous Reception (RS485) on PIC18f2520 |
Posted: Thu Apr 12, 2007 4:01 am |
|
|
I have two Device One Trasmitter and One Rreceiver:
Trasmitter (only, Not reception)
PIC18f6520, 8Mhz, 9600, NOParity.
It sends 3 byte(0x44, 0x33, 0x22) every 5 second ones, Asynchronous Mode with Address Detect Enable
Receiver (only, Not Trasmission)
PIC18f2520, 8Mhz, 9600, NOParity, Asynchronous Mode with Address Detect Enable
The Project is compile with CCS 4.032.
The Receiver has a problem, first message not receives correctly, second message is OK, third message not receives correctly and so on.
When Receiver not receives correctly, it not recognizes the Address Bit High. I see the comunication with oscilloscope and
Trasmitter sends 3 byte correctly with first byte with 9 bit high but Receiver not always recognizes the Address Bit.
Code: |
#use delay(clock=8000000,RESTART_WDT)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed oscillator
#FUSES NOPROTECT //Code not protected from reading
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV27 //Brownout reset at 2.7V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //NO Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use rs232(baud=9600, XMIT=PIN_C6,RCV=PIN_C7)
void init485 ( void )
{
BIT_SET (RCSTA1, ADDEN); // Enable address detect enable bit
BIT_SET (RCSTA1, RX9); // Set 9 bit receive
s0_Addressed = NO ;
s0_index = 0 ;
DIR = 0;
}
void initDevice (void)
{
set_tris_a(IO_PORTA);
set_tris_b(IO_PORTB);
set_tris_c(IO_PORTC);
setup_adc(ADC_OFF);
setup_wdt(WDT_OFF);
setup_ccp1(CCP_OFF);
setup_ccp2(CCP_OFF);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
BIT_CLEAR (INTCON2,7);
}
#INT_RDA
void Rs485Interrupt(void)
{
rxVal = RCREG1 ;
if ( !( RCSTA1 & 0x06 ) ) // Then if no errors
{
rxData_485 [s0_index] = rxVal ;
s0_index ++ ;
// Device Address Matching
if ( s0_Addressed == YES )
{
if (s0_index == 3)
{
s0_Addressed = NO ;
s0_index = 0 ;
BIT_SET (RCSTA1, ADDEN); // Enable address detect enable bit
}
}
else if ( (RCSTA1 & BIT0) )
{
s0_Addressed = YES;
bit_clear( RCSTA1, ADDEN ); // Clear Address Detect
}
else
{
s0_Addressed = NO ;
s0_index = 0 ;
BIT_SET (RCSTA1, ADDEN); // Enable address detect enable bit
}
}
else
{
bit_clear( RCSTA1, CREN ); // Clear any errors
rxVal = RCREG1;
bit_set( RCSTA1, CREN ); // Enable receiver.
BIT_SET (RCSTA1, ADDEN); // Enable address detect enable bit
}
}
void main()
{
// Setup device
initDevice ();
init485 ();
// End Setup
BEEP_Single(750);
// Start main loop
while(1)
{
;
}
}
|
Please Help me...
Thank you very mutch
|
|
|
funmix
Joined: 27 Mar 2007 Posts: 33
|
|
Posted: Wed Apr 18, 2007 8:08 pm |
|
|
The code you posted is for slave part? Can we see the master part? |
|
|
mikebroom Guest
|
RS485 comms |
Posted: Thu Apr 19, 2007 12:58 am |
|
|
I had problems with RS485 comms with an 18F1320. It would sometimes work, and other times not. I know it may not be the case if you are only connecting 2 PICs together. My comms was from PIC to PC, and PC to PIC using a serial terminal. In order for communications to work correctly I had to set the BITS=8 in the #use RS485 config. |
|
|
funmix
Joined: 27 Mar 2007 Posts: 33
|
|
Posted: Thu Apr 19, 2007 1:50 am |
|
|
mikebroom, post up your code. as we can refer |
|
|
Guest
|
|
Posted: Thu Apr 19, 2007 2:43 am |
|
|
Code: | #ifdef SW_UART
#use rs232(baud=9600,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=9,FORCE_SW)
#else
#use rs232(baud=9600,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=8)
#endif
//////////////////////////////////////////////////////////////////////
//Before Main
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
/*********************************************************************
* Function: void serial_isr(void)
*
* PreCondition: RDA interrupt has been enabled
*
* Input: None
*
*
* Output: Places received character into next buffer position
* and increments buffer pointer
*
*
* Side Effects: none
*
********************************************************************/
#int_rda
void serial_isr(void)
{
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
{
next_in=t; // Buffer full !!
}
}
//////////////////////////////////////////////////////////////////////
/*********************************************************************
* Macro: bkbhit ()
*
*
* PreCondition: None
*
* Input: Head and tail pointers for Rx buffer
*
*
* Output: Returns true if there is data in Rx buffer
*
* Side Effects: None
*
********************************************************************/
#define bkbhit (next_in!=next_out)
//////////////////////////////////////////////////////////////////////
// Setup of serial port either S/W control or Hardware
// within main
//////////////////////////////////////////////////////////////////////
BaudRate = read_eeprom(BAUDRATE); // Read stored baudrate and set accordingly. If not set default is 9600
switch (BaudRate)
{
#ifdef SW_UART
case 1:
#use rs232(baud=1200,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=9,FORCE_SW,FLOAT_HIGH)
break;
case 2:
#use rs232(baud=2400,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=9,FORCE_SW,FLOAT_HIGH)
break;
case 3:
#use rs232(baud=4800,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=9,FORCE_SW,FLOAT_HIGH)
break;
case 4:
#use rs232(baud=9600,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=9,FORCE_SW,FLOAT_HIGH)
break;
case 5:
#use rs232(baud=19200,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=9,FORCE_SW,FLOAT_HIGH)
break;
default:
#use rs232(baud=9600,parity=N,xmit=PIN_B1,rcv=PIN_B4,bits=9,FORCE_SW,FLOAT_HIGH)
BaudRate = 4;
break;
#else
case 1:
setup_uart(1200);
break;
case 2:
setup_uart(2400);
break;
case 3:
setup_uart(4800);
break;
case 4:
setup_uart(9600);
break;
case 5:
setup_uart(19200);
break;
default:
setup_uart(9600);
BaudRate = 4;
break;
#endif
}
#ifndef SW_UART
setup_uart(true);
#endif
//////////////////////////////////////////////////////////////////////
// Within Main code Loop
//////////////////////////////////////////////////////////////////////
#ifndef SW_UART
restart_wdt();
if (bkbhit) // Char received
{
CommsTimeout = 0; // Clear timeout counter
if (NewMsg)
{
StrBufferPtr = 0; // Clear string buffer
NewMsg = false; // Signal we have started a new message
}
InChar = bgetc();
StringBuffer[StrBufferPtr] = InChar; // Get new char into string buffer
StrBufferPtr++; // Increment pointer in buffer
if (InChar == CR) // Wait till CR occures, or timeout whichever happens first
{
NewMsg = true;
ValidMsg = true; // Indicate we have a new valid (ends with CR) message in string buffer
}
}
if (CommsTimeout == MAX_COMMS_TIME) // Allow upto MAX_COMMS_TIME seconds for a full message
{
NewMsg = true; // We are waiting for a new message
InChar = 0; // Clear InChar
next_in = 0; //
next_out = 0; // Clear down the comms buffer
CommsTimeout ++;
}
#else
gets(StringBuffer);
NewMsg = true;
ValidMsg = true; // Indicate we have a new valid (ends with CR) message in string buffer
#ifdef DEBUG
output_bit(DIR485,1);
delay_ms(1);
printf("Msg rec\r\n");
printf("Buf:");
puts(StringBuffer);
printf("\r\n");
output_bit(DIR485,0);
#endif
#endif
|
Here is the essence of my code. I am using an SN65176 485 driver, and NOT RE and DE are tied together, and drivern by DIR485 pin. DI and RO are tied to +5v via 470R.
This is being used to communicate with 485-Ethernet converter for > 4km comms, but It has been tested with many RS232-RS485 and USB RS485 PC units, and works perfectly. |
|
|
Guest
|
|
Posted: Thu Apr 19, 2007 2:46 am |
|
|
Sorry, I may be misleading you with the S/W UART code, as this is not being used. I man not have changed that to 8 bit when I rebuilt S/W for 8 bit H/W UART |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Apr 19, 2007 8:16 am |
|
|
I see your trying 9bit address detect. I don't think many people are doing that. Check that this part of the system is working OK. |
|
|
PaoloMuchetti
Joined: 12 Apr 2007 Posts: 2
|
|
Posted: Fri Apr 20, 2007 4:05 am |
|
|
We solve the problem
It's incredible.. the address detect bit (BIT0) of RCSTA1 goto 0 after read register RCREG1.
Now we read RCREG1 AFTER the control of address detect.
That it does not happen with PIC18F6520 or PIC18F6620.
Why?
Thank you for your attention |
|
|
|
|
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
|