PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Brauche Hilfe bei meinem Programmcode



Lenox
07.03.2007, 15:59
Wie ein paar von euch schon wissen bin ich so gut wie fertig mit meinem Projekt, aber die letzten beiden Probleme bekomm ich einfach nicht gelöst.

1. Die Programme sollen solange ausgeführt werden bis der Befehl für ein anderes erfolg. (Siehe Wait_and_get Subroutine) Leider funktioniert das mit dem last_ir_command so nicht, warum weiß ich leider nicht.

2. "Programmr" soll nur die rote Led dauerhaft anschalten. (Portd.6)
Problem ist das der Port nicht einfach geschaltet werden kann, da der Timer0 für die RGB PWM ja im Hintergrund läuft.

Hier der Code:


$regfile = "m16def.dat"
$framesize = 32
$swstack = 32
$hwstack = 40
$crystal = 16000000
$baud = 9600

Waitms 50 'Einschwingzeit

'//////////Ports Konfigurieren\\\\\\\\\\
Config Porta = Output 'M1
Config Portc = Output 'M2
Config Portd.6 = Output 'RGB-Rot
Config Portd.3 = Input 'TSOP

Porta.4 = 1 'Enable1 active = low
Portc.4 = 1
Enable1 Alias Porta.4
Enable2 Alias Portc.4

Portd.6 = 1 'RGB Led ausschalten
Portc.7 = 1
Portc.6 = 1

'//////////Timer konfigurieren, Vorteiler auf 1\\\\\\\\\\
Config Timer0 = Timer , Prescale = 1

'//////////RC5 konfigurieren mit Timer 2\\\\\\\\\\
Config Rc5 = Pind.3 , Timer = 2

'/////////Sub Deklarieren\\\\\\\\\\\\\
Declare Sub Wait_and_get(byval Ms As Byte)


'//////////Definiere den Interrupthandler\\\\\\\\\\
On Ovf0 Tim0_isr
Enable Interrupts

Enable Timer0 'Timer einschalten


Dim R1 As Byte ' In diese Variablen muss man
Dim G1 As Byte ' im Hauptprogram die gewünschten
Dim B1 As Byte ' Ausgabewerte laden

Dim Z As Word 'Zähler

Dim Ri1 As Byte 'Hilfsregister
Dim Gi1 As Byte
Dim Bi1 As Byte

'//////////Variablen für Hauptprogramm\\\\\\\\\\
Dim A As Byte 'Schleifenvariable RGBs

Z = 0

G1 = 0
R1 = 0
B1 = 0

Dim I As Byte 'Schleifenvariable Lauflicht
Dim I2 As Byte 'Schleifenvariable Lauflicht
Dim I3 As Byte 'Schleifenvariable Lauflicht
Dim Freilauf As Byte
Dim Ir_address As Byte
Dim Ir_command As Byte
Dim Last_ir_command As Byte
Last_ir_command = 0

Dim Programm As Byte 'Programmauswahl
Programm = 0 'Erst nix machen


'EEPROM Variablen
'Dim R_save As Eram Byte
'Dim G_save As Eram Byte
'Dim B_save As Eram Byte

Wait 1

'//////////Einstellungen\\\\\\\\\\
Freilauf = 20 'Lauflicht Freilaufzeit
'Normaldurchlauf = 2 'Anzahl der Standarddurchläufe
'//////////Hauptprogramm <Start>\\\\\\\\\\
Waitms 200
Print "Starte Hauptprogramm"

Do
Call Wait_and_get(1) 'bisschen Däumchen drehen und warten bis was gedrückt wird ;)
Loop

'//////////Hauptprogramm <Ende>\\\\\\\\\\

'Programm1: RGB LEDs
Programm1:

'Rot
For A = 0 To 254
R1 = R1 + 1
Waitms 1
Next
Waitms 10
For A = 0 To 254
R1 = R1 - 1
Waitms 1
Next

'Grün
For A = 0 To 254
G1 = G1 + 1
Waitms 1
Next
Waitms 10
For A = 0 To 254
G1 = G1 - 1
Waitms 1
Next

'Blau
For A = 0 To 254
B1 = B1 + 1
Waitms 1
Next
Waitms 10
For A = 0 To 254
B1 = B1 - 1
Waitms 1
Next

