Archiv verlassen und diese Seite im Standarddesign anzeigen : Von Unterprogramm zum Hauptprogrammanfang springen
Moin, 
ich sitz da jetzt schon einige Stunden drüber, und komm nicht drauf wie ich das am besten lösen kann. Ich möchte eine Zeitschaltung für meinen Lötkolben bauen. Dafür soll wenn ein Taster gedrückt wird der Lötkolben angehen. Wenn eine Zeit von 29.30min überschritten ist soll ein Alarm losgehn. Dann, 30 sek später, soll der Lötkolben samt Alarm abgeschaltet werden. 
doch der "Countdown" soll jederzeit durch druck auf den Taster wieder auf Null gestellt werden. (auch während des Alarmes)
Aber mein Programm funktioniert nicht so wie ich mir das vorstelle, könnt ihr mir villeicht sagen wo mein Fehler liegt?
und ob es überhaupt möglich ist aus einem Unterprogramm zum Hauptprogramm-anfang zu springen?
Mfg Hübi
 
'--------------------------------------------------------------
$regfile = "attiny2313.dat"                                 ' ATtinny 2313
$crystal = 1000000                                          'Quarz: 1,0 MHz
'******** Deklarationen ********
'******** Initialisierung ********                                                 '
   Enable Int0
   Enable Interrupts
   On Int0 Taste0int
   Ddrb = &B11111111                                        ' port B als Ausgang
   Ddrd = &B0100000                                         ' pin D2 asl eingang
   Portd.2 = 1                                              ' interne pullup widerstände aktivieren
'******** Hauptprogramm ********
 Do
     Start:
     If Pind.2 = 0 Then                                     'Wenn Taster Pind.2 gedrückt, dann
          Portb = &B10000000                                'Lötkolben an
       Wait 1770                                            ' warte 29.30 min
          Portb = &B11000000                                ' Alarm wird zugeschaltet (spätestes jetzt könnte man resetten)
       Wait 30                                              ' warte 30 Sekunden
          Portb = &B00000000                                ' alles wird ausgeschaltet
     End If
Loop
'******** Unterprogramme ********
 Taste0int:
      Sound Portd.0 , 1000 , 82                             'wenn Taster Pind.2 gedrückt, dann piept es
      Goto Start                                            ' Springe zu start und fange von vorn an
End
linux_80
03.02.2007, 14:50
Hallo,
Taste0int ist kein Unterprogramm in dem Sinne, sondern eine ISR (Interrupt).
Da kann man nicht ungestraft in das Hauptprogramm zurückspringen ! ;-)
Du kannst Dir aber eine Variable anlegen, die im Hauptprogramm abgefragt wird, und in der ISR gesetzt wird, damit man den Tastendruck mitbekommt.
Ein Sound in der ISR kommt auch nicht gut, würde ich auch in die Hauptschleife legen und über eine Variable starten.
Statt dem Wait 1770 machst Du Wait 1 und zB. eine For-Schleife drumrum die bis 1770 zählt, und die Variable der ISR abgefragt wird, wenn die Variable gesetzt ist (also einen bestimmten Wert hat), einfach Sound aufrufen, For-Schleife beenden usw.
So in der Richtung würde ich das anfangen.
Eine Sekunde Verzögerung ist hier ja kein Problem.
Moin
danke für deine schnelle Antwort, ich habe versucht das was du sagst umzusetzten aber irgentwie haut das nicht so richtig hin, ich hoffe die Ansätze sind wenigstens richtig
mfg Hübi
 
'--------------------------------------------------------------
$regfile = "attiny2313.dat"                                 '
$crystal = 1000000                                          'Quarz: 1,0 MHz
'******** Deklarationen ********
Dim A As Word
'******** Initialisierung ********                                                 '
   Enable Int0
   Enable Interrupts
   On Int0 Taste0int
   Ddrb = &B11111111                                        ' port B als Ausgang
   Ddrd = &B0100000                                         ' pin D2 asl eingang
   Portd.2 = 1                                              ' interne pullup widerstände aktivieren
'******** Hauptprogramm ********
 Do
     If Pind.2 = 0 Then Portb = &B10001000
             Wait 1
             A = A + 1
             If A > 1770 Then
               Portb = &B11000000
             End If
             If A > 1800 Then
               Portb = &B00000000
             End If
Loop
'******** Unterprogramme ********
Taste0int:
      A = 0
End
Hallo
du müsstest praktisch a nicht als null setzen sondern als 1 weil 0 = 0+ 1 wäre wieder null aber wenn 1 = 1+1 =2 usw. dann zählt er.
hier der code: mit Print gibste RS232 aus und kannst dann schauen das er hoch zählt.
'--------------------------------------------------------------
$regfile = "attiny2313.dat"                                 '
$crystal = 1000000                                          'Quarz: 1,0 MHz
'******** Deklarationen ********
Dim A As Word
'******** Initialisierung ********                                                 '
   Enable Int0
   Enable Interrupts
   On Int0 Taste0int
   Ddrb = &B11111111                                        ' port B als Ausgang
   Ddrd = &B0100000                                         ' pin D2 asl eingang
   Portd.2 = 1                                              ' interne pullup widerstände aktivieren
