Forum: Mikrocontroller und Digitale Elektronik Problem mit einer kleinen Software


von Markus B. (Firma: Home) (sukramb)


Lesenswert?

Hallo

Ich habe in Bascom folgende kleine Software geschrieben

siehe Anhang

Sie läuft einwandfrei für ca. 2-5 Minuten, selbst die Bedienung per PC
läuft in dieser zeit anstandslos, aber leider kommt es dann dazu, das 
sich der µC auf hängt und auf dem LCD nur noch müll steht, ich bin jetzt 
schon seid gestern am suchen... aber habe keine Idee mehr.

Vielleicht möchte sich ja mal einer von euch erbarmen und einmal drüber 
schauen

mfg

Markus

Anhang:

$regfile = "m88pdef.dat"
$crystal = 20000000
$hwstack = 80
$swstack = 60
$framesize = 40
$baud = 19200


Enable Interrupts

'' RS232 Krams
Dim Akey As Byte
Dim Inputstring As String * 32


Dim Korr As Single

Dim Lm As Word
Dim Volt As Single
Dim Temp As Single



Dim Ceversion As String * 8
Ceversion = "0.2"

Config Pind.2 = Input
Config Pind.3 = Input
Config Pind.4 = Input
Config Pinb.0 = Input

Config Pind.5 = Output
Config Pinb.2 = Output
Config Pinb.1 = Output
Config Portd.6 = Output

Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , 
Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5       'Display Parameter
Config Lcd = 20 * 4                                         'config LCD
Cursor Off

Config Timer2 = Pwm , Compare A Pwm = Clear Up , Prescale = 1
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm 
= Clear Up , Prescale = 1
Config Timer0 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear 
Up , Prescale = 8

Config Watchdog = 2048                                      'Timeout = 2 
Sekunden
Start Watchdog
Do

 'Command to station
 Print #1 , "*";
 Waitms 10
 'Read 7 pieces of data terminated by CR
 For I = 1 To 7 : Input #2 , S(i) : Next I
 .....
Reset Watchdog


Tup Alias Pind.3
Config Tup = Input
Tup = 1

Tdown Alias Pind.4
Config Tdown = Input
Tdown = 1

Tesc Alias Pinb.0
Config Tesc = Input
Tesc = 1

Tenter Alias Pind.2
Config Tenter = Input
Tenter = 1


Waitms 20

Config Adc = Single , Prescaler = Auto , Reference = Avcc

Start Adc

Dim Softtimer As Long
Softtimer = 0

Dim Softtimer2 As Long
Softtimer2 = 0

Dim Softtimer3 As Long
Softtimer3 = 0

Dim Softtimer4 As Long
Softtimer4 = 0

Dim Softtimer5 As Long
Softtimer5 = 0

Dim Softtimer6 As Long
Softtimer6 = 0

Dim Softtimer7 As Long
Softtimer7 = 0

Dim Displaytimer As Long
Displaytimer = 100000

Dim Command_a As String * 1
Dim Command_b As String * 3

Dim Pwmtmp As Byte
Dim Tmp As Long
Dim Tmp2 As Integer
Dim Tmp3 As Byte

Dim Ee_ersterstart As Eram Byte
Dim Ee_kuehlung As Eram Byte
Dim Ee_heizung As Eram Byte
Dim Ee_luefter As Eram Byte
Dim Ee_kontrast As Eram Byte
Dim Ee_ledback As Eram Byte

Tmp3 = Ee_ersterstart
If Tmp3 > 100 Then
   Ee_kontrast = 150
   Ee_ledback = 100
   Ee_kuehlung = 0
   Ee_heizung = 0
   Ee_luefter = 0
   Ee_ersterstart = 0
End If

Tmp3 = Ee_kontrast
Pwm0b = Tmp3                                                'Kontrast 
PWM auf 150 (max.255 / min 0 )
Tmp3 = Ee_ledback
Pwm1b = Tmp3                                                'LED 
Hintergrundbeleuchtung 0 - 100
Tmp3 = Ee_kuehlung
Pwm1a = Tmp3                                                'Peltier PWM 
0-255
Tmp3 = Ee_heizung
Pwm0a = Tmp3                                                'Heizung PWM 
0-255
Tmp3 = Ee_luefter
Pwm2a = Tmp3                                                ' Lüfter PWM 
0-255

