Forum: Mikrocontroller und Digitale Elektronik Stoppuhr mit Atmega 8 und 4x20 LCD Display


von Silvio F. (silvio123)


Lesenswert?

Hallo, ich brauch mal eure Hilfe


Ich habe vor eine Stoppuhr zu bauen. Dazu hab ich mir eine Platine 
gemacht, die den LCD Bildschirm EA W204-BNLED mit dem Atmega 8 
verbindet.
Über PC5,4,3,2 sollen Taster angeschlossen werden. Um die Zeit zu sarten 
und um 2 zeiten zu stoppen können. Der 4 Taster dient dem Reset.

Wollte es erst über den Timer 2 machen. aber da springen die Zeiten 
irgendiwe.

Dann habe ich mir einen Uhrenquarz bestellt. Damit kriege ich es aber 
acuuh nicht hin.
1
$regfile = "m8def.dat"
2
'$crystal = 1000000
3
$crystal = 3686400
4
5
 'Einstellungen für Lcd Display
6
'-------------------------
7
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
8
Config Lcd = 20 * 4
9
Cls
10
Cursor Off
11
'Deklaration für Uhr'
12
Config Clock = Soft
13
Enable Interrupts
14
Time$ = "0:00:00"
15
16
Config Pinc.5 = Input
17
Config Pinc.4 = Input
18
Config Pinc.3 = Input
19
'Portc.5 = 1;  '
20
'Portc.4 = 1;   '
21
'Portc.3 = 1;    '
22
Dim I As Integer
23
I = 0
24
25
Do
26
   Locate 1 , 1
27
   Lcd "Boot 1: " ; Time$
28
   Locate 2 , 1
29
   Lcd "Boot 2: " ; Time$
30
Loop
31
End
32
33
Sectic:
34
   Locate 1 , 1
35
   Lcd I
36
Return


Hat jemand dafür schon einen Code oder kann mir bei meinem Problem 
weiterhelfen?

Danke

von Jan Koppe (Gast)


Lesenswert?


von Vor-Stopper (Gast)


Lesenswert?

Also... nen bissel Code mußte schon selber machen. Hier gibt's nur Hilfe 
zur Selbsthilfe. Zeig deinen Timer-Code und wir sehen uns an warum der 
Timer, nunja, "springt".


Eine gescheite Stoppuhr ist für jemanand mit wenig Programmiererfahrung 
schon recht sportlich.
Wie läft das Display? über Serielle Schnittstelle oder über Protokoll 
und SPI/I2C? Das Display ist nochmal ne Baustelle für sich.


1. Du  läßt im Interrupt nen Timer laufen (Start ab dem ersten 
Flankenwechsel. Zum Ausschalten nimmste ja nen anderen Taster. Da 
brauchste auch nix entprellen. Gar nix. Dann zählste einfach in einer 
Interrupt-Routine die Timer-überläufe, liest sie in der Hauptschleife 
aus und rechnest sie in Sekunden, Minuten etc um.

2. Du mißt mit der Compare-Capture Einheit des Timers. Das erfordert 
aber schon ein bissel Hirnschmalz und vor allen Dingen Lesen des 
Datenblatts. Der Vorteil hiervon ist daß du sehr kurze Zeitabstände 
erfassen kannst (z.B. Pulsbreitenerkennung eines Modellbau-Servos).

von Weingut P. (weinbauer)


Lesenswert?

den Uhrenquarz hast Du wo angeschlossen??

$crystal = 3686400

Das ist der Controllertakt
Das hier ist dann wenn der Uhrenquarz richtig angeschlossen ist und 
richtig konfiguriert eine Subroutine der Timerinterruptroutine ...

Sectic:
   Locate 1 , 1
   Lcd I
Return

LCD-Kommandos haben nichts(!) in Interrupts verloren, die dauern ewig in 
der Abarbeitung und der Controller hängt derweil im Interrupt fest, neue 
Interrupts werden glattweg ignoriert.

von Karl H. (kbuchegg)


Lesenswert?

> Config Clock = Soft
> Enable Interrupts
> Time$ = "0:00:00"

Und die Sache mit der eingebauten Uhr - die vergisst du am besten gleich 
wieder. Die bringt dich hier nicht weiter.
Das Programmierer-Leben ist nun mal kein Ponyhof. In den meisten Fällen 
muss man als Programmierer selber ran und sich um die Logik kümmern. Die 
Logik, wie eine Uhr weitergeschaltet wird, ist ja nun wirklich keine 
Raketentechnik.

von Weingut P. (weinbauer)


Lesenswert?

Karl Heinz Buchegger schrieb:
>> Config Clock = Soft
>> Enable Interrupts
>> Time$ = "0:00:00"
>
> Und die Sache mit der eingebauten Uhr - die vergisst du am besten gleich
> wieder. Die bringt dich hier nicht weiter.
> Das Programmierer-Leben ist nun mal kein Ponyhof. In den meisten Fällen
> muss man als Programmierer selber ran und sich um die Logik kümmern. Die
> Logik, wie eine Uhr weitergeschaltet wird, ist ja nun wirklich keine
> Raketentechnik.

na, na, die Bascomroutinen für die Uhr gehen schon, kein Grund da zum 
hauen ... es fehlen einfach noch n paar Grundlagen.

$regfile = "m8def.dat"
'$crystal = 1000000
$crystal = 3686400

 'Einstellungen für Lcd Display
'-------------------------
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , 
Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
Config Lcd = 20 * 4
Cls
Cursor Off
'Deklaration für Uhr'
Config Clock = Soft
Enable Interrupts
Time$ = "0:00:00"

Config Pinc.5 = Input
Config Pinc.4 = Input
Config Pinc.3 = Input
Portc.5 = 1  ' pullups einschalten
Portc.4 = 1   ' pullups einschalten
Portc.3 = 1    ' pullups einschalten
Dim I As Integer
dim Redraw_flag as byte

Redrawflag = 0
I = 0

Do

if Redraw_flag = 1 then
   Redraw_flag = 0

   Locate 1 , 1
   Lcd "Boot 1: " ; Time$
   Locate 2 , 1
   Lcd "Boot 2: " ; Time$
   Locate 3 , 1
   Lcd I
endif

Loop
End

Sectic:
   Redraw_flag = 1
Return


Die Uhr wird dennoch springen, weil die LCD-Ausgabe einfach bremst, aber 
es geht kein Zähler verloren

von Karl H. (kbuchegg)


Lesenswert?

Fhutdhb Ufzjjuz schrieb:

> na, na, die Bascomroutinen für die Uhr gehen schon,

Das Ziel ist aber eine Stoppuhr mit 2 voneinander getrennten 'Kanälen'.

Da kommst du mit dem hier

Do

if Redraw_flag = 1 then
   Redraw_flag = 0

   Locate 1 , 1
   Lcd "Boot 1: " ; Time$
   Locate 2 , 1
   Lcd "Boot 2: " ; Time$
   Locate 3 , 1
   Lcd I
endif

nicht wirklich weiter. Oder willst du ständig Strings durch die Gegend 
kopieren, wenn der Taster betätigt wird?

(Und da der Appetit bekanntlich mit dem Essen kommt: Zum Berechnen der 
Differenzzeit wandelst du dann den String wieder in Zahlen zurück?)

Das bischen Arbeit in einer ISR, die vom Timer alle x Zeiteinheiten 
(muss ja nicht ganze Sekunden sein) angestossen wird, ist nun wirklich 
nichts was einen groß umbringt. Dafür hat man dann aber auch alles unter 
Kontrolle. Der Knackpunkt ist der Timer - da wie dort.

(Und ein paar Basistechniken zu kennen schadet nicht. Das nächste mal 
macht er eine Eieruhr, die runterzählt und steht dann erst recht wieder 
da, wie der Ochs vorm Tor)

von Weingut P. (weinbauer)


Lesenswert?

Ja, da hast Du Recht, Strings hin und her schubsen ist nicht 
zielführend, er hat ja die Variable I, deren Verarbeitung noch aussteht 
... die zwei Zeilen Time$ sind sowieso identisch, auch da hat er noch ne 
Baustelle.
Die Tastenverarbeitung kommt auch noch dazu ... er steht halt noch am 
Anfang des Lernprozesses.
Auch Du wirst irgendwann angefangen haben und wenn Du Dir heute Deine 
Erstlingswerke ansiehst wird Dich auch das kalte Grausen packen, oder?
Mir zumindest gehts so :o)

