Forum: Mikrocontroller und Digitale Elektronik Stoppuhr mit Bascom AVR


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Bachatero 1. (bachatero18)


Bewertung
0 lesenswert
nicht lesenswert
Moin Leute,

Hab jetzt schon des Öfteren mit Bascom AVR rumgespielt und nun wollte 
ich mal eine Stoppuhr programmieren und auf einen ATmega16 ziehen.

Mir persönlich würde jetzt nur einfallen dass ich im Programm jeweils 
"wait" eingebe und er dann weiter springt aber das wäre dann auch ellen 
lang das Programm.

Ich habe drei Taster für "Start" "Stopp" "Reset" und 4x 7 segment 
Anzeigen die Aufteilung soll: ss.msms

spricht sekunde sekunde. millisekunde millisekunde sein.

Habe jetzt unten mal meine Grundidee dazu geschrieben ist absolut nicht 
das beste.

Wie würdet ihr das machen?

wäre für Hilfe dankbar.

GRUNDIDEE:
 $regfile = "M16def.dat"
 $crystal = 1000000

      "Eingänge"
 Config Portc.5 = Input "Start"
 Config Portc.4 = Input "Stopp"
 Config Portc.3 = Input "Reset"

      "Ausgänge" "werden noch bestimmt"


   Do
      If Portc.5 = 1

      Then Portc.x = 1 And Portc.y "usw."

            Waitms 1

            Portc.z "usw" "Das würde aber Jahre dauern (59.999 Schritte)

: Bearbeitet durch User
von Dieter S. (dolivo)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
zwei Dinge sind bei Uhren Pflicht:
1. Der MC muss quarzgesteuert sein.
2. Der wait-Befehl ist für solche Projekte absolut ungeeignet. Man muss 
den Timer als Taktgeber nutzen. Nur so bekommt man exakte Zeiten.

In den Bascom-Foren findest Du sicher brauchbare Beispiele, die 
natürlich angepasst werden müssen.

dolivo

von Bachatero 1. (bachatero18)


Bewertung
0 lesenswert
nicht lesenswert
Hab mir schon gedacht, dass da etwas absolut nicht sein kann.

Ich hab schon einiges gefunden aber komme da nicht wirklich weiter ich 
kenne mich im Grunde kaum aus, wie gesagt ich hab rumgespielt paar 
Lauflichter gemacht aber alles mit wait befehlen.

Ich stehe mehr oder weniger im Dunkeln.

von Bachatero 1. (bachatero18)


Bewertung
0 lesenswert
nicht lesenswert
Keiner kann da helfen hab jetzt stunden lang gesucht aber nicht 
ordentliches gefunden was ich verstehe?

Die Stoppuhr muss jetzt auch nicht sehr genau laufen deshalb denke ich 
wäre der ATMEGA8 schon ok

Habe das gefunden verstehe aber nicht wo und wie er das Display 
anspricht und es ist auch nicht toll geschrieben.


Von einem ausm anderem Forum:

$regfile = "M8def.dat"
$crystal = 16000000
$baud = 9600




Config Portc = Output                                       ' Kompletter 
C Port Output
Config Pinb.0 = Input                                       ' Eingang 1
Config Pinb.1 = Input                                       ' Eingang 2

Portb.0 = 0
Portb.1 = 1


Dim W As Word
Dim A As Integer
Dim B As Integer
Dim C As Integer

Do

Config Timer1 = Timer , Prescale = 64
A = 0                                                       ' A = 1/4 
Sekunden
B = 0                                                       ' B = ganze 
Sekunden 1 - 9
C = 0                                                       ' C = 10er 
Zahlen


W = Timer1
Timer1 = 62500

If Pinb.0 = 1 Then
Sound Portb.0 , 200 , 500                                   ' Startknopf


   Print "Start"
      Enable Interrupts
      Enable Timer1                                         ' Timer: GO




                                             ' angeblich jetzt alle 
0,25s


On Timer1 Isr_timer1
Do
Loop



 Isr_timer1:
 'Print "interrupt!" ; W
 A = A + 1
 If A = 4 Then
   B = B + 1
   A = 0
 End If
 If B = 10 Then
   C = C + 1
    B = 0

   End If


   Print C ; B ; " Sekunden"




End If

                                                             ' 
Stoppknopf
If Pinb.1 = 0 Then                                          ' Timer 
STOPP
Stop Timer1
Sound Portb.0 , 200 , 500
Waitms 10
Sound Portb.0 , 200 , 500

        If A = 1 Then
       Print "Das waren " ; C ; B ; "," ; "25 Sekunden"
       End If

       If A = 2 Then
      Print "Das waren " ; C ; B ; "," ; "5 Sekunden"
       End If

      If A = 3 Then
      Print "Das waren " ; C ; B ; "," ; "75 Sekunden"
      End If

      If A = 0 Then
      Print "Das waren " ; C ; B ; "," ; A ; " Sekunden"
      End If


