PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer Problem



PiCus
21.03.2006, 19:16
Hallo,
ich hab die Beiträgen schonmal durch forstet und Teile gefunden bei denen ich der Meinung war ich könnte sie gebrauchen, aber ich kriegs einfach nicht hin.

Ich möchte für mein kleine Tochter ein Schonnenschutz mit Motor und Segeltuch bauen. Die Mechanik ist eine Getriebemotor aus einem Garagentor antrieb (24V), die Elektronik ist ein ATmege8 mit PCF8574 für Tasten und Relais (im Programm LED).
Das Programm funzt so wie es soll nur eben soll die eingeleitetet Funktion auf/ab eben nach 15-30sec selbständig abschalten. Ich hab gelesen dass man da einen Timer, Timer1 einstellen kann nur ich weiss nicht wo. Kann mir jemand bitte einen Tip geben wie es aussehen muss und wo er stehen soll. Später soll eine "Schaltuhr" realisiert werden aber erst wenn dass hier richtig läuft.

'------------------------------------------------
' i2c-pcf8574-switch
' 4 Tasten - 4 LED
'------------------------------------------------
$regfile = "m8def.dat"
$crystal = 4000000
$lib "Lcd_i2c.lib"
$lib "i2c.lib"
$baud = 19200

'------------------------------------------------
' Declarationen
'------------------------------------------------
Config Sda = Portc.4
Config Scl = Portc.5
Config Twi = 100000
'Config I2cdelay = 10
Portc.4 = 0
Portc.5 = 0

Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising


Const Pcf8574write = &H4C ' Led Ausgabe
Const Pcf8574read = &H4D ' Tasten eingabe
Const Pcf8574_lcd = &H4E ' LCD Ausgabe
Const Pcf8574_8fach = &H42

Const Aus = &B00001111
Const Ledaus = &B11111111 'LED aus
Const Ledauf1 = &B10111111 'LED 1 auf
Const Ledab1 = &B01111111 'LED 1 ab
Const Ledauf2 = &B11011111 'LED 2 auf
Const Ledab2 = &B11101111 'LED 2 ab

Config Lcd = 20 * 2
Dim _lcd_e As Byte
_lcd_e = 128

Dim Pcf_taste As Byte
Dim Pcf_8fach As Byte
Dim Anzled As Byte
Dim Taste As Byte
Dim T As Integer
Dim Auf As Bit
Dim Ab As Bit
Dim Auf2 As Bit
Dim Ab2 As Bit

Dim Led As Byte
Dim Ledaus As Byte
Dim Ledauf1 As Byte
Dim Ledab1 As Byte
Dim Ledauf2 As Byte
Dim Ledab2 As Byte


'------------------------------------------------
' Vorspann - Initialisierung
'------------------------------------------------
Cls ' Verzögerung
Locate 1 , 1 : Lcd "Lade Programm ... " :
For T = 3 To 1 Step -1
Locate 2 , 1 : Lcd "Bitte warten .... " ; T :
Wait 1
Next T
Cls

'------------------------------------------------
' Tastenabfrage
'------------------------------------------------

Anfang:

Led = Ledaus
Do
I2cstart
I2cwbyte Pcf8574read
I2crbyte Pcf_taste , Nack
Taste = Pcf_taste
I2cstop
If Taste = 253 And Ab = 0 And Auf = 0 Then : Ab = 1 : Led = Ledab1 : Wait 1
Else
If Taste = 126 Or Taste = 125 And Ab = 1 And Auf = 0 Then : Ab = 0 : Led = Ledaus : Wait 1
Else
If Taste = 254 And Ab = 0 And Auf = 0 Then : Auf = 1 : Led = Ledauf1 : Wait 1
Else
If Taste = 189 Or Taste = 190 And Auf = 1 And Ab = 0 Then : Auf = 0 : Led = Ledaus : Wait 1
End If
End If
End If
End If
Gosub 4_fach
Gosub 8_fach
Gosub Anzeige

Loop 'Until Taste <> 255 : Goto Anfang

'------------------------------------------------
' Anzeige
'------------------------------------------------
Anzeige:

I2cinit
I2cstart
I2cwbyte Pcf8574_lcd
Locate 1 , 1 : Lcd "Taste :" ; Taste
Locate 2 , 1 : Lcd "--->"
Locate 1 , 14 : Lcd "Auf:" ; Auf : Lcd "-" ; Auf2 : Print "Rollo Auf " ; Auf
Locate 2 , 14 : Lcd "Ab :" ; Ab : Lcd "-" ; Ab2 : Print "Rollo ab" ; Ab
I2cstop

Return
'------------------------------------------------
' 4 fach LED bei Tasten
'------------------------------------------------
4_fach:
I2cinit
I2cstart
I2cwbyte Pcf8574write
I2cwbyte Led
I2cstop
Return

