PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ungewollter Programm-Reset



BoondockDuck
01.07.2008, 16:43
moin moin
Ich bin mal wieder mit meinen DotMatrix-LED-Matrizen da.
Für die, die die letzten Threads nicht gelesen haben, hier nochmal schnell ein überblick:

Ich steuere vier 5*7 LED-Matrizen mit vier Max7221 über eine 64-Bitfolge (Pro Max 16 Bit) an. (Sub Max7221datenout)

String "Text" wird gelesen, die Einzelzeichen werden aus der Datenbank (mit 6 Bytes / Eintrag) gelesen. Jedes Byte wird zum Array dat(372) hinzugefügt. Sprich ein Zeichen benötigt 6 Plättze im Array.
Beispiel: String "Hallo" beginnt H(Ascii : 72). Abzüglich 32 ist das die 40. Zeile in der Datenbank.
Usw... naja ihr wisst ja schon wie das funktioniert :^o


Ich habe 3 Taster angeschlossen. Zwei Taster verändern ein Byte zwischen den Werten 32 und 127. Das steht für die Ascii-Werte die auch in der Datenbank vorhanden sind.
Das funktioniert über die Variable "Zeichen" als Byte die durch einen Taster um 1 erhöht (Sub Schalten3), durch den anderen Taster um 1 verringert wird (Sub Schalten2). ("Zeichen" kleiner als 32 bzw. größer als 127 habe ich mit den if-funktionen vermieden).

Mit dem dritten Taster wird das "Zeichen" über string(1,zeichen) an den String Text angehängt. (Sub Schalten1).
[ Wird der dritte taster nochmals gedrückt wird "Text" zurückgesetzt, d.h. die Anzeige gelöscht. (Damit man sieht obs funktioniert wird sie im Code zu Text = "x" zurückgesetzt). ]
Nach dem Anhängen des neuen Zeichens wird Text erneut gelesen, die Zeichen aus der Datenbank übernommen und dann beginnt das anzeigen auf den Matritzen von neuem.
D.h. dass während man ein Zeichen mit Taster1 und Taster2 auch nichts auf den Matrizen ausgegeben wird. (Ich hatte das ganze schon versucht parallel zueinander laufen zu lassen, nur irgendwie ging das mit der Datenausgabe und dem Debounce schief und hat nicht immer geklappt.)

Also im Prinzip ists ja eine einfache Sache. Zwei Taster wählen ein Zeichen aus, der dritte fügt es einem String hinzu.


Jetzt das Problem: Das Programm resettet sich regelmäßig. Nach ca. 20-25 mal drücken der Taster hängt das LCD kurz, Zeigt etwas Mist an. Dannach läuft das Programm wieder von vorne durch.

Ich habe schon alles mögliche getestet.
Hängt es vielleicht mit goto und gosub zusammen? Ich hatte anfänglich fast nur gosub geschrieben, dann hat es sich noch schneller resettet.
Oder liegt es an dem Debounce?

Ansonsten verstehe ich nicht warum sich das Programm resettet.
Das ganze ist vermutlich nicht super intelligent programmiert, aber ich bin ja auch AVR-Neuling und froh dass ich es soweit geschafft habe.


So... also lange Rede, noch längerer Code.
Ich hoffe ihr erbarmt auch aber trotzdem.



$regfile "m168def.dat"
$crystal = 16000000

Config Portd.5 = Output ' load(cs)
Config Portd.4 = Output ' clk
Config Portb.2 = Output ' din

Config Portc.1 = Output ' led
Config Portc.0 = Input ' taster
Config Portd.2 = Input ' taster
Config Portb.1 = Input ' taster

Led Alias Portc.1

Max_cs Alias Portd.5
Max_din Alias Portb.2
Max_clk Alias Portd.4

Set Max_cs ' cs, din, clk = high
Set Max_din
Set Max_clk

Set Led
Set Portc.0
Set Portd.2
Set Portb.1

Config Debounce = 35

Config Lcd = 16 * 1a
Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.5 , Db6 = Portc.3 , Db7 = Portb.3 , E = Portd.7 , Rs = Portd.6
Initlcd
Cls
Lcd "BAP"

