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

RS232 Buffer Question
Goto page Previous  1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 28, 2017 4:03 pm     Reply with quote

Quote:
I will post my code when I have it reduced.

And a link to your board's schematic. Or at least the part showing all
connections to the DS3695 drivers, and their connections to the PIC.
temtronic



Joined: 01 Jul 2010
Posts: 9112
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Apr 28, 2017 6:05 pm     Reply with quote

just an observation....

One thing not mentioned yet is that you're using RS-485 transceivers and some designs call for both pullup and pulldown resistors as well as the 120r connecting A to B.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Sat Apr 29, 2017 2:46 am     Reply with quote

Temtronic is right on this. Some buffers will assume an unbiased line is 'idle' others will not. It is always safer to explicitly bias the bus.

However I think the problem is still back to understanding the PIC.....

Putc, will wait until the hardware buffer can take the byte, But will return as soon as it is accepted. This does not mean the byte has been _sent_....
Transmission of the byte will have started, but it them takes 10 bit times to actually be sent (assuming 8bits no parity).

To wait for transmission to complete, you have multiple choices:

1) Test the shift register empty bit in the UART.
Code:

#bit TRMT = getenv("BIT:TRMT)

    //then
    while (TRMT!=1)
       ;
    //will wait for the byte to send


2) Let the compiler handle it for you.
This is why the compiler has the 'enable' pin definition in #use rs232. If you specify this, the compiler will set the defined pin 'high' when data is actually being transmitted.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Apr 30, 2017 10:27 am     Reply with quote

How do I send a link to my schematic or pictures?
I don't trust Facebook or Dropbox (which I have tried) and I don't have a webpage.
Here is the MASTER code for a test program, see the comment at the start for the behaviour with and without ERRORS.
Note that the slave works without ERRORS, the MASTER does not.
I'm not really using RS485. I am using a differential driver/receiver chip at each end. The MASTER sends a data stream then immediately switches to receive and waits for a reply. If it does not get one (times out) then it gors through the loop and sends again.
The SLAVE listens fro a special character (0x55) then replies with a data stream and synchronizes.
Disconnecting or turning off either end interrupts the communication and the ROV shuts down until the cable is re-connected or the unit turned back on. It works 100% as long as ERRORS is included. In use I disconnect the cable to reel out or reel in the cable. I wish I could post pictures here.
NOTE: MPLAB IDE v8.92, PCM v5.055
Code:
// CONSOLE FIRMWARE File  Console PIC_1_test.c    Console to control ROV & test communications        //
// Warning: Scan switch must be set to Horiz when programming the PIC. RB3 is LVP                   //
// Last modified:   30 Apr 2017                                                                     //
// With "ERRORS" in the #use rs232 statement displays:                                              //
//      ROV DATA, No Timeout, Start Char = 55, Counter = n (incrementing), Battery 13.8v            //
// Without "ERRORS" in the #use rs232 statement displays:                                           //
//      ROV DATA, Timeout Error, Start Char = 00, Counter =   0, Battery 0.0v                       //

/* Pre-processor directives */
 #include <16F884.H>
 #include <math.h>
 #fuses INTRC_IO, NOWDT, PUT, NOPROTECT, BROWNOUT, MCLR, NOLVP
 #use delay (clock=8000000)
 #use rs232 (baud=9600, parity=N, bits=8, enable = pin_E2, xmit=pin_C6, rcv=pin_C7, ERRORS)
 #use I2C (master, SCL=PIN_C3, SDA=PIN_C4)
 #byte porta = getenv("SFR:PORTA")
 #byte portb = getenv("SFR:PORTB")
 #byte portc = getenv("SFR:PORTC")
 #byte portd = getenv("SFR:PORTD")
 #byte porte = getenv("SFR:PORTE")

// define I2C address
// #define consolePIC_2_WRT_ADDR  0X10      // Console slave PIC 2
// #define consolePIC_2_READ_ADDR 0x11
 #define LCD_1                  0x40      // LCD 1 0x20
// #define LCD_2                  0x42      // LCD 2 0x21
// #define LCD_3                  0x44      // LCD 3 0x22
 
// constants
 #define buff_size 22                    // characters per line plus one

