PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer 1 überfordert?



-=[Cassiopeia]=-
07.12.2005, 13:56
Servus und zwar habe ich folgendes Problem ich habe einen Timer1 mit einem Interrupt alle 2sek programmiert.
Wenn der Timer abgelaufen ist soll die Batteriespannunggemessen werden, über i2C die Temperatur erfasst werden, nen Variable hochgezählt werden und das alles an nem LCD ausgegeben werden.
Das ganze funktioniert allein alles auch wunderbar aber wenn ich die anzeige mit dem timer aktualisieren will macht er mir 1-2 durchläufe und dann resettet der Controller (rncontrol 1.4)

Is das vielleicht zu viel arbeit für den controller in der Zeit?
Ich habe es auch mit nem 4 sek intervall probiert aber das hilft auch nix...
Ich möchte dann auch noch den zurückgelegten weg mit radencodern erfassen und auch noch ausgeben, das wird ja dann zu viel oder?
#Danke für eure ideen

PicNick
07.12.2005, 14:04
=-]Is das vielleicht zu viel arbeit für den controller in der Zeit?

Wieso, hat er sich beklagt ? O:)


Ohne deiner Source wird schwer zu helfen sein.

-=[Cassiopeia]=-
07.12.2005, 14:19
es kommt zu einem reset...
damit beklagt er sich.
ich kann den source schon posten nur ich rufe eine unterfunktion lcdout() auf die wiederum alle anderen subs zb zur< spannungsmessung oder temp messung per i2c aufruft. wird halt weng lang kann ich dann geg. schon machen.

PicNick
07.12.2005, 14:24
Ein Schuss ins Blaue: Hast du Frame- und Stacksize ausreichend dimensioniert (für viele Subs ?)

-=[Cassiopeia]=-
07.12.2005, 14:34
uups nen ich glaub nicht ich hab sowas gar net drin stehen....
und ich habe 20 subs... :-)
kannst du mir bitte sagen wie das geht? am besten für bascom 1.11.74.
1000 dank

ich wollte den code halt übersichtlich gestalten...

-=[Cassiopeia]=-
07.12.2005, 14:37
ich habs mit :
$regfile = "m32def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 16000000
$baud = 9600


probiert da kommt immer Assignment error 46...

PicNick
07.12.2005, 14:42
Weiss nicht, bringe bei mir keinen error raus. frisst er glatt

ABER however: das ist zu wenig:

Gröbere Sachen fahr ich mit


$framesize = 32
$swstack = 256
$hwstack = 128

-=[Cassiopeia]=-
07.12.2005, 14:49
danke picknick!
ich habs jetzt gleich im compiler eingestellt. und die werte ungefähr verdoppelt.
jetzt gehts.
wunderbar hätte nicht gedacht das es daran liegt...
mal wieder so ein neuling fehler...

danke nochmal

-=[Cassiopeia]=-
08.12.2005, 15:01
hallo nochmal,
jetzt hab ich leider ein anders problem...
jetzt fährt der rob gegen die wand:-(
also ich hab nen servo der nen sharp gp2d12 dreht. wenn spannung >300 hält er an und sucht nen neuen weg.
des funzt jetzt nicht mehr kann des sein das der timer dann genau in dem moment kommt und der controller so seine restliche arbeit vernachlässigt-)

-=[Cassiopeia]=-
08.12.2005, 15:31
so problem ist weiter eingegrenzt..
ich hab mal wieder nen voll treffer gelandet und zwar ist timer 1 auch für die pwm modulation zum motor ansteuern configuriert... uppps...
darum fährt er gegen die wand.
wie mach ich das nun jetzt.
timer 0 kan ja keine interrupts alle sek. oder?
und timer0 als pwm zu nehmen geht auch net oder?
soll ich nen timer0 nehmen und ne variable hochzählen lassen so dass er nur alle zb 4 sek das lcd aktualisiert?
wenn ich sonst im timer0 intervall des display aktualisiere das wird ihm wohl etwas zu viel sein...

PicNick
08.12.2005, 15:37
Nun, das geht wohl dann doch ans Eingemachte. Da wird mit allgemeinen Vermutngen wohl nix zu machen sein, möööglich ist alles.
Da wirst du nun wohl doch die Source rausrücken müssen

-=[Cassiopeia]=-
08.12.2005, 15:47
gut du hast es nicht anders gewollt... :-)
hier ist alles was ich habe...:


Declare Sub Taste1()
Declare Sub Taste2()
Declare Sub Taste3()
Declare Sub Taste4()
Declare Sub Taste5()
Declare Sub Move()
Declare Sub Turn180()
Declare Sub Stopnow()
Declare Sub Anfahren()
Declare Sub Turnleft()
Declare Sub Turnright()
Declare Sub Look()
Declare Sub Bremsen()
Declare Sub Rewind()
Declare Sub Lcdout()
Declare Sub Batteriespannung()
Declare Sub Temp()

Declare Function Tastenabfrage() As Byte

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



Config Adc = Single , Prescaler = Auto
Const Ref = 5 / 1023

Const Center = 109
Dim Ton As Integer
Dim Taste As Byte
Dim Volt As Single
Dim Dist(12) As Integer
Dim Servopos As Integer
Dim V As Integer
Dim Result As Byte
Dim Ms As Integer
Dim A As Byte
Dim Name As String * 20
Name = "RP 005"
Dim Text2 As String * 20
Dim Text3 As String * 20
Dim Dl As Integer
Dl = 1

'Ports für linken Motor
Config Pinc.6 = Output 'Linker Motor Kanal 1
Config Pinc.7 = Output 'Linker Motor Kanal 2
Config Pind.4 = Output 'Linker Motor PWM
'Ports für rechten Motor
Config Pinb.0 = Output 'Rechter Motor Kanal 1
Config Pinb.1 = Output 'Rechter Motor Kanal 2
Config Pind.5 = Output 'Rechter Motor PWM
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Pwm1a = 0
Pwm1b = 0
Tccr1b = Tccr1b Or &H02
'ende motorports

'In out für tasten
Config Adc = Single , Prescaler = Auto 'Für Tastenabfrage und Spannungsmessung
Config Pina.7 = Input 'Für Tastenabfrage
Porta.7 = 1 'Pullup Widerstand ein
'ende in out für tasten


'timer config
Config Timer1 = Timer , Prescale = 1024

On Timer1 Timer_irq
Const Timervorgabe = 3036
Enable Timer1

'timer config




'servo config
Config Servos = 1 , Servo1 = Porta.0 , Reload = 10
Config Pina.0 = Output
'ende servo config

'taster config
Config Pind.6 = Input
Portd.6 = 1


'lcd config
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portb.4 , Rs = Portb.3
Config Lcd = 20 * 4

'i2c config
Config Scl = Portc.0
Config Sda = Portc.1

Dim Device As Byte
Dim Deviceread As Byte
Dim Lowtemp As Byte
Dim Hightemp As Byte
Dim Value As Single
I2cinit

Device = 144
Deviceread = 145
'ende i2c temp config

Enable Interrupts







'programm start
Servopos = Center
Servo(1) = Servopos

Print "**** RN-CONTROL ist startklar... Los gehts!!! *****"
Sound Portd.7 , 400 , 450 'BEEP
Waitms 100
Sound Portd.7 , 400 , 250
Waitms 100 'BEEP
Sound Portd.7 , 400 , 450 'BEEP


Cursor Off
Text2 = "I am alive..."
Call Lcdout
Wait 1



Text2 = "Erwarte Befehle"
Call Lcdout



Do
Taste = Tastenabfrage()
If Taste <> 0 Then

Select Case Taste
Case 1
Call Taste1 'Taste 1 Servos
Case 2
Call Taste2 'Taste 2 Spannung an pin A5
Case 3
Call Taste3 'Taste 3
Case 4
Call Taste4 'Taste 4
Case 5
Call Taste5 'Taste 5
End Select
Sound Portd.7 , 400 , 500 'BEEP
End If

Waitms 100
Loop

End





Function Tastenabfrage() As Byte
Local Ws As Word

Tastenabfrage = 0
Ton = 600
Start Adc
Ws = Getadc(7)
If Ws < 500 Then
Select Case Ws
Case 400 To 450
Tastenabfrage = 1
Ton = 550
Case 330 To 380
Tastenabfrage = 2
Ton = 500
Case 260 To 305
Tastenabfrage = 3
Ton = 450
Case 180 To 220
Tastenabfrage = 4
Ton = 400
Case 90 To 130
Tastenabfrage = 5
Ton = 350

End Select
Sound Portd.7 , 400 , Ton 'BEEP

End If


End Function




Sub Taste1()


Text2 = "Servo Test"
Call Lcdout()
Wait 1

Servopos = Center
Servo(1) = Servopos
Text2 = "Mitte"
Call Lcdout()
Wait 1

