Also 300 wäre ja 00000001 00101100:
ich empfange an : im 1. Byte 00101100
im 2. Byte 11000000
und im 2. Byte liegt der Fehler das müsste ja 00000001 sein!!
Oder?
Also 300 wäre ja 00000001 00101100:
ich empfange an : im 1. Byte 00101100
im 2. Byte 11000000
und im 2. Byte liegt der Fehler das müsste ja 00000001 sein!!
Oder?
Also ich versteh es aktuell nicht.
Ich habe jetzt mal noch ein paar Versuche gemacht. Zum einen habe ich 2 Byte mit jeweils einer 10 gesendet. Die erste 10 kommt sauber an. die 2. 10 ist irgend ein Mist. Egal was ich sende das 1. Byte passt und dann kommt nur noch Käse.
Ich habe auch mit den Baudraten etwas herumgespielt. Egal was ich einstelle immer das selbe Bild.
Woran könnte das noch liegen?
Könnte es an den Abschlusswiderständen des Busses liegen? Hatte nur 110 Ohm statt 120 Ohm.
Nein die 10Ohm machen es nicht aus. Poste mal dein Code und eine komplette Verdrahtung.
Also die Schaltung sieht so aus:
und das Programm:
Code:$regfile = "m8def.dat" $crystal = 8000000 'the internal oscillator of 8 Mhz was choosen in the fusebits $baud = 19200 Osccal = &HAE $hwstack = 32 ' default use 32 for the hardware stack $swstack = 32 ' default use 32 for the SW stack $framesize = 50 ' default use 50 for the frame space 'Ports Deklarieren Relais1 Alias Portc.0 Config Relais = Output Rs485dir Alias Portd.2 Config Rs485dir = Output Rs485dir = 0 ' Empfangsmodus Taster1 Alias Pinc.2 Config Taster1 = Input Portc.2 = 1 'PullUp-Widerstand einschalten Taster2 Alias Pinc.3 Config Taster2 = Input Portc.3 = 1 'PullUp-Widerstand einschalten Stromsensor Alias Pinc.4 Config Stromsensor = Input Portc.4 = 1 'PullUp-Widerstand einschalten $timeout = 100000 'System-Timer für periodische Encoder-Abfrage Config Timer0 = Timer , Prescale = 256 On Timer0 Isr_timer0 Enable Timer0 Const Timer0_reload = 250 Config Debounce = 30 'Interrupt Daten wurden empfangen 'On Urxc Onrxd 'Interrupt-Routine setzen (Daten über UART empfangen) 'Enable Urxc 'Interrupt URXC einschalten 'Interrupt Daten wurden gesendet On Utxc Ontxd Enable Utxc Enable Interrupts 'Interrupts global zulassen 'Variablendeklaration Dim Teilnehmeradresse As Byte Teilnehmeradresse = 10 'MainLoop Do Loop On_taster1: Toggle relais 'SENDETEST Rs485dir = 1 Waitms 50 Printbin Teilnehmeradresse ; Teilnehmeradresse; Return Ontxd: Waitms 50 Rs485dir = 0 Return 'Timer 0 Isr_timer0: Timer0 = Timer0_reload Debounce Taster1 , 0 , On_taster1 , Sub Return End
Moin Demmy,
In der Sub on_taster1 wird etwas über die UART gesendet - und wenn die Sendung komplett ist, wird noch vor dem Return die ISR Ontxd ausgeführt. Ich weiß nicht, ob der TXC-Interrupt nicht schon bereits nach dem ersten gesendeten Byte ausgeführt wird. Wenn ja, könnte diese Unterbrechung vielleicht der Grund sein, weshalb beim 2. Byte Fehler entstehen.
Lass in einem ersten Schritt den TXC-Interrupt doch einfach mal weg - und setze die beiden Befehle aus der Ontxd-ISR einfach mal hinter den Printbin-Befehl in der Taster-Sub:
Code:On_taster1: Toggle relais RS485dir = 1 waitms 50 Printbin Teilnehmeradresse ; Teilnehmeradresse ; waitms 50 RS485dir = 0 Return
Wenn´s dann funktioniert, kannst Du sozusagen an der "B-Note" arbeiten:
Waitms-Befehle in ISRs sind nämlich etwas, was schnell mal problematisch werden kann. Die Hauptschleife wird nämlich ganz schön lange aufgehalten, und andere Interrupts könnten während einer laufenden ISR u.U. ignoriert werden.
In Deinem Code ist die Hauptschleife ja recht übersichtlichund deshalb wirkt sich dieser Schönheitsfehler nicht besonders aus. In komplexeren Programmen sollte man in der ISR aber idealerweise nur ein Flag-Bit auf 1 setzen, das dann in der Hauptschleife regelmäßig abgefragt wird. Ist es 1, werden die Befehle ausgeführt, die zu dem Interrupt gehören, und das Bit anschließend auf 0 gesetzt.
Und noch was:
So wie ich das hier sehe, hast Du etwa 6000 (!) Timer0-Interrupts pro Sekunde. Das hält den Controller schon ganz schön in Schach, und ich könnte mir vorstellen, dass dieses Dauerfeuer an Interrupt-Routinen den Print-Befehl auch etwas stören könnte. Wenn Du damit nur den Taster1 abfragen möchtest, ginge das wesentlich leichter: Entweder direkt in der Hauptschleife, oder aber über einen der beiden externen Interrupt-Eingänge INT0 bzw. INT1.
Also das hört sich logisch an, ich werde das auf jeden Fall später mal testen.
Wegen der Timerproblematik: ich könnte doch den Const Timer0_reload = 250 heruntersetzen um die Anzahl der Aufrufe zu verringern oder?
Klar, aber wieso brauchst Du so etwas aufwendiges wie eine ISR, nur um den Taster abzufragen? Wenn Du den debounce-Befehl in die Hauptschleife packst, sparst Du dem Controller nicht nur eine Menge Arbeit in Form von tausenden von Interrupts - sondern der Taster wird auch noch viel häufiger abgefragt! Aber am elegantesten wäre es nach wie vor, mit dem Taster einen externen Interrupt auszulösen!Wegen der Timerproblematik: ich könnte doch den Const Timer0_reload = 250 heruntersetzen um die Anzahl der Aufrufe zu verringern oder?
Lesezeichen