Jump to content

PIC18f252+SN75176 and USART


ptitjes
 Share

Recommended Posts

Hello all,

I know this is not really related to MidiBoxes but I need some help and I know some of you have the knowledge I miss...

It happens I'm trying to receive DMX512 through a SN75176 (differential transceiver) with PIC's integrated USART. I found a lot of schematics and asm sources on the Internet so I cooked myself a schematics and... got a lot of problems! Let me explain my problems and ask corresponding questions.

(Schematics below...)

It happens that the RX output of the SN75176 is electrically compatible to the VIH and VIL of the PIC. The SN75176 says VOH minimum is 2.7V but in pratice i measured 4.2V which is just above the 4V of PIC's minimum VIH. (I added a 1K pull-up just to test and it brings the VOH to 4.5V so maybe I'll that pull-up in the final design for safety). So I happily connected that to the PIC and implemented a simple (no interrupt) usart poll in my main loop.

[...]
code char at __CONFIG1H _conf0 = _OSC_HS_PLL_1H & _OSCS_OFF_1H;
[...]

#define DMX_OSC_FREQ			40000000
#define DMX_BAUD_RATE			250000
#define DMX_BAUD_RATE_SCALER	(DMX_OSC_FREQ/(16*DMX_BAUD_RATE))-1

#define DATA_RECEIVE_LED		PORTBbits.RB0
[...]

PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x40; // TX pin = 1

// 00000000 (A<7,6> outputs, A5 = Power drain output, A<4,0> outputs)
TRISA = 0x00;
// 00011110 (B<7,5> outputs, B<4,1> inputs, B0 output )
TRISB = 0x1E;
// 10001110 (C7 = TX input, C6 = RX output, C<5,4> outputs, C<3,1> inputs, C0 output)
TRISC = 0x8E;

PORTBbits.RB0 = 1; // Turn led off
[...]

TXSTA = 0;
RCSTA = 0;

TXSTAbits.SYNC = 1;
RCSTAbits.RX9 = 1;
RCSTAbits.CREN = 1;
TXSTAbits.BRGH = 1;

PIR1bits.TXIF = 0;
PIR1bits.RCIF = 0;

PIE1bits.RCIE = 0;
PIE1bits.TXIE = 0;

SPBRG = DMX_BAUD_RATE_SCALER;

//  TXSTAbits.TXEN = 1;
RCSTAbits.SPEN = 1;

while (1) {
	if (PIR1bits.RCIF) {
		DATA_RECEIVE_LED = 0; // Turn led on
		dmx_rx_data = RCREG;
		DATA_RECEIVE_LED = 1; // Turn led off
	}
}

(Note: My quartz is a 10MHz and I use HS-PLL with 33pF caps as in MBHP.)

It appears that even when TX is low, i.e. no device is connected to the bus, PIR1bits.RCIF is set. (Not convinced by my oscilloscope I even tried to directly set TX pin to ground with a 1K resistor...) I can see that because the led is a very little bit lit and putting the scope proves it too.

I read from the PIC's datasheet that reading RCREG unsets RCIF. Also I tried to manually unset it and it changes nothing...

Did I miss something ?

Thanks for your help.

Best regards, Didier.

dmx-in_thumb.png

IMG_0068-reduit_thumb.JPG

2100_dmx-in_png6c955dbe582db0c2e2fcc4cf9

IMG_0068-reduit.JPG

Link to comment
Share on other sites

In order to understand the schematic better, I have to ask a question first: why did you pull Rx to low-level (Vss)? The SN75176 is powered by the Tx line - if a frame is transmitted by the PIC, the chip will loose power, Rx will "see" Vss, and the UART will detect a start bit. Accordingly RCIF will be set after short time. Probably RCSTA.FERR will be set as well (frame error) if Rx pin is not in idle state during stop bit phase.

Best Regards, Thorsten.

Link to comment
Share on other sites

Hi Thorsten!

What do you mean by "The SN75176 is powered by the Tx line" ? In fact I think I quite not understand what you explains. Could you please re-phrase it ?

In fact, I don't transmit anything. DMX uses RS485 in a unidirectional manner. There is always only one transmitter, receivers are then daisy-chained on the RS485 bus and the bus is then terminated with a 120 resistor. This is why I do not enable the transmit part of the USART (TXSTAbits.TXEN = 0 and RCSTAbits.SPEN = 1)

Also I do not use the pull-down anymore for RX. Sorry the schematic is old. I attached the latest version... I'm not sure yet if I will pull-up RX or let it as the SN75176 drives it as I explained in my previous post.

I must admit I got inspired by the GPL work of Kelly Kohls. He provides schematic and asm source. But his work is based on a PIC16F876. He doesn't pull down RX. He pulls TX to high (10K), but I believe the PIC16F had their inputs at TLL-levels and CMOS levels as the PIC18F.