'******** Hauptprogramm ********
 Do
     If Pind.2 = 0 Then Portb = &B10001000
             Wait 1
             A = A + 1
             Print A
             If A > 1770 Then
               Portb = &B11000000
             End If
             If A > 1800 Then
               Portb = &B00000000
             End If
Loop
'******** Unterprogramme ********
Taste0int:
      A = 1
End
linux_80
03.02.2007, 17:55
Bei den If-Abfragen musst  Du noch ausschliessen, das beide gleichzeitig zutreffen können, wenn der Wert über 1800 ist, ist er auch über 1770 !
Die Zeit dazwischen ist zwar sehr kurz, aber dazwischen wird erstmal der Ausgang gesetzt.
Erst den höheren Wert abfragen und im Else den kleineren, dann werden nicht beide ausgeführt.
Vielleicht kann man auch so abfragen, solange der Wert kleiner 1770 ist, den einen Ausgang setzen, wenn >1800 alles aus, ansonsten Ausgang und Alarm.
Evtl. musst Du noch den Int0 konfigurieren, denn da kommt nix vor.
Jetzt wird ein Int ausgelöst solange der Pegel Low ist.
so, ich hoffe nun stimmt es, 
@patti16 du meinst wenn ich ein Display anschließe oder?
 
 '--------------------------------------------------------------
$regfile = "attiny2313.dat"                                 '
$crystal = 1000000                                          'Quarz: 1,0 MHz
'******** Deklarationen ********
Dim A As Word
'******** Initialisierung ********
   Config Int0 = Falling                                    '
   Enable Int0
   Enable Interrupts
   On Int0 Taste0int
   Ddrb = &B11111111                                        ' port B als Ausgang
   Ddrd = &B0100000                                         ' pin D2 asl eingang
   Portd.2 = 1                                              ' interne pullup widerstände aktivieren
'******** Hauptprogramm ********
 Do
     If Pind.2 = 0 Then Portb = &B10000000
             Wait 1
             A = A + 1
             If A > 1800 Then
               Portb = &B00000000
              End If
             If A > 1770 Then
               Portb = &B11000000
               Else
               Portb = &B10000000
             End If
Loop
'******** Unterprogramme ********
Taste0int:
      A = 1
End
ich meine die Belgung der Ports im Programm von mir musste auf deins übertragen falls es nicht gleich angeschlossen ist.
haste mal probiert?
gruß
patrick
helimike0705
03.02.2007, 19:14
hallo , habe mir auch mal ein paar gedanken gemacht.
also im simulator läuft das prog. und auf meinem bord auch
der einfachheitshalber habe ich mal die zeiten 1770 in 170
und 1800 in 180 geändert,damit es schneller abläuft im test.
also wieder in deine zeiten ändern.
gruß mike
'--------------------------------------------------------------
$regfile = "attiny2313.dat"                                 '
$crystal = 1000000                                          'Quarz: 1,0 MHz
'$sim
'******** Deklarationen ********
Dim A As Word
   Ddrb = &B11111111                                        ' port B als Ausgang
   Ddrd = &B0100000                                         ' pin D2 asl eingang
   Portd.2 = 1                                              ' interne pullup widerstände aktivieren
'******** Hauptprogramm ********
Portb.1 = 1        'zeigt ausgeschalteten zustand an
Main1:
Do
If Pind.2 = 0 Then
Goto Main2
Else
End If
Loop
Main2:
Portb = &B10000000
Do
If Pind.2 = 0 Then
A = 0
Portb = &B10000000
Else
End If
 Wait 1
  A = A + 1
  Print A
   Toggle Portb.0         'lötkolben an
     If A > 177 Then
      Portb = &B11000000
       Sound Portd.0 , 1000 , 82
     End If
  If A > 180 Then
   Portb = &B00000000
  End If
Loop Until A > 180
Portb.1 = 1               'zeigt ausgeschalteten zustand an
Do
If Pind.2 = 0 Then Goto Main1
Loop
End
linux_80
03.02.2007, 20:04
@Hübi:
Fast, die Abfrage nach den 1700 noch in das Else der 1800, denn sonst geht es nie aus:
  If A > 1800 Then
               Portb = &B00000000
           else
             If A > 1770 Then
               Portb = &B11000000
               Else
               Portb = &B10000000
             End If
         End If
