RS485 bus - starting probem


Closed Thread
Results 1 to 5 of 5
  1. #1
    Join Date
    Jul 2007
    Posts
    6

    Default RS485 bus - starting probem

    Hi!

    I´ve got a problem with the communication between two pic16f873a connected via a rs485 bus.
    The master sends a request to the slave and the slave answers which key is pressed. At the beginning of the program the masters sends some data to turn on some leds on the slave.
    This works most time fine.
    But sometimes when the devices get power the communicatoin fails.
    The master works (there are some leds on it), but the slave doesn´t turn on the leds and there´s no communication.

    I think the problem is that there is a serial buffer overrun at the start of the devices because there are some characters on the bus produced through power up.

    Hope somebody has an idea to solve my problem.


    Here is the master code:

    Code:
    'Configuration bits
    @ DEVICE pic16F873a, hs_osc, wdt_on, pwrt_on, bod_on, lvp_off, cpd_off, wrt_off, protect_on 
    
    ' Definitionen
    define osc 4 ' Resonator 4 Mhz
    include "modedefs.bas"
    
    ' Ports als Input bzw. Output definieren
    TRISA = %00001111
    TRISB = %00000000
    TRISC = %10110001
    
    ' UART Definitionen
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_TXSTA 24h
    DEFINE HSER_BAUD 19200 ' 19200 Bauds
    DEFINE HSER_CLOERR 1
    
    ' Port-Definitionen
    adcon1 = 7 'Ports auf digital
    
    ' Ein- und Ausgänge definieren
    m_data var portb.0
    m_clk var portb.1
    m_wordclk var portb.2
    
    m_mpreached var portc.0		'Memoryposition erreicht
    
    led3 var portc.3'Gelb
    led2 var portc.2'Grün
    led1 var portc.1'Rot
    
    schalter1 var porta.2'Select
    schalter2 var porta.1'Hoch
    schalter3 var porta.0'Runter
    schalter4 var porta.3'Memory
    
    busrw var porta.4
    
    ' Variablen deklarieren
    Bus_out var byte		'Ausgabepuffer für Bus
    Ebene var word			'Ebene (rot, grün, gelb)
    Benutzer var word		'Benutzerebene 1-4
    bus_in var byte			'Eingangspuffer für Bus
    c_funktion var word		'Counter zur Entprellung der Funktionstaste
    c_benutzer var word		'Counter zur Entprellung des Benutzerwechsels
    c_save var word			'Counter zur Entprellung der Speichertaste
    c_run var byte			'Hilfsvariable, die nur einmal die Übertragung von Word1 und Word2 zulässt
    c_word var byte			'Variable des Datenwortes
    c_ebene var byte		'Blockiervariable der Ebene (unterbindet Weiterschaltung ohne Taste zu lösen)
    c_user var byte			'Blockiervariable des Benutzers (unterbindet Weiterschaltung ohne Taste zu lösen)
    c_speichern var byte	'Blockiervariable des Speicherns (unterbindet Weiterschaltung ohne Taste zu lösen)
    m_bit0 var bit
    m_bit1 var bit
    m_bit2 var bit
    m_bit3 var bit
    m_bit4 var bit
    m_bit5 var bit
    c_holdmem var byte		'Selbsthaltungsvariable für Memoryfahrt
    m_memstop var byte		'Stopvariable der Memory-Funktion
    
    'Initialisierung Display
    
    
    'Led1 an (Fußschalter)
    Ebene = 0
    high Led1
    low Led2
    low Led3
    
    pause 2000
    
    'Led1 an (Handschalter)
    Bus_out = 112
    gosub SendDisplay
    Bus_out = 117
    gosub SendDisplay
    Bus_out = 121
    gosub SendDisplay
    
    'Benutzer1 darstellen (Handschalter)
    Benutzer = 0
    Bus_out = 130
    gosub SendDisplay
    
    
    ' Hauptprogramm
    '-----------------
    Hauptschleife:
    RCSTA.4 = 0
    RCSTA.4 = 1
    
    clearwdt
    
    'Handschalter abfragen
    Bus_in = 099
    Bus_out = 100
    gosub SendDisplay
    pause 10
    if PIR1.5 = 1 then Bus_in = RCREG
    
    if Bus_in < 031 and Bus_in > 37 then Bus_in = 099
    
    'Memory Unterbrechung
    m_memstop = 0
    if schalter1 = 1 or schalter2 = 1 or schalter3 = 1 then m_memstop = 1
    if Bus_in > 30 and Bus_in < 37 then m_memstop = 1
    
    if c_holdmem = 1 then
    	if m_mpreached = 1 then
    		'Stop Memory
    		high m_wordclk
    		c_holdmem = 0
    	endif
    
    	if m_memstop = 1 then
    		'User-Unterbrechung
    		high m_wordclk
    		c_holdmem = 0
    		Bus_in = 099
    	endif
    endif
    
    if c_holdmem <> 1 then
    
    	if schalter4 = 1 then Bus_in = 037
    	'Abfrage Tastendruck
    
    	if Bus_in = 031 then gosub Naechste_Ebene	
    	if Bus_in = 035 then gosub Speichern
    	if Bus_in = 037 then gosub Memory
    	if Bus_in = 036 then gosub Naechste_Benutzer
    
    	if Bus_in = 032 and Ebene = 0 then gosub Hoehe_auf
    	if Bus_in = 033 and Ebene = 0 then gosub Hoehe_ab
    	if Bus_in = 032 and Ebene = 1 then gosub Becken_auf
    	if Bus_in = 033 and Ebene = 1 then gosub Becken_ab
    	if Bus_in = 032 and Ebene = 2 then gosub Ruecken_auf
    	if Bus_in = 033 and Ebene = 2 then gosub Ruecken_ab
    
    	if schalter1 = 1 then gosub Naechste_Ebene
    	'if schalter4 = 1 then gosub Memory
    
    	if schalter2 = 1 and Ebene = 0 then gosub Hoehe_auf
    	if schalter3 = 1 and Ebene = 0 then gosub Hoehe_ab
    	if schalter2 = 1 and Ebene = 1 then gosub Becken_auf
    	if schalter3 = 1 and Ebene = 1 then gosub Becken_ab
    	if schalter2 = 1 and Ebene = 2 then gosub Ruecken_auf
    	if schalter3 = 1 and Ebene = 2 then gosub Ruecken_ab
    
    	if Bus_in = 099 and schalter1 = 0 and schalter2 = 0 and schalter3 = 0 and schalter4 = 0 then gosub Zurueck
    endif
    
    goto Hauptschleife
    
    ...
    return

    And here is the slave code:


    Code:
    'Configuration bits
    @ DEVICE pic16F873a, hs_osc, wdt_on, pwrt_on, bod_on, lvp_off, cpd_off, wrt_off, protect_on 
    
    ' Definitionen
    define osc 4 ' Resonator 4 Mhz
    include "modedefs.bas"
    
    
    TRISC  = %10000000    ' PORTC.7 is the RX input
                          ' PORTC.6 is the TX output
    ' UART Definitionen
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_TXSTA 24h
    DEFINE HSER_BAUD 19200 ' 19200 Bauds
    DEFINE HSER_CLOERR 1
    
    ' Port-Definitionen
    adcon1 = 7 'Ports auf digital
    p1 var portb.0'Pin 1
    p2 var portb.1'Pin 2
    p3 var portb.2'Pin 3
    p4 var portb.3'Pin 4
    p5 var portb.4'Pin 5
    p6 var portb.5'Pin 6
    p7 var portb.6'Pin 7
    l1 var porta.0'Pin 8 LED 1
    l3 var porta.1'Pin 9 LED 3
    l5 var porta.2'Pin 10 LED 5
    l2 var porta.3'Pin 11 LED 2 Rot
    l4 var porta.4'Pin 12 LED 4 Grün
    l6 var porta.5'Pin 13 LED 6 Gelb
    l7 var portc.0'Pin 14 LED 7
    'p15 vcc
    
    ELEIN var portc.1
    s1 var word'frei
    s2 var word'Function
    s3 var word'Hoch
    s4 var word'Runter
    s5 var word'frei
    s6 var word'Pfeil
    s7 var word'Benutzer
    s8 var word'Memory
    s9 var word'frei
    s10 var word'frei
    
    Bus_out var byte
    zaehler var word
    Bus_in var Byte
    busrw var portc.5
    'checksumme var byte
    
    ' Ports als Ein- bzw. Ausgang
    input portb.0
    input portb.1
    input portb.2
    input portb.3
    input portb.4
    input portb.5
    input portb.6
    
    output porta.0
    output porta.1
    output porta.2
    output porta.3
    output porta.4
    output porta.5
    output portc.0
    output portc.1'Display
    
    
    
    '----------------------------------------------------------------------------------
    ' Hauptprogramm
    '----------------------------------------------------------------------------------
    high ELEIN ' Display beim Einschalten aus
    'high l1'LED beim Startem aus
    high l2'LED beim Startem aus
    'high l3'LED beim Startem aus
    high l4'LED beim Startem aus
    'high l5'LED beim Startem aus
    high l6'LED beim Startem aus
    'high l7'LED beim Startem aus
    
    
    Schleife:
    clearwdt
    If PIR1.5 <>  1 Then goto Schleife'Zeichen in UART-Interrupt
    
    'RCSTA.4 = 0
    'RCSTA.4 = 1
    ' Zeichen liegt an UART an
    Bus_in = RCREG
    
    if Bus_in = 100 then gosub Taste ' Master fordert Tastendruck an
    if Bus_in = 105 then gosub Power_on ' Master schaltet Hand/Säule ein
    if Bus_in = 106 then gosub Power_off ' Master schaltet Hand/Säule aus
    'if Bus_in = 110 then low l1'LED1 anschalten
    'if Bus_in = 111 then high l1'LED1 ausschalten
    if Bus_in = 112 then low l2'LED2 anschalten
    if Bus_in = 113 then high l2'LED2 ausschalten
    'if Bus_in = 114 then low l3'LED3 anschalten
    'if Bus_in = 115 then high l3'LED3 ausschalten
    if Bus_in = 116 then low l4'LED4 anschalten
    if Bus_in = 117 then high l4'LED4 ausschalten
    'if Bus_in = 118 then low l5'LED5 anschalten
    'if Bus_in = 119 then high l5'LED5 ausschalten
    if Bus_in = 120 then low l6'LED6 anschalten
    if Bus_in = 121 then high l6'LED6 ausschalten
    'if Bus_in = 122 then low l7'LED7 anschalten
    'if Bus_in = 123 then high l7'LED7 ausschalten
    
    Bus_in = 0
    goto Schleife
    
    
    '----------------------------------------------------------------------------------
    ' Unterprogramm Tastendruck ausgeben
    '----------------------------------------------------------------------------------
    Taste:
    ' Schalter auf Null setzen
    s1=0
    s2=0
    s3=0
    s4=0
    s5=0
    s6=0
    s7=0
    s8=0
    s9=0
    s10=0
    
    ' Ebene 1 abfragen (B4=1) S1, S4, S7, S10
    high p5
    low p6
    low p7
    
    'if p1 = 1 then s1 = 1
    if p2 = 1 then s4 = 1
    if p3 = 1 then s7 = 1
    'if p4 = 1 then s10 = 1
    
    
    ' Ebene 2 abfragen (B5=1) S2, S5, S8
    low p5
    high p6
    low p7
    
    if p1 = 1 then s2 = 1
    'if p2 = 1 then s5 = 1
    if p3 = 1 then s8 = 1
    
    
    ' Ebene 3 abfragen (B6=1) S3, S6, S9
    low p5
    low p6
    high p7
    
    if p1 = 1 then s3 = 1
    if p2 = 1 then s6 = 1
    i'f p3 = 1 then s9 = 1
    
    
     
    low p5
    low p6
    low p7
    
    ' Bus_out ausgeben
    
    Bus_out = 099
    zaehler = 0
    if s1 = 1 then Bus_out=030:zaehler = zaehler +1
    if s2 = 1 then Bus_out=031:zaehler = zaehler +1
    if s3 = 1 then Bus_out=032:zaehler = zaehler +1
    if s4 = 1 then Bus_out=033:zaehler = zaehler +1
    if s5 = 1 then Bus_out=034:zaehler = zaehler +1
    if s6 = 1 then Bus_out=035:zaehler = zaehler +1
    if s7 = 1 then Bus_out=036:zaehler = zaehler +1
    if s8 = 1 then Bus_out=037:zaehler = zaehler +1
    if s9 = 1 then Bus_out=038:zaehler = zaehler +1
    if s10 = 1 then Bus_out=039:zaehler = zaehler +1
    
    if zaehler > 1 then Bus_out = 099
    if s3 = 1 and s4 = 1 then Bus_out = 098
    
    pauseus 7'???
    high busrw
    HSEROUT [Bus_out] ' Ausgabe des Tastendrucks auf UART
    while txsta.1 <> 1 
    wend
    pauseus 14'????
    
    low busrw
    return
    ...
    
    return

  2. #2
    Join Date
    Sep 2008
    Posts
    27


    Did you find this post helpful? Yes | No

    Default

    Running 19200 baud from a 4 Mhz osc, isn't that kind of pushing it a bit?

  3. #3
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    You can easily run that baud rate if you use the hardware serial port, but why are you reading the receive register directly?
    Why not use HSERIN?
    Charles Linquist

  4. #4
    Join Date
    Jul 2007
    Posts
    6


    Did you find this post helpful? Yes | No

    Default

    Where is the difference between reading the receive register by x = rcreg or hserin?
    Does hserin do a little more than only shift the receive buffer in a variable?

  5. #5
    Join Date
    Sep 2005
    Location
    Campbell, CA
    Posts
    1,107


    Did you find this post helpful? Yes | No

    Default

    Not much more - if you are receiving only one byte, but it does a good job of checking CREN and clearing it, if necessary. That is something your code doesn't do and the hardware doesn't automatically clear the bit. The CLOERR define in your header does nothing in your case.
    Charles Linquist

Similar Threads

  1. RS485 splitter
    By The Master in forum Off Topic
    Replies: 0
    Last Post: - 30th August 2009, 06:04
  2. Oscillator stops when touching with a wire
    By Wilbert Ingels in forum mel PIC BASIC Pro
    Replies: 23
    Last Post: - 25th April 2008, 08:51
  3. Need the code to write to a memory
    By Hamlet in forum General
    Replies: 0
    Last Post: - 20th August 2007, 00:22
  4. Compass module and I2C bus
    By vladimir059@hot in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 26th December 2006, 20:29
  5. Using 16f676 with comms
    By Peter1960 in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 28th October 2005, 20:01

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts