- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 9 von 9

Thema: Uart-Abfrage mit Atmega128 - Mit Lösung!

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    06.09.2009
    Beiträge
    53

    Uart-Abfrage mit Atmega128 - Mit Lösung!

    Anzeige

    E-Bike
    Hallo,

    Ich versuche mit einem ATmega128 und daran angeschlossenem Funkmodul Daten zu empfangen. Die Daten werden von einem weiteren Prozessor (A32) über ein Funkmodul gleichen Typs gesendet.

    Aber leider funktioniert das Auswerten und Beschreiben des Strings nicht.

    Als Daten werden gesendet: "Chr(15)" und danach ""Hallo!""
    Schließe ich das Sendeboard direkt an das Display an, wird das auch korrekt angezeigt, dort kann der Fehler nicht liegen.


    Bitte guckt einmal meinen Programmcode durch:


    Code:
    $regfile = "m128def.dat" ' Bei Mega 128 "
    $framesize = 40
    $swstack = 40
    $hwstack = 40
    $crystal = 16000000                              'Quarzfrequenz
    $baud = 19200                                    'Baudrate für Funkmodul
    $baud1 = 19200
    
    
    Config Pine.2 = Output
    Rdy_hostempfangsbereit Alias Porte.2                                             
    
    Open "com2:" For Binary As #2
    Config Serialin = Buffered , Size = 50 , Bytematch = 15                    
    
    Enable Interrupts
    ' ---------------------------------------------------
    Dim Z As Byte
    Dim Text As String * 6
    
    Print #2 , "RN Mega128Funk"
    
    Rdy_hostempfangsbereit = 0
    
    Echo Off
    
    Do
       Print #2 , Text
       Waitms 500
    Loop
    
    
    
    Serial0charmatch:
       Text = Inkey()
    Return

    Wem die 2te konfigurierte RS232-Schnittstelle auffällt:
    Dort habe ich ein Display angeschlossen(RN KeyLCD), das die gleiche Funktion eines Terminalprogramms hat.


    Das Ergebnis was dann im Display angezeigt wird sind nur einzelne 'H's, keine 6 Zeichen "Hallo!"



    Bitte versucht meinen Fehler zu finden!

    Mit freundlichen Grüßen
    Jimmy

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hallo Jimmy,

    in dem Serial0charmatch Unterprogramm ist dein Fehler. In deinem Programm überschreibt die Zeile "Text = Inkey()" nämlich immer die Variable Text mit dem neuesten UART "Textzeichen".
    Du musst folgendes Schreiben:
    Code:
    Serial0charmatch:
    buffer = inkey()
    text = text + buffer
    return
    Wobei ich mir momentan nicht sicher bin, ob inkey() hier richtig ist oder man besser "udr" nehmen soll....
    buffer ist hier eine zusätzliche Variable als Zwischenspeicher, welche vom gleichen Typ wie Text sein sollte.

    Gruß
    Chris

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Hallo Jimmy,
    Inkey() liest nur ein einzelnes Zeichen aus dem Input Buffer. Daher bleibt es immer bei dem "H".
    Wenn hinter dem "!" ein <CR> kommt, dann schreib doch mal
    Input Text, Noecho

    Ansonsten wäre es besser, du würdest nach deinem Text ein bestimmtes Zeichen, wie z.B. CHR(15) senden.
    Wenn jetzt der SerialCharMatch kommt, dann sind schon alle Zeichen im Puffer und das Programm braucht nicht mehr auf das Eintreffen zu warten.

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    06.09.2009
    Beiträge
    53
    Hi Chris,

    Danke für deine konstruktive Antwort!

    Meinst du das weil der Inkey-Befehl immer nur ein Zeichen aufnehmen kann?
    Ich habs in der Library nachgelesen, man kann auch den ganzen String damit befüllen.


    Ich habe deinen Vorschlag trotzdem mal ausprobiert und siehe da, nun zeigt er nicht nur eine Stelle "H" an, sondern "Ha".
    Ich müsste also das "text = text + buffer" nur für jede Stelle die der String hat wiederholen und hätte dann die ganze Nachricht.

    Aber plötzlich resettet sich der Controller immer nach einigen Sekunden selbständig, nur nach diesem Einschub...

    Läuft da eventuell "text" über?

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    06.09.2009
    Beiträge
    53
    Hallo for_ro,

    Auch dir danke ich für deinen Beitrag!

    Du meinst man kann zwar einen String mit "Inkey" beschreiben, dieser wird aber dann imer nur ein Zeichen haben?
    Warum steht aber dann in der Bascom-Library ein Beispiel mit einem 2-Zeichen-String?

    Über die Reihenfolge von Erkennunsgzeichen und den eigentlichen Daten habe ich schon nachgedacht, doch ich kam zu dem Schluss dass die Funktion ab dem Erkennunsgzeichen alle x viele Zeichen liest.

    Danke dass du mich darüber nochmal aufgeklärt hast!

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    In der Library ist aber doch ein Loop drinnen, der Inkey immer wieder aufruft.
    SerialCharMatch funktioniert so, dass zu dem Label gesprungen wird, wenn das Zeichen empfangen wurde, welches du vorgegeben hast.
    Dort fragst du mit Inkey das erste Zeichen des Puffers ab. Danach geht das Programm wieder zurück zu dem befehl, wo es unterbrochen wurde.
    Dies ist bei dir die Do..Loop mit dem Print alle 500ms. D.h. du kannst so nur ein Zeichen einlesen. Überleg es dir noch einmal.
    Du könntest es auch so machen:

    Code:
    Serial0charmatch:
       While IsCharWaiting() = 1
            Text = Text + Inkey()
       Wend
    Return

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    06.09.2009
    Beiträge
    53
    Ich habe die Änderungen eingebaut, eine gute Idee mit der while-Schleife, doch nun gibt der Controller gar nichts mehr aus, sondern resettet sich sofort.

    Sobald der Atmega etwas empfängt setzt er sich selbst zurück.

    Wenn ich das Sendeboard ausmache läuft das Programm weiter durch, nur kann es dann natürlich nichts mehr empfangen.

    Hier nochmal mein Programmcode:

    Code:
    $regfile = "m128def.dat" ' Bei Mega 128 "
    $framesize = 40
    $swstack = 40
    $hwstack = 40
    $crystal = 16000000                                         'Quarzfrequenz
    $baud = 19200                                               'Baudrate für Funkmodul
    $baud1 = 19200
    
    
    Config Pine.2 = Output
    Rdy_hostempfangsbereit Alias Porte.2                        
    
    Open "com2:" For Binary As #2
    Config Serialin = Buffered , Size = 10 , Bytematch = 15
    
    
    Enable Interrupts
    ' ---------------------------------------------------
    Dim Text As String * 6
    Dim Buffer As String * 1
    
    Print #2 , "RN Mega128Funk"
    Rdy_hostempfangsbereit = 0
    
    
    Echo Off
    
    Do
        Print #2 , Text
       Waitms 500
    Loop
    
    
    
    
    Serial0charmatch:
       While Ischarwaiting() = 1
    
          Buffer = Inkey()
          Text = Text + Buffer
          Wend
    
    Return
    Übrigens hat die Buffergröße keinerlei Einfluss auf die Zeit bis zum Reset, auch wenn ich sie erhöhe.

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Ich verstehe zwar nicht, warum du unbedingt bei der Version mit Startzeichen bleiben willst, aber sei's drum.
    Mach mal in die Sub ein Pushall und ein Popall, so wie es in der Hilfe steht.
    Nach dem Printen würde ich die Variable Text leeren, sonst wird sie immer größer.

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    06.09.2009
    Beiträge
    53
    Ich habe die Änderungen eingebaut, doch leider tat sich nach wie vor nichts, außer dem periodischen Selbst-Reset des Controllers.

    Dann habe ich nach einem anderen Weg gesucht und bin schließlich auf einen Thread gestoßen, wo du in der gleichen Frage Jemandem anders geantwortet hast.

    Damit klappt es!!! \/

    Hier mein endgültiger Code:
    Code:
    $regfile = "m128def.dat" ' Bei Mega 128 "
    $framesize = 40
    $swstack = 40
    $hwstack = 40
    $crystal = 16000000                                         'Quarzfrequenz
    $baud = 19200                                               'Baudrate für Funkmodul
    $baud1 = 19200
    
    Config Pine.2 = Output
    Rdy_hostempfangsbereit Alias Porte.2                        'Auf Low setzen wenn Empfangsbereit für Daten vom Funkmodul
    
    Open "com2:" For Binary As #2
    Config Serialin = Buffered , Size = 20 , Bytematch = 13
    
    Enable Interrupts
    ' ---------------------------------------------------
    Dim Command_key As Byte
    Dim Command_count As Byte
    Dim Command_string As String * 12
    Dim Empfang As Bit
    Empfang = 0
    Rdy_hostempfangsbereit = 0
    
    Echo Off
    
    Do
    
       If Empfang = 1 Then
       Sound Portg.2 , 200 , 650
    
        Waitms 1
       Print #2 , Command_string
        Empfang = 0
        Command_string = ""
    
        End If
    Loop
    
    
    Serial0charmatch:
        Empfang = 1
       Command_count = 0
       Command_string = ""
       While Ischarwaiting() = 1
          Command_key = Inkey()
          If Command_key <> Chr(13) Then
             Incr Command_count
             If Command_count < 12 Then
                Command_string = Command_string + Chr(command_key)
             End If
          End If
       Wend
       Clear Serialin
    Return

    Der String ist 12 Zeichen lang, wer eine andere Länge haben will muss sie oben bei "Dim String as" und unten bei "If Command_count" ändern.

    Wer ein anderes Erkennungszeichen als Chr(13) nehmen will, muss es oben bei "Config Serialin [...] Bytematch=" und unten bei "If command_key" ändern.


    Das Bit "Empfang" sorgt dafür dass nur dann Text ausgegeben wird, wenn neue Daten empfangen wurden.


    Die Geschwindigkeit ist super! Mein Sender sendet im Abstand von 200 Millisekunden "Hallo" mit einer Zählvariable die von 1 bis 9 läuft und jede Message wird korrekt angezeigt.

    Hier noch der Link zum Original-Thread:

    https://www.roboternetz.de/phpBB2/ze...t=input+string

    Viel Spaß mit dem Programm und nochmals Danke an dich Rolf! =D>

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test