End If

Return

Loop

von Spezieller Egsberrde (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Bachatero 1. schrieb:

> Habe das gefunden verstehe aber nicht wo und wie er das Display
> anspricht

Nirgendwo. Ergibt Alles per Print-Befehl seriell aus.

> und es ist auch nicht toll geschrieben.

Besser als Dein Eigenes auf jeden Fall. Das besteht nur aus einem leeren 
Blatt.

von spess53 (Gast)


Bewertung
3 lesenswert
nicht lesenswert
Hi

>Keiner kann da helfen hab jetzt stunden lang gesucht aber nicht
>ordentliches gefunden was ich verstehe?

Dann solltest du aufhören zu spielen und anfangen mit lernen.

Oder ein anderes Hobby suchen.

MfG Spess

von Bachatero 1. (bachatero18)


Bewertung
-4 lesenswert
nicht lesenswert
Nun fängt es aber an hier richtig hilfreich zu werden.

von Alex D. (allu)


Bewertung
0 lesenswert
nicht lesenswert
Bachatero 1. schrieb:
> Mir persönlich würde jetzt nur einfallen dass ich im Programm jeweils
> "wait" eingebe und er dann weiter springt aber das wäre dann auch ellen
> lang das Programm.

Wait ist ungünstig, besser den CTC-Timer verwenden.
Unter Beitrag "[Bascom/AVR] Uhr und DCF"
könnte ich Dir ein Beispiel anbieten. da bleibt noch jede Menge Zeit für 
die Anzeige.

Gruss Alex

von Dieter S. (dolivo)


Bewertung
0 lesenswert
nicht lesenswert
Eigentlich ein schönes Projekt für den Anfang, aber über einige 
Grundsätze musst Du Dir schon klar sein.
Vergiss den Wait-Befehl.
Beschäftige Dich mit dem Timer.
Anzeige im Hauptprogramm.
Mit Tasten kann man keine Tausendstel Sekunde messen (Kontaktprellen).
Geduld musst Du als Anfänger schon haben und vergiss die "hilfreichen" 
Kommentare. Solche Leute lieben diese Homepage.
dolivo

von Wolfgang (Gast)


Bewertung
-3 lesenswert
nicht lesenswert
Bachatero 1. schrieb:
> Wie würdet ihr das machen?

Erstmal würde ich die Anforderungen sauber spezifizieren.

> Anzeigen die Aufteilung soll: ss.msms
Meinst du damit eine Auflösung von 100µs?
Dann sollte, unter Berücksichtigung der Messdauer, auch die Genauigkeit 
dazu passen.

von Stephan (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Vielleicht machst Du Dir erst mal einen Plan,sowas wie hier:

https://www.mikrocontroller.net/attachment/302951/PAP_Interrupt.png

Damit kannst Du alles in Einzelteile zerlegen und lösen.

von Route_66 H. (route_66)


Bewertung
-2 lesenswert
nicht lesenswert
Wolfgang schrieb:
>> Anzeigen die Aufteilung soll: ss.msms
> Meinst du damit eine Auflösung von 100µs?

Verstehendes Lesen sollte man im technischen Bereichen können!

Er kann vier Stellen anzeigen.
Er will zwei Stellen vor dem Komma als Sekundenanzeige und zwei Stellen 
nach dem Komma als Millisekundenanzeige.

Selbst ein mittelmäßig Gebildeter kommt auch mit mathematischen 
Kunstgriffen nicht auf µs.

: Bearbeitet durch User
von Bachatero (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Soooo hab nun viel gesucht und ausprobiert und ich denke ich habe jetzt 
schon mal etwas, was fuktionieren könnte was meint ihr?

Bascom haut keine errors raus aber das heißt wenig und ich hätte gerne 
erst eure Meinung dazu bekomm ich mir einen LCD Display kaufe.

Hier einmal der Code:

 $regfile = "m8def.dat"

 $crystal = 1000000


 Config Lcd = 16 * 2

 Config Lcdpin = Pin , E = Portb.5 , Rs = Portb.4 , Db7 = Portb.3 , Db6 
= Portb.2 , Db5 = Portb.1 , Db4 = Portb.0


Config Pind.2 = Input

Config Pind.3 = Input

Config Pind.4 = Input


Portd.2 = 1

Portd.3 = 1

Portd.4 = 1


Config Portd.2 = 0

Config Portd.3 = 0

Config Portd.4 = 0

'----------

Dim Millisekunden As Byte

Dim Sekunden As Byte

Dim Minuten As Byte


Config Timer1 = Timer , Prescale = 64

Const Timervorgabe = 40536

On Timer1 Timer_irq

Enable Interrupts


Millisekunden = 00

Minuten = 0

Sekunden = 00

'---------------------------------------------
Locate 1,3
Lcd " Stoppuhr "

Do

Locate 2 , 2

Lcd "Zeit:    " ; Minuten ; ":" ; Sekunden ; "." ; Millisekunden ;

Loop

'---------------------------------------------

If Pind.2 = 0 Then

Enable Timer1

Return

'-----------------------------------------

If Pind.3 = 0 Then

stop Timer1

Return

'------------------------------

If Pind.4 = 0 Then

Stop Timer1

Waitms 1000

Cls

Sekunden = 00

Minuten = 0

Millisekunden = 00

Return

'--------------------------------------------

Timer_irq:

  Timer1 = Timervorgabe

      Incr Millisekunden

      If Millisekunden = 60 Then

      Incr Sekunden

      Millisekunden = 00

      End If
      End If


  If Sekunden = 60 Then

    Incr Minuten

    Sekunden = 00
   End If
   End If
   End If

  Return

von Ralph S. (jjflash)


Bewertung
1 lesenswert
nicht lesenswert
Hmmm, wo fängt man an?

1.) Wenn du Code postest sollte das etwas übersichtlicher und formatiert 
sein, geschickt wäre es den als Anhang mitzusenden.

2.) Wenn du wie hier angegeben tatsächlich einen Quarz mit nur 1 MHz 
verwendest hast du hier eine Periodendauer von 1µS. Der Taktvorteiler 
ist 64 also zählt dein Timer mit 64µS. Deine Timervorgabe beträgt 40536 
was ein Überlaufen des Timers nach 20000 Ticks bedeutet. Das sollten 
dann Interruptaufrufe alle 1280 Sekunden bedeuten würde....

3.) 60 Millisekunden sind nicht eine Sekunde. Das wäre also selbst dann 
falsch, würde der Interrupt jede Millisekunde aufgerufen werden.

