PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Eintrittsbedingungenproblem mit Variablen



m_herr
22.12.2005, 18:26
Hallo Leute,

ich habe von Anfang an ein Problem mit den Variablen, durch einen Timer befeuert und deren Nutzung bei als Schleifeneintrittsbedingung.

was mache ich falsch?

Bsp

Config Timer0 = Timer , Prescale = 256
Const Ticks0 = 156
On Timer0 Timer0_isr
enable etc etc

dim x as integer

if x = 10 then
zege was auf display an
x=0
end if

das geht fast nicht, schleife wird fast nie ausgeführt


if x > 10 then
zege was auf display an
x=0
end if

das geht immer, nur ist es extrems ungenau, da die schleife nun nicht mehr alle 10x0,01s, sondern so 11-14x0,01s

Timer0_isr:
Load Timer0 , Ticks0 '0,01sek erzeugen
incr x
Return

habe es an meheren systemen (m8,m16,m168,2313 etc) und immer ist es das selbe, also kann es nicht an den platinenn liegen, sondern muß an meiner programmierung liegen. alles andere, also adc, display, pwm, rs232 etc klappt.....nur diese kindergarten sache nicht..

wer kann da helfen?

Vielen Dank

PicNick
22.12.2005, 18:48
Es ist immer gefährlich, wenn ISR und normal Routinen die gleichen Werte bepflastern, überhaupt, wenn es mehrbytige sind (integer)
Je nachdem, was "display" tut, kann es auch ein timing-problem sein.
10 mS kannst du bei 9600 Baud grade ~10 Zeichen auf den Schirm bringen. d.h. wenn du danach x= 0 setzt, hätte der interrupt vielleicht schon wieder zählen wollen.
Egal:
Kontrolliere mal die logische Richtigkeit, indem du


disable interrupts
if x = 10 then
x=0
enable interrupts
zege was auf display an
end if
enable interrupts ' (2 mal macht auch nix)

dadurch prügeln sich die Burschen nicht mehr nieder und eigentlich sollte es klappen

m_herr
22.12.2005, 19:55
timing-problem ist es nicht, hab schon alles durchprobiert, bis hin zum sinnlosen vollschreiben des displays ungebremst in der main do-loop. immer das selbe.

zu erst dachte ich,daß es an den input-pin (taster auf masse liegt), aber da bin ich auch schon wieder weg, weil es selbst ohne jemals einen taster gedrückt zu haben nicht funktionierte...

ich hätte nicht gedacht, daß es so ein problem ist, wenn ich so vorgehe.

was gäbe es denn noch für möglichkeiten eine bestimmte befehlsfolge alle x ms aus zuführen?

PicNick
23.12.2005, 08:17
Ich definiere meist einen Timer0 für 1mS
Variante 1:
In der ISR Routine einen zähler bis nn, und dann einen schalter für die hauptroutine setzen.
Variante 2 (mache ich meistens):
In der ISR Routine einen schalter für die hauptroutine setzen.
In der Hauptroutine bei jedem Schalter bis nn zählen, und dann eben was tun

super_castle
23.12.2005, 08:41
Die Sprungroutinen nehmen zuviel Zeit in anspruch.
Ich habe diese routine mit Winavr-c umgesetzt und sie läuft.

Castle

m_herr
23.12.2005, 10:51
habe jetzt mit disable/enable gearbeitet, das gleiche problem - nur nicht so oft *g

kannst du freuntlicherweise so ein wenig quell-textisch beschildern was du meinst? ich denke nämlich, daß es das selbe ist was ich mache....
vielen dank

PicNick
23.12.2005, 11:23
Da geht's um zwei steppermotoren, deren Geschwindigkeit in
1mS/ schritten zu regeln sind. die details werden dich nicht interessieren, aber die sache mit dem timer kann man erkennen



'===============================================
' Timer0 Prescale for 1mS Interrupt
'==============================================

Config Timer0 = Timer , Prescale = 64 'Timer 1mS (8MHZ)
Const Tmr_c_preload = 131 'Timer 1mS (8MHZ)

On Timer0 Interrupt_ticker


....
....bla, bla,
....

'===============================================
' M A I N L O O P
'==============================================

Do
If Irptflag = 1 Then
Irptflag = 0
Gosub Stepptick1
Gosub Stepptick2
End If
Loop
End
'===============================================
' M A I N L O O P E N D
'===============================================

'===============================================
' Timer 0 interrupt
'===============================================
Interrupt_ticker:
Timer0 = Tmr_c_preload
Irptflag = 1
Return




'===============================================
' Control stepper
'===============================================
Stepptick1:
If Steppcountleft > 0 Then
Decr Steppcountleft
Else
If Steppspeedleft <> 0 Then
Portc.3 = 0 ' clock low
Absi = Abs(steppspeedleft)
Steppcountleft = 100 - Absi
Portc.3 = 1 ' clock high
End If
End If
Return

Stepptick2:
If Steppcountrite > 0 Then
Decr Steppcountrite
Else
If Steppspeedrite <> 0 Then
Portc.2 = 0 ' clock low
Absi = Abs(steppspeedrite)
Steppcountrite = 100 - Absi
Portc.2 = 1 ' clock high
End If
End If
Return

m_herr
23.12.2005, 11:34
hallo, vielen dank.
die sache hat nur einen haken, was machst du, wenn du verschiedene sachen nicht alle 1ms machen willst, sondern sub_a und sub_b alle 10ms; sub_c alle 20ms und bedingung_d alle 50ms etc?

PicNick
23.12.2005, 11:39
Na, wenn ich z.B. links alle 40 mS einen Step machen will, und rechts alle 500, dann lade ich steppcountleft mit 40 und steppcountrite mit 500.
jede millisekunde werden beide runtergezählt und bei Null schnackelt es links und rechts unabhängig.
Die 40 oder 500 werden individuell wieder nachgeladen.