Dim Lastval_kuehlung As Byte
Dim Lastval_heizung As Byte
Dim Lastval_luefter As Byte
Dim Lastval_kontrast As Byte
Dim Lastval_ledback As Byte

Lastval_kontrast = Ee_kontrast
Lastval_kuehlung = Ee_kuehlung
Lastval_ledback = Ee_ledback
Lastval_heizung = Ee_heizung
Lastval_luefter = Ee_luefter

' Programm-State steuert den allgemeinen Programmzustand
' Dabei ist State 1 für die Anzeige vorgesehen während
' State 2 für eine zu erwartende Eingabe ist
Dim State As Byte
State = 1

Dim Aktivevalue As Byte
Aktivevalue = 0

' Displaystate steuert die aktuelle Bildschirmanzeige
Dim Displaystate As Byte
Displaystate = 1

Dim Displaysaved As Bit
Displaysaved = 0



Cls

Locate 1 , 1
Lcd "    Cooled EOS     "
Locate 2 , 1
Lcd "      Manager       "
Locate 3 , 1
Lcd "                    "
Locate 4 , 1
Lcd " www.themilkyway.de "
Waitms 1500

Cls

Locate 1 , 1
Lcd "    Hallo Markus    "
Locate 2 , 1
Lcd "   Clear Sky  :)  "
Locate 4 , 1
Lcd " www.themilkyway.de "
Waitms 2500

Cls



' Endlosschleife Start
Do

   ' FTDI Kommunikation. mit jedem Prozessortick wird
   ' geschaut, ob ein CHAR im Eingang der RS232 Schnittstelle
   ' wartet. Solange es nicht 13 (ENTER) ist, wird das empfangene
   ' Char an Inputstring angehangen. Kommt irgendwann 13 (ENTER),
   ' so wird die Eingabe geparsed.
   Akey = Inkey()
   If Akey <> 0 Then

      ' ENTER empfangen
      If Akey = 13 Then

         ' Überschüssige Zeichen (Leerzeichen, ...) abfangen
         Inputstring = Ltrim(inputstring)
         Inputstring = Rtrim(inputstring)

         ' Hi - Handshake
         If Inputstring = "hi" Then
            Print "TMWCEM1"
            Cls
            Softtimer2 = 0
            Displaystate = 3
            Displaytimer = 1000001
            Print "Z" ; Lastval_kuehlung ; ";" ; Lastval_heizung ; ";" ; 
Lastval_luefter ; ";" ; Lastval_kontrast ; ";" ; Lastval_ledback

         Elseif Inputstring = "sv" Then
            Ee_kuehlung = Lastval_kuehlung
            Ee_heizung = Lastval_heizung
            Ee_luefter = Lastval_luefter
            Ee_kontrast = Lastval_kontrast
            Ee_ledback = Lastval_ledback

         ' Sonderbefehl 'dimm' dimmt das Display
         Elseif Inputstring = "di" Then
            Softtimer4 = 1

         ' Sonderbefehl 'show' blendet das Display ein
         Elseif Inputstring = "sh" Then
            Softtimer5 = 1

         ' Sonderbefehl "Version" gibt die Version (Ceversion) zurück.
         Elseif Inputstring = "ve" Then
            Print "V" ; Ceversion

         Elseif Inputstring = "gT" Then
            Lm = Getadc(07)
            Volt = Lm * 40                                  ' 5 ist die 
Spannung des uControllers
            Volt = Volt / 8192                              ' Umrechnung 
des ADV Ports in Volt
            Korr = 0
            Temp = Volt - 3.75                              ' Volt 
Umrechnung in Temperatur
            Temp = Temp / 0.01
            Temp = Temp + 100
            Temp = Temp + Korr
            Tmp2 = Temp
            Print "T" ; Tmp2

         Else

           ' Erster Buchstabe des Empfangenen ist der Befehl
           Command_a = Left(inputstring , 1)

           ' Folgender Teil des Empfangenen ist ein Parameter / eine 