Servopos = 60
Servo(1) = Servopos
Wait 1
Text2 = "Rechtsdrehung"
Call Lcdout()
For Servopos = 60 To 160 Step 10
Servo(1) = Servopos
Waitms 10
Next

Wait 1
Text2 = "Linksdrehung"
Call Lcdout()
For Servopos = 160 To 60 Step -10
Servo(1) = Servopos
Waitms 10
Next

Wait 1
Text2 = "Mitte"
Call Lcdout()
Servopos = Center
Servo(1) = Servopos




End Sub



Sub Taste2()

Text2 = "Sensor Test"
Call Lcdout()
Call Look()


End Sub


Sub Taste3()

Text2 = "Taster Test"
Call Lcdout()

Do

If Pind.6 = 0 Then
Sound Portd.7 , 800 , 800



Text2 = "Upps sorry..."
Call Lcdout()
Call Turn180
End If
Waitms 300
Loop

End Sub



Sub Taste4()

Wait 1
Call Turn180

End Sub



Sub Taste5()

Text2 = "Volle Fahrt voraus"
Call Lcdout()
Wait 1
Call Move()

End Sub













Sub Move()
Text2 = "moving..."
Call Lcdout()
Local U As Integer

Start Adc 'spannungsmessung starten

Call Anfahren 'anfahren


'Fahren

Do

'servo Rechtsdrehung"
Servopos = 89
For Servopos = 89 To 129 Step 4
Servo(1) = Servopos

If Pind.6 = 0 Then 'taster anstoss
Text2 = "Upps sorry..."
Call Lcdout()
Call Stopnow
Call Rewind
Call Turn180
Call Anfahren
Text2 = "moving..."
Call Lcdout()
End If

Waitms 80 'vorher 80
U = Getadc(5)

If U > 250 Then 'spannung am gp12d2 zu groß
Text2 = "Hindernis gefunden"
Call Lcdout()
U = 0
Call Stopnow
Call Look
Call Anfahren
Text2 = "moving..."
Call Lcdout()

End If

Next



'servo Linksdrehung"

For Servopos = 129 To 89 Step -4
Servo(1) = Servopos

If Pind.6 = 0 Then
Text2 = "Upps sorry..."
Call Lcdout()
Call Stopnow
Call Rewind
Call Turn180
Call Anfahren
Text2 = "moving..."
Call Lcdout()
End If


Waitms 80 'vorher 80ms
U = Getadc(5)
If U > 250 Then
Text2 = "Hindernis gefunden"
Call Lcdout()
U = 0
Call Stopnow
Call Look
Call Anfahren
Text2 = "moving..."
Call Lcdout()
End If

Next
Loop

'bremsen
If V > 0 Then
Call Bremsen
End If


Servopos = Center
Servo(1) = Servopos

End Sub





Sub Look()
Local Sp As Byte
Servopos = 60
Servo(1) = Servopos
Cls
'clear the LCD display
Text2 = "Suche weiteren Weg..."
Call Lcdout()


Waitms 200
Sp = 1


'Servo "Rechtsdrehung":

For Servopos = 50 To 160 Step 10 'vorher 170

Servo(1) = Servopos
Waitms 180
Dist(sp) = Getadc(5)
Incr Sp

Next
Servopos = Center
Servo(1) = Servopos


'suche nach kleinstem wert
Result = 1

For Sp = 1 To 12 'vorher 12
If Dist(sp) < Dist(result) Then Result = Sp
Next



Ms = 0
Select Case Result
Case 1
Ms = 600
Call Turnleft
Case 2
Ms = 500
Call Turnleft
Case 3
Ms = 400
Call Turnleft
Case 4
Ms = 200
Call Turnleft
Case 5
Ms = 100
Call Turnleft
Case 6
Ms = 50
Call Turnleft
Case 7
Ms = 50
Call Turnright
Case 8
Ms = 100
Call Turnright
Case 9
Ms = 200
Call Turnright
Case 10
Ms = 400
Call Turnright
Case 11
Ms = 500
Call Turnright
Case 12
Ms = 600
Call Turnright

Case Else
Sound Portd.7 , 1000 , 200

End Select

End Sub




Sub Turnleft()
Text2 = "Linksdrehung"

Call Lcdout()

'Print "drehen um " ; Ms ; " nach links"
'servo auf mitte stellen
Servopos = Center
Servo(1) = Servopos

