PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ischarwaiting <- Zeichen Empfangen ATMEGA2560 geht nicht



Steffen44
23.02.2007, 11:56
Hallo

Ich versuche gerade krampfhaft mit dem ATMEGA2560 das Register auszulesen wo hinterlegt ist ob sich ein Zeichen im RS232 Puffer befindet.

Der Befehl Ischarwaiting sollte das normalerweise im Bascom tun aber es gibt keine Reaktion auf den Befehl.


Hier mein getesteter Code :



If Ischarwaiting() = 1 Then

Bb = Waitkey(#4)

Select Case Bb
Case "Befehl1_mach_dies_mach_jenes"

Case Else
End Select
End If



Was kann ich tun damit mein Programm nicht immer bei Waitkey endet ?
Ohne die Abfrage ob sich etwas im Buffer befindet durchläuft mein µC die do loop Schleife nicht mehr.


Gruß
Steffen

PicNick
23.02.2007, 12:07
halt ein, Kollege, andere Baustelle:
"Ischarwaiting" funzt zusammen mit "CONFIG serialin=buffered"

Was du meinst, ist irgendein Flag im zuständigen Hardware-register (weiß jetzt nicht, is beim 2560 aber eh woanders)

Muttu gucken :-)

Heideltrudel
23.02.2007, 12:41
Hallo Steffen 44,
ich hatte das gleiche Problem.
Hast du schon mal auf der Seite http://www.rowalt.de/mc/index.htm
unter Einführung 4 nachgelesen ?
Ich denke das hilft dir weiter.
MfG

Steffen44
23.02.2007, 13:03
If USR.RXC = 1 Then 'Wenn Byte empfangen...
i = UDR 'Byte aus UART auslesen
Select Case i
Case "H"
Print "Hallo AVR"
Case "h"
Print "hallo avr"
Case Else
Print "Unbekannter Befehl"
End Select
End If