Value
           Command_b = Mid(inputstring , 2 , 3)
           Command_b = Ltrim(command_b)
           Command_b = Rtrim(command_b)

           ' Bei Befehl K (Kühlung) diese auf VALUE setzen
           If Command_a = "K" Then
                 Pwmtmp = Val(command_b)
                 Lastval_kuehlung = Pwmtmp
                 Pwm1a = Pwmtmp

           ' Bei Befehl H (Heizung) diese auf VALUE setzen
           Elseif Command_a = "H" Then
                 Pwmtmp = Val(command_b)
                 Lastval_heizung = Pwmtmp
                 Pwm0a = Pwmtmp

           ' Bei Befehl L (Lüftung) diese auf VALUE setzen
           Elseif Command_a = "L" Then
                 Pwmtmp = Val(command_b)
                 Lastval_luefter = Pwmtmp
                 Pwm2a = Pwmtmp

           ' Bei Befehl O (Kontrast) diese auf VALUE setzen
           Elseif Command_a = "O" Then
                 Pwmtmp = Val(command_b)
                 Lastval_kontrast = Pwmtmp
                 Pwm0b = Pwmtmp

           ' Bei Befehl B (LED Backlight) diese auf VALUE setzen
           Elseif Command_a = "B" Then
                 Pwmtmp = Val(command_b)
                 Lastval_ledback = Pwmtmp
                 Pwm1b = Pwmtmp

           ' Update - Alles Values zurücksenden
           Elseif Command_a = "U" Then
              Print "Z" ; Lastval_kuehlung ; ";" ; Lastval_heizung ; ";" 
; Lastval_luefter ; ";" ; Lastval_kontrast ; ";" ; Lastval_ledback

           ' Konnte endgültig kein Befehl erkannt werden, wird
           ' eine Fehlermeldung zurückgegeben.
           Else
              Print "UNKNOWN '" ; Inputstring ; "'"
           End If

         End If

         ' Empfangsvariable wieder leeren
         Inputstring = ""


      ' Es wurde KEIN ENTHER empfangen
      Else

         ' Empfangenes Zeichen der Empfangsvariable anhängen
         Inputstring = Inputstring + Chr(akey)

      End If

   End If

   ' Displaytimer regelt vernünftige Displayausgaben
   If Displaytimer > 100000 Then

       ' Diese Displayausgabe nur im State 1
       If State = 1 Then

           ' Ausgabe Kühlung bei Displaystate 1
           If Displaystate = 1 Then

              Tmp = Lastval_kuehlung * 100
              Tmp = Tmp / 255

              Locate 1 , 1
              Lcd "Kuehlung:";
              Locate 2 , 1
              Lcd "  " ; Tmp ; " %   "

           ' Ausgabe Heizung bei Displaystate 1
              Tmp = Lastval_heizung * 100
              Tmp = Tmp / 255

              Locate 1 , 10
              Lcd "  Heizung:";
              Locate 2 , 10
              Lcd "    " ; Tmp ; " %  "

           ' Ausgabe Lüftung bei Displaystate 1
              Tmp = Lastval_luefter * 100
              Tmp = Tmp / 255

              Locate 3 , 1
              Lcd "Lueftung:";
              Locate 4 , 1
              Lcd "  " ; Tmp ; " %    "

           ' Ausgabe Temp bei Displaystate 1
              Lm = Getadc(07)

              Volt = Lm * 40                                ' 5 ist die 
Spannung des uControllers
              Volt = Volt / 8192                            ' Umrechnung 
des ADV Ports in Volt

              Korr = 0

              Temp = Volt - 3.75                            ' Volt 