// Global Variables
    char LCD_WRT_ADDR = 0X40;                      // set to first LCD, 0x4e default
    short timeout_error = 0;                       // for timed get_c()
     
// Function prototypes
    char timed_getc (void);                        // get RS232 character, timed
    void clear_LCD (void);                         // Clear LCD
    void set_I2C_addr (char addr);                 // set the I2C address, 7 bit
    void text_position (int line, int column);     // set start for next text
    void set_font (char size);                     // set font size
    void send_str(char *buff);                     // Send string to LCD
    void beep(void);                               // beep for 100 ms

// ***************The main function*********************
void main(void)
 {
// setup ports
  set_tris_a (0xff);                    // all inputs
  set_tris_b (0xff);                    // all inputs
  set_tris_c (0xff);                    // all inputs
  set_tris_d (0xef);                    // all inputs except D4
  set_tris_e (0xfb);                    // all inputs except E2
  output_low(pin_D4);                   // sonarlert off

// declare variables
  int i;
  float volts  = 0;             // ROV Battery Voltage to 0
//  #bit trmt = 0x98.1         // TXSTA(bit 1). Tx Shift Reg Status bit, 1=empty
  char buff[buff_size];

// outgoing packets   
  const int max_s = 10;                 // array size
  char packet_s [max_s];                // packets to send
  #define ENQ            0x55           // Enquiry
  #define start_s       (packet_s [0])   // request to send
  #define main_thr      (packet_s [1])
  #define counter       (packet_s [2])   // counter for testing
  #define stbd_thr      (packet_s [3])
  #define consws        (packet_s [4])
  #define joysws        (packet_s [5])
  #define rudd          (packet_s [6])
  #define elev          (packet_s [7])
  #define pmrot         (packet_s [8])
  #define smrot         (packet_s [9])
// initialize outgoing packet array
  start_s = ENQ;                     // Enquiry in the first position
  counter = 0x00;                        // start counter at zero

// incoming packets
  const int max_r = 10;                     // array size
  char packet_r [max_r];                    // packets to receive
  #define ACK            0xaa               // Acknowledge
  #define start_r           (packet_r [0])
  #define compass           (packet_r [1])
  #define bat_volts         (packet_r [2])
  #define bat_amps          (packet_r [3])
  #define pitch             (packet_r [4])
  #define roll              (packet_r [5])
  #define status_1          (packet_r [6])  // return start_s (ENQ)
  #define status_2          (packet_r [7])  // return counter
  #define depth             (packet_r [8])
  #define dist_from_bottom  (packet_r [9])
  start_r = 0;                              // clear receive start char
  bat_volts = 50;
  status_1 = 60;
  status_2 = 70;

// Start the alphanumeric display sequences
  delay_ms(2000);                           // allow time for LCD to start
  LCD_WRT_ADDR = LCD_1;
  clear_LCD();                              // clear LCD_1
  delay_ms(5);
  set_font(10);                             // change text to size 10
  text_position(0,0);                       // start first line
  sprintf(buff, "ROV DATA");                // place text string in buffer
  send_str(buff);                           // display text array

// beep for 100 msec
    beep();

// ******************** loop continuously ***************
  while (1)
 {
// Start of data transmission    *******************************************************
    for (i=0; i<max_s; i++)                             // 10 packets, 0 to 9
     {
     putc (packet_s [i]);                              // send the packet
    }                                                  // end send packet for loop

// Timed Wait for reply
    timeout_error = FALSE;                              // so WHILE is not skipped
   while ((packet_r [0] != ACK)&&(!timeout_error))      // wait for ACK or timeout
    packet_r [0] = timed_getc();                        // in this loop
   if (!timeout_error)                                  // if no timeout error
    {
     for (i=1;i<max_r;i++)                              // get the remaining 6, or timeout
      packet_r [i] = timed_getc();                      // 1 to 6
    }

// LCD #1, display
// Should display: No Timeout, Start Char = 0x55, Counter = n (n increments)
  LCD_WRT_ADDR = LCD_1;

  text_position(0,1);                               // start second line
  if(timeout_error)
   sprintf(buff, "Timeout Error");                  // prepair to display
  else
   sprintf(buff, "No Timeout   ");                  // if timeout or not
  send_str(buff);                                   // display one of the above

  text_position(0,2);                               // start third line
  sprintf(buff, "Start Char = %x", status_1);       // display first received character
  send_str(buff);

  text_position(0,3);                               // start fourth line
  sprintf(buff, "Counter = %3U  ", status_2);       // display counter
  send_str(buff);

// adjust units and display battery status
  volts = bat_volts * 0.0586;                       // scale battery voltage
  text_position(0,6);
  sprintf(buff, "Battery %2.1fv", volts);           // display 13.8v to test
  send_str(buff);

  packet_r [0] = 0x00;                              // clear ACK
 }                         // end of while loop
}                        // end of main function