Also wenn der Wert über 1800 kommt ist alles aus,
ist er unter 1800 aber über 1770 geht der Alarm mit an,
ist der unter 1770 ist nur der Ausgang eingeschaltet.
Ob in der ISR auf 0 oder 1 gesetzt wird ist eigentlich egal,
bei 0 läuft die Schleife eine Sekunde länger.
helimike0705
04.02.2007, 11:57
man kann nach der until abfrage die do loop schleife durch goto main1
ersetzten , sonst ist es ja doppelt gemobbelt.
hallo linux_80 :
ist dein prog-beitrag auf meinen code gemünzt,oder ?
linux_80
04.02.2007, 12:51
@helimike0705
war jetzt nicht meine Absicht ;-)
kann aber sein das es auch rein passt.
PS:
Wenn man im Forum jemand bestimmten meint, hat es sich so ergeben, dass man das mit einem @ angibt an wen es gerichtet ist.
helimike0705
04.02.2007, 13:00
ja, schon okay,dachte nur du meinetes meine code,ist ja nicht der
optimalste und verbesserungen sind immer willkommen,proge erst
seit dez 06 mit bascom und habe vorher noch nie etwas mit mc gemacht.
also habe schon verstanden das es nicht bös gemeint war.
gruß
Moin, 
@helimike0705 
ja, dein Programm funzt bei mir auch super, vielen dank für deine Mühen. (nur das "Print A" verstehe ich nicht wofür ist das gut?) Ich denke ich werde es später auch so in meiner "lötstation" verwenden.    Aber ich würde trotzdem gerne noch mein eigenes Programm zur Funktion bringen (zum lernen, nur so für mich) denn bei meinen nächsten Projekten will ich euch nicht immer wieder mit meinen Anfängerfragen nerven. Mich würde interessieren ob und welche Lehrmaterialen du verwendest um das Programmieren zu erlernen(bücher ect.)
@linux_80
ja, stimmt jetzt geht es auch aus, aber leider nicht wieder an, wenn ich die taste drücke. Irgentwo muss noch ein Fehler versteckt sein, ich kann  ihn aber nicht finden :-# 
 
'--------------------------------------------------------------
$regfile = "attiny2313.dat"                                 '
$crystal = 1000000                                          'Quarz: 1,0 MHz
'******** Deklarationen ********
Dim A As Word
'******** Initialisierung ********
   Config Int0 = Falling                                    '
   Enable Int0
   Enable Interrupts
   On Int0 Taste0int
   Ddrb = &B11111111                                        ' port B als Ausgang
   Ddrd = &B0100000                                         ' pin D2 asl eingang
   Portd.2 = 1                                              ' interne pullup widerstände aktivieren
'******** Hauptprogramm ********
 Do
     If Pind.2 = 0 Then Portb = &B10000000
             Wait 1
             A = A + 1
                If A > 1800 Then
               Portb = &B00000000
               Else
               Portb = &B10000000
                If A > 1770 Then
                 Portb = &B11000000
             End If
             End If
Loop
'******** Unterprogramme ********
Taste0int:
      A = 1
End
linux_80
05.02.2007, 20:56
Es gibt auch noch ein weiteres Problem, da A immer weitergezählt wird, wird das irgendwann überlaufen, und A ist wieder 0,
dann geht der Lötkolben wieder an, nach etwa (65536-1800) sec. !
Das zählen sollte dann in den Else-Teil der 1. If-Abfrage, am besten zwischen die beiden End If's.
Und wegen dem nicht mehr einschalten, ich weiss zwar nicht obs hilft, aber schreib mal gleich nach dem Wait ein Disable Interrupts, und unten vor Loop ein Enable Interrupts. Sodass die ganze Berechnung und Auswertung von A nicht unterbrochen werden kann.
Sollte währenddessen ein Int0 auftreten, wird der ausgeführt, wenn die Interrupts wieder aktiviert werden.
Das ist zwar nur eine Vermutung, kann aber auftreten, da hier mit 2 Bytes gerechnet wird.
helimike0705
06.02.2007, 06:17
hallo hübi,
das print a war nur für den simulator gedacht,kannst dies streichen.
habe es vergessen heraus zu nehmen.aber freut mich das es dir 
gefällt.lernunterlagen ist momentan nur das internet alles was ich zu microkontrollern finde.
gruß mike
helimike0705
06.02.2007, 18:26
habe die ganze sache mal nur auf dem portd umgestellt und schon läuft nix mehr.also sprich die ledanzeigen auf pin 4,5,6.starttaste gelassen auf pin2,sowie nach dem brennen rennt das prog sofort los. warum?egal welchen atmel ich benutze ,at90s2313 oder attiny2313.wollt auf portb mein lcd anschliessen         und nun das.
auch hängt sich das programm auf ,aber im sim läuft es,
wieder ein problem das gelöst werden muss,wer weiß rat.
helimike0705
06.02.2007, 19:15
hallo hübi, dein programm aus dem ersten thread läuft !
du machst bestimmt nur einen tastendrück von kurzer dauer,richtig.
also so etwa ein halbe sekunde.lasse mal den taster solang gedückt bis 
der beep zu ende ist.dann läuft es. der grund ist das der sound befehl
den programmablauf solange stopt und erst nach dem ende zur do loop
schleife springt. wenn du in der soundausgabe die 1000 (1 sekunde) auf
100 reduzierst (100 millisekunden),ist dein programm schneller.
gruß mike
 
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.