- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: ERAM Problem mit Mega8

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    03.06.2010
    Beiträge
    8

    ERAM Problem mit Mega8

    Anzeige

    Praxistest und DIY Projekte
    Hallo,
    kurz zu mir: Ich bin neu hier und Anfänger! Bislang "spielte" ich nur auf einem Testboard mit Mega8 und LCD.

    Ich hab mich nun dran gemacht ein Projekt nachzubauen. Die Hardware läuft prima und auch die Software (Bascom) funktioniert überraschend gut.
    Im Programm sollen knapp 30 Datensätze im ERAM des Mega8 gespeichert werden. Ein Datensatz besteht aus einer 13-stelligen Zahl welche einen fünfstelligen Code (Folge), Datum und Uhrzeit beinhaltet.

    Schreiben funktioniert absolut ohne Probleme, lesen mach nach ein paar Minuten Laufzeit Probleme. Dort werden die Zahlen eines Datensatzes quer durchgemischt ausgelesen, aber nur bei einigen Datensätzen. Sprich der Großteil bleibt OK.

    Definition:
    Code:
    Dim Eepointer As Eram Byte
    Dim Pointer As Byte
    Dim Codestring As String * 13
    Dim Ecodestring(30) As Eram String * 13
    Dim Zeitlcd As String * 11
    Dim Folgelcd As String * 16
    Dim Codedat As String * 4
    Dim Codetime As String * 4
    Dim Codeuhr As String * 8
    Schreiben:
    Code:
    Pointer = Eepointer
    If Pointer = 50 Then Pointer = 0
    Incr Pointer
    Eepointer = Pointer
    Codestring = Folge + Bcd(day) + Bcd(month) + Bcd(h) + Bcd(m)
    Ecodestring(pointer) = Codestring
    Lesen:
    Code:
    If Richtung = 0 Then Incr Position
    If Richtung = 1 Then Decr Position
    If Position = 31 Then Position = 1
    If Position = 0 Then Position = 30
    If Position = 255 Then Position = 30
    Pointer = Eepointer
    Sprung = Pointer - Position
    Sprung = Sprung + 1
    If Sprung >= 0 Then
        Stelle = Pointer
        Stelle = Stelle - Position
        Stelle = Stelle + 1
      Else
        Stelle = Pointer
        Stelle = Stelle - Position
        Stelle = Stelle + 31
    End If
    Codestring = Ecodestring(stelle)
    Codeuhr = Right(codestring , 8)
    Codedat = Left(codeuhr , 4)
    Codetime = Right(codeuhr , 4)
    Zeitlcd = Left(codedat , 2) + "/" + Right(codedat , 2) + " " + Left(codetime , 2) + ":" + Right(codetime , 2)
    Folge = Left(codestring , 5)
    Im Hintergrund läuft ein PCF8583P welcher Datum und Uhrzeit über I2C bereitstellt.

    Kann man anhand dieser Codeschnipsel einen Fehler feststellen oder braucht ihr mehr? Kann gerne auch den gesamten Code reinstellen.

    Gruß
    Andy

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113

    Re: ERAM Problem mit Mega8

    Hallo Andy,

    Zitat Zitat von KL7000F
    Dim Ecodestring(30) As Eram String * 13
    If Pointer = 50 Then Pointer = 0
    Du deklarierst dir 30 Strings, benutzt aber 50.

    Zitat Zitat von KL7000F
    Code:
    If Richtung = 0 Then Incr Position
    If Richtung = 1 Then Decr Position
    If Position = 31 Then Position = 1
    If Position = 0 Then Position = 30
    If Position = 255 Then Position = 30
    Pointer = Eepointer
    Sprung = Pointer - Position
    Sprung = Sprung + 1
    If Sprung >= 0 Then
        Stelle = Pointer
        Stelle = Stelle - Position
        Stelle = Stelle + 1
      Else
        Stelle = Pointer
        Stelle = Stelle - Position
        Stelle = Stelle + 31
    End If
    Mit dieser Berechnung der Stelle zum Lesen komme ich nicht klar. Wenn in EEPointer die aktuelle Position steht, dann brauchst du doch eigentlich nur
    Stelle = EEPointer * 14 'Stringlänge 13 + Ende 0

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    03.06.2010
    Beiträge
    8
    Hallo,
    mit der Berechnung der Stelle ist folgendes bewirkt:
    Am Gerät sind drei Taster verbaut. Mit zweien kann ich durch die Datensätze switchen. Der dritte Taster ist sozusagen "Set" (für Menü). Da die Datensätze nach Eingang sortiert werden (sprich der zuletzt eingegebene Eintrag an der Nr. 1, somit werden diese immer um eine Stelle nach hinten geschoben. Bei 31 sind sie somit weg).

    Die Anzahl der Strings werde ich mal reduzieren. Warum das so ist kann ich mir gerade nicht erklären

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Wenn du wirklich immer den letzten Eintrag auf der Stelle 1 stehen hast, dann musst du alle anderen verschieben. Das ist im EEPROM sicher ganz besonders schlecht, da ja nur beschränkt oft geschrieben werden kann.
    Ich hätte jetzt gedacht, dass du das Array als Ring-Puffer benutzt und EEPointer auf die aktuelle Stelle zeigt.
    Dabei brauchst du gar nichst umzukopieren es läuft alles über den Schreib-Zeiger auf die letzte Stelle. Dein Lese-Zeiger kann dann beliebig gesetzt werden. Kommt einer der Zeiger oben oder unten ans Ende, wird er entsprechend auf das andere Ende gesetzt. Da keine Einträge verschoben werden, geht das auch viel schneller.
    Schwierig wird es nur, wenn die Elemente unterschiedlich lang sind, was bei dir aber ja nicht der Fall ist.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    03.06.2010
    Beiträge
    8
    Hi,
    zumindest wird das Programm die einzelnen Strings nicht durcheinander. Aber einige Zuordnungen werden entweder garnicht gespeichert bzw. in der Reihenfolge durcheinander gebracht. Meist nur einer oder zwei.

    Code:
    $regfile = "m8def.dat"
    $crystal = 10000000
    
    $lib "i2c.lib"
    
    
    Ddrb = &B111
    Ddrd = &B00000001
    Portd.1 = 1
    Portd.2 = 1
    Portd.3 = 1
    Portb.0 = 1
    
    Config Lcd = 16 * 2
    Config Lcdbus = 4
    Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portb.1 , Rs = Portb.2
    Cursor Off
    
    Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising , Noise Cancel = 1
    Config Aci = On , Compare = On , Trigger = Rising
    
    On Timer0 Ontimer0
    Config Timer0 = Counter , Edge = Falling
    Enable Timer0
    
    
    On Icp1 Oncapture
    Enable Icp1
    
    On Int0 Taster1
    Config Int0 = Falling
    
    
    On Int1 Taster2
    Config Int1 = Falling
    
    Enable Interrupts
    
    Config Sda = Portc.4
    Config Scl = Portc.5
    I2cinit
    
    Dim Zaehler As Word
    Dim Icr_neu As Word
    Dim Icr_alt As Word
    Dim Frequlong As Long
    Dim Frequenz As Word
    Dim A(10) As Word
    Dim Frequsumme As Word
    Dim Adizaehler As Integer
    Dim Durchschnitt As Word
    Dim Grenzeo As Word
    Dim Grenzeu As Word
    Dim Ton As String * 1
    Dim Tonalt As String * 1
    Dim Tonalt2 As String * 1
    Dim Folge As String * 5
    Dim Timeout As Word
    Dim Folgeto As Word
    
    Dim Ausgabe As String * 16
    Dim Folgealt As String * 16
    
    Dim Eepointer As Eram Byte
    Dim Pointer As Byte
    Dim Codestring As String * 13
    Dim Ecodestring(30) As Eram String * 13
    Dim Zeitlcd As String * 11
    Dim Folgelcd As String * 16
    Dim Codedat As String * 4
    Dim Codetime As String * 4
    Dim Codeuhr As String * 8
    
    Dim Richtung As Bit
    Dim Position As Byte
    Dim Stelle As Integer
    Dim Sprung As Integer
    
    'Variablen f�r RTC
    Dim S As Byte , M As Byte , H As Byte , Day As Byte , Month As Byte
    Dim Wm As Byte , Yd As Byte
    
    Dim Zeit As Byte
    Dim Zeitstring As String * 8
    Dim Rtcstellen As Bit
    Dim Zeitstellen As Byte
    
    
    Declare Sub Zuordnung
    Declare Sub Anzeige
    Declare Sub Settime
    Declare Sub Gettime
    Declare Sub Zeitanzeigen
    
    Timer0 = 196
    Cls
    Lcd "  5Ton-Decoder  "
    Lowerline
    Lcd " Bitte warten.. "
    Wait 1
    Cls
    Call Zeitanzeigen
    Lowerline
    Lcd "Uhr einstellen?"
    For Zeitstellen = 1 To 50
      If Pind.1 = 0 Then
        Zeitstellen = 51
        Call Settime
      End If
      Waitms 100
    Next
    Cls
    Call Zeitanzeigen
    Enable Int0
    Enable Int1
    
    Main:
    
    Waitms 1
    
    
    If Pind.1 = 0 Then
      Enable Timer0
      Cls
      Call Zeitanzeigen
      Waitms 100
    End If
    Frequlong = 10000000 / Icr_neu
    Icr_neu = 1
    Frequenz = Frequlong
    
    Incr Timeout
    If Timeout > 80 Then
      Folge = ""
      Tonalt = ""
      Timeout = 0
    End If
    
    Incr Folgeto
    If Folgeto > 6000 Then
      Folgealt = ""
      Folgeto = 0
    End If
    
    A(10) = A(9)
    A(9) = A(8)
    A(8) = A(7)
    A(7) = A(6)
    A(6) = A(5)
    A(5) = A(4)
    A(4) = A(3)
    A(3) = A(2)
    A(2) = A(1)
    A(1) = Frequenz
    
    Frequsumme = 0
    For Adizaehler = 1 To 10
      Frequsumme = Frequsumme + A(adizaehler)
    Next
    
    Durchschnitt = Frequsumme / 10
    Grenzeo = A(1) + 10
    Grenzeu = A(1) - 10
    
    If Durchschnitt > Grenzeu And Durchschnitt < Grenzeo Then
    
      Select Case Durchschnitt
        Case 1050 To 1070 : Ton = "1"
        Case 1150 To 1170 : Ton = "2"
        Case 1260 To 1280 : Ton = "3"
        Case 1390 To 1410 : Ton = "4"
        Case 1520 To 1540 : Ton = "5"
        Case 1660 To 1680 : Ton = "6"
        Case 1820 To 1840 : Ton = "7"
        Case 1990 To 2010 : Ton = "8"
        Case 2190 To 2210 : Ton = "9"
        Case 2390 To 2410 : Ton = "0"
        Case 2590 To 2610 : Ton = "w"
        Case Else : Goto Main
      End Select
    
    Else : Goto Main
    End If
    
    If Ton = Tonalt Then Goto Main
    Tonalt = Ton
    If Ton = "w" Then Ton = Tonalt2
    Tonalt2 = Ton
    
    Folge = Folge + Ton
    Timeout = 0
    If Len(folge) = 5 Then
      If Folge = Folgealt Then
        Folgealt = ""
        Goto Main
      Else
        Folgealt = Folge
        Folgeto = 0
        Goto Folgeerkannt
      End If
      Folge = ""
    End If
    
    Goto Main
    
    
    
    Folgeerkannt:
    
    Disable Timer0
    
    
    Pointer = Eepointer
    
    If Pointer = 31 Then Pointer = 0
    Incr Pointer
    Eepointer = Pointer
    Call Gettime
    Codestring = Folge + Bcd(day) + Bcd(month) + Bcd(h) + Bcd(m)
    Ecodestring(pointer) = Codestring
    
    Call Zeitanzeigen
    Call Zuordnung
    Locate 2 , 1
    Lcd "                "
    Locate 2 , 1
    Lcd Folgelcd
    
    If Folge = "12345" Then
      Portd.0 = 1
      Waitms 500
      Portd.0 = 0
    End If
    
    Enable Timer0
    
    Goto Main
    
    
    Sub Anzeige
    
    
    If Richtung = 0 Then Incr Position
    If Richtung = 1 Then Decr Position
    If Position = 31 Then Position = 1
    If Position = 0 Then Position = 30
    If Position = 255 Then Position = 30
    Pointer = Eepointer
    Sprung = Pointer - Position
    Sprung = Sprung + 1
    If Sprung >= 0 Then
        Stelle = Pointer
        Stelle = Stelle - Position
        Stelle = Stelle + 1
      Else
        Stelle = Pointer
        Stelle = Stelle - Position
        Stelle = Stelle + 31
    End If
    Codestring = Ecodestring(stelle)
    Codeuhr = Right(codestring , 8)
    Codedat = Left(codeuhr , 4)
    Codetime = Right(codeuhr , 4)
    Zeitlcd = Left(codedat , 2) + "/" + Right(codedat , 2) + " " + Left(codetime , 2) + ":" + Right(codetime , 2)
    Folge = Left(codestring , 5)
    Call Zuordnung
    Cls
    Upperline
    Lcd Position
    Lcd "  "
    Lcd Zeitlcd
    Lowerline
    Lcd Folgelcd
    'Lcd Codestring
    
    
    End Sub
    
    
    
    Sub Zuordnung
    Select Case Folge
    
      Case "12345" : Ausgabe = "Eins"
      Case "54321" : Ausgabe = "Zwei"
    
      Case Else : Ausgabe = Folge
    
    
    End Select
    
    Folgelcd = ""
    Folgelcd = Folge + " " + Ausgabe
    End Sub
    
    
    Taster1:
    If Rtcstellen = 1 Then
      Decr Zeit
      Lowerline
      Locate 2 , 1
      Lcd "         "
      Locate 2 , 1
      Lcd Zeit
    Else
      Disable Timer0
      Richtung = 1
      Call Anzeige
    End If
    Waitms 100
    Return
    
    Taster2:
    If Rtcstellen = 1 Then
      Incr Zeit
      Lowerline
      Locate 2 , 1
      Lcd "         "
      Locate 2 , 1
      Lcd Zeit
    Else
      Disable Timer0
      Richtung = 0
      Call Anzeige
    End If
    Waitms 100
    Return
    
    Ontimer0:
    Timer0 = 196
    Locate 1 , 1
    Call Zeitanzeigen
    Return
    
    
    Oncapture:
      Zaehler = Timer1
      Icr_neu = Zaehler - Icr_alt
      Icr_alt = Zaehler
    Return
    
    
    Sub Settime
        Rtcstellen = 1
        Enable Int0
        Enable Int1
        Call Gettime
        Waitms 200
        Cls
        Lcd "Monat:"
        Zeit = Makedec(month)
        Lowerline
        Lcd Zeit
        Do
        Loop Until Pind.1 = 0
        Waitms 200
        Month = Zeit
        Cls
        Lcd "Tag:"
        Zeit = Makedec(day)
        Lowerline
        Lcd Zeit
        Do
        Loop Until Pind.1 = 0
        Waitms 200
        Day = Zeit
        Cls
        Lcd "Stunden:"
        Zeit = Makedec(h)
        Lowerline
        Lcd Zeit
        Do
        Loop Until Pind.1 = 0
        Waitms 200
        H = Zeit
        Cls
        Lcd "Minuten:"
        Zeit = Makedec(m)
        Lowerline
        Lcd Zeit
        Do
        Loop Until Pind.1 = 0
        Waitms 200
        M = Zeit
        'values are stored as BCD values so convert the values first
        S = Makebcd(s)                                          'seconds
        M = Makebcd(m)                                          'minuts
        H = Makebcd(h)                                          'hours
        Day = Makebcd(day)                                      'days
        Month = Makebcd(month)                                  'months
    
        I2cstart                                                'generate start
        I2cwbyte &HA0                                           'write address
        I2cwbyte 0                                              'select control register
        I2cwbyte 8                                              'set year and day bit for masking
        I2cstop                                                 'generate stop
    
    
        I2cstart                                                'generate start
        I2cwbyte &HA0                                           'write mode
        I2cwbyte 2                                              'select seconds Register
        I2cwbyte S                                              'write seconds
        I2cwbyte M                                              'write minuts
        I2cwbyte H                                              'write hours
        I2cwbyte Day                                            'write days
        I2cwbyte Month                                          'write months
        I2cstop
        Rtcstellen = 0
    End Sub
    
    Sub Gettime
        Dim Dum As Byte
        I2cstart                                                'generate start
        I2cwbyte &HA0                                           'write addres of PCF8583
        I2cwbyte 2                                              'select second register
        I2cstart                                                'generate repeated start
        I2cwbyte &HA1                                           'write address for reading info
        I2crbyte S , Ack                                        'read seconds
        I2crbyte M , Ack                                        'read minuts
        I2crbyte H , Ack                                        'read hours
        I2crbyte Day , Ack                                      'read year and days
        I2crbyte Month , Nack                                   'read weekday and month
        I2cstop                                                 'generate stop
    
    Rem You Could Also Use The Lcd Statement For Displaying The
    Rem Time On The Lcd Display
    End Sub
    
    Sub Zeitanzeigen
      Call Gettime
      Locate 1 , 1
      Lcd "                "
      Locate 1 , 1
      Lcd Bcd(day) ; "/" ; Bcd(month)
      Lcd " " ; Bcd(h) ; ":" ; Bcd(m) ;
    End Sub
    Mich verwirren gerade total die Zurordnungen der einzelnen Einträge im ERAM und die ganze Pointergeschichte. [schild=2 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]Hilfe![/schild]

    Dein Eintrag "Stelle = EEPointer * 14 'Stringlänge 13 + Ende 0" funktioniert bei mir gar nicht, sondern erzeugt eine Fehlermeldung: "Source variable does not match the target variable"

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Code:
    If Pointer = 31 Then Pointer = 0 
    Incr Pointer 
    Eepointer = Pointer 
    Call Gettime 
    Codestring = Folge + Bcd(day) + Bcd(month) + Bcd(h) + Bcd(m) 
    Ecodestring(pointer) = Codestring
    Hiermit wird ganz sicher nicht auf Position 1 der neueste Eintrag abgespeichert, sondern an der Stelle Pointer. Das ganze ist ein Ringspeicher, genauso wie ich den gemacht hätte.
    Schreiben scheint also klar zu sein. Lesen geht wohl so:
    Code:
    If Richtung = 0 Then Incr Position           'Position ist die aktuelle Lese position (z.B. 17)
    If Richtung = 1 Then Decr Position 
    If Position = 31 Then Position = 1           'max 30, darüber wieder bei 1
    If Position = 0 Then Position = 30           'min 1, darunter wieder 30
    If Position = 255 Then Position = 30       'Sinn ist mir nicht klar
    Pointer = Eepointer                               'EEPointer ist die letzte SchreibPosition (z.B. 25)
    Sprung = Pointer - Position                    'Sprung = 25 - 17 = 8
    Sprung = Sprung + 1                            'Sprung = 9
    If Sprung >= 0 Then 
        Stelle = Pointer                                'Stelle = 25
        Stelle = Stelle - Position                    'Stelle = 25 - 17 = 8
        Stelle = Stelle + 1                            'Stelle = 9
      Else 
        Stelle = Pointer                                'angenommen Pointer war 5
        Stelle = Stelle - Position                    'Stelle = 5 - 17 = -12
        Stelle = Stelle + 31                          'Stelle = -12 + 31 = 19
    End If 
    Codestring = Ecodestring(stelle)            'in einem Fall liest er bei 9, im anderen bei 19
    Warum an diesen Stellen gelesen wird, verstehe ich nicht. Hast du das programmiert? Weißt du, warum dies so ist?

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    03.06.2010
    Beiträge
    8
    Nein, wurde nicht von mir geschrieben. Somit kann ich das jetzt auch nicht wirklich erkläen. Aber so wie von dir dargestellt macht das ganze erstmal wenig Sinn. Ich werde morgen mal die ganze Lesestelle rausschmeißen und wie du geschrieben hast "einfacher" über einen simplen LesePointer machen. Daran kann es wohl auch liegen das einige Einträge komplett verschwinden bzw. von falscher Stelle aufgerufen werden.

    Danke schonmal für deine Mühe!!

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    03.06.2010
    Beiträge
    8
    @for_ro: Wie würdest du den Bereich "Lesen" machen? Ich hab verschiedene Ansätze probiert, aber alles führte zu noch mehr Datenchaos.

    Zu dem original Code: Soweit ich das verstanden habe liest er damit immer die aktuelle Position des Schreibpointers aus und weiß dadurch wo sich die Nr. 1 befindet. Zum großteil funktioniert es auch, warum auch immer.

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Zitat Zitat von KL7000F
    @for_ro: Wie würdest du den Bereich "Lesen" machen?
    Hängt davon ab, welche Funktionalität du beim Lesen haben möchtest. Z.B. was die Taster für Hoch und Runter bewirken sollen.
    Generell denke ich an so etwas ganz simples:
    If Richtung = 0 Then Incr Position
    If Richtung = 1 Then Decr Position
    If Position = 31 Then Position = 1
    If Position = 0 Then Position = 30
    Codestring = Ecodestring(Position)
    Codeuhr = Right(codestring , 8)
    Codedat = Left(codeuhr , 4)
    Codetime = Right(codeuhr , 4)
    Zeitlcd = Left(codedat , 2) + "/" + Right(codedat , 2) + " " + Left(codetime , 2) + ":" + Right(codetime , 2)
    usw.

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    03.06.2010
    Beiträge
    8
    Hi,
    soweit funktioniert es. Über diesen Weg ist halt die Sortierung (letzter Durchlauf/Eintrag steht unter Position 1) weg. Aber das ist erstmal egal. Vieleicht fällt mir irgendwann noch eine Lösung ein.

    Großes Danke an Dich!

    Gruß
    Andy

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

12V Akku bauen