// Functions
// function 'timed_getc' waits up to 50 ms for a character
   char timed_getc()
   {
    long timeout;
    timeout_error = FALSE;
    timeout = 0;
    while (!kbhit() && (++timeout<5000))  // 50 msec
     delay_us(10);
    if (kbhit())
     return (getc());
    else
    {
     timeout_error = TRUE;
     return(0);
    }
   }

// Clear Display
void clear_LCD (void)
   {
   I2C_START ();                // start I2C
   I2C_WRITE (LCD_WRT_ADDR);    // addr of LCD
   I2C_WRITE ('C');             // C CL to clear display
   I2C_WRITE ('L');             // L
   I2C_STOP ();                 // stop I2C
   }

// set the I2C address, 7 bit
void set_I2C_addr (char addr)
    {
   I2C_START ();                // start I2C
   I2C_WRITE (LCD_WRT_ADDR);    // addr of LCD
   I2C_WRITE ('S');             //
   I2C_WRITE ('I');             //
   I2C_WRITE ('2');             //
   I2C_WRITE ('C');             //
   I2C_WRITE ('A');             //
   I2C_WRITE (addr);            //
   I2C_STOP ();                 // stop I2C
    }

// set position of next text
void text_position(int line, int column)
   {
   I2C_START ();                // start I2C
   I2C_WRITE (LCD_WRT_ADDR);    // addr of LCD
   I2C_WRITE ('T');             // T, TP set text position
   I2C_WRITE ('P');             // P
   I2C_WRITE (line);            // line position
   I2C_WRITE (column);          // column position
   I2C_STOP ();                 // stop I2C
   }
// Set Font Size
void set_font (char size)
   {
   I2C_START ();                // start I2C
   I2C_WRITE (LCD_WRT_ADDR);    // addr of LCD
   I2C_WRITE ('S');
   I2C_WRITE ('F');
   I2C_WRITE (size);
   I2C_STOP ();                 // stop I2C
   }

// send string to LCD
// void send_str(char buff[buff_size])
void send_str(char *buff)
   {
   int i;
   I2C_START ();                // start I2C
   I2C_WRITE (LCD_WRT_ADDR);    // addr of LCD
   I2C_WRITE('T');              // send TT for text coming
   I2C_WRITE('T');
    for (i=0; i<buff_size; i++)
   {
   I2C_WRITE(buff[i]);          // send string
   }
   I2C_WRITE(0);                // send termination
   I2C_STOP ();                 // stop I2C
   delay_ms(30); 
   }


// beep for 100 ms
void beep()
   {
   output_high(pin_D4);                  // Sonarlert on
   delay_ms(100);
   output_low(pin_D4);                   // for 0.1 sec
   }
// end


Here is the code for the slave.

Code:
/// MAIN THRUSTER FIRMWARE    28 Apr 2017         ///
// This version actually works without "ERRORS" in the #use rs232 statement
/* Pre-processor directives */
 #include <16F874A.H>
 #fuses HS, NOWDT, PUT, NOPROTECT
 #use delay (clock=8000000)
 #use rs232 (baud=9600, parity=N, bits=8, enable = pin_C5, xmit=PIN_C6, rcv=PIN_C7,ERRORS)
 #use I2C (master, SCL=PIN_C3, SDA=PIN_C4)
 #byte porta = getenv("SFR:PORTA")
 #byte portb = getenv("SFR:PORTB")
 #byte portc = getenv("SFR:PORTC")
 #byte portd = getenv("SFR:PORTD")
 #byte porte = getenv("SFR:PORTE")

