CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem with Asynchronous Reception (RS485) on PIC18f2520

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PaoloMuchetti



Joined: 12 Apr 2007
Posts: 2

View user's profile Send private message

Problem with Asynchronous Reception (RS485) on PIC18f2520
PostPosted: Thu Apr 12, 2007 4:01 am     Reply with quote

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... Crying or Very sad

Thank you very mutch


Wink
funmix



Joined: 27 Mar 2007
Posts: 33

View user's profile Send private message

PostPosted: Wed Apr 18, 2007 8:08 pm     Reply with quote

The code you posted is for slave part? Can we see the master part?
mikebroom
Guest







RS485 comms
PostPosted: Thu Apr 19, 2007 12:58 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Apr 19, 2007 1:50 am     Reply with quote

mikebroom, post up your code. as we can refer
Guest








PostPosted: Thu Apr 19, 2007 2:43 am     Reply with quote

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








PostPosted: Thu Apr 19, 2007 2:46 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Thu Apr 19, 2007 8:16 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Apr 20, 2007 4:05 am     Reply with quote

We solve the problem Laughing Laughing Laughing

It's incredible.. the address detect bit (BIT0) of RCSTA1 goto 0 after read register RCREG1.
Shocked Shocked Shocked

Now we read RCREG1 AFTER the control of address detect.

That it does not happen with PIC18F6520 or PIC18F6620. Question Question Question

Why?


Thank you for your attention
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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