Declare Sub Max7221datenout(d As Word , E As Word , F As Word , G As Word)
Declare Sub Max7221init
Declare Sub Textlesen
Declare Sub Schreiben
Declare Sub Schalten
Declare Sub Schalten1
Declare Sub Schalten2
Declare Sub Schalten3

Dim Led_operation As Word $prog &HFF , &HFF , &HD7 , &HF9 ' generated. Take care that the chip supports all fuse bytes.
Dim Zeichen As Byte
Dim Text As String * 62
Dim Loeschen As Byte
Dim A As Word , B As Word , C As Word , D As Word , E As Word , F As Word
Dim Beginn_zeichen As Word , Ende_zeichen As Word , Db_zeiger As Word
Dim Bz As Word
Dim Tl As Byte
Dim Ez As Byte
Dim Dat(372) As Byte
Dim Einzelzeichen As String * 1

Zeichen = 32
Loeschen = 0
Text = "BAP"

Declare Function Reversed(source As Byte) As Byte


Gosub Max7221init


Goto Textlesen 'call

''''''''''''''''''''''''''''''''''

Sub Schreiben
Do
For A = 1 To B

C = &B0000000000000000
D = &B0000000000000000
E = &B0000000000000000
F = &B0000000000000000
Call Max7221datenout(c , D , E , F)

C = &B0000000100000000 + Dat(a + 1)
D = &B0000000100000000 + Dat(a + 6)
E = &B0000000100000000 + Dat(a + 12)
F = &B0000000100000000 + Dat(a + 17)
Call Max7221datenout(c , D , E , F)

C = &B0000001000000000 + Dat(a + 2)
D = &B0000001000000000 + Dat(a + 7)
E = &B0000001000000000 + Dat(a + 13)
F = &B0000001000000000 + Dat(a + 18)
Call Max7221datenout(c , D , E , F)

C = &B0000001100000000 + Dat(a + 3)
D = &B0000001100000000 + Dat(a + 8)
E = &B0000001100000000 + Dat(a + 14)
F = &B0000001100000000 + Dat(a + 19)
Call Max7221datenout(c , D , E , F)

C = &B0000010000000000 + Dat(a + 4)
D = &B0000010000000000 + Dat(a + 9)
E = &B0000010000000000 + Dat(a + 15)
F = &B0000010000000000 + Dat(a + 20)
Call Max7221datenout(c , D , E , F)

C = &B0000010100000000 + Dat(a + 5)
D = &B0000010100000000 + Dat(a + 10)
E = &B0000010100000000 + Dat(a + 16)
F = &B0000010100000000 + Dat(a + 21)
Call Max7221datenout(c , D , E , F)

Waitms 100
Debounce Pinc.0 , 0 , Schalten1 ', Sub
Debounce Pind.2 , 0 , Schalten2 ', Sub
Debounce Pinb.1 , 0 , Schalten3 ', Sub
Next A

Loop

End Sub


Sub Textlesen
Tl = Len(text)
B = 1

For A = 1 To Tl
Einzelzeichen = Mid(text , A , 1)
Ez = Asc(einzelzeichen)

Bz = Ez - 32 'ASCII-Table ohne die ersten 32 Eintraege

Beginn_zeichen = Bz * 6 '*6 da je 6 datensätze pro eintrag
Ende_zeichen = Beginn_zeichen + 5

For Db_zeiger = Beginn_zeichen To Ende_zeichen
Dat(b) = Lookup(db_zeiger , Zeichensatz) 'db_zeiger: position im Zeichensatz
Dat(b) = Reversed(dat(b))
Incr B
Next Db_zeiger
Next A

Print "lesen done - " ; "Text: " ; Text

Goto Schreiben 'gosub
End Sub


Sub Max7221init
Led_operation = &B0000110000000000 ' shutdown mode normal operation
Call Max7221datenout(led_operation , Led_operation , Led_operation , Led_operation)
Led_operation = &B0000110000000001 ' shutdown mode normal operation
Call Max7221datenout(led_operation , Led_operation , Led_operation , Led_operation)
Led_operation = &B0000100100000000 ' decode mode code b for digit 7-0
Call Max7221datenout(led_operation , Led_operation , Led_operation , Led_operation)
Led_operation = &B0000101000001100 ' intensity | &H0A01 = 2/16 | &H0A09 = 10/16 | &H0A0F = 15/16(max on)
Call Max7221datenout(led_operation , Led_operation , Led_operation , Led_operation)
Led_operation = &B0000101100000111 ' scan limit digit 0-7
Call Max7221datenout(led_operation , Led_operation , Led_operation , Led_operation)

Print "init done"
Return
End Sub


Sub Max7221datenout(d As Word , E As Word , F As Word , G As Word)
Max_cs = 0
Shiftout Max_din , Max_clk , G , 1 , 16
Shiftout Max_din , Max_clk , F , 1 , 16
Shiftout Max_din , Max_clk , E , 1 , 16
Shiftout Max_din , Max_clk , D , 1 , 16
Max_cs = 1
End Sub

'''''''''''''''''''''''''''''''''''''''''