// Global variables
 short timeout_error = 0;        // error for timed_getc

// Function prototypes
 char timed_getc();

// ****************************************************************************
/* The main function */
void main(void)
 {
// declare variables
  int i;

// initialize
  #define read_port  0xff      // all bus pins input
  #define write_port 0x00      // all bus pins output
 
// Receive Packet from surface
 #define ENQ      0x55          // Enquiry
 const int max_r = 10;              // number of parameters to receive
 char packet_r [max_r];             // size of receive packet array
 #define start_r   (packet_r [0])   // start byte
 #define m_motor   (packet_r [1])   // main motor speed & direction
 #define counter   (packet_r [2])   // use as counter
 #define s_motor   (packet_r [3])   // stbd motor speed & direction
 #define consws    (packet_r [4])   // console switch settings
 #define joysws    (packet_r [5])   // joystick switches
 #define rudder    (packet_r [6])   // rudder position
 #define elevator  (packet_r [7])   // elevator position
 #define pm_rot    (packet_r [8])   // port motor rotate posn
 #define sm_rot    (packet_r [9])   // stbd motor rotate posn
  start_r = 0x00;                   // clear ENQ

// Transmit Packet to surface
  const int max_s = 10;                     // number of parameters to send
  #define ACK 0xaa                          // Acknowledge
  char packet_s [max_s];                    // size of send packet array
  #define start_s           (packet_s [0])  // start byte
  #define compass           (packet_s [1])  // Compass heading
  #define bat_volts         (packet_s [2])  // Battery voltage
  #define bat_amps          (packet_s [3])  // Battery current
  #define pitch             (packet_s [4])  // pitch angle
  #define roll              (packet_s [5])  // roll angle
  #define status_1          (packet_s [6])  // side thrusters and servos status
  #define status_2          (packet_s [7])  // main thruster & PIC status
  #define depth             (packet_s [8])  // depth from surface
  #define dist_from_bottom  (packet_s [9])  // distance to bottom

// Initialize transmit packet array
  start_s           = ACK;          // acknowledge in first byte
  compass           = 0x38;         // South direction
  bat_volts         = 236;          // 13.8 volts
  bat_amps          = 120;          // -620 mA
  pitch             = 0x23;         // +35 degrees
  roll              = 0x85;         // -5 degrees
  status_1          = 0x00;         // clear problems
  status_2          = 0x00;         // clear problems
  depth             = 16;           // depth
  dist_from_bottom  = 22;           // DTB

// Initialize port directions
  set_tris_a(0b00011111);               // Port A inputs except E0,E1, E2
  set_tris_b(0b11110001);               // B1 to B3 outputs, the rest inputs
  set_tris_c(0b10011000);               // set Port C3, C4, C7 inputs, the rest outputs
  set_tris_d(0b11111111);               // set Port D Compass & Clinometers to inputs

// Turn off L6201 motor controller
  output_low(PIN_C0);
  output_low(PIN_C1);
// turn off all controls, lamps & camera
  output_low(PIN_B1);
  output_low(PIN_B2);
  output_low(PIN_B3);

// setup PWM, RS232, and ADC
  setup_ccp1(CCP_PWM);                  // sets up for PWM
  setup_timer_2(T2_DIV_BY_16,255,2);    // freq of 300 Hz. Note 255 max???
  setup_adc (ADC_CLOCK_DIV_32);         // configures ADC, 2-6 us reqd in .h
  setup_adc_ports (AN0_AN1_AN2_AN3_AN4);   // amps, volts, depth, spare, spare

// **********************************************************************************
  while (1)
  {

// wait for transmission  ****************************
   timeout_error = FALSE;
  while ((start_r != ENQ)&&(!timeout_error))  // wait for enquiry or timeout
   packet_r [0] = timed_getc();               // to get first packet
  if (! timeout_error)
   {
   for(i=1;i<max_r;i++)                       // 10 packets; 0 to 9
    packet_r[i] = timed_getc();               // get other 9 packets
   }

// prepare reply. Always send the first character received back in status_1 (packet_s[6])
// and if correct increment status_2. If not correct make status_2 all ones (packet_s[7]).
    status_1=start_r;           // always send first received back
    if(start_r==ENQ)            // if it is actually 0x55
    {
    status_2 = status_2 + 1;         // increment the counter to send back
    }
    else
    status_2=0xff;              // else return all ones

//  delay_ms(10);     // 80ms is max for 50ms timeout in console, just testing

// send reply
   for (i=0; i<max_s; i++)              // 7 packets, 0 to 6
    putc (packet_s [i]);                // send the packet

  start_r = 0x00;                             // clear ENQ

  }                                     // end of while loop
 }                                      // end of main function

