![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Backfire
Joined: 12 Oct 2020 Posts: 46
|
RS485 With MAX3085 & PIC16F15356 |
Posted: Tue Jan 31, 2023 4:47 am |
|
|
Hello all,
I've a question on RS485, which admittedly may be more hardware-focused at the moment, but I also want to ensure my PIC configuration is correct...
I have a Waveshare USB->RS485 driver that is generating the signals shown on the 'scope trace below, these are the signals as measured into a MAX3085 chip at the A & B chip pins, on a custom PCB.
This trace was also captured with a GND/0V signal bias on the B line (via a 715R resistor) and a +5V signal bias (again, via resistor) on the A line, also applied near the MAX3085 driver IC itself.
The trace was captured when including both the 120R termination resistor near the A/B output (currently only attempting data reception by the PIC) of the Waveshare module, and another termination resistor at the A/B pins of the MAX3085.
The yellow trace is the 'A' signal, and the blue trace 'B', using the MAX3085 nomenclature. The purple/pink trace is the oscilliscope math function of 'A-B'.
My current PIC configuration is as follows;
Driving the DE and (NOT)RE pins of the MAX3085 low, and my PIC is running other code without issue from the internal oscillator, @ 32MHz, with the RS485 serial port configured with the following parameters;
Code: | #use rs232(STREAM=RS485, BAUD=9600, BITS=9, LONG_DATA, ENABLE=RS485_DE, XMIT=PIN_C6, RCV=PIN_C7, STOP=1, ERRORS) |
And my Rx'd data ISR is:
Code: |
#INT_RDA
void RDA_ISR(void)
{
int8 RxdByte = 0;
if(kbhit(RS485))
RxdByte = fgetc(RS485);
fprintf(DEBUG, "%c\r", RxdByte);
}
|
So my theory is, I should at least see some data output from the MAX3085 RO pin with this setup on my 'scope, when I send data through the Waveshare module, but instead I see no voltage at any point, regardless of the signals shown above being present at the A/B terminals of the RS485 transceiver.
Any help would be gladly appreciated! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Jan 31, 2023 5:14 am |
|
|
First, your INT_RDA, wants:
Code: |
#INT_RDA
void RDA_ISR(void)
{
int8 RxdByte = 0;
//if(kbhit(RS485)) //Not needed. The fact the interrupt
//has occurred says there is data.
RxdByte = fgetc(RS485);
fprintf(DEBUG, "%c\r", RxdByte);
//This is a problem. You are sending two characters when
//one is received. Result the code will stay inside this
//interrupt longer than one character time. Can easily
//result in the input UART buffer overflowing
//So you really need to only send one character.
}
|
On your RE/DE wiring. Connect these together, and connect both to
the RS485_DE pin on the PIC. You should have a pull up resistor
on the RO pin of the MAX driver otherwise you can see garbage when
you transmit.
How is the GND of the PIC board connected?. It needs to go to the GND
of the Waveshare board. |
|
![](templates/subSilver/images/spacer.gif) |
Backfire
Joined: 12 Oct 2020 Posts: 46
|
|
Posted: Tue Jan 31, 2023 6:33 am |
|
|
Hi Ttelmah,
thanks for your reply.
I can confirm that the devices all share a well-established common ground.
I have made the modifications to my ISR, but presently that never triggers, hence my suspicion I've a hardware issue currently.
Can I ask why you recommed that the (NOT)RE & DE pins are tied together? I can see this is a common implementation, but surely if the PIC can drive those pins to any state, or combination of states I should still have a valid reception?
As for a pull-up on RO, I've not seen one mentioned in the datasheet as being required... As this device is already soldered to a custom PCB, would the PIC's internal WPU likely to work, for testing at least?
Many thanks again for your advice. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Tue Jan 31, 2023 7:06 am |
|
|
comment...
if you tie both -RE and DE together ,only ONE pic pin is needed to control BOTH receive and transmit of the RS485 device....otherwise you need 2 pins and we always run out of pins before the end of the project....
to make RS-485 bus 'bullet proof', you use 750r pullup, pull down AND the 125r bias resistor. While you 'may' get away with fewer resistors,sooner or later, depending on chips used, PCB layout, wiring, gremlins...you WILL have a 'problem'...... So spending 3 cents for 3 parts makes sense .
in the end, you want to design/build RELIABLE equipment,and no amount of costly and clever software will FIX faulty hardware. |
|
![](templates/subSilver/images/spacer.gif) |
Backfire
Joined: 12 Oct 2020 Posts: 46
|
|
Posted: Tue Jan 31, 2023 7:13 am |
|
|
Hi temtronic,
I agree with you 100%, I have run out of pins on many projects, and the frustration is real!
That said, I don't believe my schematic is electrically incorrect, just maybe inefficient regarding the separated drives for (NOT)RE and DE.
As for the RS485 'side' of the circuit, on my target PCB I have the full biasing and termination network, and have terminated at the driver-end also.
Are you suggesting I need to add the biasing resistors at the point where the signal is introduced by the Waveshare module, as well as the termination resistor that is already present?
Many thanks for your input! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Jan 31, 2023 7:26 am |
|
|
The point is that chips vary. Some RS485 receivers will receive if RE is
low, whatever the state of DE. Problem is then that the device will receive
what is being sent. In your case if RE is high and DE low it goes into a
shutdown mode. Much safer to use just the two states. RE and DE both low,
which receives, and RE and DE both high for transmit. This saves a pin on
the PIC and avoids the possibility of receiving while transmitting, and of
going into the shutdown mode. |
|
![](templates/subSilver/images/spacer.gif) |
Backfire
Joined: 12 Oct 2020 Posts: 46
|
|
Posted: Tue Jan 31, 2023 7:35 am |
|
|
Hi Ttelmah,
I completely understand, the two pins tied together is a more elegant solution, and inherently avoids some possible pitfalls.
But I have driven both (NOT)RE and DE low, am sending data into the MAX3085 as shown above, and I am still seeing no output from the RO pin of the MAX3085.
Is my configuration of the UART correct for RS485 reception?
Here's my current config;
Code: |
#define RS485_NRE PIN_A6
#define RS485_DE PIN_A7
#use rs232(STREAM=RS485, BAUD=9600, BITS=9, LONG_DATA, ENABLE=RS485_DE, XMIT=PIN_C6, RCV=PIN_C7, STOP=1, ERRORS)
|
And in the code body I drive both low in my device initialisation also. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Jan 31, 2023 7:47 am |
|
|
No.
This is a PPS chip. Look at the sticky at the head of the forum on how
to use the UART with this. |
|
![](templates/subSilver/images/spacer.gif) |
Backfire
Joined: 12 Oct 2020 Posts: 46
|
|
Posted: Tue Jan 31, 2023 7:53 am |
|
|
Hi Ttelmah,
I have already attempted configuration as follows, including the below;
Code: |
#pin_select U1TX = PIN_C6
#pin_select U1RX = PIN_C7
|
And then including the 'UART1' parameter in the #use rs232(), rather than specifying the pins directly in the #use rs232() statement.
I can't see an obvious #pin_select for the enable pin... |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Jan 31, 2023 8:11 am |
|
|
The enable pin is done in software, not part of the UART hardware.
The PIN_SELECT and UART1 way is the correct configuration for your chip.
Unplug the MAX3085, and check the RX pin is high to the PIC. I must
admit I suspect you have something like a whisker preventing the line
going low. |
|
![](templates/subSilver/images/spacer.gif) |
Backfire
Joined: 12 Oct 2020 Posts: 46
|
|
Posted: Tue Jan 31, 2023 8:44 am |
|
|
Hi Ttelmah,
thanks again for all your input thus far. Do you mean disconnecting the RS485 driving module? Sadly the MAX3085 in question is a SMD, so simply unplugging it is not an option. I have probed the voltage at the PIC pin 18 (UART1 default Rx) and seen ~0.15-0.2V.
Just for completeness, here's all the RS485-related code, as I'm running it at this moment;
In main.h I have the following configuration;
Code: |
#pin_select U1TX = PIN_C6
#pin_select U1RX = PIN_C7
#define RS485_NRE PIN_A6
#define RS485_DE PIN_A7
#use rs232(STREAM=RS485, BAUD=9600, BITS=9, LONG_DATA, ENABLE=RS485_DE, UART1, STOP=1, ERRORS)
|
And in main.code, the following routines;
Code: |
#INT_RDA
void RDA_ISR(void)
{
int8 RxdByte = 0;
RxdByte = fgetc(RS485);
fprintf(DEBUG, "%c", RxdByte);
}
void RS485EnableRx(void)
{
// Set up our RS485 reception...
while(kbhit(RS485)) {getc();} // Clear RX buffer, RDA interrupt flag & overrun flag
setup_uart(UART_ADDRESS, RS485);
setup_uart(TRUE, RS485);
output_low(RS485_NRE);
output_low(RS485_DE);
enable_interrupts(INT_RDA);
}
|
After calling RS485EnableRx() from my main routine, I then enable global interrupts and go into a while(TRUE) loop, which just dumps out some status info in a loop; the ISR simply never fires, and I can see no data at the RO output of the MAX3085. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9168 Location: Greensville,Ontario
|
|
Posted: Tue Jan 31, 2023 9:22 am |
|
|
curious...
is it just me or is there a lot of 'noise' on those lines in the 'scope' screen ?
also
i see bits=9, so how do you read the 9th incoming bit ? |
|
![](templates/subSilver/images/spacer.gif) |
Backfire
Joined: 12 Oct 2020 Posts: 46
|
|
Posted: Tue Jan 31, 2023 9:51 am |
|
|
Hi temtronic,
my 'scope is truly a bottom of the line unit, to give some context, heres my scope as pulling from its own calibration output;
I work with what I have, ever-deaming of being able to afford an upgrade!
Both the PIC and the MAX3085 have local high-frequency decoupling (0.1uF) and small tank capacitors (10uF) though.
The example code in the CCS supplied rs485.c example file has 'bits=9', its reading through that file I was using as my starting point. |
|
![](templates/subSilver/images/spacer.gif) |
gaugeguy
Joined: 05 Apr 2011 Posts: 296
|
|
Posted: Tue Jan 31, 2023 10:18 am |
|
|
Your code appears to be trying to echo a received byte, but you are probably not receiving properly formatted data, so nothing will be sent out.
Try just sending a known character at a periodic rate. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19358
|
|
Posted: Tue Jan 31, 2023 10:28 am |
|
|
There is another problem. You are specifying long_data, so you don't
receive an int8, you receive an int16.... |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|