'Blau/Grün
For A = 0 To 254
B1 = B1 + 1
G1 = G1 + 1
Waitms 1
Next
Waitms 10
For A = 0 To 254
B1 = B1 - 1
G1 = G1 - 1
Waitms 1
Next

'Blau/Rot
For A = 0 To 254
B1 = B1 + 1
R1 = R1 + 1
Waitms 1
Next
Waitms 10
For A = 0 To 254
B1 = B1 - 1
R1 = R1 - 1
Waitms 1
Next

'Grün/Rot
For A = 0 To 254
G1 = G1 + 1
R1 = R1 + 1
Waitms 1
Next
Waitms 10
For A = 0 To 254
G1 = G1 - 1
R1 = R1 - 1
Waitms 1
Next

'Grün/Rot/Blau
For A = 0 To 254
G1 = G1 + 1
R1 = R1 + 1
B1 = B1 + 1
Waitms 1
Next
Waitms 10
For A = 0 To 254
G1 = G1 - 1
R1 = R1 - 1
B1 = B1 - 1
Waitms 1
Next

Return

'Programm2: Lauflicht
Programm2:


For I = 0 To 15
Porta = I
Enable1 = 0
Waitms Freilauf
Enable1 = 1
Next I

For I = 0 To 11
Portc = I
Enable2 = 0
Waitms Freilauf
Enable2 = 1
Next I
Call Wait_and_get(0)

Return

'Programm3: Lauflicht2
Programm3:


For I = 0 To 15
Porta = I
Enable1 = 0
Waitms 10
Enable1 = 1
Next I

For I = 0 To 11
Portc = I
Enable2 = 0
Waitms 10
Enable2 = 1
Next I
Call Wait_and_get(0)

Return

Programmr:

'R1 = 255
Disable Timer1
Portd.6 = 0
Waitms 100
Portd.6 = 1
Call Wait_and_get(0)
'R1 = 0

Return

'/////////////////Funktion zum RC5 empfangen und warten\\\\\\\\\\\\\\\
Sub Wait_and_get(byval Ms As Byte)
Getrc5(ir_address , Ir_command) 'Empfangen

'Wenn was empfangen dann reagieren
If Ir_address <> 255 Then
Ir_command = Ir_command And &B01111111 'Togglebit entfernen

'Hier die Codes an die Fernbedienung anpassen
Print "IR Befehl: " + Str(ir_command)

If Ir_command = 255 Then 'wenn nichts emfangen wird,
Ir_command = Last_ir_command 'dann akt. Programm weiter
Else 'ausführen
If Ir_command = 17 Then Gosub Programm1
If Ir_command = 18 Then Gosub Programm2
If Ir_command = 19 Then Gosub Programm3
If Ir_command = 20 Then Gosub Programmr
End If



End If

Waitms Ms 'warten
End Sub


'//////////Interupthandler Timer0 <Start>\\\\\\\\\\
Tim0_isr:

If Z = 0 Then 'Gewünschte Ausgabewerte an
Ri1 = R1 'Hilfsregister übergeben
Gi1 = G1
Bi1 = B1
Z = 255
End If

Z = Z - 1

'PWM Kanäle

'RGB LEDs
If Ri1 > 0 Then
Portd.6 = 0
Else
Portd.6 = 1
End If
Ri1 = Ri1 - 1
If Ri1 = 255 Then Ri1 = 0

If Gi1 > 0 Then
Portc.7 = 0
Else
Portc.7 = 1
End If
Gi1 = Gi1 - 1
If Gi1 = 255 Then Gi1 = 0

If Bi1 > 0 Then
Portc.6 = 0
Else
Portc.6 = 1
End If
Bi1 = Bi1 - 1
If Bi1 = 255 Then Bi1 = 0

Return
'//////////Interupthandler Timer0 <Ende>\\\\\\\\\\


Ich wäre euch sehr dankbar für eure Hilfe da ich mittlerweile echt dran verzweifel ](*,)

Lenox
07.03.2007, 23:28
Hmm kann mir keiner weiterhelfen?
Woran scheitert es?