4.) Zähle mal deine "End if" in deinem Interruptvektor

5.) Nach deiner Endlosschleife ist die Abfrage von GPIO-Pins unsinnig, 
dorthin verzweigt dein Programm nie, abgesehen davon dass nach der 
Abfrage der GPIOs ein Return erfolgt, aber nirgendwo ein Aufruf (call) 
vorhanden war. Würde die Abfrage erreicht werden, wäre ein 
Stack-Underrun die Folge.

Wenn du mit µC "spielen" magst, beschäftige dich grundsätzlich zum einen 
mit Elektronik und hier dann mit den Interna der Controller. 
Programmtechnisch solltest du dich einlesen, was Interrupts sind und wie 
man die verwendet.

Es ist zwar eine programmtechnische Möglichkeit über einen 
Timerinterrupt zu pollen, aber nicht immer die beste Lösung.

Für deine Stopuhr wäre angesagt (wie hier versucht), einen Timer für 
einen Interruptaufruf zu verwenden und für die Tastenabfrage einen 
Pinchangeinterrupt zu verwenden.

Bekommst du den Pinchangeinterrupt nicht hin, so muß die Abfrage in der 
Endlosschleife erfolgen (eben über den Interrupt pollen). Grundsätzlich 
den Timer abzuschalten macht allerdings auch keinen Sinn, geschickter 
wäre es über eine Steuervariable innerhalb des Timerinterrupts das 
Hochzählen deiner Uhrvariablen zu stoppen.

Viiiiiiel zu tun und zu lernen für dich ! Vielleicht (auch wenn ich 
dafür wohl zerrissen werde) solltest du dich mit einer strukturierteren 
Spache befassen oder zumindest den Einsatz von "gosub" innerhalb von 
Basic ergründen!

von BasicOderKeinBasic (Gast)


Bewertung
-5 lesenswert
nicht lesenswert
Wo sind denn hier die Bascom Experten auf einmal.
Wenn irgendwer es wagt anzuzweifeln das Bascom die beste Sprache der 
Welt ist, dann sind sie da und lösen einen Shitstorm ohne Ende aus.
Wenn aber jemand für Bascom Hilfe braucht dann hört man auf einmal 
nichts mehr von ihnen, dann kommt maximal ein

> In den Bascom-Foren findest Du sicher brauchbare Beispiele