Mir ging es zunächst darum die "Handbremse" LCD aus der ISR raus zu 
bekommen und den Grund dafür zu verdeutlichen.

von Karl H. (kbuchegg)


Lesenswert?

Fhutdhb Ufzjjuz schrieb:

> Die Tastenverarbeitung kommt auch noch dazu ... er steht halt noch am
> Anfang des Lernprozesses.

Das ist schon klar.

> Auch Du wirst irgendwann angefangen haben und wenn Du Dir heute Deine
> Erstlingswerke ansiehst wird Dich auch das kalte Grausen packen, oder?

Oooooohhhh  ja. :-)

> Mir ging es zunächst darum die "Handbremse" LCD aus der ISR raus zu
> bekommen und den Grund dafür zu verdeutlichen.

Und das hast du sehr gut gemacht.
(Obwohl, wenn es bei 2 Texten alle 1 Sekunde ausgeben, an der Ausgabe 
hackelt, dann ist noch was faul :-)

von Silvio F. (silvio123)


Angehängte Dateien:

Lesenswert?

Vor-Stopper schrieb:
> Wie läft das Display? über Serielle Schnittstelle oder über Protokoll
> und SPI/I2C? Das Display ist nochmal ne Baustelle für sich.

Also das Display habe ich versucht so ähnlich wie das Display vom MyAVR 
LCD v2.5 anzuschließen. Siehe auch Dateianhang.

Was ist denn nun besser? Wenn ich einen Uhrenquarz nehme, mit dem 
internen 1MHz quarz arbeite und den Uhrenquarz für die $Time-Funktion 
ohne Kondensatoren an den Eingängen des normalen Quarz nutze oder wenn 
ich einen normalen Quarz nehme und es über die Timerfunktion mache?

von Silvio F. (silvio123)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das Ziel ist aber eine Stoppuhr mit 2 voneinander getrennten 'Kanälen'.

Naja ich möchte beide Zeiten mit einem Notausknopf beim runterdrücken 
starten. Resettet werden sollen die Zeiten wenn ich ihn wieder hoch 
ziehe. Und dann habe ich am liebsten noch einen Taster. Wenn ich den 
taster das erste mal drücke soll zeit 1 stehen bleiben (bzw. die zeit 
weiterzählen und sich die erste zeile nichtmehr verändern) und beim 2. 
drücken auf den taster soll zeit 2 stehen bleiben.

von spess53 (Gast)


Lesenswert?

Hi

>Also das Display habe ich versucht so ähnlich wie das Display vom MyAVR
>LCD v2.5 anzuschließen. Siehe auch Dateianhang.

Die können anscheinend auch keine Datenblätter lesen. DB0...3 vom 
Display gehören nicht an GND. Die Pins haben interne 
Pull-Up-Widerstände.

MfG Spess

von Silvio F. (silvio123)


Lesenswert?

hatte es auch schon so probiert
1
 $regfile = "m8def.dat"