'Linker Motor ein
Portc.6 = 1 'bestimmt Richtung
Portc.7 = 0 'bestimmt Richtung
Portd.4 = 1 'Linker Motor EIN

'Rechter Motor ein
Portb.0 = 0 'bestimmt Richtung rechter Motor
Portb.1 = 1 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

'beschleunigen der motoren
V = 0
Do
Pwm1a = V
Pwm1b = V
Waitms 20
V = V + 200
Loop Until V > 1000

Waitms Ms
Call Bremsen

Ms = 0

End Sub




Sub Turnright()
Text2 = "Rechtsdrehung"

Call Lcdout()

'servo auf mitte stellen
Servopos = Center
Servo(1) = Servopos


'Linker Motor ein
Portc.6 = 0 'bestimmt Richtung
Portc.7 = 1 'bestimmt Richtung
Portd.4 = 1 'Linker Motor EIN

'Rechter Motor ein
Portb.0 = 1 'bestimmt Richtung rechter Motor
Portb.1 = 0 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

'beschleunigen der motoren
V = 0
Do
Pwm1a = V
Pwm1b = V
Waitms 20
V = V + 200
Loop Until V > 1000

Waitms Ms

Call Bremsen

Ms = 0

End Sub




Sub Turn180()
'servo auf mitte stellen
Text2 = "180 Grad Drehung"
Call Lcdout()


'Linker Motor ein
Portc.6 = 0 'bestimmt Richtung
Portc.7 = 1 'bestimmt Richtung
Portd.4 = 1 'Linker Motor EIN

'Rechter Motor ein
Portb.0 = 1 'bestimmt Richtung rechter Motor
Portb.1 = 0 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

'beschleunigen der motoren
If V = 0 Then
Do
Pwm1a = V
Pwm1b = V
Waitms 20
V = V + 100
Loop Until V > 1000
End If

Waitms 1250 'warten


'ab
Call Bremsen


End Sub





Sub Stopnow()
Text2 = "Vollbremsung"
Call Lcdout()
V = 0
Pwm1a = V 'Linker Motor aus
Pwm1b = V 'rechter Motor aus
End Sub


Sub Anfahren()
Text2 = "Anfahren"
Call Lcdout()
'Linker Motor ein
Portc.6 = 0 'bestimmt Richtung
Portc.7 = 1 'bestimmt Richtung
Portd.4 = 1 'Linker Motor EIN

'Rechter Motor ein
Portb.0 = 0 'bestimmt Richtung rechter Motor
Portb.1 = 1 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

'Beschleunigen
V = 0
Do
Pwm1a = V
Pwm1b = V
Waitms 10
V = V + 100
Loop Until V > 1000
End Sub




Sub Bremsen()
Text2 = "Bremsen"
Call Lcdout()

Do
Pwm1a = V
Pwm1b = V
Waitms 20
V = V - 200
Loop Until V < 1

Pwm1a = 0 'Linker Motor aus
Pwm1b = 0

End Sub






Sub Rewind()
Text2 = "Rewind..."
Call Lcdout()

'Linker Motor ein
Portc.6 = 1 'bestimmt Richtung
Portc.7 = 0 'bestimmt Richtung
Portd.4 = 1 'Linker Motor EIN

'Rechter Motor ein
Portb.0 = 1 'bestimmt Richtung rechter Motor
Portb.1 = 0 'bestimmt Richtung rechter Motor
Portd.5 = 1 'rechter Motor EIN

'Beschleunigen
V = 0
Do
Pwm1a = V
Pwm1b = V
Waitms 10
V = V + 100
Loop Until V > 1000

Waitms 100

End Sub


Sub Lcdout()
Cls
Locate 1 , 1
Lcd Name

Locate 2 , 1
Lcd Text2

Call Temp
Locate 3 , 1
Lcd "Temp= " ; Fusing(value , "#.#") ; " Grad " ; Dl

Call Batteriespannung
Locate 4 , 1
Lcd "Ubatt= " ; Fusing(volt , "#.##") ; " V"


Incr Dl

End Sub





Sub Batteriespannung()
Local W As Word
Local Z As String * 10

Start Adc
W = Getadc(6)
Volt = W * Ref
Volt = Volt * 5.2941

End Sub




Sub Temp()

I2cstart
I2cwbyte Device
I2cwbyte &HEE
I2cstop

I2cstart
I2cwbyte Device
I2cwbyte &HAA
I2cstop

