Willkommen in unserer Community

Werde Teil unserer Community und registriere dich jetzt kostenlos ...

Bascom LCD Anzeige PC4004LRU von Powertip

Dieses Thema im Forum "LED + LCD" wurde erstellt von Logger, 29. April 2018.

Schlagworte:
  1. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Habe heute mal nach langerzeit wider etwas gebastelt.
    Hatte noch eine LCD-Anzeige mit 4 x 40 Zeichen und 2 KS0066U Kontrollern auf der Rückseite rumfliegen.
    Sie zum Leben zu bringen war nicht ganz einfach, da es zu dieser Anzeig kein passendes Datenblatt gibt.
    Angehangen habe ich den Bascom Code, womit die Anzeige Funktioniert und 2 Bilder.
    Vieleicht hilft es einem weiter.
    Wenn noch jemand verbesserungen bei dem Code sieht bitte melden, bin für jede info Dankbar.

    Gruß Ralf
     

    Anhänge:

    Dirk gefällt das.
  2. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Das alte Android auf meinem Tablet zickt irgendwie rum wenn ich versuche, den angehängten Code runterzuladen - auf dem Mobile geht es zwar, aber Übersicht ist was anderes...
    Deswegen hier erstmal der Code als Text (hoffe, Du bist damit einverstanden):

    CodeBox BascomAVR
    '*******************************************************************************
    '* Test des LCD Display von Powertip PC4004LRU-BSO-C 4 x 40, 2x KS0066U        *
    '* Benutzter Controller Atmega 8                                               *
    '*                                                                             *
    '* Ralf Neubert Dinslaken                                                      *
    '* Logger @ www.makerconnect.de    ( www.AVR-Praxis.de )                       *
    '*                                                                             *
    '* AVR = Bez.= LCD-Pin                                                         *
    '*                                                                             *
    '*       DB0 = GND                                                             *
    '*       DB1 = GND                                                             *
    '*       DB2 = GND                                                             *
    '*       DB3 = GND                                                             *
    '* PD0 = DB4 = 11                                                              *
    '* PD1 = DB5 = 12                                                              *
    '* PD2 = DB6 = 13                                                              *
    '* PD3 = DB7 = 14                                                              *
    '* PD4 = E   = 15                                                              *
    '* PD5 = E2  = 16                                                              *
    '* PD6 = RS  = 4                                                               *
    '*       RW auf GND                                                            *
    '*                                                                             *
    '* Habe die Pin'S ausmessen müssen, da es kein Passendes Datenblatt gab.       *
    '*                                                                             *
    '*******************************************************************************
    
    
    $Regfile="m8def.dat"
    $Crystal=16000000
    $Hwstack=40
    $Swstack=16
    $Framesize=32
    
    'PortD auf Ausgabe setzen, LCD Konfigurieren und Pin's festlegen
    Config PortD = Output
    Config Lcd = 40x4
    Config Lcdbus = 4
    Config Lcdpin = Pin , Db4 = Portd.0 , Db5 = Portd.1 , Db6 = Portd.2 , Db7 = Portd.3 , E = Portd.4  , E2 = PortD.5 , Rs = Portd.6
    
    
    ' Pin für 1wire Schnittstelle festlegen
    Config 1wire = Portb.0
    
    Dim ___lcdno As Bit
    Dim T1 As Integer                                           'hilfs Variable für die berechnung Temp1
    Dim T2 As Integer                                           'hilfs Variable für die berechnung Temp1
    Dim T3 As Integer                                           'hilfs Variable für die berechnung Temp2
    Dim T4 As Integer                                           'hilfs Variable für die berechnung Temp2
    Dim T5 As String * 5                                        'Variable für Temp1 zur anzeige auf dem LCD
    Dim T6 As String * 5                                        'Variable für Temp2 zur anzeige auf dem LCD
    Dim T7 As Single                                            'hilfs Variable für die berechnung Temp1
    Dim T8 As Single                                            'hilfs Variable für die berechnung Temp2
    Dim Id1(8) As Byte                                          'für die adresse Sensor 1
    Dim Id2(8) As Byte                                          'für die adresse Sensor 2
    Dim Ar1(9) As Byte
    Dim Ar2(9) As Byte
    Dim Tmp1 As Byte , Tmp2 As Byte
    Dim W As Byte
    
      'Unterprogramme
    Declare Sub Con_temp
    Declare Sub Temp1
    Declare Sub Temp2
    
       '1wire Bus absuchen
    W = 1wirecount()
    Id1(1) = 1wsearchfirst()
    Id2(1) = 1wsearchnext()
    
    
    'Ersten text aufs Display schreiben
    
    ___lcdno = 0                                                'Obere Displayhälfte initialisieren, für den ersten Controller
    Initlcd
    Cls
    Cursor Off Noblink
    Locate 1 , 1
    Lcd "Innen  :"
    Locate 2 , 1
    Lcd "Aussen :"
    
    ___lcdno = 1                                                'Untere Displayhälfte initialisieren, für den zweiten Controller
    Initlcd
    Cursor Off Noblink
    Locate 1 , 1
    Lcd "LCD-typ: PC4004LRU-BSO-C 4 x 40 Zeichen "
    Locate 2 , 1
    Lcd "LCD Kontroller KS0066U; (c) Ralf Neubert"
    
    
      'Hauptprogramm
    Do
    
      Gosub Con_temp
      Gosub Temp1
      Gosub Temp2
    
      'Temperaturen und °C aufs Display schreiben
       ___lcdno = 0
       Cursor Off Noblink                                             'Obere Displayhälfte initialisieren, für den ersten Controller
       Locate 1 , 10
       Lcd T5 ; " C" '; Chr(0);Chr(1)
       Locate 2 , 10
       Lcd T6 ; " C" '; Chr(0);Chr(1)
    
    Loop
    
          'Temperaturen Convertieren
    sub Con_temp
       1wreset
        1wwrite &HCC
        1wwrite &H44
          Waitms 500
        1wreset
    End Sub
    
    
      'Temperatur 1 Berechnen
    Sub Temp1
     1wreset
      1wwrite &H55
      1wwrite Id1(1) , 8
      1wwrite &HBE
       Ar1(1) = 1wread(9)
       1wreset
         Tmp1 = Ar1(1) And 1
         If Tmp1 = 1 Then Decr Ar1(1)
         T1 = Makeint(ar1(1) , Ar1(2))
         T1 = T1 * 50
         T1 = T1 - 25
         T2 = Ar1(8) - Ar1(7)
         T2 = T2 * 100
         T2 = T2 / Ar1(8)
         T1 = T1 + T2
         T1 = T1 / 10
         T7 = T1 / 10
         T5 = Fusing(t7 , " ##.&&" )
    End Sub
    
      'Temperatur 2 Berechnen
    Sub Temp2
     1wreset
      1wwrite &H55
      1wwrite Id2(1) , 8
      1wwrite &HBE
       Ar2(1) = 1wread(9)
       1wreset
         Tmp2 = Ar2(1) And 1
         If Tmp2 = 1 Then Decr Ar2(1)
         T3 = Makeint(ar2(1) , Ar2(2))
         T3 = T3 * 50
         T3 = T3 - 25
         T4 = Ar2(8) - Ar2(7)
         T4 = T4 * 100
         T4 = T4 / Ar2(8)
         T3 = T3 + T4
         T3 = T3 / 10
         T8 = T3 / 10
         T6 = Fusing(t8 , " ##.&&" )
    End Sub
    End
    
     
  3. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    So, Du hattest um konstruktive Kritiken gebeten...

    offensichtlich hattest Du dreu Baustellen zu bewältigen:
    1. die Ansteuerung des Displays (insbesondere wegen der zwei Kontroller)
    2. die Ansteuerung der 1wire-Sensoren
    3. die Aufbereitung der empfangenen Werte und deren Darstellung
    1. hast Du unter Zuhilfenahme von "Config LCD" gelöst. Wiedersprechen sich nicht die Zeilen 37 und 38 ?
    Das wesentliche scheint das Flag "___lcdno" zu sein, welches zwischen den beiden Controllern wechselt - entsprechende Hinweise finde ich in der Bascom-Onlinehilfe nicht. da es bei Dir offensichtlich so funktioniert, hilft das Listing möglicherweise anderen suchenden...
    2. hast Du (logischerweise auch) mit Bascom-Bordmitteln gelöst ("Config 1wire" usw). Mir ist kein AVR mit nativer 1wire bekannt, also muß da immer zu Fuß gegangen werden. Bascom bietet dazu die verwendete Softwarelösung.

    Zu den beiden Punkten kann ich(!) nichts weiter sagen (bzw ist vielleicht auch nichts weiter zu sagen).

    Zu 3. müßte man mehr über die verwendeten Sensoren wissen, am besten auch mit einem Link auf die Datenblätter - zumindest jedoch die Namen...
    Ich würde ein paar Sachen bei der Berechnerei ändern...
     
  4. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Moin

    Danke für die Kritik.
    Als Baustelle war eigentlich nur die Ansteuerung vom Display, die Geschichte mit dem 1Wire habe ich ja so aus der Bascom hilfe und für mich zurecht geschnitten.
    Die Berechnug ist dann aus dem Datenblatt und dem Internet.
    Ist übrigens ein Dallas DS1820.

    Das steht so auch in der Bascom hilfe, ist das falsch ?

    Bin gespannt.
     

    Anhänge:

  5. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Wo?

    Grundsätzlich kannst Du das erstmal in den Compiler-Settings (oder so) einstellen. Hast Du entsprechendes "Config blablub" im Code, gilt das statt der Voreinstellungen, klar (Ich hab die Angaben lieber im Code).
    So, ...
    Das sind parallel angesteuerte Displays, also über einen Datenbus (4 oder 8 Bit breit). Die "E"-Signale sind dann quasi Bestandteil des Adressbusses. Gedacht ist das eigentlich, um so'n Display zusätzlich zu irgendwelchen anderen parallelen "Geräten" anzusteuern - Speicher zum Beispiel.
    So würde ich CONFIG LCDMODE verstehen.
    Im Busmode kannst Du dann mit $LCD=Adresse dann die Adresse des (einen) Displays am Adressbus festlegen. Das "E" müßte dann aus dem Adressbus abgeleitet werden.
    Default ist allerdings der vier-bit-Port-Mode.
    Warum also Zeile 37? (Die sollte im Port-Mode irrelevant sein).
    Das ___LCDNO-Flag schaltet zwischen den beiden "E"s um - ist Zeile 100 da (nochmal) nötig?
    Ich hätte von Bascom eigentlich erwartet, daß es wie bei Kommunikationsschnittstellen die Möglichkeit gibt, mehrere "Kanäle" über ein Tag (legt das "E" fest) zu definieren, und dieses dann bei der Ausgabe zu verwenden (LCD #1 "blablub").
    In Deiner Hauptprogrammschleife machst Du folgendes:
    1. Single Conversion an allen Sensoren (am 1wire) auslösen. Über eine Subroutine. Korrekt?
    2. Über eine Sub einen Sensor auslesen und die Werte in einen String konvertieren.
    3. Über eine Sub einen Sensor auslesen und die Werte in einen String konvertieren.
    4. Ausgabe aufs Display.
    Können die Sensoren nicht auf continous conversions gestellt werden, 1. dann entfallen?
    2. und 3. sind quasi vollkommen identisch. Was sich ändert, ist die ID (also das Array). Als Ergebnis soll ein String rauskommen. Ich würde statt der beiden quasi identischen subs eine Funktion implementieren, die als Typ den fertigen String liefert, und das ID-Array als Parameter (byref) übergeben bekommt.
    Der Aufruf könnte dann in Zeile 105 zB so aussehen:

    CodeBox BascomAVR
    Lcd getTemperature(ID1) ; " C" '; Chr(0);Chr(1)

    Zeile 107 entsprechend:

    CodeBox BascomAVR
    Lcd getTemperature(ID2) ; " C" '; Chr(0);Chr(1)

    Zur eigentlichen Rechnerei muß ich erstmal 'n Blick ins Datenblatt der Sensoren werfen...
     
  6. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Moin

    Danke schon mal für's durch schauen des Code.
    Du hast Recht, das Funktioniert auch ohne "Config Lcdbus = 4", ist auch in der Bascom hilfe so nicht dargestellt.

    Das muß so sein, da ja immer die passende Display hälfte damit angesprochen wird, ansonsten wird es auf der falsche Hälfte angezeigt.

    Das werde ich heute abend mal umprogrammieren, nur das dauert bei mir, ich bin da eher der anfänger.

    Gruß Ralf
     
  7. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Zeile 99 ist klar. Aber das Cursor noblink in Zeile 100?

    Wegen der Rechnerei: Ich versuche noch, die Formel zu verstehen...
    Die 0,25 müssen meiner Meinung nach vom Runden auf halbe Kelvin stammen.
    Als Assembler-Programmierer würde ich auf die Fliesskomma-Divisionen verzichten wollen. Mit der Formel werden quasi die Nachkommabits gewonnen. Das sollte hinreichend genau mit 16bit-Ganzzahlarithmetik gehen.
     
  8. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Alabel möge mich korrigieren - ich verstehe (ansatzweise) den Sensor etwa so:
    Zwei unterschiedlich stark temperaturabhängige Oszillatoren treiben einen Counter an (bzw ein Oszillator inkrementiert den Counter, der andere bestimmt die Zähldauer).
    Das Zähl-Register ist mit -55 initialisiert, in Zweierkomplementdarstellung (also als 16bit-Integer) - ABER um eine Stelle nach links geschoben.
    Außerdem wird eine Nachkomma-Information gewonnen, die als "½-Kelvin-Bit" an der minderwertigsten Position des Zählregisters abgelegt wird.
    Addiert man auf diese ½ jetzt konstant ¼, hat man nach abhacken des Rests effektiv auf halbe Kelvin gerundet.
    Meine Vermutung ist also, daß die Inhalte von Count_Remain und Count_per_C nach der Formel wegen dieses Rundens 0,25 Kelvin zu groß sind, und daß deswegen auf den ganzzahligen Anteil (Temp_Read) des Ergebnisses der gebrochene Rest ((Cnt_PC-Cnt_Rem)/Cnt_PC) addiert werden muß, und ein viertel-Kelvin subtrahiert werden muß.

    So, zurück zur Praxis:
    Kannst Du mal ein paar Beispieldaten posten (also die vier Werte, Deine erhaltenen Werte kann auch der Simulator ermitteln) - dann könnte man auch ohne Sensor experimentieren.

    Irgendwo im SRAM wird ein (Byte-) Array angelegt, in das die Bytes des Sensors eingelesen werden. (Das CRC mußt Du übrigens nicht unbedingt auslesen, wenn Du es nicht verarbeiten willst).

    Code:
          Array
    
    1 Temp_Low
    2 Temp_High
    3 User_1
    4 User_2
    5 Res_1
    6 Res_2
    7 Cnt_Rem
    8 Cnt_PC
    9 CRC
    Nötig sind die ersten beiden, die enthalten die gelesene Temperatur als 16Bit-Integer (also in Zweierkomplementdarstellung). Relevant sind neun Bits, wobei das LSB (least significant bit) einem halben Kelvin entspricht).
    Für eine höhere Auflösung müssen dann "7" und "8" verarbeitet werden.

    Zum Rechenweg:

    Das "halb-Kelvin-Bit" ist laut Datenblatt zu verwerfen. Was aus dem Datenblatt nicht ganz offensichtlich ist ist, daß außerdem durch zwei geteilt werden müßte. Das Abschneiden erledigst Du etwas komliziert in den Zeilen126 und 127 (eigentlich solltest Du das Bit auch einfach Null setzen können ("Ar1(1).1=0"). Durch zwei teilst Du, indem Du mit verhundertfachten Werten arbeitest, aber nur mit 50 multiplizierst. Das ist Dezimal. Ich würde auf dem Binärsystem bleibend stattdessen mit 128 "multiplizieren" bzw erst "durch zwei teilen" und dann "mit 256 multiplizieren". Dazu wird das Temp-Doppel-Byte (Integer) einfach einmal nach rechts geschoben/gerollt (asymmetrisch). Kostet zwei Takte. Fertig. mit 256 multiplizieren ist noch leichter - das High-Byte beinhaltet jetzt keine Information mehr (außer Vorzeichen-Nullen oder -Einsen), ein Vorzeichenbit wurde in das Lowbyte gerollt. Wenn man sich dieses Lowbyte jetzt als Highbyte eines Integers denkt (dessen Lowbyte null ist), hat man das 256-fache (so, als wenn du im Dezimalsystem 'ne "0" an 'ne Zahl hängst und mit 10 multipliziert hast). Beim Denken hilft Dir Bascom, indem Du auf die Speicherzellen mit einem anderen Variablennamen zugreifst, der Overlay definiert ist:
    Code:
       Array     Temp_Read (Integer-Overlay-Variable)
      Dummy      = Temp_Read_L
    1 Temp_Low   = Temp_Read_H
    2 Temp_High
    3 User_1
    4 User_2
    5 Res_1
    6 Res_2
    7 Cnt_Rem
    8 Cnt_PC
    9 CRC
    Overlay heißt, daß kein neuer Speicherplatz reserviert wird, sondern nur ein neuer Name (und/oder ggf ein anderer Datentyp) auf diese Speicherzelle zugreift.
    Damit ist auch das "Makeint" aus Zeile 128 erledigt - der Sensor lefert Dir diesen Integer bereits. Laut Bascom-Hilfe rechnet Bascom Highbyte*256+Lowbyte - ich denke allerdings, daß einfach nur die beiden Bytes in den SRAM (zwei aufeinanderfolgende Adressen) kopiert werden. Das ist aber bereits der Fall. (Basom legt Integer und Words im SRAM so ab. Erst das Lowbyte, dann das Highbyte).

    Die Overlay-Definitionen erzeugen keinen Code durch die Definition haben wir bisher mit nur zwei Instruktionen den ganzzahligen Teil freigestellt und mit 128 Multipliziert. Der Rest (Zeile 130ff) folgt noch. die Ausgabe muß dann natürlich auch angepaßt werden - Fusing geht nur mit singles oder?
    "LCD integervariable" sollte natürlich gehen, aber dann zappelt die Anzeige wegen abgeschnittener führender Nullen.
     
  9. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Hi LotadaC

    Danke für die hinweise und anregungen, man merkt das du Profesioneller Programmierer bist, ich hingegen bin froh wenn ich in Bascom etwas funktionstüchtiges Zustande bringe.
    Ich werde mir deine Hinweise die nächsten Tage in Ruhe zu Gemüte führen und schauen das ich dies umsetzen kann.
    Werde auf jeden Fall Rückmeldung geben.
     
  10. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Nein, ich bin wie fast alle hier Hobbyist. Bin halt nur seit ca 10 Jahren dabei. Das Wissen habe ich auch nur autodidaktisch aus dem Forum und den Datenblättern.
    Mein besonderess Interesse gilt den eigentlichen AVR, also der Hardware. Dementsprechend bin ich recht früh von Bascom auf Assembler umgestiegen (wobei man bei Bascom sehr schön Assemblercode einbinden kann).

    Du hast das Display leider an PortD angeschlossen, insbesondere an den Hardware-UART (D0/D1).
    Sonst hättest Du einfach mal mit "Print" die vier Bytes und Deinen Ergebnisstring an den PC schicken können. Zweimal pro Sekunde, und dabei den Sensor Kühlen/Heizen.
    Dann hätte man 'ne Liste...
    Also entweder das Display auf PortB umstöpseln (Achtung: mindestens einer der Oscillator-Pins ist auf dem STK nicht mit dem PortB-Header verbunden sondern mit dem Takt-Netz des STK - und liegt dann stattdessen folglich auf dem AUX/PortE-Header.) und in der Konfiguration anpassen (Zeile 35 und 38), oder...

    einfach einen Software-Uart von Basom erzeugen lassen, auf einem beliebigen Pin.
    (Man könnte die vier Bytes und den String mit ein paar Trennzeichen zu einem String zusammenfassen lassen, und den dann mit "serout" (=SoftUART) übergeben lassen - drei Zeilen Bascom-Code.)

    P.S.: Dein Programm hast Du selbst bereits geschrieben. Es funktioniert offensichtlich. Was wir hier jetzt gerade machen ist Gehirnjogging. Nicht unbedingt nötig, aber 'ne Übung, wenn Du(!) tiefer in die Materie einsteigen willst(!).
     
  11. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Ja das würde ich gerne, nur fehlt mir oft die Zeit.

    Genau das mache ich gerade.
    Hättest du ein Buch das du mir als Anfänger für Assembler empfehlen kannst ?
    Mit beispielen und übungen.
     
  12. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.142
    Zustimmungen:
    115
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Hallo Ralf,

    ich weiß leider nicht, ob es überhaupt Literatur als Buch zu AVR+Assembler gibt.

    Du kannst hier mal schauen, vielleicht hilft dir die Seite weiter.
    http://www.avr-asm-tutorial.net/
    (oder auch mal hier im Forum nach Assembler Beispielen suchen)

    Ansonsten mach es vielleicht so wie ich es auch gemacht habe.
    Nehm dir das Datenblatt des AVR vor, den du verwenden möchtest (STK500 zum "spielen" hast du ja).

    Ziemlich am Ende vom Datenblatt sind die Instructions aufgeführt. In der Tabelle steht bei jedem Instruction,
    - welche Register verwendet werden,
    - welche Flags beeinflusst werden,
    - und wieviele Maschinenzyklen benötigt werden.

    Wenn du mal genauere Informationen benötigst, diese findest du zum Beispiel hier
    https://www.microchip.com/webdoc/avrassembler/avrassembler.wb_instruction_list.html


    Wenn du dir erst einmal eine Art "Template" erstellt hast, also eine Programmstruktur, ist Assembler gar nicht so schwer.

    (1) Adresse 0 RESET, Programmstart (Sprung zum Hauptprogramm, bzw. zu Initialisierungen)
    (2) Falls Interrupts verwendet werden, hier eine Art Sprungtabelle zu den Interrupt-Serviceroutinen (falls nicht dann kann hier direkt das Programm anfangen)
    (3) Initialisierungen
    (4) Hauptpramm Endlosschleife (darin dann Bedingungen abfragen, Sprünge zu Routinen ...)
    ...
    Routinen, Interrupt-Serviceroutinen, Tabellen im Flash

    Beginne am besten mit einem einfachen Programm, keine Interrupts.
    Eine Endlosschleife, darin eine Taste abgragen, wenn gedrückt LED an.
    Und das baue dann weiter aus.
     
  13. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Dirk hat neben dem Controllerdatenblatt bereits auf DIE zwei Quellen hingewiesen.
    Auf Gerhards Seite findest Du unter "Zur deutschen Seite" bei "Assembler lernen" ein PDF, mit dem ich damals auch angefangen habe. Einige Sachen sind nicht mehr ganz aktuell (gewesen), den ganzen Kram mit den Programmern kannst Du sicher auch überspringen (STK500).
    Entwicklungsumgebung wäre aktuell das Atmel Studio 7, steinalte AVR wie der AT90S2343 werden allerdings nicht mehr unterstützt. Parallel habe ich zB noch das AVR Studio 4.19 installiert. Das Archiv mit auch alten Versionen findest Du hier.

    Meiner Meinung nach am wichtigsten ist aber, mal so'n komplettes Controllerdatenblatt durchgelesen zu haben. Da werden am Anfang gut die Speicherbereiche und die Hardware als Block/Schema gezeigt.
    Im Instruction Set findet sich auch näheres zur Arbeitsweise der ALU.

    'Ne gute Informationsquelle stellt auch der FAQ-Bereich hier im Forum dar. Alabel hat da mal'ne Zusammenfassung relevanter Themen versucht (AVR generell, nicht nur ASM).

    Wie gesagt kann man in Bascom recht einfach ASM einbinden. Bei Deinem Programm zB kann man Bascom dann den ganzen 1wire-Kram machen lassen - die Konvertiererei der empfangenen Daten aber schneller/einfacher mit etwas hardwarenahem Bitgeschubse erledigen. Die Displayausgabe dann wieder mit Bascoms LCD-Bibliothek...
     
  14. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Hi Dirk , Hi LotadaC

    Danke für die ganzen infos.
    Werde jetzt erstmal zusehen das ich das Programm neu schreibe ohne LCD dafür aber mit UART-Ausgabe.
    Dann kommen die Erinnerungen an die Befehle langsam wider, macht wider richtig spass, zum leidwesen meiner Frau.
    Habe den Schreibtisch wider voll Bücher liegen und dem Datenblatt des DS1820.
     
  15. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    HI

    Habe mal Experimentiert, aber irgendwo ist noch ein Fehler.
    Ich denke ich Lese mit Rom (1-8) das scratchpad aus, aber ist wohl nicht der fall.
    Schau mal drüber.


    CodeBox BascomAVR
    '*******************************************************************************
    '* Test des 1Wirebus und deren Sensoren                                        *
    '* Benutzter Controller Atmega 8                                               *
    '*                                                                             *
    '* Ralf Neubert Dinslaken                                                      *
    '* Logger @ [URL='http://www.makerconnect.de']www.makerconnect.de[/URL]    ( [URL='http://www.AVR-Praxis.de']www.AVR-Praxis.de[/URL] )                       *
    '* Geholfen hat das Buch von Burkhard Kainka "Basiskurs Bascom-AVR" und        *
    '* Programmstücke von Temperaturmessung mit DS1820                             *
    '*******************************************************************************
    
    $regfile = "m8def.dat"
    $crystal = 16000000
    $baud = 38400
    Config 1wire = Portb.0
    
    Dim Rom(9) As Byte
    Dim Temp As Single
    Dim Tempdif As Single
    Dim Id1(8) As Byte
    Dim Id2(8) As Byte
    Dim Id3(8) As Byte
    Dim I As Integer
    
    
    Id1(1) = 1wsearchfirst()
    Id2(1) = 1wsearchnext()
    Id3(1) = 1wsearchnext()
    
    I = 1wirecount()
    Print I
    
    For I = 1 To 8
        Print Bin(id1(i));
    Next
    Print
    Wait 1
    
    Do
      1wreset
       If err = 1 Then
        Print "Sensor Fehler "                                                 'print error 1 if error
        Print " "
       else
        Print "Sensor OK"
        Print " "
       End If
      1wwrite &HCC                                              'SKIP ROM
      1wwrite &H44
      Waitms 800
    
      1wreset
      1wwrite &H55                                              'Match ROM
      For I = 1 To 8
        1wwrite Id1(i)
      Next I
      1wwrite &HBE
      Rom(1) = 1wread(9)
    
    
         Print "LSB : "; Bin(Rom(1))
         Print "MSB : "; Bin(Rom(2))
         Print "UserB_1 : ";Bin(Rom(3))
         Print "UserB_2 : ";Bin(Rom(4))
         Print "Res_1 : ";Bin(Rom(5))
         Print "Res_2 : ";Bin(Rom(6))
         Print "Cnt_Rem : ";Bin(Rom(7))
         Print "Cnt_Per_C : ";Bin(Rom(8))
         Print "Crc_ : ";Bin(Rom(9))
    
      Temp = Rom(1) / 2
      Temp = Int(temp)
      Tempdif = 16 - Rom(7)
      Tempdif = Tempdif / 16
      Temp = Temp + Tempdif
      Print Fusing(temp , "#.##")
      Print "    "
    
    Loop
    End
    


    Danke
     

    Anhänge:

    #15 Logger, 5. Mai 2018
    Zuletzt bearbeitet: 5. Mai 2018
  16. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Wiso nicht? Sieht doch eigentlich so aus. Sind die empfangenen Werte plausibel? (ein paar mal knapp unter null sieht komisch aus, die mit 127°C++ auch. Die UserBytes sollten immer denselben Wert haben (solange Du da nichts anderes in den korrespondierenden Eeprom schreiben läßt). Die beiden reservierten Bytes müssen immer(!) 0xFF sein.)
    Du hast ein paar mal alles (oder fast alles) einsen - das sieht irgendwie nach 'nem Wackelkontakt aus (der Pullup zieht die Leitung hoch, die Verbindung zum Sensor ist getrennt).

    Ich meinte eigentlich, die Werte zusammen mit Deinem Original-Rechenweg auszugeben (beschränkt auf einen Sensor).
    Unplausibel sind zumindest alle Telegramme, bei denen das MSB nicht 0x00 oder 0xFF liefert. Was konkret bei Ergebnissen außerhalb des -55..+125-Fensters geliefert wird, weiß ich nicht.

    Möglicherweise sollte man mal die CRC miteinbeziehen, und unstimmige Werte gleich verwerfen (1wire ist meiner Meinung nach recht störanfällig - je nach Drahtlänge, Umgebung...)
    (Beim CRC hilft Dir Bascom auch wieder)

    Wenn(!) Du die CRC-Kontrolle erfolgreich integriert hast, brauchst Du nicht mehr alle ScratchPad-Bytes ausgeben. Die vier und das von Dir berechnete Ergebnis reichen...
     
  17. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Ich würde an Deiner Stelle erstmal zurück zum Code aus #1 (bzw #2) gehen. Da aber den UART mit einbauen (also das Display an andere Beine Stecken, oder weglassen und den Code anpassen).
    Init von LCD (ggf), 1wire und UART wären soweit klar, die Suche nach 1wires, das Array mit den IDs und das generelle Anstoßen der Messung auch. Ob Du das nun über 'ne Gosub oder 'ne sauber deklarierte Subroutine (ohne Parameter) machst, ist letztendlich kein Unterschied.
    Aber den Empfang würde ich umstrukturieren.
    Statt der zwei Scratchpad-Abbild-Arrays würde ich nur eins definieren, und es auch so nennen: "DS1820_Scratchpad". Erstmal global, später kann man es dann immer noch verschieben.
    Das Auslesen und die weitere Verarbeitung würde ich in entsprechende Subroutinen bzw Funktionen verlagern.
    Erstmal nur das Auslesen:
    Die Funktion benötigt die ID (genauer das ID-Array) und Platz für die empfangenen Bytes (auch ein Array). Bascom-Funktionen akzeptieren Arrays nur als Referenz. Das referenzierte Array wird also durch die Funktion direkt manipuliert - zurückgeben tun wir nicht das Array, sondern das Ergebnis der zyklischen Redundanzprüfung. Die Funktion könnte also wie folgt deklariert werden:


    CodeBox BascomAVR
    declare function DS1820_ScratchpadReadError(byref source() as Byte, byref target() as Byte)as byte

    Die Funktion soll also vom, mit source() referenzierten Sensor die Daten lesen, und in das Array, was mit target() referenziert ist schreiben. Anschließend die CRC berechnen(kontrollieren), und das Ergebnis zurückliefern. Statt eines Bytes könnte man auch ein Bit (Flag) nehmen, aber beim Byte ist es einfacher: man kann nämlich einfach des Ergebnis der CRC auf "DS1820_ScratchpadReadError" zuweisen.
    In Deiner Main-Loop könntest Du Die Funktion dann mit einer If-Anweisung aufrufen:

    CodeBox BascomAVR
    If DS1820_ScratchpadReadError(ID1(1), DS1820_Scratchpad(1))=0 Then
       'Auswerten/ausrechnen/ausgeben
    Else
       'ggf Fehlermeldung
    end if


    In der Funktion selbst implementierst Du das auslesen der Bytes und das berechnen der CRC (und die Zuweisung).
     
  18. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Hallo LotadaC

    Danke für deine anregung werde mal Versuchen sie umzusetzten, was aber eine weile dauern wird.

    So mal ein zwischen stand meiner Versuche.
    Ich muss mir alles wieder anlesen und nachschlagen, 7 Jahre nichts tun bei einer Sprache ist Fatal.
    Ich muss zugeben, hättest du nicht so Tiefgründige Fragen zum DS1820 gestellt, hätte ich mich damit garnicht weiter beschäftigt, den es lief ja alles.
    Aber Danke dafür, den es macht spass und ganz langsam kommen erfolgreiche ergebnisse zustande.



    CodeBox BascomAVR
    '*******************************************************************************
    '* Test des 1Wirebus und deren Sensoren                                        *
    '* Benutzter Controller Atmega 8                                               *
    '*                                                                             *
    '* Ralf Neubert Dinslaken                                                      *
    '* Logger @ www.makerconnect.de    ( www.AVR-Praxis.de )                       *
    '* Geholfen hat das Buch von Burkhard Kainka "Basiskurs Bascom-AVR" und        *
    '* das Internet, Herr Google                            *
    '*******************************************************************************
    $Regfile = "m8def.dat"
    $Crystal = 16000000
    $Baud = 19200
    $Hwstack=40
    $Swstack=16
    $Framesize=32
    
    $version 0 , 0 , 82
    Dim Buildinfo As String * 20
    Dim Buildinfo2 As String * 20
    Buildinfo = Version(1)                                     ' enthält Datum und Uhrzeit des Erstellzeitpunkts
    Buildinfo2 = Version(2)
    
    ' Pin für 1wire Schnittstelle festlegen
    Config 1wire = Portb.0
    
    Dim T1 As Integer                                           'hilfs Variable für die berechnung
    Dim T2 As Integer                                           'hilfs Variable für die berechnung
    Dim T3 As String * 5                                        'hilfs Variable zur Ausgabe an LCD oder Print
    Dim T4 As String * 5                                        'hilfs Variable zur Ausgabe an LCD oder Print
    Dim T5 As String * 5                                        'hilfs Variable zur Ausgabe an LCD oder Print
    Dim T7 As Single                                            'hilfs Variable für die berechnung
    Dim Id1(8) As Byte                                          'für die adresse Sensor 1
    Dim Id2(8) As Byte                                          'für die adresse Sensor 2
    Dim Id3(8) As Byte                                          'für die adresse Sensor 3
    Dim Id4(8) As Byte                                          'für die adresse Sensor 4
    Dim Ar1(9) As Byte                                          'Array fürs Scratchpad  Sensor 1
    Dim Ar2(9) As Byte                                          'Array fürs Scratchpad  Sensor 2
    Dim AR3(9) As Byte                                          'Array fürs Scratchpad  Sensor 3
    Dim Tmp1 As Byte , Tmp2 As Byte , Tmp3 As Byte
    Dim W As Byte
    Dim I As Byte
    
      'Unterprogramme benennen
    Declare Sub Con_temp
    Declare Sub Temperature
    Declare Sub Temp1
    Declare Sub Temp2
    Declare Sub Temp3
    'Declare Function DS1820_ScratchpadReadError(byref Id1() as Byte, byref target() as Byte)as byte
    
       '1wire Bus absuchen
    W = 1wirecount()
    Id1(1) = 1wsearchfirst()
    Id2(1) = 1wsearchnext()
    Id3(1) = 1wsearchnext()
    Id4(1) = 1wsearchnext()
    
    Print W ; " Sensoren gefunden"
    Print "      "
    For I = 1 to 8
       Print Hex(id1(i));
       Print "";
    Next
    Print "  "
    For I = 1 to 8
       Print Hex(id2(i));
       Print "";
    Next
    Print "  "
    For I = 1 to 8
       Print Hex(id3(i));
       Print "";
    Next
    
    WAITms  200
    
      'Hauptprogramm
    Do
    
       Con_temp
       Temperature
    
    Loop
    
    Sub Temperature
       1wwrite &HCC : 1wwrite &H44
       Waitms 300
       Temp1
       Temp2
       Temp3
       'Temp4
       If Err = 1 Then
         Print "Sensor Fehler  "
       Else
         Print T3 ; " C " ;
         Print T4 ; " C " ;
         Print T5 ; " C "
         Print "         "
       End If
    End Sub
    
          'Temperaturen Convertieren
    sub Con_temp
       1wreset
       1wwrite &HCC
       1wwrite &H44
       Waitms 600
       1wreset
    End Sub
    
    
      'Temperatur 1 Berechnen
    Sub Temp1
       1wreset
       1wwrite &H55
       1wwrite Id1(1) , 8
       1wwrite &HBE
       Ar1(1) = 1wread(9)
       If AR1(9) = Crc8(AR1(1) , 8) Then
        1wreset
        Tmp1 = Ar1(1) And 1
        If Tmp1 = 1 Then Decr Ar1(1)
         T1 = Makeint(ar1(1) , Ar1(2))
        T1 = T1 * 50
        T1 = T1 - 25
        T2 = Ar1(8) - Ar1(7)
        T2 = T2 * 100
        T2 = T2 / Ar1(8)
        T1 = T1 + T2
        T1 = T1 / 10
        T7 = T1 / 10
        T3 = Fusing(t7 , " ##.&" )
       else
    
           Print "CRC Fehler S1 : "
    
       End if
    End Sub
    
      'Temperatur 2 Berechnen
    Sub Temp2
        1wreset
       1wwrite &H55
       1wwrite Id2(1) , 8
       1wwrite &HBE
       Ar2(1) = 1wread(9)
       If AR2(9) = Crc8(AR2(1) , 8) Then
        1wreset
        Tmp2 = Ar2(1) And 1
        If Tmp2 = 1 Then Decr Ar2(1)
         T1 = Makeint(ar2(1) , Ar2(2))
        T1 = T1 * 50
        T1 = T1 - 25
        T2 = Ar2(8) - Ar2(7)
        T2 = T2 * 100
        T2 = T2 / Ar2(8)
        T1 = T1 + T2
        T1 = T1 / 10
        T7 = T1 / 10
        T4 = Fusing(t7 , " ##.&" )
      else
    
           Print "CRC Fehler S2 : "
    
      End if
    End Sub
    
      'Temperatur 3 Berechnen
    Sub Temp3
        1wreset
       1wwrite &H55
       1wwrite Id3(1) , 8
       1wwrite &HBE
       Ar3(1) = 1wread(9)
       If AR3(9) = Crc8(AR3(1) , 8) Then
        1wreset
        Tmp3 = Ar3(1) And 1
        If Tmp3 = 1 Then Decr Ar3(1)
         T1 = Makeint(ar3(1) , Ar3(2))
        T1 = T1 * 50
        T1 = T1 - 25
        T2 = Ar3(8) - Ar3(7)
        T2 = T2 * 100
        T2 = T2 / Ar3(8)
        T1 = T1 + T2
        T1 = T1 / 10
        T7 = T1 / 10
        T5 = Fusing(t7 , " ##.&" )
      else
    
           Print "CRC Fehler S3 : "
    
      End if
    End Sub
    
    End
    
     
  19. Logger

    Logger Mitglied

    Registriert seit:
    25. Februar 2009
    Beiträge:
    102
    Zustimmungen:
    2
    Ort:
    Dinslaken
    Sprachen:
    BascomAVR
    Map
    Den CRC Fehler löse ich übrigens aus, in dem ich einen Sensor mit Kälte spray unterkühle.
     
  20. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.877
    Zustimmungen:
    42
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Bisher sind's noch parameterlose Subroutinen. Wenn Du meinem Vorschlag folgst, sollen es Funktionen mit Parametern werden.
    Wenn Du weitere Hinweise brauchst, meldest Du Dich.
     
  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)