2
$crystal = 3686400
3
4
 'Einstellungen für Lcd Display
5
'-------------------------
6
Cls
7
8
Config Pind.2 = Input
9
Config Pind.3 = Input
10
Portd.2 = 1
11
Portd.3 = 1
12
Config Portd.2 = 0
13
 Config Portd.3 = 0
14
'----------
15
Config Portc.5 = Output
16
Config Portc.5 = 1
17
 portc.5 = 1
18
19
Dim Millisekunden As Byte
20
Dim Minuten As Byte
21
Dim Sekunden As Byte
22
Dim Runden As Byte
23
Dim Flag As Integer
24
25
26
Config Timer1 = Timer , Prescale = 64
27
Const Timervorgabe = 40536
28
On Timer1 Timer_irq
29
Enable Interrupts
30
31
32
Millisekunden = 00
33
Minuten = 0
34
Sekunden = 0
35
Runden = 0
36
Flag = 0
37
38
Declare Sub Start1
39
Declare Sub Stop1
40
Declare Sub Reset1
41
42
'---------------------------------------------
43
Do
44
45
Debounce Pind.2 , 0 , Start1 , Sub
46
Debounce Pind.3 , 0 , Stop1 , Sub
47
Debounce Pind.2 , 0 , Reset1 , Sub
48
Debounce Pind.3 , 0 , Reset1 , Sub
49
50
51
If Runden = 10 Then
52
disable timer1 : toggle Portc.5
53
End If
54
55
Locate 1 , 5
56
Lcd " Runden" ; Runden
57
58
Locate 2 , 2
59
Lcd "Zeit:    " ; Minuten ; ":" ; Sekunden ; ":" ; Millisekunden ; " "
60
61
Locate 1 , 1
62
Lcd Flag
63
64
Loop
65
'---------------------------------------------
66
Start1:
67
Enable Timer1
68
69
Return
70
'-----------------------------------------
71
Stop1:
72
73
Runden = Runden + 1
74
return
75
'------------------------------
76
77
Reset1:
78
Reset Timer1
79
disable timer1
80
81
Locate 1 , 1
82
Lcd "Reset"
83
Wait 1
84
Cls
85
Sekunden = 0
86
Minuten = 0
87
Runden = 0
88
Millisekunden = 0
89
Flag = 0
90
91
Return
92
93
'--------------------------------------------
94
Timer_irq:
95
  Timer1 = Timervorgabe
96
      Incr Millisekunden
97
      If Millisekunden = 10 Then
98
      Incr Sekunden
99
      Millisekunden = 00
100
      End If
101
    'End If
102
  If Sekunden = 60 Then
103
    Incr Minuten
104
    Sekunden = 00
105
  End If
106
107
  Incr Flag
108
109
Return

funktioniert mit meinem myavr mk2 board ganz gut, aber die zeiten laufen 
irgendwie in einer anderen geschwindigkeit als gedacht. Da hatte ich 
dann den Crystal 3,6864 verwendet und die intervalle zum hochzählen 
entsprechend eingestellt

von Silvio F. (silvio123)


Lesenswert?

spess53 schrieb:
> Die können anscheinend auch keine Datenblätter lesen. DB0...3 vom
> Display gehören nicht an GND. Die Pins haben interne
> Pull-Up-Widerstände.

Stimmt hatte die Schaltung von dem 16x2 Display übernommen. Hab mit dem 
falschen Datenblatt verglichen. Hab mir jetzt mal das richtige genommen.

Dann muss ich ja anscheinend meine Platine nochmal neu machen

von spess53 (Gast)


Lesenswert?

Hi

>Dann muss ich ja anscheinend meine Platine nochmal neu machen

Na ja, da RW fest auf Masse liegt passiert da außer etwas mehr 
Stromverbrauch nichts ernsthaftes.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Silvio Franz schrieb:

> funktioniert mit meinem myavr mk2 board ganz gut, aber die zeiten laufen
> irgendwie in einer anderen geschwindigkeit als gedacht. Da hatte ich
> dann den Crystal 3,6864 verwendet und die intervalle zum hochzählen
> entsprechend eingestellt

Wenn du dich hier nicht verrechnet hast

Config Timer1 = Timer , Prescale = 64
Const Timervorgabe = 40536

(ich hab jetzt nicht nachgerechnet), dann stimmt in so einem Fall die 
CRYSTAL Angabe nicht.
Beachte: Du kannst in Crystal reinschreiben was immer du willst. Nur 
weil du da eine Zahl reinschreibst, heist das noch lange nicht, dass der 
µC auch mit dieser Frequenz läuft.
Genau dasselbe mit dem Quarz. Nur weil du einen Quarz physisch an den µC 
angeschlossen hast, heist das noch lange nicht, dass der auch benutzt 
wird. Du musst mittels der Fuse-Bits den AVR auch umstellen, so dass der 
Quarz auch tatsächlich benutzt wird. Wenn du das nicht tust, dann läuft 
der µC nachwievor auf den internen 1Mhz, so wie im Auslieferungszustand. 
Rechnest du dann mit 3.4Mhz ist klar, dass deine Zeiten hinten und vorne 
nicht stimmen.

von Silvio F. (silvio123)


Lesenswert?

Habe die Fusebits auf externen Quarz umgestellt.
Aber die Fusebitsvon meinem MK2 Board kopiert

Wichtig wäre mir jetzt erstmal ob ich die Datenleitungen 0 bis 7 an PD0 
bis PD7 vom Atmega anschließn soll oder nicht

von Karl H. (kbuchegg)


Lesenswert?

Silvio Franz schrieb:

> Wichtig wäre mir jetzt erstmal ob ich die Datenleitungen 0 bis 7 an PD0
> bis PD7 vom Atmega anschließn soll oder nicht