Umrechnung in Temperatur
              Temp = Temp / 0.01
              Temp = Temp + 100
              Temp = Temp + Korr

              Tmp2 = Temp

              Locate 3 , 10
              Lcd "  Temp:"
              Locate 4 , 10
              Lcd "    " ; Tmp2 ; " C  "

           ' Ausgabe Werbung bei Displaystate 2
           ' und zurücksetzen auf erstes Displaystate
           Elseif Displaystate = 2 Then

              Locate 1 , 1
              Lcd "    Coolead EOS     "
              Locate 2 , 1
              Lcd "      Manager       "
              Locate 3 , 1
              Lcd "                    "
              Locate 4 , 1
              Lcd " www.themilkyway.de "

           ' Ausgabe Verbindungsinfo
           Elseif Displaystate = 3 Then

              Locate 2 , 1
              Lcd " Mit Computer     "
              Locate 3 , 1
              Lcd " verbunden..      "

           End If

       Elseif State = 2 Then

         Locate 1 , 1
         Lcd "Einstellen:         "

         If Aktivevalue = 1 Then
            Tmp = Lastval_kuehlung * 100
            Tmp = Tmp / 255
            Locate 2 , 1
            Lcd "Kuehlung - " ; Tmp ; " %  "

         Elseif Aktivevalue = 2 Then
            Tmp = Lastval_heizung * 100
            Tmp = Tmp / 255
            Locate 2 , 1
            Lcd "Heizung - " ; Tmp ; " %  "


         Elseif Aktivevalue = 3 Then
            Tmp = Lastval_luefter * 100
            Tmp = Tmp / 255
            Locate 2 , 1
            Lcd "Lueftung - " ; Tmp ; " %  "

         Elseif Aktivevalue = 4 Then
            Tmp = Lastval_kontrast * 100
            Tmp = Tmp / 255
            Locate 2 , 1
            Lcd "Kontrast - " ; Tmp ; " %  "

         Elseif Aktivevalue = 5 Then
            Tmp = Lastval_ledback
            Locate 2 , 1
            Lcd "LED-Backlight     "
            Locate 3 , 1
            Lcd " " ; Tmp ; " %    "

         Elseif Aktivevalue = 6 And Displaysaved = 0 Then
            Locate 1 , 17
            Lcd " Ja"
            Locate 3 , 1
            Lcd "als Standard    "
            Locate 4 , 1
            Lcd " speichern?     "
            Locate 4 , 16
            Lcd "Nein"

         Elseif Displaysaved = 1 Then
            Locate 1 , 17
            Lcd "   "
            Locate 2 , 1
            Lcd " Erfolgreich    "
            Locate 3 , 1
            Lcd " gespeichert!   "


         End If

       End If

       Displaytimer = 0

   End If

   ''''''''''''' TODOOO ''''''''''''''''''''''''''''''''''''''''''''''''
   ' Hier muss auf Eingabe durch die Buttons geprüft werden.
   ' Sobald ein Button gedrückt wird, wird State 2 aktiv.
   ' Der Displaystate bleibt bestehen und ändert sich nicht,
   ' bis Softtimer3, der durch State 2 aktiviert wurde,
   ' tickt. Bei jeder weiteren Eingabe muss Softtimer3 und Displaytimer
   ' auf 0 zurückgesetzt werden.  Wenn Softtimer 3 tickt,
   ' wechselt die Anwendung wieder auf State 1 und wechselt
   ' wieder das Display durch.
   ' Mögliche implementierung: UP und DOWN ändern Displaystate
   '                           LEFT und RIGHT ändern Value entsprechend
   '                           des Displaystates.
   ''''''''''''' TODOOO ''''''''''''''''''''''''''''''''''''''''''''''''

   ' Button-Erkennung... mehr als 100 ticks gedrückt = Aktion
   If Tup = 0 Or Tdown = 0 Or Tesc = 0 Or Tenter = 0 Then
      Incr Softtimer6
      If Softtimer6 > 5000 Then

         Softtimer7 = 0

         ' Button wurde lange genug gedrückt für eine einzige Aktion

         '' Wird ESC gedrückt, wird der Einstellungsmodus verlassen
         '' Rückkehr zu Displaystate 1 und so
         If Tesc = 0 Then
            'Displaystate = 1
            State = 1
            Aktivevalue = 0
            Cls
            Displaytimer = 100000
            Displaysaved = 0
            ' Update an den PC senden
            Print "Z" ; Lastval_kuehlung ; ";" ; Lastval_heizung ; ";" ; 
Lastval_luefter ; ";" ; Lastval_kontrast ; ";" ; Lastval_ledback
         End If

         '' Wird Enter gedrückt, wird der aktive Wert gewechselt
         If Tenter = 0 Then
            Incr Aktivevalue
            If Aktivevalue > 6 Then
               Aktivevalue = 1
            End If
            State = 2
            Cls
            Displaytimer = 100000
            Displaysaved = 0                                ' Display 
auslösen
         End If

         If Tup = 0 Or Tdown = 0 Then

            ' Kühlung
            If Aktivevalue = 1 Then

               Pwmtmp = Pwm1a
               If Tup = 0 Then
                  If Pwmtmp < 255 Then
                     Pwmtmp = Pwmtmp + 5
                     If Pwmtmp > 255 Then
                        Pwmtmp = 255
                     End If
                  End If
               Elseif Tdown = 0 Then
                  If Pwmtmp > 0 Then
                     Pwmtmp = Pwmtmp - 5
                     If Pwmtmp < 0 Then
                        Pwmtmp = 0
                     End If
                  End If
               End If

               Lastval_kuehlung = Pwmtmp
               Pwm1a = Pwmtmp
               Displaytimer = 100000

            ' Heizung
            Elseif Aktivevalue = 2 Then

               Pwmtmp = Pwm0a
               If Tup = 0 Then
                  If Pwmtmp < 255 Then
                     Pwmtmp = Pwmtmp + 5
                     If Pwmtmp > 255 Then
                        Pwmtmp = 255
                     End If
                  End If
               Elseif Tdown = 0 Then
                  If Pwmtmp > 0 Then
                     Pwmtmp = Pwmtmp - 5
                     If Pwmtmp < 0 Then
                        Pwmtmp = 0
                     End If
                  End If
               End If

               Lastval_heizung = Pwmtmp
               Pwm0a = Pwmtmp
               Displaytimer = 100000

            ' Lüftung
            Elseif Aktivevalue = 3 Then

               Pwmtmp = Pwm2a
               If Tup = 0 Then
                  If Pwmtmp < 255 Then
                     Pwmtmp = Pwmtmp + 5
                     If Pwmtmp > 255 Then
                        Pwmtmp = 255
                     End If
                  End If
               Elseif Tdown = 0 Then
                  If Pwmtmp > 0 Then
                     Pwmtmp = Pwmtmp - 5
                     If Pwmtmp < 0 Then
                        Pwmtmp = 0
                     End If
                  End If
               End If

               Lastval_luefter = Pwmtmp
               Pwm2a = Pwmtmp
               Displaytimer = 100000

            ' Kontrast
            Elseif Aktivevalue = 4 Then

               Pwmtmp = Pwm0b
               If Tup = 0 Then
                  If Pwmtmp < 255 Then
                     Pwmtmp = Pwmtmp + 5
                     If Pwmtmp > 255 Then
                        Pwmtmp = 255
                     End If
                  End If
               Elseif Tdown = 0 Then
                  If Pwmtmp > 0 Then
                     Pwmtmp = Pwmtmp - 5
                     If Pwmtmp < 0 Then
                        Pwmtmp = 0
                     End If
                  End If
               End If

               Lastval_kontrast = Pwmtmp
               Pwm0b = Pwmtmp
               Displaytimer = 100000

            ' LED Backlight
            Elseif Aktivevalue = 5 Then

               ' Max 100

               Pwmtmp = Pwm1b
               If Tup = 0 Then
                  If Pwmtmp < 100 Then
                     Pwmtmp = Pwmtmp + 5
                     If Pwmtmp > 100 Then
                        Pwmtmp = 100
                     End If
                  End If
               Elseif Tdown = 0 Then
                  If Pwmtmp > 0 Then
                     Pwmtmp = Pwmtmp - 5
                     If Pwmtmp < 0 Then
                        Pwmtmp = 0
                     End If
                  End If
               End If

               Lastval_ledback = Pwmtmp
               Pwm1b = Pwmtmp
               Displaytimer = 100000

            ' Speichern
            Elseif Aktivevalue = 6 Then

               If Tup = 0 Then
                  Ee_kuehlung = Lastval_kuehlung
                  Ee_heizung = Lastval_heizung
                  Ee_luefter = Lastval_luefter
                  Ee_kontrast = Lastval_kontrast
                  Ee_ledback = Lastval_ledback
                  Displaysaved = 1
                  Displaytimer = 100000
                  Cls
               Elseif Tdown = 0 Then
                  'Displaystate = 1
                  State = 1
                  Aktivevalue = 0
                  Cls
                  Displaytimer = 100000
                  Displaysaved = 0
                  Print "Z" ; Lastval_kuehlung ; ";" ; Lastval_heizung ; 
";" ; Lastval_luefter ; ";" ; Lastval_kontrast ; ";" ; Lastval_ledback
               End If

               Displaytimer = 100000

            End If

         End If

         '' Wird UP gedrückt, wird ein entsprechender Wert Incrementiert

         '' Wird Down gedrückt, wir ein entsprechender Wert 
decrementiert

         Softtimer6 = 0
      End If
   Else
      Softtimer6 = 0
   End If

   ' Nach langer Pause Tastendruck wieder zurückstellen
   If State = 2 Then
      Incr Softtimer7
      If Softtimer7 > 200000 Then
         State = 1
         Aktivevalue = 0
         Displaysaved = 0
         Cls
         Displaytimer = 100000
         Print "Z" ; Lastval_kuehlung ; ";" ; Lastval_heizung ; ";" ; 
Lastval_luefter ; ";" ; Lastval_kontrast ; ";" ; Lastval_ledback
      End If
   End If

   ' Softtimer 1 auslösung - Werbung einblenden
   If Softtimer > 3004000 Then
      Softtimer = 0
      Softtimer2 = 0
      Displaystate = 2
      Displaytimer = 1000001
   End If

   ' Softtimer2 setzt den Displaystate wieder zurück
   If Softtimer2 > 200000 Then
      If Displaystate <> 1 Then
         Displaystate = 1
         Displaytimer = 100001
         Cls
      End If
      Softtimer2 = 0

   End If

   ' Softtimer3 setzt den STATE nach kurzer Zeit auf 1 zurück
   If Softtimer3 > 4000000 Then

      State = 1
      Softtimer3 = 0

   End If

   ' Softtimer4 dimmt das Display
   If Softtimer4 > 100 Then
      Pwmtmp = Pwm1b
      If Pwmtmp > 0 Then
         Decr Pwmtmp
         Pwm1b = Pwmtmp
         Softtimer4 = 1
      Else
         Softtimer4 = 0
      End If
      Lastval_ledback = Pwmtmp
   End If

   ' Softtimer5 blendet das Display ein
   If Softtimer5 > 100 Then
      Pwmtmp = Pwm1b
      If Pwmtmp < 100 Then
         Incr Pwmtmp
         Pwm1b = Pwmtmp
         Softtimer5 = 1
      Else
         Softtimer5 = 0
      End If
      Lastval_ledback = Pwmtmp
   End If

   ' Softtimer 1 und 2 und Displaytimer zählen die ganze Zeit
   Incr Softtimer
   Incr Softtimer2
   Incr Displaytimer

   ' Wenn State 2 aktiv ist, zählt der Softtimer hoch
   If State = 2 Then
      Incr Softtimer3
   End If

   ' Wenn Softtimer 4 aktiviert wurde, erhöhen
   If Softtimer4 > 0 Then
      Incr Softtimer4
   End If

   ' Wenn Softtimer 5 aktiviert wurde, erhöhen
   If Softtimer5 > 0 Then
      Incr Softtimer5
   End If



Loop

End

von Kai S. (hugstuart)


Lesenswert?

Der Fehler liegt in Zeile 181.

von Michael W. (Gast)


Lesenswert?

@ Markus B. (Firma: Home) (sukramb)

Hast Du im Abschnitt 'Wichtige Regeln - erst lesen, dann posten!' den 
Teil:
'Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang' 
nicht gelesen oder ihn nicht verstanden???

Oh man oh man...

von Chr. M. (snowfly)


Lesenswert?

kann es sein dass du den Watchdog in der Main Loop nicht mehr resetest?
und warum gibt es 2x Do

EDIT:
Nachdem der Watchdog wohl zurückgesetzt wird
vermute ich einen Stack overflow wegen der zwei "Do"

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.