Vitis
08.03.2007, 01:55
ich kann in deinem listing keine konfiguration vom timer1 = pwm sehen.
der timer0 ist n 8-bit timer, der da alle 255 takte nen interrupt auslöst, da prescaller=1. dazu die lange ISR vom timer0, der dürfte da fast garnicht aus dem Interrupt raus kommen, oder?
bei so kurzen timerintervallen verwende ich gern flag-register, sprich s-ram um nen wert zwischenzuspeichern, das eben interrupt ausgelöst wurde. die Behandlung der ISR mach ich dann aus dem hauptprogramm heraus in der subroutine, die dann das flag wieder löscht

Lenox
08.03.2007, 15:45
Ah sorry timer0 war PWM für die RGBs.
Timer1 ist für den RC5 (macht er ja automatisch).
Doch, er müsste aus dem Interrupt rauskommen, denn das Lauflicht braucht ca. 2 sek für einen Durchgang.

Das dürfte doch eig. nicht so schwer sein, dass wenn kein RC5 emfangen wird, und Getrc5(), dann 255 als IR_command zurückliefert (stimmt das?), er einfach das letzte Programm (Sub) wieder aufruft.

Bluesmash
08.03.2007, 16:07
mach mal vor dem getrc5():
Last_ir_command = Ir_command

gruss bluesmash

Lenox
08.03.2007, 16:27
Geht leider nicht.
Was soll das den bringen?
Ir_command ist beim ersten Durchlauf noch nicht definiert.

Nochmal zum verständnis, du meintest:


'/////////////////Funktion zum RC5 empfangen und warten\\\\\\\\\\\\\\\
Sub Wait_and_get(byval Ms As Byte)
Last_ir_command = Ir_command
Getrc5(ir_address , Ir_command) 'Empfangen

'Wenn was empfangen dann reagieren
If Ir_address <> 255 Then
Ir_command = Ir_command And &B01111111 'Togglebit entfernen

'Hier die Codes an die Fernbedienung anpassen
Print "IR Befehl: " + Str(ir_command)

If Ir_command = 255 Then 'wenn nichts emfangen wird,
Ir_command = Last_ir_command 'dann akt. Programm weiter
Else 'ausführen
If Ir_command = 17 Then Gosub Programm1
If Ir_command = 18 Then Gosub Programm2
If Ir_command = 19 Then Gosub Programm3
If Ir_command = 20 Then Gosub Programmr
End If



End If

Waitms Ms 'warten
End Sub

Bluesmash
08.03.2007, 16:37
sorry sollte vielleicht noch erklären warum ;)
Last_ir_command wird am anfang auf 0 gesetzt und danach nie wieder ein wert rein geschrieben... oder übersehe ich etwas?
du must doch irgendwo das letzte commado speichern...

gruss bluesmash

Lenox
08.03.2007, 16:57
Achso ja stimmt vergessen^^ wäre ja dann


Sub Wait_and_get(byval Ms As Byte)
'Last_ir_command = Ir_command
Getrc5(ir_address , Ir_command) 'Empfangen

'Wenn was empfangen dann reagieren
If Ir_address <> 255 Then
Ir_command = Ir_command And &B01111111 'Togglebit entfernen

'Hier die Codes an die Fernbedienung anpassen
Print "IR Befehl: " + Str(ir_command)

If Ir_command = 255 Then 'wenn nichts emfangen wird,
Ir_command = Last_ir_command 'dann akt. Programm weiter
Else
Last_ir_command = Ir_command
If Ir_command = 17 Then Gosub Programm1
If Ir_command = 18 Then Gosub Programm2
If Ir_command = 19 Then Gosub Programm3
If Ir_command = 20 Then Gosub Programmr
End If



End If

Waitms Ms 'warten
End Sub


Leider geht das auch nicht, der RS232 kommt auch nur halb an.. ah ich glaub ich muss das Programm mal komplett überholen.

Bluesmash
08.03.2007, 17:26
probier mal das:



Sub Wait_and_get(byval Ms As Byte)

Getrc5(ir_address , Ir_command) 'Empfangen

'Wenn was empfangen dann reagieren
If Ir_address <> 255 Then
Ir_command = Ir_command And &B01111111 'Togglebit entfernen

'Hier die Codes an die Fernbedienung anpassen
Print "IR Befehl: " + Str(ir_command)
End If

If Ir_command = 255 Then Ir_command = Last_ir_command 'wenn nichts emfangen wird,