Du kannst. Musst aber nicht.
Diese LCD kann man in 2 MOdi betreiben.
4-Bit Modus und 8-Bit Modus.
8-Bit Modus: die volle Breitseite D0 bis D7 wird angeschlossen
4-Bit MOdus: nur D4 bis D7 werden angeschlossen, D0 bis D3 bleiben frei.


In der Theorie ist der 8Bit Modus natürlich schneller. In der Praxis 
spielts aber keine wirkliche Rolle. Dafür spart man im 4Bit Modus an 
Leitungen und belegt mit den kompletten LCD Leitungen nur einen einzige 
Port (und den nicht zur Gänze)

von Karl H. (kbuchegg)


Lesenswert?

> Was ist denn nun besser? Wenn ich einen Uhrenquarz nehme, mit dem
> internen 1MHz quarz arbeite

den gibt es nicht.
Die internen 1Mhz werden von einem RC-Schwingkreis erzeugt. Die sind 
ungefähr so konstant, wie der Wasserstand in der Donau.

> und den Uhrenquarz für die $Time-Funktion

Uhrenquarz kann man nehmen.

> ich einen normalen Quarz nehme und es über die Timerfunktion mache?

Das wäre das, wie ich es machen würde.
Damit stehen mir alle Möglichkeiten offen.

Ich brauch nicht noch eine Zusatzbeschaltung und mit einem Timer im CTC 
Modus und Weiterzählung in einer ISR erreicht man mit wenig 
Softwareaufwand eine genau gehende Uhr, die dann auch Zehntel oder 
Hunderstelsekunden macht. Und der Abgleich (den man auch bei einem 
Uhrenquarz machen muss!) ist nicht das große Problem, solange es nur um 
einen Kurzzeittimer geht. Wenn die Uhr in einem Jahr Laufzeit möglichst 
geringe Abweichung haben soll, dann sieht die Sache anders aus, dann 
zählt die exakte Kentniss der genauen Schwingfrequenz. Aber bei 
Zeiträumen von ein paar Minuten/STunden kann man das meist ignorieren, 
dass ein 4.000 Mhz Quarz eben nicht exakt 4000000 Schwingungen in der 
Sekunde macht, sondern 58 mehr oder weniger.

von Weingut P. (weinbauer)


Lesenswert?

So wie Du hier die Subroutinen einbindest brauchst Du das Declare nicht.

wie passt das:
Config Pind.2 = Input
Config Pind.3 = Input
....
zu dem?
Config Portd.2 = 0
Config Portd.3 = 0

Die Configs sind fürs Data Direction Register, hier passt das zufällig 
mit der 0 und dem Input ... das zweite mal Config also weglassen.

dann hier:

Debounce Pind.2 , 0 , Start1 , Sub
Debounce Pind.3 , 0 , Stop1 , Sub
Debounce Pind.2 , 0 , Reset1 , Sub
Debounce Pind.3 , 0 , Reset1 , Sub

Du drückst also den Taster D.2 für Start, da enablest Du den Timer, und 
gleich danach wird Reset1 ausgeführt, der disabled und noch dazu n "wait 
1" dabei hat.

Dein LCD wird bei jedem Durchlauf der Mainloop überschrieben, was extrem 
Zeitaufwändig ist, also da bessser auf Refreshflag gehen zur 
Aktualisierung.
Wenn Du Start drückst, dann macht es Sinn, den Timer auf den Startwert 
zu setzen, damit der nicht irgendwo schon hoch steht und die erste 
zehntel zu kurz wird.

für Zehntel hab ich heraus bei $crystal = 3686400:
Config Timer1 = Timer, Prescale = 8
Timervorgabe = 19456

von Weingut P. (weinbauer)


Lesenswert?

ach so, eins noch, Bascom hat den wunderbaren Befehl "Alias", den 
verwende ich persönlich sehr gerne.
Man kann da definieren wie z.B. n Taster heißt und den Namen dann im 
Code beliebig verwenden.

Also in dem Fall:

Taster_start Alias Pind.2
Taster_stop Alias Pind.3
Config Taster_start = Input
Config Taster_stop = Input

Debounce Taster_start , 0 , Start1 , Sub
Debounce Taster_stop , 0 , Stop1 , Sub

ist eine Frage des persönlichen Geschmacks, hat aber auch praktische 
Gesichtspunte. Will man nen Code von einem µC zum anderen portieren, 
wenn Dir z.B. für die Funktion n ATTiny2313 reichen sollte, kann man 
einfach einmal die Aliaszuordnung ändern und die Änderung geht auf den 
ganzen Code über.

von Weingut P. (weinbauer)


Lesenswert?

Silvio Franz schrieb:
> Dann muss ich ja anscheinend meine Platine nochmal neu machen

nee, mit Teppichmesser die Leiterbahn auftrennen oder pins mit 
Seitenschneider kappen und D0 bis D3 floaten lassen. passt.

ist gängige Methode beim "rework"

von Karl H. (kbuchegg)


Lesenswert?

Fhutdhb Ufzjjuz schrieb:
> Silvio Franz schrieb:
>> Dann muss ich ja anscheinend meine Platine nochmal neu machen
>
> nee, mit Teppichmesser die Leiterbahn auftrennen oder pins mit
> Seitenschneider kappen und D0 bis D3 floaten lassen. passt.
>
> ist gängige Methode beim "rework"

Yup