Sub Schalten
Toggle Led

If Loeschen = 2 Then
Text = "x" '"x" damit man weiterhin sieht ob die Matrizen noch angesteuert werden.
Cls ' Im fertigen Programm soll hier Text = "" sein.
Lcd "text geloescht"
Print "text geloescht"
Loeschen = 0
Print Text
Goto Textlesen
Else
Goto Textlesen
End If

End Sub


Sub Schalten1
Text = Text + String(1 , Zeichen)
Incr Loeschen
Goto Schalten
End Sub


Sub Schalten2
Loeschen = 0
If Zeichen > 32 Then
Decr Zeichen
Else
Zeichen = 127
End If
Cls
Lcd "add: " ; Chr(zeichen) ; " (" ; Zeichen ; ")"
'Waitms 100
Do
Debounce Pinc.0 , 0 , Schalten1 , Sub
Debounce Pind.2 , 0 , Schalten2 , Sub
Debounce Pinb.1 , 0 , Schalten3 , Sub
Waitms 45
Loop
End Sub


Sub Schalten3
Loeschen = 0
If Zeichen < 127 Then
Incr Zeichen
Else
Zeichen = 32
End If
Cls

Lcd "add: " ; Chr(zeichen) ; " (" ; Zeichen ; ")"
'Waitms 100
Do
Debounce Pinc.0 , 0 , Schalten1 , Sub
Debounce Pind.2 , 0 , Schalten2 , Sub
Debounce Pinb.1 , 0 , Schalten3 , Sub
Waitms 45
Loop
End Sub


'''''''''''''''''''''''''''''''''''''''''




Function Reversed(byval Source As Byte) As Byte
Local Dest As Byte
Dest.0 = Source.6
Dest.1 = Source.5
Dest.2 = Source.4
Dest.3 = Source.3
Dest.4 = Source.2
Dest.5 = Source.1
Dest.6 = Source.0
Dest.7 = Source.7
Reversed = Dest
End Function

''''''''''''''''''''''''''''''''''

End 'end program