Schämt euch und stellt euch in eine Ecke, das ist ja armselig

von Stephan (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bachatero schrieb:
> If Millisekunden = 60 Then
>
>       Incr Sekunden

Warum heißen die Milli ? Wieviel ist Milli ?
Wieviele "Milli-Meter" hat ein Meter ?

von Casbom (Gast)


Bewertung
0 lesenswert
nicht lesenswert
BasicOderKeinBasic schrieb:
> Wo sind denn hier die Bascom Experten auf einmal.

Es gibt Dutzende von uns! Dutzende!

von Karl B. (gustav)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
in ASM könnte ich was anbieten.
Im Prinzip funktioniert das so, wie in der Flowchart angegeben.
Der 16-Bit CTC-Timer wird beispielsweise auf Hundertstelsekunde-Teiler 
eingestellt, also Quarzfrequenz durch Teiler.
Bin dadurch weitestgehend unabhängig vom tatsächlich verwendeten Quarz.
Takt Minus 1:
Teiler: Bei 4 MHz : 39999

In der ISR wird heruntergezählt
Bei Beendigung der ISR ein Flag gesetzt, das in der Main-Routine 
abgefragt wird, und entweder zurückloopt oder Programm weiterführt zur 
Tastenabfrage und Ausgaberoutine.

ciao
gustav

von Bachatero 1. (bachatero18)


Bewertung
0 lesenswert
nicht lesenswert
Das mit 6000 millisekunden stimmt hatte ich einen denk fehler hab jetzt 
auf 10 geändert.

Das mit dem Takt ist soweit auch richtig, wusste nicht genau wie ich es 
richtig ausrechne und vor allem wie viel MHz der Controller onboard drin 
hat und schafft. Hätte es sonst durch probieren halbwegs angepasst, da 
die Uhr auch nur um die 20 Sekunden laufen soll.

Abweichung ist ok er soll halt die Abweichung immer wieder gleich haben.

End if hab ich zum Schluss paar reingemacht weil ich die weiter oben 
nicht gemacht habe und Bascom  dann gezickt hatte.

Was sind Gpio-pins?

von normal (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bachatero 1. schrieb:
> End if hab ich zum Schluss paar reingemacht weil ich die weiter oben
> nicht gemacht habe und Bascom  dann gezickt hatte.

Wenn du am Anfang paar End if auf Vorrat reinmachst, hast du hinterher 
kein Gezicke.

Gpio-pins sind general Purpose input/output Pins

von Bachatero 1. (bachatero18)


Bewertung
0 lesenswert
nicht lesenswert
End if hab ich jetzt auch geändert sodass die unten nicht stehen.

Aber ich verstehe nicht weshalb meine Input-Pins unsinning sind.

Er fragt ja aber und wenn einer null ist dann startet er oder stopt den 
Timer weshalb sollte er da nicht hinspringen?

von Ralph S. (jjflash)


Bewertung
0 lesenswert
nicht lesenswert
Bachatero 1. schrieb:
> End if hab ich zum Schluss paar reingemacht weil ich die weiter oben
> nicht gemacht habe und Bascom  dann gezickt hatte.

... hau ich halt irgendwo ein paar Steuerkommandos rein, vollkommen 
wurstegal ob die programmtechnisch an der richtigen Stelle stehen. Hm, 
ist das hier ein Troll?

von Bachatero 1. (bachatero18)


Bewertung
-3 lesenswert
nicht lesenswert
Meine Güte bleib mal sachlich ist ja schlimm

von allu (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Um die Berechnung der Zeit übersichtlicher zu gestalten und um zu viele 
IFs zu vermeiden verwende ich folgendes Schema:


' starten und stoppen der Uhr mit:

Dim Uhr_modus As Byte
Const Aus = 0
Const Ein = 1

Uhr_modus = Ein
'--------------------------------------------

' im IRQ

Uhr_berechnen:

If Uhr_modus = Aus Then Goto Uhr_fertig

   Incr 10millisekunden
   If 10millisekunden < 100 Then Goto Uhr_fertig
   10millisekunden = 0

   Incr Sekunden
   If Sekunden < 60 Then Goto Uhr_fertig
   Sekunden = 0

   Incr Minuten
   If Minuten < 60 Then Goto Uhr_fertig
   Minuten = 0

Uhr_fertig:
   Return

von Karl B. (gustav)


Bewertung
0 lesenswert
nicht lesenswert
Hi @allu,
ziemlich genau meine Vorstellung.
Es gibt allerdings noch das Problem mit der "langsamen" LCD-Ausgabe.
Die macht man am besten in die Mainroutine rein. Und die wird eben durch 
das (die) Jobflag(s) getriggert. So kann man nur einmal in der Sekunde 
eine Ausgabe steuern, oder bei Stop.

ciao
gustav

von allu (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Karl B. schrieb:
> Die macht man am besten in die Mainroutine rein. Und die wird eben durch
> das (die) Jobflag(s) getriggert.

Ja, das funktioniert gut, so mache ich das auch.
Gruß  Alex

Für den CTC-Timer verwende ich folgendes:
Diese CTC-Timereinstellung habe ich mir vor ein paar Jahren gebastelt. 
Der Compiler kennt die $crystal-Frequenz und versucht die Teilerfaktoren 
auch bei "krummen" Frequenzen möglichst genau zu treffen. Selbst 
berechen entfällt somit.

Die gewünschte Hardware-IRQ-Dauer wird vorgegeben (im Beispiel 10msec):
 Const _irq_abstand = 10000000       ' in nsec, HIER ZEIT EINTRAGEN

Weiterhin wird noch ein Teilerfaktor (hier 1 sec)für einen Softwaretimer 
in der IRQ-Routine berechnet (IRQ hier nicht dargestellt):
 Const _irq_stufe_1 = 1000           ' in msec, HIER ZEIT EINTRAGEN

Prinzip:
Gosub Init_ctc_timer
do
  Hauptprogramm
loop


'#######################################################################
'***********************************************************************
'   *****   Initialisierung  des CTC-Timers                       ******
'***********************************************************************

Init_ctc_timer:
'   Abstand der IRQ-Impulse
    Const _irq_abstand = 10000000       ' in nsec, HIER ZEIT EINTRAGEN
'   Stufenweise die Timerzeit verlängern
    Const _irq_stufe_1 = 1000           ' in msec, HIER ZEIT EINTRAGEN

'----------------------------------------------------------------------*

'    Gesamten Wert Berechnen Für Timer1
Const _irq_teiler_max = Int((_xtal * _irq_abstand /(1000000000)) + 0.5)

'    Prescaler Einstellung für Timer1 bestimmen
'    Const _irq_vorteiler -> Einstellmöglichkeiten: 1/8/64/256/1024
#if _irq_teiler_max > &H00FFFFFF
   Const _irq_vorteiler = 1024
#elseif _irq_teiler_max > &H003FFFFF
   Const _irq_vorteiler = 256
#elseif _irq_teiler_max > &H0007FFFF
   Const _irq_vorteiler = 64
#elseif _irq_teiler_max > &H0000FFFF
   Const _irq_vorteiler = 8
#else
   Const _irq_vorteiler = 1
#endif

'     Aus Prescaler-Wert die Einstellung des Timer-Registers berechnen
Const _irq_teiler = Int((_xtal * _irq_abstand / _
                    (1000000000 * _irq_vorteiler )) + 0.5) -1

'     Aus _irq_abstand Einstellung für die 1. Stufe berechnen
Const _irq_wert_1 = Int((1000000 * _irq_stufe_1 / _irq_abstand ) + 0.5)

'     Initialisiere timer1
Config Timer1 = Timer , Prescale = _irq_vorteiler , Clear Timer = 1 , _
                        Compare A = Disconnect
Ocr1a = _irq_teiler


On Oc1a Uhr_berechnen        ' Für Stoppuhr als Beispiel-Sprungziel

'     Timer1 freigeben und starten
Enable Oc1a
Enable Interrupts                       ' Interrupts freigeben


'  zur Überpüfung der Einstellwerte mit Simulator
'  PRINT NUR IM SIMULATOR FREIGEBEN
'  Print "Prescaler = " ; _irq_vorteiler
'  Print "Timerregister (max 65535) = " ; _irq_teiler
'  Print "_irq_wert_1 (max 255) = " ; _irq_wert_1

Return

von Bachatero 1. (bachatero18)


Bewertung
0 lesenswert
nicht lesenswert
Ok das ist schon mal sehr hilfreich danke auf jeden Fall !! werde mir 
das mal gleich genau durch lesen und verstehen.

Jetzt zum LCD ihr sagtet der wäre zu langsam als dass er alle 100ms die 
zahlen anzuzeigen ist das richtig ?  Was wäre die folge davon ?

von Manfred (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bachatero schrieb:
> Bascom haut keine errors raus aber das heißt wenig und ich hätte gerne
> erst eure Meinung dazu bekomm ich mir einen LCD Display kaufe.

Dieser Satz sehr schlechtes Deutsch und Inhalt müssen werden erraten.

Bachatero 1. schrieb:
> Jetzt zum LCD ihr sagtet der wäre zu langsam als dass er alle 100ms die
> zahlen anzuzeigen ist das richtig ?

Nochmal ein schlechter Text! Zur Ansteuerung eines LCD braucht man Zeit, 
je nach Art der Anschaltung und Software gerne einige Dutzend 
Millisekunden. Bei einer Stoppuhr kann das sehr störend sein.

Dein gesamter Thread macht wenig Sinn: Mikrocontroller und Display 
bekommt man für niedrig einstellige Euro, also baue den Kram real auf 
und komm' wieder, wenn es (nicht) funktioniert.

von Karl B. (gustav)


Bewertung
0 lesenswert
nicht lesenswert
Bachatero 1. schrieb:
> Jetzt zum LCD ihr sagtet der wäre zu langsam als dass er alle 100ms die
> zahlen anzuzeigen ist das richtig ?  Was wäre die folge davon ?

Hi,
"meine" Stoppuhr liest die Zählerstände in Puffer ein, ohne zunächst die 
LCD-Ausgabe vorzunehmen.
Erst bei Drücken der Stopp-Taste wird in der Main-Routine auf die 
Ausgaberoutine der Pufferinhalte auf LCD gesprungen.
Vorher muss noch die Binär-Dezimal-ASCII-Umwandlungsroutine durchlaufen 
werden.

Die durchrasenden Hundertstelsekunden braucht man nicht auf der Anzeige.

ciao
gustav

von allu (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Bachatero 1. schrieb:
> Ich habe drei Taster für "Start" "Stopp" "Reset"

Um die Eingänge zu konfigurieren folgender Vorschlag:

Config Portd.2 = Input
Config Portd.3 = Input
Config Portd.4 = Input

Set Portd.2                             'Pullups einschalten
Set Portd.3
Set Portd.4

Taster_start Alias Pind.2
Taster_stop Alias Pind.3
Taster_reset Alias Pind.4


Beispiel Taster Start und Stop auswerten;
Const Gedrueckt = 0

If Taster_start = Gedrueckt Then Uhr_modus = Ein
If Taster_stop = Gedrueckt Then Uhr_modus = Aus

Diese beiden Programmzeilen dann als erstes in der IRQ-Routine ausführen

Gruß  Alex

von Fred R. (fredylich)


Bewertung
0 lesenswert
nicht lesenswert
Mal auf der schnelle ein Codeschnipsel aus Projekt <Feuerwehr> erstellt.
Stoppuhr und vollautomatische Behälterkontrolle(zwei Behälter-Vergleich 
und Steuerung).
Ist ein Projekt für Trainings- und Wettkampfbedingungen.

Code wollte ich nicht komplett einstellen da mit TFT Display und 
Zeitabgleich.
Sollte Interesse bestehen kann ich Projekt hier veröffentlichen.
Hoffe aber dieser Schnipsel ist erst mal eine Anregung für Threadworker.

$crystal = 16000000

 Dim Millsek As Byte
 Dim Sek1 As Byte
 Dim Minu1 As Byte
 Zeit As String * 8

Config Pinc.5 = Input
    Portc.5 = 1 
'Pullupwiderstand
   Start1 Alias Pinc.5
Config Pinc.4 = Input
    Portc.4 = 1 
'Pullupwiderstand
   Stop1 Alias Pinc.4

'****Timer1 1 mSek Clook *****
   Const Timer1_preload =  45536                            'mit 
Display-Verzögerung 46100
   Config Timer1 = Timer , Prescale = 8
     'Enable Timer1
      Timer1 = Timer1_preload
     On Timer1 Isr_timer1
   Enable Interrupts

Neustart:
     Print Zeit
‚rücksetzen
 Start1 = 1
 Stop1 = 1
 Millisek = 0
 Sek1 = 0
 Minu1 = 0
'***** Meßschleife ************************
        Enable Timer1                                       'Zähler 
starten
Do
 If Start1 = 0 Then                            'Taster(Startknopf)
  Zeit =  Minu1+ ":" + Sek1 + ":" + Millsek     'in String speichern
 End If
 If Stopl = 0 Then                                'Messung stop
  Goto Neustart
 End IF
Loop

*********Stoppuhr Zeit erstellen ********
 Isr_timer1:
   Timer1 = Timer1_preload
      Incr Millsek
     If Millsek > 99 Then
       Incr Sek1
       Millsek = 0
     End If
     If Sek1 > 59 Then
       Incr Minu1
       Sek1 = 0
     End If
  Return

Mit freundlichen Grüßen
fredred

von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Fred R. schrieb:
> Incr Millsek
>      If Millsek > 99 Then

Zentisek wäre passender :-)

von Fred R. (fredylich)


Bewertung
0 lesenswert
nicht lesenswert
Dieter F. schrieb:
> Zentisek wäre passender :-)

Danke!!
Aber wenn wie hier im Beispiel alle 10 ms „Millsek“ erhöht wird, könnte 
es wohl passen oder?
Habe auf 0,001 Sekundengenauigkeit im praktischem Bereich verzichtet. 
Ist wohl im Amateurbereich für eine Stoppuhr nicht genau genug.

Gruß

von Dieter F. (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Fred R. schrieb:
> Aber wenn wie hier im Beispiel alle 10 ms „Millsek“ erhöht wird, könnte
> es wohl passen oder?

Wenn Du unbedingt einen Zähler für Zentisekunden mit Millisekunden 
bezeichnen willst - grundsätzlich ja.
Wenn Du - wie ich - ü50 bist und/oder andere auch mal das Programm lesen 
können sollen ohne nachzurechnen - nein :-).

von Alex D. (allu)


Bewertung
0 lesenswert
nicht lesenswert
Fred R. schrieb:
> Habe auf 0,001 Sekundengenauigkeit im praktischem Bereich verzichtet.

Mit entsprechend aufgebauter IRQ-Routine ist das mit Bascom ohne Problem 
möglich. Da bleibt in der Do-Loop-Hauptprogrammschleife noch jede Menge 
Zeit zum Anzeigen und was sonst noch so anfällt und nicht Zeitkritisch 
ist.

Ob 1 msec überhaupt sinnvoll ist, muss jeder für sein Projekt selbst 
wissen.

Gruß Alex

: Bearbeitet durch User
von Fred R. (fredylich)


Bewertung
0 lesenswert
nicht lesenswert
Alex D. schrieb:
> Ob 1 msec überhaupt sinnvoll ist, muss jeder für sein Projekt selbst
> wissen.

Na klar.
Theoretisch möglich aber Starttaste und dann Stopptaste drücken und 
Innerhalt einer msec dieser Zeit noch Auswertungen treffen, ist schon 
sportlich.
Naja wenn ein Mensch im digitalen Kreislauf mitentscheiden muss, sollte 
doch seine Trägheit mitbetrachtet werden. Also Optimum und nicht 
Maximum.

Grüß
fredred

von Joachim B. (jar)


Bewertung
0 lesenswert
nicht lesenswert
es hat auch keinen Sinn mehr als 4x pro Sekunde das LCD zu aktualisieren 
wenn die Uhr läuft.

So schnell kann keiner lesen und es frisst nur µC Zeit

also zur Stoppuhr counter mitlaufen lassen und wenn 250ms um sind LCD 
aktualisieren

von Fred R. (fredylich)


Bewertung
0 lesenswert
nicht lesenswert
Joachim B. schrieb:
> also zur Stoppuhr counter mitlaufen lassen und wenn 250ms um sind LCD
> aktualisieren

Nein, Nein  die entgültige Auswertung wird erst nach Stopp auf LCD 
angezeigt.
Die Aktualisierung läuft im Hintergrund.
Wollte doch grob im Codeschnipsel mit „Print“ darauf hinweisen.
Gruß

von Elektrorentner (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Wozu so umständlich?
Verstehe zuerst mal gewisse Prinzipien.Im Hauptprogramm Bedingungen für 
Timerfreigabe und stoppen schaffen. Den Timer im CTC Modus betreiben und 
zwar je  nach Bedarf alle 1 Millisekunden oder nur alle 10 Millisekunden 
einen Interrupt ausführen lassen, wenn freigegeben.

Als Zeit Variable einen sinnvollen Namen wählen und den als Long 
definieren.
In der Timerinteruptroutine jeweils nur diese Longvariable 
incrementieren und  Timer wieder auf Timerloadwert setzen, dann raus aus 
Interupt.

Wenn Stopptaste gedrückt, Timer anhalten. Es liegt nun die bisher 
abgelaufene Zeit als Long-Wert der Timerincrements vor.
Die Zeitwerte für die Anzeige bekommst du durch Teilungen der Longzahl 
durch entsprechende Teilerfaktoren.

Eine Sekunde hat wieviele Millisekunden? Oder wieviele 
Zehnmillisekunden?
Usw usf. Somit bekommst du durch sinnvolles umrechnen der entsprechenden 
Anteile sogar die jeweiligen Ziffern für deine Anzeige.

Natürlich gilt vor jedem neuen starten der Stoppuhr, diese Longvariable 
zu Nullen. Das kann in der Startbedingung schon intergriert sein. 
Ähnlich könnte das starten der Stoppuhr erneut erst zugelassen werden, 
wenn die vorherige Stoppuhrzeit mindestens so lange auf dem Display 
angezeigt wurde, dass man diesen Wert lesen konnte.

Wenn das Prinzip verstanden wurde, los legen, Bascom-Hilfe bemühen wo 
notwendig. Lesen wie Timmer0 z.B. im CTC Modus alle 1 mS in seine 
Interuptroutine spribgt, dort neu vorgeladen wird (falls notwendig). 
Dort immer nur die definierte Longvariable incrementieren lassen.

Ansonsten Variable für Anzeige definieren und Verrechnungsanteilen.
Angenommen diese Longvariable hast den Wert 47564 und die Increments 
erfolgten alle 1 Millisekunden. Welche Zeit entspricht das in üblichen 
Anteilen? Falls es nur auf eine normale LCD Anzeige auszugeben ist, 
genügen die entsprechende Punkt Setzung und dahinter das Wort Sekunden 
oder Sek.

von Fred R. (fredylich)


Bewertung
0 lesenswert
nicht lesenswert
Dieter F. schrieb:
> Wenn Du - wie ich - ü50 bist und/oder andere auch mal das Programm lesen
> können sollen ohne nachzurechnen - nein :-).

Mein wichtiger Hinweis war „Codeschnipsel“ also nur aus ein Projekt 
gezogen um zu helfen.
Vermute, hätte ich das Programm eingestellt würdest Du mich als Troll 
abwerden.
P.S. Bin schon eine weile Regelaltersrentner.

Gruß

von Alex D. (allu)


Bewertung
0 lesenswert
nicht lesenswert
Elektrorentner schrieb:
> Als Zeit Variable einen sinnvollen Namen wählen und den als Long
> definieren.
> In der Timerinteruptroutine jeweils nur diese Longvariable
> incrementieren und  Timer wieder auf Timerloadwert setzen, dann raus aus
> Interup

Ich nehme an dieser Stelle Byte-Variablen weil mir diese als Index auf 
eine Tabelle die Umsetzung in einen ASCII-String von 00 bis 99 in 
wenigen µsec ermöglichen. Anstelle der ASCII-Ziffern könnten da auch die 
Muster von 7-Segment-Anzeigen eingetragen sein.

Gruß   Alex

So in meiner DCF-Uhr verwendet:

'  Strings zur Zeitanzeige aufbauen

   Uhr_str_stunde = Tab_zahl_str(uhr_stunde )
   Uhr_str_minute = Tab_zahl_str(uhr_minute )
   Uhr_str_sekunde = Tab_zahl_str(uhr_sekunde )

: Bearbeitet durch User
von Dieter F. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Fred R. schrieb:
> Vermute, hätte ich das Programm eingestellt würdest Du mich als Troll
> abwerden.

Nein - wieso? Ich bin schlicht der Meinung, dass ein Variablen-Name - 
sprechend finde ich immer gut - auch das bezeichnen sollte, was drin 
ist.

Ich würde eine Variable mit "Anzahl_Birnen" auch nicht "Anzahl_Aepfel" 
nennen.

von Alex D. (allu)


Bewertung
0 lesenswert
nicht lesenswert
Fred R. schrieb:
> Theoretisch möglich aber Starttaste und dann Stopptaste drücken und
> Innerhalt einer msec dieser Zeit noch Auswertungen treffen, ist schon
> sportlich.

Sportlich, gutes Stichwort!
Unter sportlich verstehe ich keine Unsicherheit über (z.B.) den Ausgang 
einer Wette.

Beim Eintritt in das IRQ-Programm setze ich einen Ausgang auf 1 und beim 
verlassen wieder auf 0. Mein Oszi ist dann so freundlich mir die längste 
IRQ-Dauer anzuzeigen.

Nicht alle Bascom-Befehle sind IRQ geeignet. Mit den "schnellen" 
Bascom-Befehlen lässt sich aber einiges in den IRQ einbauen.

Zum Funk-Empfang von Temperatur- und Feuchte-Sensoren verwende ich 
333µsc. Läuft schon seit Jahren durchgehend.

Gruß  Alex

von allu (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Bachatero 1. schrieb:
> Wie würdet ihr das machen?

In etwa so ...

Falls Du das angehängte Bascom-Prg. ausprobieren möchtest, wäre von dir 
noch die Anpassung an deine Hardware vorzunehmen. Ubersetzt zum Testen 
habe ich das Prg. mit Basom Version 2.0.81.

Text, Zeitanzeigeformat und Taster-Ports sind deinem Prog. entnommen.

Gruß  Alex

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.