Last_ir_command = Ir_command
If Ir_command = 17 Then Gosub Programm1
If Ir_command = 18 Then Gosub Programm2
If Ir_command = 19 Then Gosub Programm3
If Ir_command = 20 Then Gosub Programmr


Waitms Ms 'warten
End Sub

Lenox
08.03.2007, 20:12
Vielen Dank Bluesmash!
Funktioniert wunderbar ;)

Bluesmash
08.03.2007, 20:32
dass freut mich :)

Lenox
08.03.2007, 21:58
Mist PWM geht nicht wirklich.
Rot fadert hoch und er tut nichts.. paar Sekunden später startet er einfach neu.

Am RS232 kommt dann sowas an:

’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’ ’’’’’’LR Befehlŗč’’’’’’’
’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’Starte Hauptprogramm
IR

Bricht er vielleicht zusammen?
Das Teil macht mich langsam bekloppt.

Zudem wollte ich gerade die
Waitms 20 in Programm 2 mit Call Wait_and_get(20) ersetzen (um halt auch wärend der Programmausführung das Programm wechseln zu können), dann läuft das Lauflicht bis zur Hälfte und das wars.
Jedesmal jedoch anders.

Lenox
09.03.2007, 16:20
So Problem ist einfach verschwunden, fragt bitte nicht warum.
Das Programm wurde überholt, aber die PWM ruckelt komigerweise,
und wenn ich aus der PWM das program mwechsel bleiben die RGBs stehen.



$regfile = "m16def.dat"
$framesize = 32
$swstack = 32
$hwstack = 40
$crystal = 16000000
$baud = 9600

Waitms 50 'Einschwingzeit

'//////////Ports Konfigurieren\\\\\\\\\\
Config Porta = Output 'M1
Config Portc = Output 'M2
Config Portd.6 = Output 'RGB-Rot
Config Portd.3 = Input 'TSOP

Porta.4 = 1 'Enable1 active = low
Portc.4 = 1
Enable1 Alias Porta.4
Enable2 Alias Portc.4

Portd.6 = 1 'RGB Led ausschalten
Portc.7 = 1
Portc.6 = 1

'//////////Timer konfigurieren, Vorteiler auf 1\\\\\\\\\\
Config Timer0 = Timer , Prescale = 1

'//////////RC5 konfigurieren mit Timer 2\\\\\\\\\\
Config Rc5 = Pind.3 , Timer = 2

'/////////Sub Deklarieren\\\\\\\\\\\\\
Declare Sub Wait_and_get(byval Ms As Byte)


'//////////Definiere den Interrupthandler\\\\\\\\\\
On Ovf0 Tim0_isr
Enable Interrupts

Enable Timer0 'Timer einschalten


Dim R1 As Byte ' In diese Variablen muss man
Dim G1 As Byte ' im Hauptprogram die gewnschten
Dim B1 As Byte ' Ausgabewerte laden

Dim Z As Word 'Zļæ½ler

Dim Ri1 As Byte 'Hilfsregister
Dim Gi1 As Byte
Dim Bi1 As Byte

'//////////Variablen fr Hauptprogramm\\\\\\\\\\
Dim A As Byte 'Schleifenvariable RGBs

Z = 0

G1 = 0
R1 = 0
B1 = 0

Dim I As Byte 'Schleifenvariable Lauflicht
Dim I2 As Byte 'Schleifenvariable Lauflicht
Dim I3 As Byte 'Schleifenvariable Lauflicht
Dim Ir_address As Byte
Dim Ir_command As Byte

Wait 1

'//////////Einstellungen\\\\\\\\\\
Const Freilauf = 20 'Lauflicht Freilaufzeit
'Normaldurchlauf = 2 'Anzahl der Standarddurchlļæ½fe
'//////////Hauptprogramm <Start>\\\\\\\\\\
Waitms 200
Print "Starte Hauptprogramm"

Standby:
Do

Call Wait_and_get(5) 'Dļæ½mchen drehen und auf Befehl warten

Loop

'//////////Hauptprogramm <Ende>\\\\\\\\\\

'Programm1: RGB LEDs
Programm1:
Do

'Rot
For A = 0 To 254
Incr R1
Call Wait_and_get(0)
Next
Call Wait_and_get(10)
For A = 0 To 254
Decr R1
Call Wait_and_get(0)
Next