Und Silvio. Wart jetzt erst mal ab, was sonst noch so alles auftaucht. 
Mit Teppichmesser, etwas dünnem Draht und einem Lötkolben, kann man so 
manche Falschverdrahtung oder Umverdrahtung vornehmen, ohne gleich 
jedesmal eine neue Platine machen zu müssen. Nenn die jetzige einfach 
Version 0.9. Wichtig: Jede Änderung an der Platine gleich im 
Platinen_layout_Programm nachziehen, sonst vergisst man sie.
Und wenn dann alles fertig ist, das Programm zur Zufriedenheit läuft, 
alle Hardwaremacken zunächst provisorisch mit Messer und Kabel gefixt 
wurden, erst dann ist es Zeit die Version 1.0 der Platine zu machen. (So 
man dann noch Lust dazu hat. Es ist gar nicht so ungewöhnlich, dass man 
dann sagt: Ah, geh. Ob da jetzt ein paar dünne Kabel aus Fädeldraht an 
der Platine sind oder nicht, ist doch nur ein optisches 'Problem'. Passt 
schon. Gehäuse her, Platine rein, keiner siehts mehr und mich störts 
nicht)

von Silvio F. (silvio123)


Lesenswert?

Na war nicht so tragisch. habe ja erstmal ne lochrasterplatine gemacht.

So also Display geht jetzt erstmal. Hab die 4 Bitvariante gemacht.

Es zeigt mir bei folgendem Code aber immer Fragezeichen, Slasch und Os 
an. Hab meinen Crsytal auf 3686400 gestellt und die Fusebits gesetzt.

Weiß nicht genau warum. Wenn er mir dann die richtigen Zeichen anzeigt 
mach ich mit der uhr weiter

Code von Programm wo er Fragezeichen anzeigt
1
$regfile = "m8def.dat"
2
$crystal = 3686400
3
4
 'Einstellungen für Lcd Display
5
'-------------------------
6
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
7
Config Lcd = 20 * 4
8
Cls
9
Cursor Off
10
'Deklaration für Uhr'
11
Config Clock = Soft
12
Enable Interrupts
13
Time$ = "0:00:00"
14
15
Config Pinc.5 = Input
16
Config Pinc.4 = Input
17
Config Pinc.3 = Input
18
'Portc.5 = 1;  '
19
'Portc.4 = 1;   '
20
'Portc.3 = 1;    '
21
Dim I As Integer
22
I = 0
23
24
Do
25
   Locate 1 , 1
26
   Lcd "Boot 1: " ;
27
   Locate 2 , 1
28
   Lcd "Boot 2: " ;
29
Loop
30
End
31
32
Sectic:
33
34
Return

und ein Code den ich vll für die uhr nehmen könnte, ist jetzt aus einem 
anderen Projekt wo ich versucht habe eine stopuhr einzubauen
1
'Programm sendet ca. 26 Messungen pro Sekunde
2
3
4
' compiler steuerung
5
$regfile = "m8def.dat"
6
$crystal = 3686400
7
$framesize = 64
8
$swstack = 64
9
$hwstack = 64
10
$baud = 9600
11
$lib "i2c_twi.lbx"
12
'
13
' hardware konfigurieren
14
' - i2c
15
Config Twi = 200000
16
Config Scl = Portc.5
17
Config Sda = Portc.4
18
'Timer
19
Config Timer1 = Timer , Prescale = 1
20
On Timer1 Timer1_isr
21
Enable Timer1
22
Enable Interrupts
23
Const Timerstartwert = 61850
24
Timer1 = Timerstartwert
25
' variablen dimensionieren
26
Dim V(6) As Byte
27
Dim Az As Integer At V(5) Overlay
28
Dim Acc_cntr As Byte
29
Dim I As Byte
30
Dim Acc_range As Byte
31
Dim D2g As Single
32
Dim S As Single
33
Dim Analogwandler As Integer
34
Dim Zeitms As Integer
35
Dim Zeitm As Integer
36
Dim Zeits As Integer
37
Zeitms = 0
38
Zeitm = 0
39
Zeits = 0
40
'
41
' konstanten
42
Const Acc_w = &H70
43
Const Acc_r = &H71
44
45
46
Config Adc = Single , Prescaler = Auto , Reference = Avcc
47
48
' hauptprogramm
49
I2cinit
50
'
51
'Call Set_acc_range(0)
52
53
Dim Range As Byte
54
Range = 0
55
I2cstart
56
' sensor adressieren
57
I2cwbyte Acc_w
58
' kontrollregister adressieren
59
I2cwbyte &H14
60
'
61
I2cstop
62
'
63
I2cstart
64
' kontrollregister lesen
65
I2cwbyte Acc_r
66
I2crbyte Acc_cntr , Nack
67
'
68
I2cstop
69
'
70
' kontrollregister manipulieren
71
Acc_cntr.3 = Range.0
72
Acc_cntr.4 = Range.1
73
'
74
I2cstart
75
'
76
' kontrollregister zurückschreiben
77
I2cwbyte Acc_w
78
I2cwbyte &H14
79
I2cwbyte Acc_cntr
80
'
81
I2cstop
82
'
83
' umrechnungsfaktor neu berechnen
84
D2g = 2 ^ Range
85
D2g = D2g * 2
86
D2g = D2g / 512
87
88
89
' messbereich:
90
' Set_acc_range(0) -> +/- 2g (default)
91
' Set_acc_range(1) -> +/- 4g
92
' Set_acc_range(2) -> +/- 8g
93
'
94
Do
95
I2cstart
96
'
97
' sensor adressieren
98
I2cwbyte Acc_w
99
'
100
' acc datenregister adressieren
101
I2cwbyte &H02
102
'
103
I2cstop
104
'
105
I2cstart
106
'
107
' daten lesen
108
I2cwbyte Acc_r
109
'
110
For I = 1 To 5
111
I2crbyte V(i) , Ack
112
Next I
113
I2crbyte V(6) , Nack
114
'
115
I2cstop
116
'
117
' format konvertieren
118
Az = Az / 64
119
'
120
' in beschleunigungen umrechnen & ausgeben
121
Analogwandler = Getadc(3)
122
If Analogwandler > 300 Then
123
   S = Az * D2g
