PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Neustart bei Tastenabfrage an Port D (D.1) (UART-Probl?) M8



Finor
11.07.2005, 17:06
Hallo,

ich befasse mich seit wenigen Wochen mit der Programmierung von Microcontrollern. Mein Anfangsprojekt ist ein kleines Testboard für den ATmega8 um erstmal ein bisschen "rumzuspielen" (der ganz gewöhnliche Einstieg mit LED und Tastern eben).
Funktioniert auch bis jetzt ganz prima.

Bei meinen Versuchen bin ich jedoch nun auf ein kleines Problem gestoßen. In der Forum-Suche habe ich einen Treffer für ein scheinbar ähnliches Problem gefunden, hilft aber leider nicht weiter.

Ich benutze einen ATmega 8 mit internem Takt (1MHz), an Port B sind die obligatorischen LED angeschlossen, am Port D die Taster (gegen Masse, interne Pull-Up's).
Die Taster sollen die LED's in verschiedenen Arten ein- und ausschalten (Schalterfunktion, Tasterfunktion). Ich hoffe, die Funktion der verschiedenen Taster erschließt sich aus dem Code.


'************************************************* ************************************************** *********
'Program: Taster
'************************************************* ************************************************** *********

$regfile = "m8def.dat"
$crystal = 1000000
$baud = 19200

RESET UCR.3
RESET UCR.4

Declare Sub Taste_1 'Deklaration Unterprogramm für Taste Nr. 1
Declare Sub Taste_2 'Deklaration Unterprogramm für Taste Nr. 2
Declare Sub Taste_3 'Deklaration Unterprogramm für Taste Nr. 3
Declare Sub Taste_4 'Deklaration Unterprogramm für Taste Nr. 4
Declare Sub Taste_5 'Deklaration Unterprogramm für Taste Nr. 5
Declare Sub Taste_6 'Deklaration Unterprogramm für Taste Nr. 6
Declare Sub Taste_7 'Deklaration Unterprogramm für Taste Nr. 7
Declare Sub Taste_8 'Deklaration Unterprogramm für Taste Nr. 8
Declare Sub LED_Test(byval T1 As Integer) 'Deklaration Unterprogramm LED-Test

Dim T_1 As Bit 'Variable für Zustand der Taste Nr. 1
Dim T_2 As Bit 'Variable für Zustand der Taste Nr. 2
Dim T_3 As Bit 'Variable für Zustand der Taste Nr. 3
Dim T_4 As Bit 'Variable für Zustand der Taste Nr. 4
Dim T_5 As Bit 'Variable für Zustand der Taste Nr. 5
Dim T_6 As Bit 'Variable für Zustand der Taste Nr. 6
Dim T_7 As Bit 'Variable für Zustand der Taste Nr. 7
Dim T_8 As Bit 'Variable für Zustand der Taste Nr. 8
Dim I as Byte 'Variable für Portausgang
Dim N as Integer 'Laufvariable
Dim Taster_Nummer As Integer 'Variable für Tastennummer


Config PortD = Input 'Konfig. PortD als Eingang
Config PortB = Output 'Konfig. PortB als Ausgang
Config Debounce = 30 'Entprellzeit festlegen (ms)


PortD = &HFF 'interne Pullup's einschalten
PortB = &HFF 'Ausgänge PortB auf 1 setzen
T_1 = 0 'Variablen initialisieren
T_2 = 0
T_3 = 0
T_4 = 0
T_5 = 0
T_6 = 0
T_7 = 0
T_8 = 0

call LED_Test(300) 'Aufruf LED-Test

Do

For N = 1 To 8
Taster_Nummer = N
Select Case Taster_Nummer
Case 1 : Debounce PinD.0 , 0 , Taste_1 , Sub 'Abfrage Taste D0, Taste Nr. 1
Case 2 : Debounce PinD.1 , 0 , Taste_2 , Sub 'Abfrage Taste D1, Taste Nr. 2
Case 3 : Debounce PinD.2 , 0 , Taste_3 , Sub 'Abfrage Taste D2, Taste Nr. 3
Case 4 : Debounce PinD.3 , 0 , Taste_4 , Sub 'Abfrage Taste D3, Taste Nr. 4
Case 5 : Debounce PinD.4 , 0 , Taste_5 , Sub 'Abfrage Taste D4, Taste Nr. 5
Case 6 : Debounce PinD.5 , 0 , Taste_6 , Sub 'Abfrage Taste D5, Taste Nr. 6
Case 7 : Debounce PinD.6 , 0 , Taste_7 , Sub 'Abfrage Taste D6, Taste Nr. 7
Case 8 : Debounce PinD.7 , 0 , Taste_8 , Sub 'Abfrage Taste D7, Taste Nr. 8
End Select
Next




Loop


'*******************************************
'Unterprogramm Taste_1
'*******************************************
Sub Taste_1
If T_1 = 0 Then
T_1 = 1
PortB.0 = 0
Else
T_1 = 0
PortB.0 = 1
End If
'Waitms 100
End Sub


'*******************************************
'Unterprogramm Taste_2
'*******************************************
Sub Taste_2
PortB.1 = 0
Waitms 100
PortB.1 = 1
End Sub


'*******************************************
'Unterprogramm Taste_3
'*******************************************
Sub Taste_3
If T_3 = 0 Then
T_3 = 1
PortB.2 = 0
Else
T_3 = 0
PortB.2 = 1
End If
'Waitms 100
End Sub


'*******************************************
'Unterprogramm Taste_4
'*******************************************
Sub Taste_4
PortB.3 = 0
Waitms 100
PortB.3 = 1
End Sub


'*******************************************
'Unterprogramm Taste_5
'*******************************************
Sub Taste_5
PortB.4 = 0
Waitms 150
PortB.4 = 1
End Sub


'*******************************************
'Unterprogramm Taste_6
'*******************************************
Sub Taste_6
If T_6 = 0 Then
T_6 = 1
PortB.5 = 0
End If
End Sub


'*******************************************
'Unterprogramm Taste_7
'*******************************************
Sub Taste_7
If T_6 = 1 Then
T_6 = 0
PortB.5 = 1
End If
End Sub


'*******************************************
'Unterprogramm Taste_8
'*******************************************
Sub Taste_8
If T_8 = 0 Then
T_8 = 1
PortB.7 = 0
Else
T_8 = 0
PortB.7 = 1
End If
'Waitms 100
End Sub


'*******************************************
'Unterprogramm LED-Test
'*******************************************
Sub LED_Test(byval T1 As Integer byval)

PortB = &HFF 'alle LED's aus
Print "LED AUS!"
Waitms T1
PortB = &H00 'alle LED's an
Print "LED AN!"
Waitms T1
PortB = &HFF 'alle LED's aus
Print "LED AUS!"
Waitms T1
PortB = &H00 'alle LED's an
Print "LED AN!"
Waitms T1
PortB = &HFF 'alle LED's aus
Print "LED AUS!"
Waitms T1
PortB = &H00 'alle LED's an
Print "LED AN!"
Waitms T1
PortB = &HFF 'alle LED's aus
Print "LED AUS!"
Waitms T1

End Sub



End


Bis auf den an D.1 angeschlossenen Taster funktioniert die Schaltung. Bei Betätigung des Tasters an D.1 scheint in den meisten Fällen das Programm von vorn zu starten (Abbruch / Reset?), manchmal (eher selten) funktioniert die Tastenfunktion, zumindest solange, bis nach 2-3 maliger Betätigung wieder ein Neustart erfolgt.

Ich habe das Board schon überprüft (kein Kurzschluß, keine Unterbrechung, ...), habe die Leiterbahnen direkt am Portpin aufgetrennt und einen anderen Taster angeschlossen, habe einen anderen ATmega8 benutzt - ohne Erfolg!

In der Beschreibung zum ATmega8 und auch in der BASCOM-Hilfe steht, daß dieser Pin auch für die RS-232-Schnittstelle benutzt wird (Signal Tx -> Ausgang).
"• TXD – Port D, Bit 1
TXD, Transmit Data (Data output pin for the USART). When the USART Transmitter is enabled, this pin is configured as an output regardless of the value of DDD1."

Leider konnte ich an diesen Quellen bislang nicht finden, wie der USART Transmitter generell enabled oder disabled werden kann. Ich glaube schon, daß hier mein Problem verursacht wird.

Auch kann ich zur Zeit nicht überprüfen, ob die Angabe in der BASCOM-Hilfe
"When pins TXD and RXD are not used for RS-232 they can be used as an input or output pin.
No PRINT, INPUT or other RS-232 statement may be used in that case. The UCR register will by default not set bits 3 and 4 that enable the TXD and RXD pins for RS-232 communication. It is however reported that this not works for all chips. In this case you must clear the bits in the UCR register with the following statements:
RESET UCR.3
RESET UCR.4"
wirklich weiterhilft, da ich erst am Wochenende weiterbasteln kann.
Ich habe auch bislang noch keinen Code hier im Roboternetz gefunden, der diese Anweisungen benutzt.

Auf meinem Board ist keine zusätzliche Hardware für die RS-232-Schnittstelle vorhanden, es ist auch sonst nichts anderes an D.1 angeschlossen.

Weitere Daten:
Win XP prof. SP2, BASCOM 1.11.7.7 (vollversion), Eigenbau ISP Programmer (Parallelport)

Wäre sehr dankbar, wenn mir jemand hilfreich unter die Arme greifen könnte.

Viele Grüße

Finor

PicNick
11.07.2005, 17:14
Hi, BasCom belebt die UART durch die $BAUD Anweisung.
Du hast "Print"-Befehle drinnen. Wo sollen die hingehen ?

chr-mt
11.07.2005, 17:25
Hi,
der END Befehl muß vor der ersten SUB stehen, bei dir also hinter Loop.

Gruß
Christopher

Finor
11.07.2005, 17:29
Wow PicNick, das ging aber schnell.

Die Printbefehle nutze ich um im BASCOM-internen Simulator zu sehen, was das Programm gerade so macht. (ich habe noch kein LCD Display und noch keine Terminal-RS-232-Hardware - kommt als nächstes!)

Also die $BAUD-Anweisung weglassen und die Print-Anweisungen auskommentieren, dann klappt's auch mit Taste an D.1, oder habe ich die Antwort fehlinterpretiert?

Vielen Dank,

Dirk

chr-mt
11.07.2005, 18:23
Hi,
Baud schaltet die Schnittstellenpins auf den UART.
Normales setzen/lesen des Pins geht dann nicht mehr.
Man kann die Schnittstellenpins aber auch während der Laufzeit ein und ausschalten.

SET UCR.3 schaltet TXD ein
SET UCR.4 schaltet RXD ein
RESET UCR.3 schaltet TXD aus
RESET UCR.4 schaltet RXD aus

Ich hatte mal ein Problem, daß ich einen Pin sowohl für die Schnittstelle, sowie auch als "normalen" Pin brauchte.
Das hat mit den genannten Befehlen auch prima funktioniert.

Gruß
Christopher

PicNick
11.07.2005, 19:39
@chr-mt : Du hast im Prinzip recht, aber nach "DO... LOOP" kannst du das "End" hinschreiben, wo du willst
@Finor: baud weglassen sollte reichen, sonst mach es wie CHR-MT beschreibt.

chr-mt
11.07.2005, 21:41
Hi PicNick,
nee, ich hatte schon öfter Probleme mit neu startenden Controllern, wenn das END hinter einem Unterprogramm stand.
Irgendwo habe ich das auch mal gelesen, daß man das END vor das erste Unterprogramm setzen muß.
Ich suche mal, vielleicht finde ich das ja noch irgendwo.

Gruß
Christopher

Marco78
11.07.2005, 22:19
@chr-mt ich habe damit auch noch keine Probleme gehabt. Ich bin aber auf die Quelle gespannt, bzw auf die Erklärung in der Quelle.
Wenn im Programm irgendwo ein Print oder Input oder was anderes steht was RS232 ähnlich kommt, und kein $Baud im Listing steht wird automatisch die Einstellung des Compilers übernommen.
Ich könnte mir auch vorstellen, das das roblem der Missbrauch von TxD und RxD ist.
Evtl die Stacks zu niedrig eingestellt?! Dann kann sich das Programm nicht mehr merken wohin es wieder zurück muss.

chr-mt
11.07.2005, 22:30
Leider habe ich noch nichts gefunden.
Ich hatte aber Probleme mit Programmen die ich neu compiliert hatte , die unter älteren BASCOM - Versionen noch mit END am Schluss liefen und habe dann das END vor das erste Unterprogramm gesetzt.
Dann lief es.
Ich verwende übrigens ausschließlich Gosub..

Eine Erklärung hatte ich damals auch nicht gefunden, nur den Hinweis, daß man es eben so machen sollte.
Erklären kann ich es also leider nicht. :(

Gruß
Christopher

Marco78
11.07.2005, 23:04
Evtl nur ein Bug einer älteren Version?
Ich glaube es dir ja. Aber mit der .7.4 Demo hatte ich das Problem noch nicht.
Aber vielleicht ist der Bug in der .7.7 ja wieder drin?
Ich denke aber trotzdem das es an RS232 und Missbrauch liegt.

PicNick
12.07.2005, 09:39
Der Befehl "END" generiert einen Sprung auf sich selbst und sonst nix. Er baut dadurch eine Blockade, damit nicht ein Programm ungewollt z.B. in eine Sub reinläuft.
Wenn aber vorher ein anderer unbedingte Sprung steht ( wie bei DO..Loop) isses natürlich wurst.
Das gilt natürlich nur bei MC, denn normalerweise erfolgt bei BASiC dort der Rücksprung ins Betriebssystem.

Die meisteb Definitionen mit $... haben ein Equivalent in der "programm.CFG" Datei. Es kann schon sein, daß der Befehl "PRINT" auch wieder die UART aktiviert, kann man ausprobieren, bringt aber nix. Denn der PRINT würde ohne UART vermutlich ins Nirwana gehen.
Also in deinem Fall mußt du alles vermeiden, was irgendwie nach RS232 stinkt.
(Oder eben explizit deaktivieren --> CH-MT Methode)

Finor
14.07.2005, 07:59
Hallo an alle,

vielen Dank für Eure Hilfe.
$baud raus und es funktioniert wie erwartet!

Auch interessant, was man an "Nebenbei"-Info's noch so erhält!

Viele Grüße

Dirk