PDA

View Full Version : SERIN2/SEROUT2 - first data received is always garbage



flotulopex
- 30th July 2016, 21:45
Hi,

I'm wondering what I'm doing wrong in my programs.

Each time I use SERIN2/SEROUT2 commands, the very first data received on the other end is garbage. The correct data will appear only after I've sent the data from the second time and on. I can see this on my serial LCD, on any serial com software or even in the PICKit2's UART tool.

I found out that if I do not to declare the receiving port (here PORTB.5) as an Input in the TRIS register, the garbage is gone.

Any idea what I'm doing wrong? Am I missing some init stuff or any DEFINE?


' Serial Comm test

' ====== FUSES ================================================== ===================================
' PIC 16F690
@ __Config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_HS_OSC &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF

' ====== REGISTERS ================================================== ===============================
' 76543210
OPTION_REG = %10000000 ' PORT A&B Pull-Ups disabled (look WPUA & WPUB) INTEDG rising edge on A2
ANSEL = %00000000 ' Analog inputs Channels 0 to 7
ANSELH = %00000000 ' Analog inputs Channels 8 to 11
ADCON0 = %00000000 ' A/D Module is OFF
CM1CON0 = %00000000 ' Comparator1 Module is OFF
CM2CON0 = %00000000 ' Comparator2 Module is OFF
INTCON = %00000000 ' INTerrupts CONtrol
TRISA = %00000100 ' Set Input/Output (0 to 5)
PORTA = %00000000 ' Ports High/Low (0 to 5)
'''
TRISB = %00010000 ' Set Input/Output (4 to 7)
'''
PORTB = %00000000 ' Ports High/Low (4 to 7)
TRISC = %00000000 ' Set Input/Output (0 to 7)
PORTC = %00000000 ' Ports High/Low (0 to 7)

' ====== DEFINES ================================================== =================================
DEFINE OSC 4

' ====== VARIABLES ================================================== ===============================
Serial_In VAR PORTB.5 ' serial data in
Serial_Out VAR PORTB.7 ' serial data out
PollFlag VAR BIT ' if POLLING is requested, set flag
PollFlag = 0

'Serial_Bps CON 84 'For PICKit2 (9600 Driven True None)
Serial_Bps CON 32852 'For FTDI cable (9600 Open True None)
'Serial_Bps CON 16468 'For PC, HyperTerminal, MCS Terminal, LCD Display (9600 Driven Inverted None)

'======= PROGRAM ================================================== =================================

MAIN:
SERIN2 Serial_In, Serial_Bps, [WAIT ("POLL"),DEC PollFlag]
IF PollFlag = 1 THEN
SEROUT2 Serial_Out, Serial_Bps, ["Hello",13,10]
ENDIF
GOTO MAIN:
END

Ioannis
- 1st August 2016, 08:01
You should set Serial Port to a High state BEFORE using it.

Try this. In that exact order:




PORTB = %10000000 ' Ports High/Low (0 to 5)
TRISB = %00010000 ' Set Input/Output (4 to 7)



Ioannis

flotulopex
- 2nd August 2016, 08:34
Try this!
Is this magic or what?

Why did you set bit PORTB.7?

Ioannis, you must explain why this works (please please please) :)

HenrikOlsson
- 2nd August 2016, 09:32
Because the idle state of the serial line, for the mode you've selected, is high and you're driving the pin low when the PIC starts up. When the receiver sees that low it Thinks its the startbit and starts to shift in data which you aren't actually sending. That's the garbage you get. This happens BEFORE the execution of the SEROUT command which will THEN set it up properly for you.

If you, in your "startup code" set the pin you're going to use as the serial out pin high and then set it to output (as Ioannis showed) then the "line" idles at the correct state and the receiver isn't "triggered" until the SEROUT command actually exectutes.

Another (IMHO better) option is to NOT clear the TRIS bit for that particular pin.
That way it'll remain in high impedance mode until the SEROUT command actually executes - and it will set the pin to output AND set the idle state properly based on the MODE you select.

/Henrik.

flotulopex
- 2nd August 2016, 09:41
Thanks a lot ;)

Ioannis
- 2nd August 2016, 11:59
Ioannis, you must explain why this works

I explained it in my first line of the post, but I guess it was a bit laconic. Henrik explained in detail.

As always, microcontroller should be set in a known condition to avoid bizzare behaviour.

Ioannis

picster
- 2nd August 2016, 15:45
Great illustration here of the need to have predefined states. I had been "tossing out" the first byte of data received, now I don't need to do that. Thanks guys.

Picster

Scampy
- 2nd August 2016, 18:39
Slightly off topic, is this only true for SERIN2 / SEROUT2, and not applicable when using HSERIN / HSEROUT and the dedicated hardware /PINS on a PIC. I've always tend to use PICs with serial ports and used the excellent PIC MultiCALC tool by mister_e ( http://www.picbasic.co.uk/forum/showthread.php?t=4994 ) to give me the defines.

Ioannis
- 2nd August 2016, 19:42
Depends if you use it directly on RS-232 bus or with a driver which is actually an inverter.

Bus should stay at the predefined idle state which is -12 Volts meaning that TTL logic level of the controller is at High (3 or 5 volts).

So, the answer is yes, either Serout or Hserout.

But if you drive directly the RS-232 bus, TTL should be reversed in the Serout2 setup and Hserout should only be used if there is a special setting in the PIC's UART that reverses the TTL state.

Hope this is not too complicated.

Ioannis