'Grn
For A = 0 To 254
Incr G1
Call Wait_and_get(0)
Next
Call Wait_and_get(10)
For A = 0 To 254
Decr G1
Call Wait_and_get(0)
Next

'Blau
For A = 0 To 254
Incr B1
Call Wait_and_get(0)
Next
Call Wait_and_get(10)
For A = 0 To 254
Decr B1
Call Wait_and_get(0)
Next

'Blau/Grn
For A = 0 To 254
Incr B1
Incr G1
Call Wait_and_get(0)
Next
Call Wait_and_get(10)
For A = 0 To 254
Decr B1
Decr G1
Call Wait_and_get(0)
Next

'Blau/Rot
For A = 0 To 254
Incr B1
Incr R1
Call Wait_and_get(0)
Next
Call Wait_and_get(10)
For A = 0 To 254
Decr B1
Decr R1
Call Wait_and_get(0)
Next

'Grn/Rot
For A = 0 To 254
Incr G1
Incr R1
Call Wait_and_get(0)
Next
Call Wait_and_get(10)
For A = 0 To 254
Decr G1
Decr R1
Call Wait_and_get(0)
Next

'Grn/Rot/Blau
For A = 0 To 254
Incr G1
Incr R1
Incr B1
Call Wait_and_get(0)
Next
Call Wait_and_get(10)
For A = 0 To 254
Decr G1
Decr R1
Decr B1
Call Wait_and_get(0)
Next
Loop
'ende des 1. programms

'Programm2: Lauflicht
Programm2:
Do

For I = 0 To 15
Porta = I
Enable1 = 0
Call Wait_and_get(Freilauf)
Enable1 = 1
Next I

For I = 0 To 11
Portc = I
Enable2 = 0
Call Wait_and_get(Freilauf)
Enable2 = 1
Next I
Call Wait_and_get(0)
Loop
'ende des 2. programms


'Programm3: Lauflicht2
Programm3:
Do

For I = 0 To 15
Porta = I
Enable1 = 0
Waitms 10
Enable1 = 1
Next I

For I = 0 To 11
Portc = I
Enable2 = 0
Waitms 10
Enable2 = 1
Next I
Call Wait_and_get(0)
Loop
'ende lauflicht 2

Programmr:
R1 = 255
Goto Standby

'/////////////////Funktion zum RC5 empfangen und warten\\\\\\\\\\\\\\\
'Sub zum empfangen und warten
Sub Wait_and_get(byval Ms As Integer)
Getrc5(ir_address , Ir_command) 'Empfangen

'Wenn was empfangen dann reagieren
If Ir_address = 0 Then
Ir_command = Ir_command And &B01111111 'entfernt das togglebit

If Ir_command = 17 Then Goto Programm1
If Ir_command = 18 Then Goto Programm2
If Ir_command = 19 Then Goto Programm3
If Ir_command = 20 Then Goto Programmr
' If Ir_command = irgendwas Then Goto Standby
End If

Waitms Ms 'warten
End Sub


'//////////Interupthandler Timer0 <Start>\\\\\\\\\\
Tim0_isr:

If Z = 0 Then 'Gewnschte Ausgabewerte an
Ri1 = R1 'Hilfsregister bergeben
Gi1 = G1
Bi1 = B1
Z = 255
End If

Z = Z - 1

'PWM Kanļæ½e

'RGB LEDs
If Ri1 > 0 Then
Portd.6 = 0
Else
Portd.6 = 1
End If
Decr Ri1
If Ri1 = 255 Then Ri1 = 0

If Gi1 > 0 Then
Portc.7 = 0
Else
Portc.7 = 1
End If
Decr Gi1
If Gi1 = 255 Then Gi1 = 0

If Bi1 > 0 Then
Portc.6 = 0
Else
Portc.6 = 1
End If
Decr Bi1
If Bi1 = 255 Then Bi1 = 0

Return
'//////////Interupthandler Timer0 <Ende>\\\\\\\\\\


Langsam überleg ich schon es einfach in die Tonne zu werfen, aber ist ist ja so gut wie fertig.

Hier mal der Schaltplan, kann es sein das es an den transen liegt?
War schonmal einer kaputt.
http://dastefan.da.funpic.de/Srv/sch.JPG