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


 
		
		 
						
					 
			 
			 
			 
					
					 RS485 bus - starting probem
 RS485 bus - starting probem
		



Bookmarks