Kommunikation zwischen zwei MCs über UART

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Kommunikation zwischen zwei MCs über UART

      Hallo,

      ich versuche gerade die Kommunikation zwischen zwei Mcs (Atmega256&Atmega128) zum laufen zu bekommen, allerdings geben mir die beiden immer noch nicht die richtigen Werte aus... vielleicht kann mir ja jemand von euch sagen ob ich irgendetwas im Ansatz falsch mache, mehr Augen sehen mehr: (Achja und ich bin neu im Forum bitte weißt mich gerne auf Fehler zur Formatierung des Themas hin;))

      AtMega256.bas
      ATMega128.bas


      Vielen Dank schon mal für eure Hilfe!
    • Hey danke für die Antwort.
      Grundsätzlich sollen die Werte von 0 bis 1023 hin und her geschickt werden (ADC Messwerte von Drucksensoren).
      Von den Com Ports sind im eigentlichen Programm(das natürlich etwas umfangreicher ist), die anderen Kanäle alle belegt, im Testprogramm werden nur die betroffenen angesprochen(habe die anderen nur drin gelassen damit ersichtlich ist warum ich beim 256 auf einen Software UART zurückgreifen muss).
      Ja beim rausfiltern der Komponenten habe ich vergessen eine dementsprechende Main hinzuzufügen a_45_132ca9f5 (ist in den aktualisierten Dateien s.u. behoben sowie die Copy&Paste Fehler die ich noch hatte).
      AtMega256.bas
      ATMega128.bas
    • Das sieht recht kompliziert aus. Warum nicht in Klartext? For a=1 to 5: Print word(a);","; :Next: Print
      Damit kann es auch ein Terminal beobachten /simulieren und ein sauberer Abschluss (CrLf) ist auch vorhanden. (Die 75 könnte auch ein Low Byte sein).
      PS Warum soll dem 128 mitgeteilt werden das er empfangen soll? Wäre da ein Handshake nicht angebrachter (Cts/Rts)?
    • Das muss ich morgen mal probieren, sieht definitiv einfacher aus^^. Bin leider noch nicht so versiert in BASCOM aber das wird hoffentlich noch :)

      Für CTS/RTS benötige ich doch den serial input/output buffer der mir beim Software UART fehlt, oder habe ich da etwas falsch verstanden?

      Finde es auf jeden Fall toll, dass ich von euch so schnell Antworten erhalte, kenn ich aus Foren in anderen Fachgebieten nicht so ;)
    • Ballistic_Cross schrieb:

      Für CTS/RTS benötige ich doch den serial input/output buffer der mir beim Software UART fehlt
      Beim SW Uart muß der Avr alles selber erledigen. Da muß man sich Gedanken über das Timing/Prioritäten machen:
      Gibt es Dinge die wichtiger sind als zuzuhören bzw nicht unterbrochen werden dürfen und länger Dauern als ein bit (bei 9600 Baud ca 100ns)?
      Muß er jede Sendung verstehen? Oder reicht es zuzuhören wenn er Zeit hat?
      Da würde eine Leitung "Ich spreche jetzt" nicht wirklich helfen (Einen Interrupt kann auch von Rx ausgelöst werden)
      Zwei Leitungen jedoch schon "Ich hab was zu sagen" (CTS) dann wenn er Zeit hat "Dann leg los" (RTS)
      Damit hätte der Empfänger keinen Stress mehr. Aber evt der Sender. Wie lange darf der seine Arbeit unterbrechen bis er senden darf?
      PS Von den verbrauchten HW Uart werden alle Rx gebraucht? Keiner der nur spricht?
    • Hallo Ballistic_Cross,

      da die RS232 fast nur die elektrischen Eigenschaften der asynchronen Schnittstelle beschreibt ist es eventuell zum weiterführenden Verständnis nützlich, mal die nächste Ebene (V.24) anzuschauen. Dort sind die Handshake- Eigenschaften sogar in einer Norm definiert.
      Hier kann man auch Antworten finden, welche sich mit dem manchmal kritischen Timing-Verhalten der beiden asynchronen Partner beschäftigt.
      Die nächste Entwicklungsstufe wäre die Implementierung eines standardisierten Xon/Xoff Protokolls.
      Für jede dieser Ebenen hält Google massenhaft gute Informationen bereit.

      Gruß Rudi
      Immer Glück haben ist fast wie können..
    • Ballistic_Cross schrieb:

      Das muss ich morgen mal probieren, sieht definitiv einfacher aus^^. Bin leider noch nicht so versiert in BASCOM aber das wird hoffentlich noch

      Für CTS/RTS benötige ich doch den serial input/output buffer der mir beim Software UART fehlt, oder habe ich da etwas falsch verstanden?
      Aller Anfang ist bekanntlich schwer.

      Man kann mit dem Empfangsbuffer RTS/CTS konfigurieren. Muss man aber nicht.
      Man kann die Signale auch "von Hand" steuern. RTS (Request to Send) ist ja die Anfrage an den Empfänger, ob der Empfangsbereit ist. Dies meldet der mit CTS (Clear to Send) zurück.

      In deinem Code hast du offensichtlich alle Mühe mit dem Senden und Empfangen.
      Daher habe ich mal eine kleine (ungetestete) Demo geschrieben, die dir vielleicht das Verständnis etwas näher bringt.

      Deinem Code konnte ich entnehmen, dass du ein Startbyte "A" und dann ein "K" sendest.
      Das hat mich auf "AT" als Startsequenz gebracht, die ich im Code verwendet habe.
      Angelehnt an deinen Code sende ich werden dann 4 Word-Werte und ein Checkbyte übertragen.

      Es wird bei mir kein Empfangsbuffer verwendet und auch kein Timer.
      (Mit Empfangsbuffer wäre das einfacher.)

      Am besten du schaust dir den Code mal an und versuchst den nachzuvollziehen.
      Viel Erfolg!

      BASCOM-Quellcode: Demo Senden/Empfangen mit UART1

      1. ' Demo Empfang und Senden mit UART1
      2. ' Beschreibung
      3. ' Dieses Demo aktiviert mit Taste den Empfang für ein Paket.
      4. ' Wird dieses korrekt empfangen, wird dieses zurück gesendet.
      5. ' Im Fehlerfall wird der Empfang automatisch neu getriggert.
      6. ' Handshake wird nicht verwendet, kann aber recht einfach implementiert werden.
      7. ' Paket: "AT"<Word1><Word2><Word3><Word4><CheckByte>
      8. $regfile = "m128def.dat"
      9. $hwstack = 64
      10. $swstack = 40
      11. $framesize = 40
      12. $crystal = 16000000
      13. ' ---------------------------------------------------
      14. ' Variablen und Deklaration
      15. ' ---------------------------------------------------
      16. ' Bytes für Senden
      17. Dim TxWert1 as Word ' 4x Daten Word
      18. Dim TxWert2 as Word
      19. Dim TxWert3 as Word
      20. Dim TxWert4 as Word
      21. Dim TxSum as Byte ' Byte-Checksumme Senden
      22. ' Bytes für Empfangen
      23. Dim RxBuffer(12) as Byte ' Buffer für Datenempfang
      24. Dim RxIndex as Byte ' Array-Index Datenbuffer
      25. Dim RxByte as Byte ' temporäres Empfangenes Byte
      26. Dim RxSum as Byte ' Byte-Checksumme Empfang
      27. Dim RxCompleted as Bit ' Paket komplett empfangen und gültig (Checksumme korrekt)
      28. Dim RxError as Bit ' Paket fehlerhaft (Checksumme ungültig)
      29. ' Hilfsvariablen um auf die Wordwerte im Buffer zuzugreifen
      30. Dim RxWord1 as Word at RxBuffer(3) Overlay ' Word 1
      31. Dim RxWord2 as Word at RxBuffer(5) Overlay ' Word 2
      32. Dim RxWord3 as Word at RxBuffer(7) Overlay ' Word 3
      33. Dim RxWord4 as Word at RxBuffer(9) Overlay ' Word 4
      34. Declare Sub SendAllValues()
      35. Declare Sub TxWord(Byval value as Word)
      36. Declare Sub GetAllValues()
      37. Declare Sub RxDataByte()
      38. ' ---------------------------------------------------
      39. ' Initialisierung
      40. ' ---------------------------------------------------
      41. Config Com2 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
      42. Open "com2:" For Binary As #1 ' Hardware UART RX/TX für MainProzessor (PD2/PD3)
      43. Taste Alias PinC.0
      44. Config Adc = Single , Prescaler = Auto , Reference = Avcc
      45. Start Adc
      46. Enable Interrupts
      47. ' ---------------------------------------------------
      48. ' Hauptschleife
      49. ' ---------------------------------------------------
      50. Do
      51. ' Es braucht einen Auslöser (Trigger), der das Empfangen anstößt
      52. ' Hier wird beispielhaft eine Taste verwendet.
      53. ' Wird ein gültiges Paket empfangen, wird es zurück gesendet
      54. If Taste = 0 then
      55. Call GetAllValues() ' Empfang triggern
      56. End If
      57. Call RxDataByte() ' Permanent abfragen (Datenempfang)
      58. ' Empfangs-Status abfragen und darauf reagieren
      59. If RxCompleted = 1 then ' Empfang von Paket komplett
      60. ' Empfangene Daten stehen jetzt im RxBuffer zur Verarbeitung bereit
      61. ' In der Demo werden diese einfach zurück gesendet.
      62. ' Die 4 Word-Werte in die Sende-Variablen übernehmen
      63. TxWert1 = RxWord1
      64. TxWert2 = RxWord2
      65. TxWert3 = RxWord3
      66. TxWert4 = RxWord4
      67. Call SendAllValues() ' Daten zurück-senden
      68. ElseIf RxError = 1 then ' Checksumme war falsch
      69. ' Fehler beim Datenempfang. Empfang erneut versuchen
      70. Call GetAllValues() ' Empfang nochmal starten
      71. End If
      72. Loop
      73. ' ---------------------------------------------------
      74. ' Routinen für das Senden
      75. ' ---------------------------------------------------
      76. ' Sendet ein Datenpaket incl. berechnete Byte-Ckecksumme
      77. Sub SendAllValues()
      78. TxSum = 0 ' Byte-Checksumme auf 0
      79. Print #1 , "AT"; ' Startbyte's (65, 84) absetzen (nicht in Byte-Checksumme berücksichtigt)
      80. ' 4x Word-Wert absetzen
      81. Call TxWord(TxWert1) ' Word 1
      82. Call TxWord(TxWert2) ' Word 2
      83. Call TxWord(TxWert3) ' Word 3
      84. Call TxWord(TxWert4) ' Word 4
      85. Printbin #1 , TxSum ' Byte-Checksumme
      86. End Sub
      87. ' Sendet Word-Wert und aktualisiert Byte-Checksumme
      88. ' Wird von SendAllValues() aufgerufen
      89. Sub TxWord(Byval value as Word)
      90. txSum = txSum + Low(value) ' Wordwert in Checksumme verrechnen
      91. txSum = txSum + High(value)
      92. PrintBin #1 , value ' Word-Wert absetzen
      93. End Sub
      94. ' ---------------------------------------------------
      95. ' Routinen für den Empfang
      96. ' ---------------------------------------------------
      97. ' Initiiert den Empfang eines Pakets
      98. ' Wenn der Empfang starten soll, wird diese Routine 1x aufgerufen
      99. Sub GetAllValues()
      100. RxIndex = 1
      101. RxCompleted = 0
      102. RxError = 0
      103. End Sub
      104. ' Empfang von einzelnen Datenbytes
      105. ' Diese Routine wird permanent aufgerufen, bis eines der Falfs gesetzt ist.
      106. ' RxCompleted = 1, wenn Paket mit korrekter Checksumme empfangen wurde
      107. ' RxError = 1, wenn Paket empfangen wurde, aber Checksumme nicht stimmt
      108. Sub RxDataByte()
      109. If IsCharWaiting(#1) = 0 then Exit Sub ' Sub verlassen, wenn nichts empfangen wurde
      110. Select Case RxIndex
      111. Case 1 ' Empfang von "A"
      112. InputBin #1 , RxByte ' Byte einlesen
      113. If RxByte = "A" then ' 1. Startbate "A" ?
      114. RxBuffer(RxIndex) = RxByte ' Byte im Buffer ablegen
      115. Incr RxIndex
      116. RxSum = 0
      117. End If
      118. Case 2 ' Empfang von "T"
      119. InputBin #1 , RxByte ' Byte einlesen
      120. If RxByte = "T" then ' 2. Startbyte "K" ?
      121. RxBuffer(RxIndex) = RxByte ' Byte im Buffer ablegen
      122. Incr RxIndex
      123. End If
      124. Case 3 to 10 ' Empfang Daten (4 Word's)
      125. InputBin #1 , RxByte ' Datenbyte
      126. RxSum = RxSum + RxByte ' Byte-Checksumme aktualisieren
      127. RxBuffer(RxIndex) = RxByte ' Byte im Buffer ablegen
      128. Incr RxIndex
      129. Case 11 ' Empfang TxSum
      130. InputBin #1 , RxByte ' Checksum-Byte
      131. RxBuffer(RxIndex) = RxByte ' Byte im Buffer ablegen
      132. If RxByte = RxSum then ' Checksumme stimmt
      133. Set RxCompleted ' Flag setzen für gültiges Paket
      134. Else
      135. Set RxError ' Flag setzen, Empfang ungültig
      136. End If
      137. Incr RxIndex
      138. Case 12 ' Paket komplett / Empfang beendet
      139. ' Dummy-State
      140. End Select
      141. End Sub
      Alles anzeigen