PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Bascom



Blacktom
06.11.2010, 09:59
Hallo,
ich bin ziemlich neu hier und hab gerade mit Bascom angefangen. Ein bisschen kann ich schon, aber ich hab folgendes Problem: Ich hab eine Schaltung mit dem ATmega8, 2 Schalter sind an Int0 und Int1, und drei LED's an PC0-PC2. Ich soll ein Pogramm mit Bascom schreiben das bei Int0 das Programm startet und bei Int1 beendet, so dass es erst wieder angeht (also die LED's leuchten) wenn ich wieder auf Int0 grückte (alsoauf den ersten Taster).

Kann mir jemand helfen?

Sauerbruch
06.11.2010, 10:59
Sicherlich möchtest Du ja nicht nur irgeneinen vorgekauten Code in Deinen Controller laden, sondern auch verstehen WAS passiert, oder?

In diesem Fall kann ich Dir wärmstens das folgende Buch empfehlen:

http://www.rowalt.de/index.htm

Ich habe mir wirklich etliche Bücher gekauft, um den Einstieg in die Mikrocontroller zu finden - aber dieses ist aus meiner Sicht für einen Anfänger mit Abstand das beste.

Blacktom
06.11.2010, 11:16
ich hab schon einen code aber weiß nicht ob er funktioniert da ich keinen programmer habe, deshalb muss ich das in der schule machen

Blacktom
06.11.2010, 11:20
' Verwendete CPU (ATmega8) festlegen
$regfile = "m8def.dat"

' Taktfrequenz einstellen (1MHz)
$crystal = 1000000


' Pin's an Port C als Ausgang festlegen (Pin's der LED's)
Config Portc.0 = Output
Config Portc.1 = Output
Config Portc.2 = Output

' Pin an Port D2 als Eingang festlegen (Pin des linken Taster)
Config Pind.2 = Input

Config Int1 = Falling
' generell Interrupts zulassen


' Variable (Speed = 1s) als Ganzzahl festlegen
Dim Speed As Integer
Speed = 1000


Enable Interrupts
Enable Int1
' Zu Unterprogramm springen
On Int1 Beenden





' Hauptschleife
Do
If Pind.2 = 1 Then
' Programmschleife
Do

Portc.0 = 1
Waitms Speed
Portc.0 = 0
Portc.1 = 1
Waitms Speed
Portc.1 = 0
Portc.2 = 1
Waitms Speed
Portc.2 = 0

Loop
End If
Loop

' Unterprogramm
Beenden:
Portc.0 = 0
Portc.1 = 0
Portc.2 = 0
Return

End

Wir das Funktionieren?

Blacktom
06.11.2010, 11:48
das oben ist mein code aber wird der gehen

Sauerbruch
06.11.2010, 13:06
Also, für den Anfang schon mal ganz gut!

Was würde bei diesem Code passieren?

Wenn PIND.2 High ist, läuft die 3-Sekunden-Hauptschleife an. Übrigens: Statt eine Integer-Variable zu definieren, kannst Du auch schreiben waitms 1000 oder wait 1, beides führt zu 1 Sekunde Verzögerung.

Also - die Hauptschleife läuft - und jetzt kommt der Interrupt:

Alle LEDs werden ausgeschaltet - das Programm springt anschließend aber genau wieder an die Stelle, an der es unterbrochen wurde, d.h. Deine Hauptschleife läuft weiter! Und das soll ja nicht der Fall sein, wenn ich Dich richtig verstanden habe - das Lauflicht soll doch erst wieder anlaufen, wenn der andere Taster gedrückt wurde, oder?

Die Fragestelung klingt ja schon so, als wenn Ihr mit zwei (!) Interrupts arbeiten solltet. Was hältst Du also von folgender Lösung:

Du definierst zwei Interrupts:



Config INT0 = falling
On INT0 Einschalten
Enable INT0

Config INT1 = falling
On INT1 Ausschalten
Enable INT1

Enable Interrupts


In Deiner Hauptschleife lässt Du einfach das Lauflicht laufen:




Do

PORTC.0=1
wait 1
PORTC.0=0
PORTC.1=1
wait 1
PORTC.1=0
PORTC.2=1
wait 1
PORTC.2=0

Loop



Und in den Interrupts schaltest Du die Anschlüsse C0 - C2 einfach als Ausgänge (LEDs leuchten) oder Eingänge (LEDs leuchten nicht):




Einschalten:
Config PORTC.0 = Output
Config PORTC.1 = Output
Config PORTC.2 = Output
Return

Ausschalten:
Config PORTC.0 = Input
Config PORTC.1 = Input
Config PORTC.2 = Input
Return



Mit weniger Schreibarbeit ginge es auch, wenn Du direkt das Register manipulierst, in dem festgelegt wird, ob die Anschlüsse als Ein- oder Ausgänge konfiguriert sein sollen - das sogenannte "DDR"-Register (Data Direction Register):



Einschalten:
DDRC = &B00000111 (C0, C1, C2 sind Ausgänge)
Return

Ausschalten:
DDRC = &B00000000 (Alle C-Anschlüsse sind Eingänge)
Return


("&B" heißt: Jetzt kommt ´ne Binärzahl. Für den Compiler nicht ganz unwnichtig :-) )

Noch zwei allgemeine Dinge:

Bist Du sicher, dass der Taster den Eingang auf High zieht? Mikrocontroller haben nämlich eingebaute Pull-Up-Widerstände, die (wenn sie aktiv sind) den Pin auf ein sauberes High ziehen - deshalb ist es oft sinnvoll, Taster nach Masse zu legen und den Tastendruck mit der Abfrage eines "LOW" zu realisieren. Deshalb hast Du Deinen Interrupt ja auch auf "fallling" konfiguriert.

In diesem Zusammenhang empfiehlt es sich, die PullUp-Widerstände der Eingangspins auch wirklich zu aktivieren: Für die INT0 und INT1-Eingänge (D.2 und D.3) geht das, indem Du die entsprechenden PORT-Bits auf 1 setzt:

PORTD.2 = 1
PORTD.3 = 1


2. Auf vielen Boards sind die LEDs nicht zwischen den Controller und Masse geschaltet, sondern zwischen + und den Controller. D.h. sie gehen an, wenn der Pin LOW ist, und aus, wenn der Pin HIGH ist. Das müsstest Du natürlich berücksichtigen!

Ich hoffe, Dir ein wenig weitergeholfen zu haben...


Gutes Gelingen!

Besserwessi
06.11.2010, 13:09
Wenn das Programm nicht besonders lang ist, so wie hier, kann man den Simulator (als Teil von BASCOM) nutzen, um ein Programm zu testen.


Das Programm oben wird wohl noch nicht ganz richtig gehen. Das Abbrechen dürfte nicht funktionieren: Es werden zwar wohl in der ISR die LEDs ausgeschaltet, aber das Programm läuft danach einfach weiter.
So ganz einfach ist das auch nicht zu lösen: die einfache Lösung wäre über so etwas zur abbrechen einfach so etwas wie einen Reset auszulösen, also einfach wieder ganz von vorne anfangen (per GOTO 0) wenn ich mit richtig erinnere. Allerdings ist das dann schon Compiler spezifisch und nicht mehr ganz im strengen Sinne einer strukturierten Programmierung.



Je nach Hardware (wenn da nur die Taster nach GND an den Eingängen hängen) könnte es nötig sein bei den Eingängen Pull-ups zu aktivieren.

Blacktom
06.11.2010, 13:44
Erst mal danke für die Tipps und Vorschläge. Ich versuche sie um zu setzen. Das mit dem Ausschalten ist auch mein größtes Problem, ich will ja mit dem ersten Taster das Programm starten und mit dem zweiten Taster beenden und wenn ich dann wieder auf den ersten Taster (also Start drücke) soll das Progamm wieder von vorne anfangen.

Blacktom
06.11.2010, 14:55
Also ich will mein Problem nochmal beschreiben: Ich habe mein Board selbst gemacht, ein Taster liegt an PD2 und der andere auf PD3 (an beiden Tastern liegt eine Spannung über einen Widerstand an und Gnd befindet sich am anderen Kontakt des Tasters), jeweils eine LED befindet sich an PC0, PC1 und PC2 (die Pluskontakte befindet sich an diesen Pins). Das Programm soll folgender Maßen aussehen: Bekommt der ATmega8 Strom, soll er nichts machen, erst wenn ich den ersten Taster einmal drücke (also nicht gedrückt halten), soll die erste LED für 1s angehen, dann die zweite dann die dritte und dann wieder die erste: Das Programm soll erst aufhören, wenn ich auf den zweiten Taster drücke, dann soll der Atmega8 nichts mehr machen und wenn ich dann wieder auf den ersten Taster drücke, sollen die LED's wieder leuchten.

Das müsste doch gehen, aber ich bekomme es nicht hin, hat einer von euch eine Lösung dafür?

hardware.bas
06.11.2010, 16:39
Also... Programme ohne Programmierer, also rein theoretisch zu entwickeln ist fast ummöglich! Ein Programm mit halbwegs Sinn zu entwickeln bedarf die Angelegenheit Stück für Stück durchzutesten. Alles Andere ist echt brotlose Kunst ! 99Prozent aller Programmfehler entdeckt man durch Lauftest der Hardware ! VG Micha

Vitis
07.11.2010, 09:51
Also... Programme ohne Programmierer, also rein theoretisch zu entwickeln ist fast ummöglich! Ein Programm mit halbwegs Sinn zu entwickeln bedarf die Angelegenheit Stück für Stück durchzutesten. Alles Andere ist echt brotlose Kunst ! 99Prozent aller Programmfehler entdeckt man durch Lauftest der Hardware ! VG Micha

Bis zu einem gewissen Grad geht das mit dem Simulator schon, nur wenns dann an
externe Hardware und komplexere Programmstrukturen geht, bzw. nicht determinierte Programmabläufe (unregelmäßige Interrupts, Benutzereingaben,
Statemachine, Daten externer Bausteine (Messwerte))
wirds sehr ätzend.

Bei meinem größten Programm sagt der Simulator "to many Files" :)

hardware.bas
07.11.2010, 10:51
Stimmt.... sind so Erfahrungswerte: Man denkt, jetzt hat man alle Fehler
ausgemerzt, man flasht... und stellt fest, das und dies läuft noch
nicht... Naja, das Erfolgserlebnis entschädigt dann zu guter Letzt.
VG Micha