Zeichensatz: 'ASCII-Table ohne die ersten 32 Eintraege
Data 0 , 0 , 0 , 0 , 0 , 0 'Leerzeichen
Data 0 , 0 , 6 , 95 , 6 , 0 '!
Data 0 , 7 , 3 , 0 , 7 , 3 '""
Data 0 , 36 , 126 , 36 , 126 , 36 '#
Data 0 , 36 , 43 , 106 , 18 , 0 '$
Data 0 , 6 , 9 , 9 , 6 , 0 '%
Data 0 , 54 , 73 , 86 , 32 , 80 '&
Data 0 , 0 , 7 , 3 , 0 , 0 ''
Data 0 , 0 , 62 , 65 , 0 , 0 '
Data 0 , 0 , 65 , 62 , 0 , 0 '
Data 0 , 8 , 62 , 28 , 62 , 8 '*
Data 0 , 8 , 8 , 62 , 8 , 8 '+
Data 0 , 0 , 224 , 96 , 0 , 0 ',
Data 0 , 8 , 8 , 8 , 8 , 8 '-
Data 0 , 0 , 96 , 96 , 0 , 0 '.
Data 0 , 32 , 16 , 8 , 4 , 2 '/
Data 0 , 62 , 81 , 73 , 69 , 62 '0
Data 0 , 0 , 66 , 127 , 64 , 0 '1
Data 0 , 98 , 81 , 73 , 73 , 70 '2
Data 0 , 34 , 73 , 73 , 73 , 54 '3
Data 0 , 24 , 20 , 18 , 127 , 16 '4
Data 0 , 47 , 73 , 73 , 73 , 49 '5
Data 0 , 60 , 74 , 73 , 73 , 48 '6
Data 0 , 1 , 113 , 9 , 5 , 3 '7
Data 0 , 54 , 73 , 73 , 73 , 54 '8
Data 0 , 6 , 73 , 73 , 41 , 30 '9
Data 0 , 0 , 108 , 108 , 0 , 0 ':
Data 0 , 0 , 236 , 108 , 0 , 0 ';
Data 0 , 8 , 20 , 34 , 65 , 0 '<
Data 0 , 36 , 36 , 36 , 36 , 36 '=
Data 0 , 0 , 65 , 34 , 20 , 8 '>
Data 0 , 2 , 1 , 89 , 9 , 6 '?
Data 0 , 62 , 65 , 93 , 85 , 30 '@
Data 0 , 126 , 9 , 9 , 9 , 126 'A
Data 0 , 127 , 73 , 73 , 73 , 54 'B
Data 0 , 62 , 65 , 65 , 65 , 34 'C
Data 0 , 127 , 65 , 65 , 65 , 62 'D
Data 0 , 127 , 73 , 73 , 73 , 65 'E
Data 0 , 127 , 9 , 9 , 9 , 1 'F
Data 0 , 62 , 65 , 73 , 73 , 122 'G
Data 0 , 127 , 8 , 8 , 8 , 127 'H
Data 0 , 0 , 65 , 127 , 65 , 0 'I
Data 0 , 63 , 64 , 64 , 64 , 48 'J
Data 0 , 127 , 8 , 20 , 34 , 65 'K
Data 0 , 127 , 64 , 64 , 64 , 64 'L
Data 0 , 127 , 2 , 4 , 2 , 127 'M
Data 0 , 127 , 2 , 4 , 8 , 127 'N
Data 0 , 62 , 65 , 65 , 65 , 62 'O
Data 0 , 127 , 9 , 9 , 9 , 6 'P
Data 0 , 62 , 65 , 81 , 33 , 94 'Q
Data 0 , 127 , 9 , 9 , 25 , 102 'R
Data 0 , 38 , 73 , 73 , 73 , 50 'S
Data 0 , 1 , 1 , 127 , 1 , 1 'T
Data 0 , 63 , 64 , 64 , 64 , 63 'U
Data 0 , 31 , 32 , 64 , 32 , 31 'V
Data 0 , 63 , 64 , 60 , 64 , 63 'W
Data 0 , 99 , 20 , 8 , 20 , 99 'X
Data 0 , 7 , 8 , 112 , 8 , 7 'Y
Data 0 , 97 , 81 , 73 , 69 , 67 'Z
Data 0 , 0 , 127 , 65 , 65 , 0 '[
Data 0 , 2 , 4 , 8 , 16 , 32 '\
Data 0 , 0 , 65 , 65 , 127 , 0 ']
Data 0 , 4 , 2 , 1 , 2 , 4 '^
Data 128 , 128 , 128 , 128 , 128 , 128 '
Data 0 , 0 , 3 , 7 , 0 , 0 '`
Data 0 , 32 , 84 , 84 , 84 , 120 'a
Data 0 , 127 , 68 , 68 , 68 , 56 'b
Data 0 , 56 , 68 , 68 , 68 , 40 'c
Data 0 , 56 , 68 , 68 , 68 , 127 'd
Data 0 , 56 , 84 , 84 , 84 , 8 'e
Data 0 , 8 , 126 , 9 , 9 , 0 'f
Data 0 , 24 , 164 , 164 , 164 , 124 'g
Data 0 , 127 , 4 , 4 , 120 , 0 'h
Data 0 , 0 , 0 , 125 , 64 , 0 'i
Data 0 , 64 , 128 , 132 , 125 , 0 'j
Data 0 , 127 , 16 , 40 , 68 , 0 'k
Data 0 , 0 , 0 , 127 , 64 , 0 'l
Data 0 , 124 , 4 , 24 , 4 , 120 'm
Data 0 , 124 , 4 , 4 , 120 , 0 'n
Data 0 , 56 , 68 , 68 , 68 , 56 'o
Data 0 , 252 , 68 , 68 , 68 , 56 'p
Data 0 , 56 , 68 , 68 , 68 , 252 'q
Data 0 , 68 , 120 , 68 , 4 , 8 'r
Data 0 , 8 , 84 , 84 , 84 , 32 's
Data 0 , 4 , 62 , 68 , 36 , 0 't
Data 0 , 60 , 64 , 32 , 124 , 0 'u
Data 0 , 28 , 32 , 64 , 32 , 28 'v
Data 0 , 60 , 96 , 48 , 96 , 60 'w
Data 0 , 108 , 16 , 16 , 108 , 0 'x
Data 0 , 156 , 160 , 96 , 60 , 0 'y
Data 0 , 100 , 84 , 84 , 76 , 0 'z
Data 0 , 8 , 62 , 65 , 65 , 0 '{
Data 0 , 0 , 0 , 119 , 0 , 0 '|
Data 0 , 0 , 0 , 0 , 0 , 0 '}
Data 0 , 2 , 1 , 2 , 1 , 0 '~
Data 0 , 0 , 0 , 0 , 0 , 0 '