// functions       ***********************************************************


// function 'timed_getc' waits up to 50 ms for a character
   char timed_getc()
   {
    long timeout;
    timeout_error = FALSE;
    timeout = 0;
    while (!kbhit() && (++timeout<50000))  // 0.5 sec
     delay_us(10);
    if (kbhit())
     return (getc());
    else
    {
     timeout_error = TRUE;
     return(0);
    }
   }
// end

Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Sun Apr 30, 2017 10:31 am     Reply with quote

The reason that ERRORS affects things, is that this copies the UART status into the variable RS232_ERRORS. Since this can't happen till after the byte transfer has completed, adding 'ERRORS' makes the software wait until the transmission has completed.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Apr 30, 2017 11:39 am     Reply with quote

PCM Programmer;
it is quite simple. The DS3695 has 8 pins, power and ground, two differential line drivers/receivers, an input pin and an output pin.
this leaves the two pins that enable the receiver or driver. one is low select and the other is high select so if they are tied together and connected to the ENABLE pin controlled by #use rs232() the software selects send or receive automatically. I just have to make sure that both chips don't send at the same time, hence the master initiating the communications and always switching immediately to receive (even between sending each bit). I wish I could post a screen shot of the DSO.
I think Ttelmah has the answer but it doesn't explain why the SLAVE does not need ERRORS. I do know that with the full program it does need ERRORS, it is just this test program that works without it. The test MASTER program definitely needs it.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 30, 2017 11:40 am     Reply with quote

Quote:
How do I send a link to my schematic or pictures?

Here are instructions on how to link to an image. However, this is not
permanent. The website listed below will delete the image after a while.

How to post an image on the CCS forum:
Go to this website: http://postimage.org/
Upload your image. Select family safe. Then click the first button for
"Hotlink to Forum" to get a link to the image.
Then go to the CCS forum and type Ctrl-V to paste the link into a post.

If postimage.org doesn't work in your country, then use Google to find
another free image hosting site for forums.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Apr 30, 2017 1:07 pm     Reply with quote

Not quite that easy (for me) I can't find any instructions and nothing is obvious (to me). I think this may work:

Console 1.jpg is the schematic for the console. The PIC on this schematic controls another PIC and several Graphic LCDs by I2C. See the second schematic Console 2.jpg
Enable_send.jpg shows the ENABLE pulse generated by #use rs232(ENABLE=pin_E2)
The last one is Master Enable, Tx, Slave Enable, Rx. Note that the signals seem messy but this is just a function of the sampling of the DSO. If expanded they are just as clear as those in picture 3. I have identified the start bit, the 8 data bits, and the stop bit by expanding and moving the delay just to satisfy myself of what I am seeing.










Last edited by rovtech on Sun Apr 30, 2017 5:22 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Sun Apr 30, 2017 1:21 pm     Reply with quote