I2cstart
I2cwbyte Deviceread
I2crbyte Lowtemp , Ack
I2crbyte Hightemp , Nack

I2cstop

Value = Lowtemp * 10
If Hightemp = 128 Then
Value = Value + 5
End If
Value = Value / 10

End Sub


Timer_irq:
Timer1 = Timervorgabe

Call Lcdout
Return

-=[Cassiopeia]=-
08.12.2005, 15:49
also des problem ist nur wie aktualisieren ich meine display anzeige alle 1 sek ohne timer1
thx

Werner_Just
08.12.2005, 16:25
Hallo,

> also des problem ist nur wie aktualisieren ich meine display anzeige alle
> 1 sek ohne timer1

Du nimmst Timer 0 oder Timer 2, Prescale = 1024 und dann zählst Du im OvF- Interrupt bis 61.

Oder Du nimmst Timer 2 und spendierst ihm einen eigenen Quarz.

Oder Du schreibst Dein Programm auf einen freilaufenden Timer1 um und verwendest die Output Compare Interrupts.

Oder...

Ciao,
Werner

-=[Cassiopeia]=-
08.12.2005, 16:42
servus werner,
tja nächstes problem timer0 wird von den servos verwendet oder?
wie mach ich das dann mit timer 2 und hat den mein atmega 32 überhaupt?
danke soweit

PicNick
08.12.2005, 16:50
uiuiuiui.
Timer0 für eine Sekunde, damit Timer1 frei wird:
Ganz einfach: definiere 1/100 Sekunde Interrupts. im interrupt zählst du irgend ein (neues) Byte immer eins drauf. isses 100, dann ist eine Sekunde rum, du setzt das Zählbyte wieder auf 0.
Das is mal das.

Bei dir ist es gefährlich, da sich dein Programm mit der Interrupt routine um LCDOUT streitet und um den ADC.

Wenn der Robby spinnt, dann verziche testweise mal auf den LCDOUT im Interrupt, und schau, ob es was verändert.

-=[Cassiopeia]=-
08.12.2005, 20:02
servus nochmal,
also ich kann den timer 0 leider net verwenden weil der für die servo ansteuerung von bascom verwendet wird.
oder hab ich da was falsch verstanden?
und nen timer 2 hat der mega32 net oder?
ja weil mit timer 0 hab ichs schon versucht dann gehen die servos nimmer...
auszug aus bascom hilfe:
" Resources used:
TIMER0 is used to create the ISR."
danke für euere mühen...

PicNick
09.12.2005, 06:42
Au weia, da werden wir wohl den Kopf schief halten müssen, damit das Hirn zusammenläuft und uns was einfällt. Timer 2 sollte es geben, aber da les ich erst lieber mal nach, ob's da was zu wissen gibt.

Werner_Just
09.12.2005, 07:09
Hallo Cassiopeia,

> und nen timer 2 hat der mega32 net oder?

das Datenblatt zum verwendeten µC ist häufig eine unerschöpfliche Quelle an Information! :-$

Auszug aus dem M32 Datenblatt der Firma Atmel:

8-bit Timer/Counter2 with PWM and Asynchronous Operation

Timer/Counter2 is a general purpose, single compare unit, 8-bit Timer/Counter module.

The main features are:
• Single Compare unit Counter
• Clear Timer on Compare Match (Auto Reload)
• Glitch-free, Phase Correct Pulse Width Modulator (PWM)
• Frequency Generator
• 10-bit Clock Prescaler
• Overflow and Compare Match Interrupt Sources (TOV2 and OCF2)
• Allows clocking from External 32 kHz Watch Crystal Independent of the I/O Clock

Overview
A simplified block diagram of the 8-bit Timer/Counter is shown in Figure 53. For the actual placement of I/O pins, refer to “Pinout ATmega32” on page 2. CPU accessible I/O Registers, including I/O bits and I/O pins, are shown in bold. The device-specific I/O Register and bit locations are listed in the “8-bit Timer/Counter Register Description” on page 123.

Ciao,
Werner

-=[Cassiopeia]=-
09.12.2005, 08:54
danke an werner und picnick,
ich habe alle verfügbaren neuralen ressourcen aktiviert und es nun geschafft der timer2 läuft und alles ist perfekt.
danke für eure hilfe
gruß und prost
CP

super_castle
09.12.2005, 09:17
Du solltest dein Programm mal ein bisschen ordnen, dann kannst du auch schneller die Fehler finden.
Auch die Abläufe sind nicht optimal organisiert.

Castle