124
   Print "z: " ; Fusing(s , "#.##")
125
   Print "t: " ; Zeitm ; ":" ; Zeits ; "." ; Zeitms
126
End If
127
Waitms 25
128
'
129
Loop
130
'
131
End
132
'
133
134
135
136
137
Timer1_isr:
138
Timer1 = Timerstartwert
139
If Zeitms < 999 Then
140
   Zeitms = Zeitms + 1
141
Else
142
   Zeitms = 0
143
   If Zeits < 59 Then
144
      Zeits = Zeits + 1
145
   Else
146
      Zeits = 0
147
      Zeitm = Zeitm + 1
148
   End If
149
End If
150
Return

Danke für eure Bemühungen schonmal

von Karl H. (kbuchegg)


Lesenswert?

Silvio Franz schrieb:

> Es zeigt mir bei folgendem Code aber immer Fragezeichen, Slasch und Os
> an. Hab meinen Crsytal auf 3686400 gestellt und die Fusebits gesetzt.
>
> Weiß nicht genau warum.

Systematisch vorgehen:

alles aus dem Programm raus, was nicht unmittelbar mit dem Problem 'LCD' 
zu tun hat
Auf dem LCD einen Teststring ausgeben, der es einem auch ermöglicht 
mögliche systematische Fehler in der Verkabelung zu erkennen
1
$regfile = "m8def.dat"
2
$crystal = 3686400
3
4
 'Einstellungen für Lcd Display
5
'-------------------------
6
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
7
Config Lcd = 20 * 4
8
Cls
9
Cursor Off
10
11
Lcd "ABCDEFGHIJKL" ;
12
13
Do
14
Loop
15
End

Was wird angezeigt, welche Zeichen?
Wie lautet der ASCII Code dieser Zeichen? Am besten bitweise aufmalen.
Daneben gegenüberstellen die ASCII Codes von A B C D etc. aufschreiben. 
Ebenfalls binär. Gibt es Auffälligkeiten, wie zb das bestimmte, immer 
gleiche Bits vertauscht sind?

Wenn ja: Dann hast du dich einfach bei deiner Verkabelung verhaut und zb 
2 Kabel gekreuzt, was nicht hätte sein sollen.
(Und darum ist Flachbandkabel so einer Einzelverdrahtung immer 
überlegen. Damit ist es deutlich schwieriger, nur 2 Drähte zu 
vertauschen. Entweder das Kabel ist um 180 verdreht drauf und alles ist 
falsch oder alles ist richtig, wenn die Lötpads auf den Platinen in der 
richtigen Reihenfolge sind.)

von Weingut P. (weinbauer)


Lesenswert?

Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , 
Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3

Config Pind.2 = Input
Config Pind.3 = Input
Portd.2 = 1
Portd.3 = 1


D.2 und D.3 hast Du schonmal mit Deinen Tastern ... soll das so sein? 
... eher nicht, oder?

ach so, hinter dem config lcdpin kannst Du noch n Initlcd setzen zur 
Sicherheit.

von Silvio F. (silvio123)


Lesenswert?

In meinem Testprogramm hatte ich ja noch keine Schalter drin und das 
mit dem Teststring und ausrechnen welches Kabel vll vertauscht ist mache 
ich noch.
Ma cystall oder der Baudrate kann es aber nicht liegen oder?
Wenn ich bei meiner Bluetoothverbindung die Bausrate falsch einstelle 
kommt auch so ein unsinn raus.

Wie macht bascom das eigendlich wenn ich ein String von drei zeichen 
sende, sendet der dann bei ABC
65,66,67
oder macht er die Zeichenlänge voll
also 65,66,67,32,32,32,32,32,32...?

von Karl H. (kbuchegg)


Lesenswert?

Silvio Franz schrieb:

> Ma cystall oder der Baudrate kann es aber nicht liegen oder?

Dann würdest du das LCD gar nicht initialisiert bekommen. Aus der 
Tatsache, dass das LCD überhaupt was anzeigt, kann man schliessen, dass 
da schon einiges richtig sein muss. Unter anderem ist das Timing schon 
mal so falsch nicht.


> Wie macht bascom das eigendlich wenn ich ein String von drei zeichen
> sende, sendet der dann bei ABC
> 65,66,67

Wenn du "ABC" ans Display gibst, dann kriegt das Display auch A B C und 
sonst nichts. Wenn du ABC und 3 Leerzeichen willst, dann musst du eben 
"ABC   " ausgeben lassen.

> oder macht er die Zeichenlänge voll
> also 65,66,67,32,32,32,32,32,32...?

Warum soll er das tun?
Das ergibt doch keinen Sinn. Damit würde sich jegliche Technik des "Ich 
schreib aufs LCD nur die Dinge die sich geändert haben" von selbst 
verbieten.

von Weingut P. (weinbauer)


Lesenswert?

ähm ... der crystal kann durchaus fürs Timing zur Berechnung von 
Waitstates möglicherweise Auswirkungen haben, würd ich nicht 
ausschließen.

von Silvio F. (silvio123)


Lesenswert?

So Bildschirm geht jetzt. Es war nichts falsch angeschlossen. Der Strom 
von meinem Testboard war anscheinend zu niedrig

von Silvio F. (silvio123)


Lesenswert?

Also Programm läuft schon ganz gut.
Habe einen Schalter zum Stopuhr anschalten und resetten
und einen Taster zum Zeiten anhalten
Taster 1x betätigt zeit 1 bleibt stehen
Taster noch 1x betätigt zeit 2 bleibt stehen