First, you need a pull-up resistor on the RX input to the PIC. When the receive buffer is disabled, this line is floating. It 'may' stay high, but is quite likely not to....
Then you have no sign of any termination or bias on the 485 lines. Termination is needed. Bias is also probably needed (a couple of the drivers 'warrant' to receive 'idle' when the bus is not driven, but most don't). Have a look at:
<http://www.edn.com/design/analog/4442598/Understanding-RS-485-passive-fail-safe-biasing->
If picture 3, is the operation using 'enable', this looks fine. It is disabling the drive as soon as the bus goes idle, so there is a tiny period when it turns off the drive. Provided the bus is biased so it goes to the idle level when this happens, this will give correct data out.
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Sun Apr 30, 2017 1:36 pm     Reply with quote

This is my ROV

photo uploading

and I cannot get the control console pic to show.

thanks Ttelmah. This is going to take me some time reading the data sheets and trying some of your suggestions.
I have removed comments that I added here and put them in a new reply since they really start a new discussion.


Last edited by rovtech on Mon May 01, 2017 8:09 am; edited 1 time in total
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Mon May 01, 2017 8:09 am     Reply with quote

For anyone following this thread my system is similar to Fig 27, page 19 of http://www.ti.com/lit/an/slla070d/slla070d.pdf, and yes the terminations are a good idea especially if I go to longer cable in the future.

The DS3695 data sheet shows that if ENABLE (/RE+DE) = 0, in other words both in receive, then the bus is high impedance and Rx could be anything. The bus differential voltage for a reliable output is +0.2v or -0.2v. Termination resistors will hold the bus close to 0v. This condition is described in the TI document, referenced above, on page 12 and reproduced below:

The Need for Failsafe Protection
In any party-line interface system with multiple driver/receivers, long periods of time may occur when all
the driving devices are inactive. This state is known as line idle or bus idle and occurs when all drivers
place their outputs into a high-impedance state. During bus idle, the differential bus voltage is left floating
(i.e., indeterminate: neither logic-high nor logic-low state) if there is no termination resistors, and the
differential bus voltage is close to zero in the case where termination resistors are used. In both cases, as
a result, the receiver can be falsely triggered into either a logic-high or logic-low state, depending on the
presence of noise and the last polarity of the floating lines. Obviously, this is undesirable, as the circuitry
following the receiver could interpret this as valid information. It is best to detect such a situation and place
the receiver outputs into a known and predetermined state. The name given to methods that ensure this
condition is receiver failsafe. An additional, desirable feature that a failsafe provides is to protect the
receiver from shorted line conditions, which can again cause erroneous processing of data.

I will add 120 ohm termination resistors at each end and close to the DS3695s. I don't see how a pullup on Rx of the PIC will have any effect since the PIC has active outputs. I'm not sure how the compiler handles the input if it is flipping randomly but it does not do this and it works reliably with no termination resistors as long as ERRORS in in the #use rs232().
I'm not sure how to make this "both listening" condition failsafe.
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Mon May 01, 2017 8:15 am     Reply with quote

and this "Rx could be anything", is why there needs to be a pull-up resistor on the line to the PIC. Smile
rovtech



Joined: 24 Sep 2006
Posts: 262

View user's profile Send private message AIM Address

PostPosted: Mon May 01, 2017 8:58 am     Reply with quote

I don't think so. Rx is determined by the state of the bus and the DS3695 will send Rx high or low depending on noise on the bus, or the last state of the bus which I think is the case. The only "pullup" that can help is on the bus to provide a bias in one direction or the other. Putting a pullup on an active output will have little, if any, effect.
I meant the DS3695 has active outputs, not the PIC, in the above. Tx is an input.
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Mon May 01, 2017 9:14 am     Reply with quote

When the RX buffer is disabled, (/RE is high) 'RX can be anything'.
When RE is 1, RO is 'X' (high impedance). At this point, the receive input to the PIC is _floating_. It's 'probably' stay high(ish), but any RF noise, or resistance on the board, and it'll drift low. Result 'garbage' received.....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 01, 2017 9:15 am     Reply with quote

Here is a similar problem. He argues and doesn't want to do it
(put a pull-up on Rx pin of the PIC), but when he finally does it,
it fixes the problem:
http://www.avrfreaks.net/forum/rs485-framing-error-when-toggling-re-pin

Other forum threads saying the same thing (i.e., add a pull-up on Rx):
https://www.ghielectronics.com/community/forum/topic?id=16600
http://www.electro-tech-online.com/threads/rs485-sn75176-do-i-need-a-pullup-pulldown-or-nothing-on-rx.30909/
https://developer.mbed.org/questions/727/RS485-with-mbed-microcontroller-Not-rece/

http://janaxelson.com/rs-485_circuits.htm
Quote:

When the receiver is disabled, the receiver's output is high impedance. If
the output doesn't connect to a input with an internal pullup, adding a
pullup here will ensure that the node doesn't see false Start bits when its
receiver is disabled.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3  Next
Page 2 of 3

 
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