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 support@ccsinfo.com

RS485 with PIC24

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



Joined: 13 Jan 2012
Posts: 3
Location: Germany

View user's profile Send private message

RS485 with PIC24
PostPosted: Mon Sep 16, 2013 2:10 pm     Reply with quote

I have a question about the handling of RS485 with the PIC24 Family.
For PIC18 the code works fine but with PIC24 only send works but receive hangs.
The essential part of the code is:
Code:

#define RS485_ID            11      // The device's RS485 address or ID
#define RS485_RX_PIN        PIN_F4  // Data receive pin
#define RS485_TX_PIN        PIN_F5  // Data transmit pin
#define RS485_ENABLE_PIN    PIN_F3  // Controls DE pin.  RX low, TX high.
#define RS485_RX_ENABLE     PIN_F2  // Controls RE pin.  Should keep low.
#define RS485_BAUD          9600    // Transmission speed

#include "TMCL.c"

TMCL.C:
Code:

#ifndef TMCL_RS485_DRIVER
#define TMCL_RS485_DRIVER

#ifndef RS485_ID
#define RS485_ID  0x10                 // The device's RS485 address or ID
#endif

#ifndef RS485_RX_PIN
#define RS485_RX_PIN       PIN_B0   // Data receive pin
#endif

#ifndef RS485_TX_PIN
#define RS485_TX_PIN       PIN_B3   // Data transmit pin
#endif

#ifndef RS485_ENABLE_PIN
#define RS485_ENABLE_PIN   PIN_B4   // Controls DE pin.  RX low, TX high.
#endif

#ifndef RS485_RX_ENABLE
#define RS485_RX_ENABLE    PIN_B5   // Controls RE pin.  Should keep low.
#endif

#ifndef RS485_BAUD
#define RS485_BAUD    9600   // Baud rate
#endif

#PIN_SELECT INT2=RS485_RX_PIN

#use rs232(baud=RS485_BAUD, xmit=RS485_TX_PIN, rcv=RS485_RX_PIN, enable=RS485_ENABLE_PIN, bits=8, long_data, force_sw, errors, stream=RS485)
#use rs232(baud=RS485_BAUD, xmit=RS485_TX_PIN, rcv=RS485_RX_PIN, enable=RS485_ENABLE_PIN, bits=8, long_data, force_sw, multi_master, errors, stream=RS485_CD)

#define RCV_OFF() {disable_interrupts(INT_EXT2);}

#define RS485_wait_time 20             // Wait time in milliseconds

#bit    rs485_collision = rs232_errors.6

#ifndef RS485_RX_BUFFER_SIZE
#define RS485_RX_BUFFER_SIZE  40
#endif

int rs485_ni, rs485_no;
int rs485_buffer[RS485_RX_BUFFER_SIZE];


// Purpose:    Enable data reception
// Inputs:     None
// Outputs:    None
void RCV_ON(void)
{
    output_low(RS485_RX_ENABLE);
    clear_interrupt(INT_EXT2);
    enable_interrupts(INT_EXT2);
}


// Purpose:    Initialize RS485 communication. Call this before
//             using any other RS485 functions.
// Inputs:     None
// Outputs:    None
void tmcl_init()
{
   output_high (PIN_G7); // only for interrupt test

    RCV_ON();
    rs485_ni=0;
    rs485_no=0;
    ext_int_edge(2, H_TO_L);
    enable_interrupts(INT_EXT2);
    enable_interrupts(GLOBAL);
    output_low(RS485_RX_ENABLE);
}


// Purpose:    Interrupt service routine for handling incoming RS485 data
#INT_EXT2
void serial_isr()
{
   int8 t;
 
   output_high (PIN_A3); // only for interrupt test

   rs485_buffer[rs485_ni] = fgetc(RS485);
   t = rs485_ni;
   rs485_ni = (rs485_ni+1) % sizeof(rs485_buffer);
   if(rs485_ni == rs485_no)
      rs485_ni=t;        // Buffer full !!
   output_low (PIN_A3);  // only for interrupt test
}

#define bkbhit (rs485_ni != rs485_no)

int8 bgetc()
{
   int8 c;

   while(!bkbhit);
   c = rs485_buffer[rs485_no];
   rs485_no = (rs485_no+1) % sizeof(rs485_buffer);
   return c;
}


// Purpose:    Wait for wait time for the RS485 bus to become idle
// Inputs:     TRUE - restart the watch dog timer to prevent reset
//             FALSE - watch dog timer not restarted
// Outputs:    None
void rs485_wait_for_bus(int1 clrwdt)
{
   int16 i;

   RCV_OFF();
   for(i=0; i <= (rs485_wait_time*20); ++i)
   {
      if(!input(RS485_RX_PIN))
         i = 0;
      else
         delay_us(50);

      if(clrwdt)
         restart_wdt();
   }
}

One difference is in teh PIC18 code: instead of INT_EXT2 I use INT_EXT2_H2L, INT_EXT2 and ext_int_edge(2, H_TO_L);
does not work with the PIC18 so I guess there is some compiler Problem.
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