PicNick
01.07.2008, 17:10
So, wie du sagst, könnte
$HWSTACK = 64
$SWSTACK = 64
helfen
die defaultwerte sind recht sparsam

fhs
01.07.2008, 17:18
Hallo,

ich kann nur von meinen Erfahrungen mit Assembler und C ausgehen: Dort kann ein RESET eigentlich nur aus 4 Ursachen vorkommen:

1. "echte" Reset-Quelle (z.B. PowerOn-Reset)
2. fehlende/falsche Adresse in der Interrupt-Vektor-Tabelle
3. Programmzähler läuft über das Ende des Programms hinaus, alle Flash-Zellen werden als "NOP" interpretiert, so dass schließlich wieder "vorne" (=beim RESET-Vektor) begonnen wird
4. Stack-Überlauf (kann zu "2" oder "3" führen)

Bei BASCOM wird's wohl kaum anders sein.

Gruß

Fred

Bluesmash
01.07.2008, 17:34
Ich hab das programm mal kurz überflogen. goto's solltes du wenn immer möglich verhindern, und schon gar nicht subroutinen mit goto's anspringen, sondern mit gosub sonst hast du probleme mit den rücksprungadressen oder irgendwann gibt es einen stackoverflow und der prozessor weiss gar nicht mehr wohin er springen sollte...
goto's machen den code auch sehr unübersichtlich.

Ich kann dir folgende Programmstruktur empfehlen:



...Deklarationen...

Do
--Hauptprogramm--
gosub sub1
--Code--
gosub sub2
--Code--
gosub sub3
Loop

sub1:
--Code--
return

sub2:
--Code--
gosub sub3
return

sub3:
--Code--
return


Somit hast du eine schöne gliederung und auch kein durcheinander mit den Subroutinen.

gruss bluesmash

BoondockDuck
01.07.2008, 22:10
danke soweit :)

ich habe den Code jetzt insgesamt nochmal neu strukturiert und noch ein paar Kleinigkeiten entfernt die nicht nötig sind.
Jetzt läuft die Anzeige auch parallel zum Auswählen des neuen Zeichens weiter.


@PicNick
was genau bezeichnet hwstack und swstack?
Wieviel Speicherplatz jeweis zugeordnet wird?
Ich hab mir die Erklärung im Manual durchgelesen werd daraus aber nicht ganz schlau.

Aber nach der Abänderung des Codes funktioniert er auch wenn ich hwstack und swstack nicht definiere.
Ich hab es jetzt aber trotzdem mit reingeschrieben.

PicNick
02.07.2008, 08:18
HWstack / swstack

https://www.roboternetz.de/wissen/index.php/Bascom_Inside

BoondockDuck
03.07.2008, 08:28
ok vielen Dank :)