Finally they use the same mechanism here. (schematic) They also use a PIC16F877, but with RX pull-down.

Oh sorry!! I just re-read my previous post and see that I told all wrong. You must read RX everywhere i wrote TX in the last paragraphs... So let me re-phrase it :

It appears that even when RX is low, i.e. no transmitter is connected to the bus (nothing plugged on the differential side of the SN75176), PIR1bits.RCIF is set. (Not convinced by my oscilloscope I even tried to directly set RX pin to ground with a 1K resistor...) I can see that RCIF is set because the led is a very little bit lit and putting the scope proves it too.

I scratch my head on this for three days now!! You can't imagine how this even gives me nightmares :) This code is so simple that I can't see where I am wrong!

Best regards, Didier.

dmx-in_thumb.png

2104_dmx-in_png6c955dbe582db0c2e2fcc4cf9

Link to comment
Share on other sites

Btw.: it wasn't the first time where you mixed Tx with Rx, see also the TRISC initialisation:


// 10001110 (C7 = TX input, C6 = RX output, C<5,4> outputs, C<3,1> inputs, C0 output)
TRISC = 0x8E;
[/code]

RC7 is the Rx input, and not Tx output

(however, the TRISC configuration itself is ok)

My statement "SN75176 is powered by the Tx line" was wrong, and therefore confusing. I overlooked the connection to Vdd. The schematic is very hard to read on my screen! :-( Btw.: a pull-device doesn't make much sense on an output pin. ;)

You are writing, that Rx is low when no transmitter is connected to the bus.

But the required idle level of Rx is high!

A low level will be detected as a start bit, and if it is permanently low, the UART will receive multiple bytes with frame error (FERR flag set) due to the missing stop bit. RCIF will be set as well in such cases, this matches with your observations?

If this doesn't make sense to you, just have a look into the PIC datasheet, e.g. search for the "Asynchronous transmission" diagram (figure number depends on datasheet version, it is figure 16-2 of DS39564B)

Since it isn't clear to me, if your schematic and/or descriptions about observations are complete and correct, I will stop speculations and wait for an answer ;)

Best Regards, Thorsten.

P.S.: please doublecheck, if the Rx terminal is connected to pin RC7 of the PIC, and not RC6

Link to comment
Share on other sites

Hi Thorsten!

You're right! My C comment is wrong too... My goal was to say : C7 = RX input, C6 = TX output

So! I double-check (should I say nth-check... :)) my breadboard and this is correct in respect to my schematic. Also, TX goes correctly to the RC6 pin and RX to the RC7 pin...

I have re-read the USART datasheet more and this is more clear to me. In fact I was not sure about the high-level during idle. I also checked the informations I got about DMX and this is comfirmed.

What I observe :

- When nothing is connected, I have a +5V on the RX line, which is good. But the RCIF is constantly set to 1 anyway.

- When a 12-channel lighting desk is connected, I have a good signal on the RX line, which studied at the osciloscope reveals :

    * a long low-level break followed by a 3 bits high (3*4µs), so this creates a frame error which identifies the start of a DMX paquet

    * 13 * the following sequence (1 start-code value = 0 and 12 channel values)

        * 9 bits low (8*4µs), so this is the start bit + 8 low bits of the value

        * 3 bits high (3*4µs), so this is the 9th bit of the value (which is always 1) + the stop bit + 1 bit idle

So this signal is a correct DMX signal.

Also, as low level is +0V and hight level is +5V, the SN75176 does seem to work well !

What I can't understand is why I have RCIF set when the RX pin is high...

Best regards, Didier.

Edit: When I power up my circuit, the RX line is low at first. Then I plug DMX, have signal on RX line. And when I unplug DMX, then RX line goes to high. I can't explain why it does not go to high at first!!

Link to comment
Share on other sites

Due to this "power-up behaviour", it could make sense to handle the error flags (FERR and OERR) correctly - once integrated into your small test loop, check again if RCIF is still flagged after RCREG readout.

FERR: whenever set, it should be cleared by software

OERR: whenever set, disable the receiver with CREN=0, thereafter enable it again (CREN=1). Overrun errors should be notified somehow by your program, e.g. a LED could lit - very useful for debugging.

Best Regards, Thorsten.

Link to comment
Share on other sites

Yeah!! Thank you Thorsten.

In fact, I was in my previous code only handle on error (either OERR or FERR) for each RCIF. So, I handle both now reseting two times the usart and this works like a charm. Got DMX input!!!!! :)

BTW, REFF is read-only. You also have to reset the usart (CREN=0; CREN=1) to get off of it.

Thanks again Thorsten. You helped me so much also because I felt less alone ;) I'm sure you know what it is!!

Best regards, Didier.

Edit: Still not found why RX line is low at power-on but this makes my DMX receive led blink so this is ok for now but if you have an idea of what the problems come from...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...