funktioniert überhaupt nicht :-( da der ATMEGA2560 andere Register oder Flags hat oder was auch immer.


Ich habe jetzt schon mal die Portnummer mit angegeben aber es funzt trotzdem nicht.



Open "com4:" For Binary As #4 'USB Port

If Ischarwaiting(#4) = 1 Then
Bb = Waitkey(#4)

Select Case Bb
Case "do-something"
Sound Portl.4 , 400 , 450 ' Beep when Ischarwaiting(#4) = 1
Case Else
End Select
End If


Die Port Nummer die das USB verwendet ist 4 aber es kommt trotzdem wieder ein Fehler : "Label not found [_ISKEY4 ] in file ...."

Ich verstehe es einfach nicht und es funzt nicht :-(


Gruß
Steffen

Steffen44
23.02.2007, 13:49
so wie es ausschaut ist es ein Bug und erst ab der Version 1.11.8.4 von Bascom behoben nur wo bekommt man das nun her. Im Download Berreich von Bascom findet sich nur die 1.11.8.3.


Naja hoffentlich wird die Beta 1.11.8.5 am wochenende freigegeben da hab ich vieleicht mehr Glück.

Gruß
Steffen

Heideltrudel
23.02.2007, 19:05
Hallo Steffen44,
ich habe noch einmal nachgesehen wie ich das mit einem Atmega 128 programmiert habe. Hier der Code:

'--------------------------------------------------------------

' serial INPUT

'--------------------------------------------------------------
$regfile = "m128def.dat"
$crystal = 8000000
$baud = 19200



Config Serialin1 = Buffered ', Size = 20
Enable Interrupts
Enable Urxc
On Urxc Interrupt0


Dim A As Byte

Open "Com1:" For Binary As #1




A = 0

Anfang:

Cls
Lcd "A=" ; A
Waitms 300
Goto Anfang



Interrupt0:

Inputbin #1 , A

Return


End



Im Simulator für den Atmega 128 lief es.
Du mußt nur das Regfile auf deinen Atmega 256 ändern.
Der Prozessor wartet nicht auf ein Zeichen sondern benutzt den Interrupt.
In der Zwischenzeit läuft er durch das normale Programm. In meinem Fall durch die mit Anfang gekennzeichnete Schleife. Erst wenn ein Zeichen empfangen wurde Wird URXC auf 1 gesetzt. Dann wird der Interrupt ausgelöst und springt zum Punkt Interrupt und legt das Zeichen in der Variable A ab darach springt an die Stelle zurück wo er herkam bevor er in den Interrupt sprang.
Dann läuft er durch die "Anfang"-Schleife und zeigt das Zeichen auf einem Display, das am Port A angeschlossen ist an.

Mfg Jürgen

Steffen44
26.02.2007, 07:40
Hallo Jürgen

der ATMEGA2560 ist übelst bockig entweder Bascom ist noch voller Fehler oder ich bin zu dumm. Der Code von dir wird ohne Fehler kompiliert soweit alles ok aber ich erhalte keine Reaktion auf meinem LCD Display A=0 wird immer angezeigt.


Die einzigste Kommunikation die ich hinbekomme habe ist eine Bit Auswertung aber eine Zeichenkette/String zu senden ist unmöglich.




'Diese Anweisung setzt die Fusebits automatisch korrekt (Syntax $PROG LB, FB , FBH , FBX )
$prog , 255 , &B11011001 , 'Quarz an / Teiler aus / Jtag aus

$regfile = "m2560def.dat"


$hwstack = 32
$swstack = 16
$framesize = 40
$crystal = 16000000 'Quarzfrequenz


'Ist 1 wenn USB angeschlossen

'Definition USB
Config Com4 = 38400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0


'Definition für LCD Display 40x4
Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portb.7 , Db5 = Porth.2 , Db6 = Porth.0 , Db7 = Porte.4 , E = Portb.5 , Rs = Porte.6
Config Lcdbus = 4


Open "com4:" For Binary As #4





Dim A As Byte , S As String * 2

Do



A = Inkey(#4)
If A = 1 Then 'we got something
A = Waitkey(#4) 'get it
End If

If A = 49 Then 'wenn die 1 auf der tastatur gedrückt wird dann mach was
Sound Portl.4 , 400 , 450
Print #4 , "ASCII code " ; A ; " from serial"
End If



Print #4 , "Test"

Waitms 100

' End If

Loop



Wenn ich nur wüßte wie man den Simulator bedient das das Teil gibt mir nur Rätsel auf.

Gruß
Steffen

Heideltrudel
26.02.2007, 17:35
Hallo Steffen,
nur nicht den Mut verlieren, wir schaffen das schon.
Als erstes würde ich mir den empfangenen Wert ( A ) auf dem Display anzeigen lassen. Dies machst du wie folgt:

cls
LCD "A= " ; A
waitms 100

füge es ein vor die Zeile
IF A = 49 then

Zeigt das Display irgend etwas an, wenn du ein Zeichen sendest ?

Dann beschreib doch mal deinen Aufbau der Hardware !
Wie dibst du das Zeichen, das der Prozessor empfangen soll ein?
Hast du ein Evulationsboard?
Hast du deinen PC über eine RS232 an den Prozessor angeschlossen ?

Ich benötige mehr Informationen.

MfG Jürgen

Steffen44
27.02.2007, 06:46
Ok also ich habe hier ein selbstgebautes Experimentierboard das auf dem RN-MEGA2560 basiert. Das Board hat 8 Digitalausgänge, 16 Analogeingänge und 12 Digitaleingänge. Angeschlossen ist ein 4x20 Zeichen Display.

Die ganze Hardware kommuniziert per RS232/USB mit dem Excel 2000 über das MSCOMM OCX. Das Excel habe ich im Prinzip als Grundlage um mir vernümftig etwas Visualisieren zu lassen. Wenn man alles im Hyper terminal anschauen muss wird man wahnsinnig.

Das der µController vermutlich mit Inputbin und Input nichts anzeigt ist garantiert noch ein Bug in Bascom. Ich habe diese Befehle auch schon ohne Interupt versucht aber es gibt überhaupt keine Reaktion darauf.


Das hatte ich auch schonmal vor die Schleife gesetzt aber es hat keine Auswirkung :
cls
LCD "A= " ; A
waitms 100.


Ich denke mal ich lasse es erstmal auf meiner Lösung beruhen auch wenn diese nicht gerade sehr fortschrittlich ist.

Mein jetziges Problem ist das wenn ich aus dem Excel eine Zahl schicke damit der µC den Digitalausgang schaltet dann kann ich immer nur einen Impuls schicken. Mit nur einem kurzem Impuls kann ich aber keinen der Digitalausgänge permanent einschalten bis zum Ausschaltimpuls.

Das müsste irgendwie wie eine Selbsthaltung funktionieren.


Gruß
Steffen

Heideltrudel
27.02.2007, 11:18
Hallo Steffen,

Ich kenne 2 Möglichkeiten die Selbsthaltung deines Ports zu realisieren.

1. beim Einlaufen des Zeichens den entsprechenden Port auf 1 setzen und
beim nächsten Mal den Port auf 0 setzen.

2. Den Befehl Toggle zu benutzen
If A = 1 Then Toggle Portb.0
Dieser Befehl negiert den Ausgang einfach, egal ob er vorher 1 oder 0 war.

MfG Jürgen

Steffen44
27.02.2007, 15:50
Hallo Jürgen,

das mit Toggle habe ich schon probiert und es ging nicht weil vermutlich :

-angenommen der Variable A aus dem Beispiel gebe ich nun kurz einen Impuls von 0 oder 1 dann springt doch nur der Ausgang solange wie der Impuls anliegt auf den negierten Zustand.

Das wäre sozusagen ein negierter gepulster Ausgang oder nicht ?
Oder sollte er bei Toggle den Ausgang halten ?

If A = 1 Then Toggle Portb.0

Was ich dazusagen muß ist das ich alles in einer Endlosschleife habe do loop und das Programm auch nicht unterbrechen kann nur damit mehere Ausgänge parallel permanent angezogen bleiben. Das ist voll die Zwickmühle :-k


Gruß
Steffen

Heideltrudel
27.02.2007, 19:21
Hallo Steffen,
mit dem Toggle ist das so, dass wenn ein Impuls einen Ausgang toggelt, wird der Ausgang auf dauer negiert. d.h.
War der Ausgang auf H dann geht er auf L und umgekehrt und das so lange bis der nächste Impuls kommt.
Das solltest du mal mit einem ganz kurzen Programm durchspielen und dann in dein richtiges Prog "einbauen".

Jürgen

Steffen44
28.02.2007, 10:35
du hast recht es liegt irgendwie am Ablauf meiner do loop schleife ich habe darin nur einmal die Anweisung waitms 40 und nur solange die 40ms laufen liegt auch der Impuls an den ich aus dem Excel schicke.

Wenn ich die Warteanweisung ganz rausnehme kommt gar kein Schaltimpuls mehr am Ausgang an. Vermutlich ist das ganze nur über Interrupts zu lösen aber das habe ich bisher schon über 2 Tage versucht zum laufen zu bekommen naja ich bin kurz davor das Handtuch zu schmeißen.

Gruß
Steffen

Heideltrudel
28.02.2007, 12:11
Hallo Steffen,
habe mir das ganze noch einmal durch den Kopf gehen lassen und ein Bild von deinem Problem genacht.

- Du drückst einen Taster auf deiner Tastatur und sendest ein Zeichen
( z.B. 1 ) zum Atmega2560.

-Dein Atmega soll dann welchen Ausgang schalten ?
- Der zu schaltende Ausgang soll dauerhaft Ein sein.
- Beim nächsten Druck auf die Tastatur ( z.B. nochmal 1) soll dein Ausgang
wieder auf Aus gehen.

Es kann sein, dass deine Tastatur beim Druck auf die Taste 1 nicht nur einmal die 1 sendet sondern solange die 1 sendet bis der Finger von der
Taste genommen wird. Das hätte die Folge das deine LED flimmert. Man könnte auch den Eindruck haben, dass sie dauerhaft EIN ist.

Abhilfe könntest du da schaffen, wenn du die
Taste 1 für LED1 EIN nimmst und die
Taste 2 für LED1 AUS
Taste 3 für LED2 EIN
Taste 4 für LED2 AUS

u.s.w

Jürgen

Steffen44
28.02.2007, 16:10
da mein Programmcode sehr lang geworden ist will ich diesen hier lieber nicht posten aber ich erkläre mal was ich mache.

Über waitkey warte ich auf das das zu empfangende Zeichen.
Es empfängt eine 1 und soll dann einen Ausgang 1 auf high schalten.
Wenn es eine 2 empfängt dann soll der Ausgang 1 auf low schalten.
(Im Prinzip mache ich es schon so wie du vorgeschlagen hast)

Diese Befehle stecken nun in der do loop schleife.

Was mir aufgefallen ist :

wenn ich aus meiner do loop schleife waitms 40 entferne dann wird der Ausgang überhaupt nicht mehr geschalten bleibt die Wartezeit aber darin dann sehe ich den Ausgang nur für 40ms auf high.

Ich habe zum testen dann mal eine simple schleife nachgebaut die das Problem verdeutlicht :

do
toggle port x.x
waitms 40
loop

Hier blinkt der Ausgang/LED permanent im 40ms Takt. Wenn ich den waitms befehl rausnehme wird der Port permanent auf High gehalten.

Ich halte das ganze für ziemlich unlogisch oder ergibt das für dich ein Sinn ?


Gruß
Steffen

Heideltrudel
28.02.2007, 16:53
Hey,
na klar gibt das einen Sinn !!!
Das ist genau das was du programmiert hast !

do
toggle port x.x
waitms 40
loop

Wenn du den uP in die "do" Schleife schickst toggelt er den angegebenen Port, wartet 40 Millisekunden, geht auf "Loop" und springt dann wieder auf "do" und beginnt das Spiel von neuem. Da der uP 40 Millisekunden wartet nimmt das Auge noch ein Blinken wahr. Wenn du den uP nicht warten läßt sondern er mit seiner vollen Geschwindigkeit die "do"-Schleife immer wieder durchfährt und dabei den Ausgang von Ein auf Aus und umgekehrt wechselt ist er so schnell das das Auge einen "Ein-Zustand" wie schon beschrieben wahrnimmt. Ich glaube dein Denkfehler liegt darin das du meinst, das der uP nur einmal durch die "do"-Schleife fährt und den Ausgang nur Einmal wechselt. Das ist nicht der Fall. Wie vor beschrieben.
Jürgen

Steffen44
01.03.2007, 13:04
Ich glaube langsam verstehe ich was du meinst. Über den do loop Befehl habe ich bisher nicht viel nachgedacht.

Es müßte demnach so sein: Ab dem loop Befehl vergisst der Controller den Ursprungszustand und nimmt erst mit dem Beginn des neuen Programmes seinen Zustand wieder annimmt. Deswegen ist eine do loop Schleife total ungeeignet für das was ich vorhabe.


Das dumme ist ich habe schon ein riesen Programm das in der do loop Schleife läuft und ich möchte auch das es regelmäßig die Analogen Ports abfragt und mir den Meßwert per RS232 sendet. Wenn ich den do loop Befehl weglasse kommt gar nichts mehr auf der RS232 Schnittstelle an :-(

Ich denke mal wenn mir etwas hilft dann irgendwie eine andere Hierarchie des Programmablaufes nur mehr als do loop und subroutinen kenne ich nicht und an den Interrupts will ich mich nicht groß vergreifen aber was bleibt dann übrig ?


Gruß
Steffen

Frank
01.03.2007, 13:18
Also irgendwie verstehst du da grundlegend was falsch. Wait macht nichts anderes als Warten, mit Ports oder Portzustand hat der garnichts zu tun. Und wenn du den Port auf einen Zustand einstellst, dann schaltet de rauch niemals von allein zurück.

Vielleicht verstehst du den "toggle port x.x" Befehl nicht, siehe mal Hilfe in bascom. Er kehrt nur den Zustand des Portes um. Wenn der Port auf 1 (High) geschaltet ist ind dur rufst toggle auf, so wird er auf 0 (Low) geschaltet. Wenn de rPort abe rzuvor 0 ist, dann wird er durhc Toggle auf High geschaltet. Die Schleife führt also dazu das er ständig ein und ausgeschaltet wird. Heideltrudel hat es ja schon weitergehend erklärt.

Irgendwo ist in deinem Programm für dein Vorhaben ein Fehler. Du solltest mal ein kleines kurzes Rumpfprogramm schreiben bei dem man genau sieht was du machen willst und das komplett posten. Da kann dir dann sicher besser geholfen werden weil man so als im dunkeln rumtappt .