Display über SPI

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Display über SPI

      Hallo,

      ich habe als Beifang ein Display erhalten, (EADIP204B-6NLW)
      leider bekomme ich die saubere Ansteuerung im 4-bit-Mode nicht hin, das Netz ist voll von diesem Thema, aber es scheint keine einfache Lösung zu geben, und gefühlt 100 Zeilen Code eintippen für ein 4x20 Display habe ich keine Lust.
      Jetzt gibt es bei dem Display die Möglichkeit einer Ansteuerung über SPI (das soll funktionieren)
      Ich würde das gerne mal probieren, habe mich bisher aber noch nicht damit befasst. Wenn ich die Hilfe lese (und auch etliche andere Beiträge) habe ich das Gefühl, dass ich den Anfang des Fadens noch nicht in der Hand halte.
      Hat vielleicht mal jemand ein einfaches Programm(-schnipsel) dass ich mal sehe, wie man das angeht, bzw. worauf es ankommt?
      Bisher stochere ich schon bei der Frage, Hard- oder Soft.., im Nebel

      Danke
      Gruß
      Hans
    • ja, habe ich probiert, normale Zeichen/Zahlen macht es auch, aber Sonderzeichen, z.B. "_" geht nicht.


      siehe:
      Antwort:
      Leider ist die BASCOM-Hilfe falsch. Es genügt, das Display mit


      ::::::::::::::::::::::::::::::::::::::::::::


      Config Lcd = 20 * 4a , Chipset = Ks077
      ::::::::::::::::::::::::::::::::::::::::::::


      (kein Schreibfehler) anstelle von
      Config Lcd = 20 * 4 zu deklarieren
      Im Listing des Programms sieht das dann so aus:


      ::::::::::::::::::::::::::::::::::::::::::::


      Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.5 , Rs = Portb.4
      Config Lcdbus = 4
      'Konfiguration der Port-Einstellungen


      Config Lcd = 20 * 4a , Chipset = Ks0077

      wobei in der letzten Zeile ja wieder ein Fehler drin ist, KS0077 statt KS077


      Außerdem habe ich mit dem Display noch eine Merkwürdigkeit, bei der ich aber noch nicht sicher bin, ob es am Display liegt.
      (muss mal ein anderes ausprobieren)
      lcd Fusing(var_single, "#.##") sollte doch eine Anzeige in der Form x.yy ergeben, allerdings wird diese manchmal(!) wesentlich länger, d.h. es werden viel mehr Stellen angezeigt, welche dann von der ersten in die dritte Zeile rutschen.

      Single_var = long_var/word_var, das müsste doch erlaubt sein und Single ergeben, oder mache ich da einen Fehler?
      (in anderen Programmteilen funktioniert das problemlos)
      Gruß
      Hans
    • oka, ihr habt ja recht,

      Source Code

      1. 'Bascom ATmega328
      2. 'LCD 16 x 4 /20x4a
      3. 'Drehzahleingang über ROD 426, 500 Striche
      4. '
      5. $regfile = "m328pdef.dat"
      6. $crystal = 16000000
      7. $hwstack = 64
      8. $swstack = 64
      9. $framesize = 48
      10. Baud = 9600
      11. '---------------------------------------------------------------------------------
      12. 'Definition LCD
      13. '---------------------------------------------------------------------------------
      14. 'Config Lcdbus = 4
      15. Config Lcd = 20x4a , Chipset = Ks077
      16. Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.5 , Rs = Portc.4
      17. Initlcd
      18. Waitms 100
      19. Cursor Off
      20. '---------------------------------------------------------------------------------
      21. 'Definition der Ein- und Ausgänge
      22. '---------------------------------------------------------------------------------
      23. Config Pind.1 = Input 'Inkrementalgeber Kanal B
      24. Config Pind.4 = Input 'Inkrementalgeber Kanal A (Trigger)
      25. '---------------------------------------
      26. 'Definition der Variablen
      27. '---------------------------------------
      28. Dim N_ist As Single
      29. Dim Striche As Dword
      30. Dim Rod_long As Dword
      31. Dim Strich_alt As Dword
      32. Dim Strich_neu As Dword
      33. Dim Strich_diff As Dword
      34. Dim U_sec As Single
      35. Dim U_sec_alt As Single
      36. Dim U_sec_max As Single
      37. Rod_long = 500
      38. Strich_neu = 0
      39. Strich_alt = 0
      40. U_sec_alt = 0
      41. U_sec_max = 0
      42. N_ist = 0
      43. '
      44. '---------------------------------------
      45. 'Definition Interrupt's
      46. '---------------------------------------
      47. Enable Pcint2
      48. Pcmsk2 = &B00010000 'Pind.4
      49. On Pcint2 Pcint20_isr
      50. '--------------------------------------------------
      51. 'Configuration Timer1 (16bit)
      52. '---------------------------------------------------
      53. Config Timer1 = Timer , Prescale = 64 'Timer
      54. On Timer1 Isr_timer1
      55. Dim Preload As Word
      56. Preload = 40536
      57. Timer1 = Preload
      58. '---------------------------------------
      59. 'Configuration der ALIAS
      60. '---------------------------------------
      61. Kanal_a Alias Pind.4 'Pcint Inkrementalgeber Kanal A
      62. Kanal_b Alias Pind.1 'Inkrementalgeber Kanal B
      63. Enable Interrupts
      64. Config Single = Scientific , Digits = 2
      65. Cls
      66. Locate 1 , 1
      67. Lcd "N Ist = "
      68. Locate 2 , 1
      69. Lcd "U/secmax= "
      70. Enable Timer1
      71. Do
      72. N_ist = Striche / Rod_long
      73. Locate 1 , 10
      74. Lcd Fusing(n_ist , "#.##")
      75. Locate 2 , 10
      76. Lcd Fusing(u_sec_max , "#.###")
      77. Loop
      78. End
      79. '---------------------------------------
      80. 'Interruptbearbeitung
      81. '---------------------------------------
      82. Isr_timer1:
      83. Strich_alt = Strich_neu
      84. Strich_neu = Striche
      85. Strich_diff = Strich_neu - Strich_alt
      86. U_sec = Strich_diff / 50 'Timer 1/10 sec => 50 Striche
      87. If U_sec > U_sec_max Then
      88. U_sec_max = U_sec
      89. End If
      90. U_sec_alt = U_sec
      91. Timer1 = Preload
      92. Return
      93. '------------------------------------
      94. 'Strichzähler ROD
      95. '------------------------------------
      96. Pcint20_isr:
      97. If Kanal_a = 1 Then 'steigende Flanke Kanal A => isr wird bearbeitet
      98. If Kanal_b = 1 Then 'Linkslauf = Vorwärts
      99. Incr Striche 'Zähler läuft vorwärts
      100. Else 'Rechtslauf = Rückwärts
      101. Decr Striche 'Zähler läuft rückwärts
      102. End If
      103. End If
      104. Return
      Display All
      Gruß
      Hans
    • Michael wrote:

      Ich würde die Rechnung mit U_sec usw. in der Hauptschleife machen.
      oder am Ende in der isr ein flag setzen, dass ein neuer Wert vorliegt und jetzt bisschen Zeit bleibt, den anzuzeigen. Dann bei der Anzeige der Werte auf das flag warten und dann die werte anzeigen/weiterverarbeiten, wenn diese gerade nicht mehr durch die isr geändert werden.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Ich bin mittlerweile sicher, dass es ein timing-Problem ist.Der Fehler sieht jedesmal anders aus, manchmal früher, manchmal päter, manchmal nicht, aber eben auch (sehr selten) sofort nach dem Einschalten des Zählers, ohne dass der Motor dreht!
      Es passiert aber fast immer, wenn der Motor stoppt.

      das Mit dem Flag muss ich mal probieren
      Gruß
      Hans
    • Meine Meinung wäre dazu, du beschreibst das Display zu schnell. Es braucht leider mehr Zeit als hier zur verfügung gestellt wird.
      Ein "Waitms 500" probehalber mal in deine "Do Loop" Schleife setzen. Wird es besser , dann das Flag in der ISR einbringen wie
      Tschoeatsch empfiehlt. Kann mich aber auch irren. Nur eine Vermutung. Habe selbst solche Schreibfehler bei anderen
      Lcd - Displays gehabt und das Beschreiben verlangsamt.
    • Du musst bedenken, das fusing wandelt das single in Text um und beschneidet den Text. Das braucht Zeit, und da kann dann der interrupt hineinplatzen und fummelt an der single rum, die ja grad bearbeitet wird.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • habe zwischenzeitlich die Berechnung in die Hauptschleife gepackt, das Flag eingebaut, alles ohne Erfolg,
      nebenbei bin ich mal an den Drehgeber gestossen (ganz leicht) und siehe da. der Fehler war da, bei stehendem Motor.
      das habe ich mehrmals getestet (einfach mit der Hand angedreht) , bei Vorärtsdrehung konnte ich den Fehler manchmal vermeiden, bei Rückwärtsdrehen war er immer da.
      Vermutlich dreht der Schrittmotor manchmal beim Start (Enable kommt vor den Impulsen) kurz rückwärts, abhämgig von der Stellung.
      Nun alle Dword-Variablen auf Long gesetzt (negative Zahlen zulässig) und schon gehts,
      (hoffentlich auch auf Dauer, habs jetzt so etwa 15-20mal probiert)

      (wie hat jemand in der Signatur, "kaum macht man es richtig,......)
      Gruß
      Hans
    • Würdest du in der ISR noch die Wertebereiche prüfen, würde ein Werteüberlauf nicht passieren können

      BASCOM Source Code

      1. Pcint20_isr:
      2. If Kanal_a = 1 Then 'steigende Flanke Kanal A => isr wird bearbeitet
      3. If Kanal_b = 1 Then 'Linkslauf = Vorwärts
      4. if Striche < 1000 then
      5. Incr Striche 'Zähler läuft vorwärts
      6. end if
      7. Else 'Rechtslauf = Rückwärts
      8. if Striche > 0 then
      9. Decr Striche 'Zähler läuft rückwärts
      10. end if
      11. End If
      12. End If
      13. Return
      Display All
      Code first, think later - Natural programmer :D
    • Die Begrenzung nach oben ist doch kontraproduktiv. 1000 wäre ja nur 2 Umdrehungen. Nachdem mit Striche auch die Gesamtumdrehungszahl errechnet wird, braucht Striche einen großen Wertebereich.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • eben, wenn ich von max 9999 Umdrehungen ausgehe, benötige ich für Striche einen Bereich bis 5Mio,die negativen kann/sollte ich ausblenden.

      Aber irgendein Problem bei diversen Berechnungen habe ich immer noch, manchmal sind die Ergebnisse okay, manchmal Blödsinn,
      ich vermute, dass bei irgendeiner Rechnung manchmal ein Fehler im Dateityp entsteht, welcher dann zu einem Überlauf im Display führt.
      Da suche ich noch
      Gruß
      Hans
    • Du berechnest in deiner isr ja nur die U/s, die du nur zur Info anzeigst. Du könntest jetzt in der main ein flag setzen, wenn du den Wert angezeigt hast. In der isr wird das flag ausgewertet und, wenn das flag gesetzt ist, ein aktueller Wert für die U/s berechnet und das flag zurück gesetzt. In der main wird bei zurückgesetztem flag dieser neue Wert angezeigt und das flag wieder gesetzt. So wird sichergestellt, dass die Variable nur von einem Programmteil verwendet/bearbeitet wird.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------