Jetzt soll er mir die Differenzeit in Zeile 4 anzeigen
Aber dabei kommt nur murks raus
Irgendwie kann Bascom nicht vernünftig rechnen
Oder ich bin zu doof daür
Könnt ihr nochmal über den Code gucken?
Und einen richtigen Startwert für die Uhr brauche ich noch
1
$regfile = "m8def.dat"
2
$crystal = 3686400
3
4
 'Einstellungen für Lcd Display
5
'-------------------------
6
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
7
Config Lcd = 20 * 4
8
Cls
9
Cursor Off
10
11
Dim Zehntelsekunden As Integer
12
Dim Minuten As Integer
13
Dim Sekunden As Integer
14
Dim Zehntelsekundenboot1 As Integer
15
Dim Minutenboot1 As Integer
16
Dim Sekundenboot1 As Integer
17
18
Dim Wert1 As Integer
19
Dim Wert2 As Integer
20
Dim Wert3 As Integer
21
Dim Wert4 As Integer
22
23
24
Dim Boot As Integer
25
Boot = -1
26
Zehntelsekunden = 0
27
Minuten = 0
28
Sekunden = 0
29
30
31
32
33
'Timer
34
Config Timer1 = Timer , Prescale = 8
35
On Timer1 Timer1_isr
36
Enable Interrupts
37
Const Timervorgabe = 22456
38
Timer1 = Timervorgabe
39
40
Config Portc.5 = Input
41
Config Portc.4 = Input
42
Taste_startreset Alias Pinc.5
43
Taste_stop Alias Pinc.4
44
Portc.5 = 1                                                 'Pullupwiderstand
45
Portc.4 = 1                                                 'Pullupwiderstand
46
47
Locate 2 , 6
48
Lcd "Willkommen"
49
Wait 2
50
Cls
51
52
Locate 1 , 1
53
Lcd "Boot 1: "
54
Locate 2 , 1
55
Lcd "Boot 2: "
56
57
58
Do
59
   If Taste_startreset = 0 Then
60
      Enable Timer1
61
      Boot = 0
62
   End If
63
   If Boot > -1 Then
64
      Debounce Taste_stop , 0 , On_tasterstopp , Sub
65
   End If
66
   Cursor Off
67
68
   If Boot = 2 Then                                         'Wenn zweite Zeit gestoppt
69
      Boot = Boot + 1
70
      Dim Dif As Integer
71
      Wert1 = 600 * Minuten
72
      Wert2 = 10 * Sekunden
73
      Wert3 = Wert1 + Wert2
74
      Wert4 = Wert3 + Zehntelsekunden
75
      Wert1 = 600 * Minutenboot1
76
      Wert2 = 10 * Sekundenboot1
77
      Wert3 = Wert1 + Wert2
78
      Wert3 = Wert3 + Zehntelsekundenboot1
79
      Dif = Wert4 - Wert3
80
      Wert1 = Dif Mod 10
81
      Wert2 = Dif / 10
82
      Wert3 = Wert2 Mod 60
83
      Wert4 = Wert2 / 60
84
      Locate 3 , 1
85
      Lcd "--------------"
86
      Locate 4 , 1
87
      Lcd "Dif:"
88
      Locate 4 , 9
89
      Lcd Wert4 ; ":" ; Wert3 , "." ; Wert1
90
   Elseif Boot = 1 Then                                     'Wenn erste Zeit gestoppt
91
      Zehntelsekundenboot1 = Zehntelsekunden
92
      Minutenboot1 = Minuten
93
      Sekundenboot1 = Sekunden
94
      Locate 2 , 9
95
      Lcd Minuten ; ":" ; Sekunden ; "." ; Zehntelsekunden
96
   Elseif Boot = 0 Then
97
      Locate 1 , 9
98
      Lcd Minuten ; ":" ; Sekunden ; "." ; Zehntelsekunden
99
      Locate 2 , 9
100
      Lcd Minuten ; ":" ; Sekunden ; "." ; Zehntelsekunden
101
   End If
102
103
Loop
104
End
105
106
Timer1_isr:
107
If Zehntelsekunden < 9 Then
108
   Zehntelsekunden = Zehntelsekunden + 1
109
Else
110
   Zehntelsekunden = 0
111
   If Sekunden < 59 Then
112
      Sekunden = Sekunden + 1
113
   Else
114
      Sekunden = 0
115
      Minuten = Minuten + 1
116
   End If
117
End If
118
Return
119
120
121
On_tasterstopp:
122
   Boot = Boot + 1
123
Return

Danke

von Silvio F. (silvio123)


Lesenswert?

Also Taster funktionieren jetzt auch
Nur noch 2 Probleme
  Differenzeit geht nicht
  Zeit nicht richtig
Ich habe einen Startwert von 19456 bei Timer 1
Die Uhr zeigt nach einer reellen Minute aber erst ca. 45s an

Einer eine Idee?
1
$regfile = "m8def.dat"
2
$crystal = 3686400
3
4
 'Einstellungen für Lcd Display
