Bascom LCD Anzeige PC4004LRU von Powertip

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
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

  • Like
Wertungen: Dirk

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
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
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
So, Du hattest um konstruktive Kritiken gebeten...

offensichtlich hattest Du drei 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...
 
Zuletzt bearbeitet:

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
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.

1. hast Du unter Zuhilfenahme von "Config LCD" gelöst. Wiedersprechen sich nicht die Zeilen 37 und 38 ?
Das steht so auch in der Bascom hilfe, ist das falsch ?

Ich würde ein paar Sachen bei der Berechnerei ändern...
Bin gespannt.
 

Anhänge

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
steht so auch in der Bascom hilfe, ist das falsch ?
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...
 

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
Moin

Danke schon mal für's durch schauen des Code.
Warum also Zeile 37? (Die sollte im Port-Mode irrelevant sein).
Du hast Recht, das Funktioniert auch ohne "Config Lcdbus = 4", ist auch in der Bascom hilfe so nicht dargestellt.

Das ___LCDNO-Flag schaltet zwischen den beiden "E"s um - ist Zeile 100 da (nochmal) nötig?
Das muß so sein, da ja immer die passende Display hälfte damit angesprochen wird, ansonsten wird es auf der falsche Hälfte angezeigt.

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.
Das werde ich heute abend mal umprogrammieren, nur das dauert bei mir, ich bin da eher der anfänger.

Gruß Ralf
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Das muß so sein, da ja immer die passende Display hälfte damit angesprochen wird,
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.
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Die 0,25 müssen meiner Meinung nach vom Runden auf halbe Kelvin stammen.
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.
 

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
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.
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
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).

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.
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(!).
 

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
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(!).
Ja das würde ich gerne, nur fehlt mir oft die Zeit.

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...
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.
 

Dirk

Administrator
Teammitglied
28 Jan 2007
4.299
146
63
Mittelhessen, Giessen
Sprachen
ANSI C, C++, C#, Java, Kotlin, Pascal, Assembler, PHP
Hättest du ein Buch das du mir als Anfänger für Assembler empfehlen kannst ?
Mit beispielen und übungen.
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.
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
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...
 

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
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.
 

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
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

Zuletzt bearbeitet:

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
Ich denke ich Lese mit Rom (1-8) das scratchpad aus, aber ist wohl nicht der fall.
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...
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.401
62
48
Marwitz
Sprachen
BascomAVR, Assembler
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).
 

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
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
 

Logger

Mitglied
25 Feb 2009
106
2
18
Dinslaken
Sprachen
BascomAVR
Den CRC Fehler löse ich übrigens aus, in dem ich einen Sensor mit Kälte spray unterkühle.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)