'------------------------------------------------
' 8 fach LED
'------------------------------------------------
8_fach:
I2cinit
I2cstart
I2cwbyte Pcf8574_8fach
I2cwbyte Led
I2cstop
Return

'------------------------------------------------
' Uhr
'------------------------------------------------


End


Bitte nicht hauen wenn einige Teile etwas schlecht geprogt sind ich hab eben im Moment nur den Timer im Kopf aber eben nicht im Programm. LCD ist nur für die Anzeige was das Programm grad macht und die 8_Fach ist als parallel Anzeieg für Relais oder so und auch als Test ob's geht.

Bitte schreibt mir befor ich das Ganze in die Tonne trete.
Dank im voraus

linux_80
21.03.2006, 20:04
Hallo,

wie schauts mit Wait aus ?
passt das ins Konzept, bei Wait 20 wird halt nur gewartet und sonst nix gemacht ?

PiCus
21.03.2006, 20:29
Nee,
wait stoppen doch das Programm und es soll doch auf jeden Fall noch auf die Taste reagieren.
Also Taste -Ab- normal 15Sek wenn in dieser Zeit -Ab_ nochmal gedrückt wird ist dass praktisch wie eine Stop-Funktion, und mit waits haut dass nicht hin.
Ich hab auch schon eine Zähl-Schleife eingebaut dass funzt aber zu unterschiedlichen Zeiten weil die Schleife irgendwo greift beim Tastendruck.

Zur Funktion vielleicht mal
Taste 1 Rollo auf, Taste1 Rollo auf ist stop, Taste2 Rollo ab, Taste2 ab ist stop genau so ist es bei einer Funktion irgendeine Taste immer zuerst stop.

Dank für die Antwort

linux_80
22.03.2006, 00:19
Also nommal zum Timer,
Timer1 ist 16 Bit breit, dH. nach spätestens 2^16 Impulsen ist er einmal durch, und kann einen IRQ erzeugen,
der grösste Prescaler ist 1024, bei 4MHz sollte man dann auf max. 16777 ms für einen Durchlauf kommen.
Wenn man damit mehrere Sekunden überbrücken will, muss man mit einer hilfsvariablen die einzelnen IRQs mitzählen bis der gewünschte Wert erreicht ist.

PiCus
22.03.2006, 09:43
Hallo linux_80
wie die Timer funktionieren ist mir bekannt, dass ich die zur Erreichnung mit Variablen hochzählen muss, nur ich weiss nicht wie ich den/die in meinem Programm einbauen soll.
Ich weiss Timer einstellen, einschalten zählen lassen usw nur wie und wo in meinem Programm und wie sag ich's dem Interrupt ??

linux_80
22.03.2006, 12:51
Assoo,
dann würd ich sagen, nach dem der Timer eingestellt ist und schon mal vor sich hinzählt, braucht man die ISR, die nach jedem Timerdurchlauf aufgerufen wird, in dieser zählt man eine Variable hoch, sonst muss man nix weiter machen, ausser man will den Timer nicht von 0 weglaufen lassen, um zB. eine genauere Zeit zu bekommen. Diese Variable setzt und prüft man vom Hauptprogramm aus, also wenn man weiss, in zB. 15 Sec. soll was sein, diese Variable auf 0 setzen, und dann regelmässig prüfen bis die Variable auf 15 (oder was entsprechend rauskommt für die gewünschte Zeit) prüfen, und dann die gewünschte Aktion aufrufen.

Ich denke das mit diesem Fragment auf die Sprünge geholfen werden kann (ungetestet !):


Config Timer1 = Timer , Prescale = 1024

Dim Count_1 As Integer

Enable Interrupts

On Timer1 Timer1_isr


Count_1 = 0

Do

' wichtige ProgrammSachen ...



' Timer soll neu gestartet werden,
' alle Werte auf 0 damits auch von vorne losgeht
If Irgendwas Then
Timer1 = 0
Count_1 = 0
Enable Timer1
End If

' prüfen ob die Zeit schon abgelaufen ist
If Count_1 = 15 Then
Waswichtiges()
Count_1 = 0
' Timer_IRQ wieder aus wenn er nicht gebraucht wird
Disable Timer1
End If

' andere wichtige Sachen ...

Loop

End


Timer1_isr:
Count_1 = Count_1 + 1

Return

HTH!

-tomas-
22.03.2006, 13:53
ich würde anstatt
If Count_1 = 15 Then
immer schreiben...
If Count_1 > 14 Then
...man weiß ja nie :-)

PiCus
23.03.2006, 19:15
Danke linux_80 und -tomas-

hab alles zusammen gebaut, und es funzt ich werd nun die hardware basteln und beides auf einander abstimmen.

ich werd mich mal wieder in den hinergrund hängen.

bis denn dann

PiCus