5
'-------------------------
6
Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7 , E = Portd.2 , Rs = Portd.3
7
Config Lcd = 20 * 4
8
Cls
9
Cursor Off
10
11
Dim Zehntelsekunden As Integer
12
Dim Minuten As Integer
13
Dim Sekunden As Integer
14
Dim Zehntelsekundenboot1 As Integer
15
Dim Minutenboot1 As Integer
16
Dim Sekundenboot1 As Integer
17
Dim Rennen As Boolean
18
Dim Zuruecksetzen As Boolean
19
20
21
Dim Wert1 As Integer
22
Dim Wert2 As Integer
23
Dim Wert3 As Integer
24
Dim Wert4 As Integer
25
26
Dim Boot As Integer
27
Boot = -1
28
Zehntelsekunden = 0
29
Minuten = 0
30
Sekunden = 0
31
Rennen = 0
32
Zuruecksetzen = 0
33
34
35
'Timer
36
Config Timer1 = Timer , Prescale = 8
37
On Timer1 Timer1_isr
38
Enable Interrupts
39
Const Timervorgabe = 19456
40
Timer1 = Timervorgabe
41
42
Config Portc.5 = Input
43
Config Portc.4 = Input
44
Taste_startreset Alias Pinc.5
45
Taste_stop Alias Pinc.4
46
Portc.5 = 1                                                 'Pullupwiderstand
47
Portc.4 = 1                                                 'Pullupwiderstand
48
49
Locate 2 , 6
50
Lcd "Willkommen"
51
Locate 4 , 4
52
Lcd "IMAS-SPORT.COM"
53
Wait 3
54
Cls
55
56
Locate 1 , 1
57
Lcd "Boot 1: "
58
Locate 2 , 1
59
Lcd "Boot 2: "
60
61
62
Do
63
   If Taste_startreset = 0 Then
64
      If Rennen = 0 Then
65
         Enable Timer1
66
         Boot = 0
67
         Rennen = 1
68
         Zuruecksetzen = 1
69
      End If
70
   Else
71
      If Zuruecksetzen = 1 Then
72
         Disable Timer1
73
         Boot = -1
74
         Zehntelsekunden = 0
75
         Minuten = 0
76
         Sekunden = 0
77
         Cls
78
         Locate 1 , 1
79
         Lcd "Boot 1: "
80
         Locate 2 , 1
81
         Lcd "Boot 2: "
82
         Locate 1 , 9
83
         Lcd "0:00.0"
84
         Locate 2 , 9
85
         Lcd "0:00.0"
86
         Rennen = 0
87
         Zuruecksetzen = 0
88
      End If
89
   End If
90
   If Boot > -1 Then
91
      Debounce Taste_stop , 0 , On_tasterstopp , Sub
92
   End If
93
   Cursor Off
94
95
   If Boot = 2 Then                                         'Wenn zweite Zeit gestoppt
96
      Boot = Boot + 1
97
      Dim Dif As Integer
98
      Wert1 = 600 * Minuten
99
      Wert2 = 10 * Sekunden
100
      Wert3 = Wert1 + Wert2
101
      Wert4 = Wert3 + Zehntelsekunden
102
      Wert1 = 600 * Minutenboot1
103
      Wert2 = 10 * Sekundenboot1
104
      Wert3 = Wert1 + Wert2
105
      Wert3 = Wert3 + Zehntelsekundenboot1
106
      Dif = Wert4 - Wert3
107
      Wert1 = Dif Mod 10
108
      Wert2 = Dif / 10
109
      Wert3 = Wert2 Mod 60
110
      Wert4 = Wert2 / 60
111
      Locate 3 , 1
112
      Lcd "--------------"
113
      Locate 4 , 1
114
      Lcd "Dif:"
115
      Locate 4 , 9
116
      Lcd Wert4 ; ":" ; Wert3 , "." ; Wert1
117
   Elseif Boot = 1 Then                                     'Wenn erste Zeit gestoppt
118
      Zehntelsekundenboot1 = Zehntelsekunden
119
      Minutenboot1 = Minuten
120
      Sekundenboot1 = Sekunden
121
      Locate 2 , 9
122
      Lcd Minuten ; ":" ; Sekunden ; "." ; Zehntelsekunden
123
   Elseif Boot = 0 Then
124
      Locate 1 , 9
125
      Lcd Minuten ; ":" ; Sekunden ; "." ; Zehntelsekunden
126
      Locate 2 , 9
127
      Lcd Minuten ; ":" ; Sekunden ; "." ; Zehntelsekunden
128
   End If
129
130
Loop
131
End
132
133
Timer1_isr:
134
If Zehntelsekunden < 9 Then
135
   Zehntelsekunden = Zehntelsekunden + 1
136
Else
137
   Zehntelsekunden = 0
138
   If Sekunden < 59 Then
139
      Sekunden = Sekunden + 1
140
   Else
141
      Sekunden = 0
142
      Minuten = Minuten + 1
143
   End If
144
End If
145
Return
146
147
148
On_tasterstopp:
149
   Boot = Boot + 1
150
Return

von Silvio F. (silvio123)


Lesenswert?

Habe nochmal getestet
irgendwie ist es egal was ich bei Timerstartwert einstelle, der zählt 
immer genausolangsam

von Weingut P. (weinbauer)


Lesenswert?

es müssten genau gesagt 42,2 Sekunden sein :o)

weil?? ... ja, der Timer eben nicht nach Überlauf auf die Vorgabe neu 
gesetzt wird in der ISR ;o)

probiers mal so:

Timer1_isr:
Timer1 = Timervorgabe
If Zehntelsekunden < 9 Then
   Zehntelsekunden = Zehntelsekunden + 1
Else
   Zehntelsekunden = 0
   If Sekunden < 59 Then
      Sekunden = Sekunden + 1
   Else
      Sekunden = 0
      Minuten = Minuten + 1
   End If
End If
Return

Das bedeutet, der Timer Overflow wird jedes mal ausgelöst wenn der Timer 
65535 erreicht, aber was macht er dann?? Er zählt wieder von 0 los, bis 
wieder die 65535, es sei denn, er wird auf nen anderen Wert gesetzt, 
dann zählt er von diesem los.

von Silvio F. (silvio123)


Lesenswert?

Fhutdhb Ufzjjuz schrieb:
> es müssten genau gesagt 42,2 Sekunden sein

Danke, da hast du recht
Habe ich nur noch das Problem, dass bei der Zeitdifferenz irgendwas 
total verbockt ist

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.