PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ... jeder fängt irgendwann mal mit BASCOM an ...



M*I*B
18.10.2009, 15:12
... und nun auch ich ...

Allerdings gestaltet sich die Sache schwieriger als erwartet, da es trotz intensiver Suche kein in meinen Augen brauchbares Tutorial gibt... Oder hat irgendwer Empfehlungen, auch in Buchform?

Gleich eine Frage zu BASCOM (aktuelle Version) vorweg:
Kann es wohl sein, das der komische Hardware-Simulator (das Dingen mit den LED's und dem LCD) nicht ordentlich funktioniert? Das betrifft auch das Fenster Variables. Beide aktualisieren sich bei einer Simulation nicht automatisch. Erst wenn ich mit der Maus z.B. auf eine LED eines nicht benutzen Port's klicke, wird es aktualisiert, ansonsten nicht.
Liegt das an meinem Rechner/OS (XP Pro x64, AMD Phenom 9750 Quad)? Wenn nicht, ist der Simulator doch vollkommen witzlos ](*,)

Nun zum Thema:

Zur Geschichte ist zu sagen, das ich mir dachte, das ein Basic- Dialekt gerade für ganz einfache Steuerungsaufgaben in Verbindung mit den kleinen Tiny's wesentlich einfacher und schneller zu verwenden ist als ASM oder C.
In diesem Sinne habe ich mir auch ein Projekt als Übung ausgedacht, welches hier als rein analoge Lösung existiert (NE556, OP's, ...). Dabei handelt es sich um eine "intelligente" Außenlichtsteuerung mit IR- Bewegungsmelder, 2 Taster im Flur und Helligkeitssensor

Diese Funktionalität möchte ich als Übung unter BASCOM so oder so ähnlich incl. einiger Erweiterungen (über die Taster programmierbar, 1wire, ...) mit einem Tiny84 nachbauen.

Im Grunde habe ich schon das Grundgerüst komplett. Allerdings stehe ich noch vor ein paar Schwierigkeiten, bei denen mir ggf. hier wer auf den richtigen Weg helfen könnte?!?

Das erste betrifft die BIT- Manipulation innerhalb eines mit DIM gesetzten Bytes. Das Setzen eines einzelnen BIT's ist ja kein Thema (BITS(x.y....), =&h... oder =&b...), aber das gezielte Löschen klappt irgendwie nicht.

Das zweite betrifft die Verwendung von DEBOUNCE. Im Prinzip ist mir die Verwendung klar, allerdings kommt dabei, zumindest über den Simulator, immer was anderes heraus als erwartet. Ich hatte DEBOUNCE für jeden der drei Eingänge auf L-Pegel mit GOSUB gesetzt und bin von allen drei Abfragen zur gleichen SUB gesprungen, um dort die letztendliche Auswertung vorzunehmen. Das klappt aber irgendwie nicht ...

Ein letztes (bis jetzt) ist die Auswertung der PCINTx (PinChangeInterrupts). Kann es sein, das BASCOM das garnienicht unterstützt?

Das sind erstmal meine derzeitigen Probleme. Ich bastle natürlich immer am Quellcode rum, so das eine Veröffentlichung an dieser Stelle m.E. keinen Sinn macht. Mache ich aber gerne, wenn es wer möchte. Das betrifft auch die Beschreibung des finalen Funktionsumfanges ...

MiniMax
18.10.2009, 15:35
Hi Micha,
Na dann erstmal ein herzliches Willkommen in der Bascom Basic Programmierung =D> =D>
Als Turitual kann ich dir nur die Rn Wissen's Artikel (http://www.rn-wissen.de/index.php/Kategorie:Quellcode_Bascom) Empfehlen ! Ansonsten kann ich dir leider nicht weiter Helfen. Viel Glück mit deiner Steuerung \:D/ \:D/

TKRoth
18.10.2009, 15:45
Schaue einmal auf www.DieElektronikerseite.de. Dort sind mehrere Lehrgänge in Bascom.

M*I*B
18.10.2009, 16:05
@MiniMax: Danke, da schau ich doch schon immer ;) Hat mir auch schon an manchen Stellen weiter geholfen.
Was ich bis jetzt gefunden habe, ist eine DEBOUNCE mit ASM und Softwaretimer. Da blicke ich noch nicht dran lang.

@THRoth: Danke für den Tipp. Allerdings bin ich über den Status schon hinaus. Da werden eher Grundlagen vermittelt und so spezielle Fragen, wie z.B. PCINTx, werden in Verbindung mit BASCOM nicht behandelt.

for_ro
18.10.2009, 16:40
Kann es wohl sein, das der komische Hardware-Simulator (das Dingen mit den LED's und dem LCD) nicht ordentlich funktioniert? Das betrifft auch das Fenster Variables. Beide aktualisieren sich bei einer Simulation nicht automatisch. Erst wenn ich mit der Maus z.B. auf eine LED eines nicht benutzen Port's klicke, wird es aktualisiert, ansonsten nicht.
Liegt das an meinem Rechner/OS (XP Pro x64, AMD Phenom 9750 Quad)? Wenn nicht, ist der Simulator doch vollkommen witzlos ](*,)
Wahrscheinlich aus Geschwindigkeitsgründen werden nicht alle Darstellungen des Simulator während der Ausführung des Programms aktualisiert. Dies wird aber in vielen anderen Simulatoren auch nicht gemacht.
Wenn du die aktuellen Werte sehen möchtest, kannst du die Ausführung jederzeit anhalten. Entweder durch die Knöpfe oben links oder durch Haltepunkte (Breakpoints), die du auf alle Zeilen setzen kannst, die vorne einen gelben Punkt haben.


Diese Funktionalität möchte ich als Übung unter BASCOM so oder so ähnlich incl. einiger Erweiterungen (über die Taster programmierbar, 1wire, ...) mit einem Tiny84 nachbauen.
halte ich für eine gute Übung und auch machbar. Ich schätze auch, dass der tiny84 dazu locker in der Lage sein sollte.


Das erste betrifft die BIT- Manipulation innerhalb eines mit DIM gesetzten Bytes. Das Setzen eines einzelnen BIT's ist ja kein Thema (BITS(x.y....), =&h... oder =&b...), aber das gezielte Löschen klappt irgendwie nicht.
Du kannst jedes Bit der ganzzahligen Variablentypen separat auf 0 oder 1 setzen. Ebenso die einzelnen Pins eines Ports.
My_Byte.0 = 0 setzt dir das Bit 0 von My_Byte auf 0, alle anderen bleiben unverändert
My_Long.30 = 1 macht das entsprechende bei der Long Variable.
PortA.3 = 1 setzt den Pin3 von PortA auf High-Pegel, bzw. schaltet den PullUp ein.
Das geht auch mit einem Alias
Ausgang alias PortA
Ausgang.3 = 1 hätte den gleichen Effekt.


Das zweite betrifft die Verwendung von DEBOUNCE. Im Prinzip ist mir die Verwendung klar, allerdings kommt dabei, zumindest über den Simulator, immer was anderes heraus als erwartet. Ich hatte DEBOUNCE für jeden der drei Eingänge auf L-Pegel mit GOSUB gesetzt und bin von allen drei Abfragen zur gleichen SUB gesprungen, um dort die letztendliche Auswertung vorzunehmen. Das klappt aber irgendwie nicht ...

Zeig mal den Code dazu. Bedenke auch, dass der Pin immer noch mal auf High gehen muss, ansonsten gibt es keine Ausführung der Sub. Die Zeit Überwachung von Debounce funktioniert im Simulator glaube ich nicht.


Ein letztes (bis jetzt) ist die Auswertung der PCINTx (PinChangeInterrupts). Kann es sein, das BASCOM das garnienicht unterstützt?
Wenn du dir das Datenblatt des Tiny84 anschaust, dann wirst du feststellen, dass es keinen PCINTx direkt gibt. Anders als der externe Interrupt INT0 werden die PCINT Eingänge gemeinsam abgefragt.
Die PCINTs von Porta sind unter PCINT0 zusammengefasst, die von PortB unter PCINT1.
Wenn du den Pin 3 von PortA benutzen willst, musst die diesen aktivieren. Dies geht über PCMSK0.3 = 1 oder auch PCMSK.PCINT3 = 1
Den Sprung in die ISR legst du so fest:
On PCINT0 PCINT0_ISR
wobei der Name PCINT0_ISR willkürlich gesetzt werden kann.
Wenn du mehrere aktive Pins hast, dann musst du nun in der ISR rausfinden, welcher gesetzt ist.

M*I*B
18.10.2009, 18:40
Hey for_ro,

das nenne ich mal eine ausführliche Antwort! Vielen Dank!!! Das bringt mich fett voran =D>

BIT- Manipulation:
... au menno! Ist vermutlich viel zu trivial, als das ich da selber hätte drauf kommen können ](*,) Ich habe immer nach einem bestimmten Befehl gesucht like BITS() oder so ...

PCINTx:
Ok, das habe ich wohl beflissentlich mehrfach übersehen. Jetzt wird mir auch alles klar (glaub ich). Das würde dann bedeuten, das ich z.b. PCINT0 auswerte und springe, um dort z.B. mit DEBOUNCE abfrage, welcher PIN es denn nun war, oder?

DEBOUNCE:
Die Nummer habe ich derzeit nicht mehr im Code, da es irgendwie nicht klappen wollte. Wenn ich mich recht erinnere, hatte ich das in etwa so:


Config Porta.1 = Input : Irs Alias Porta.1
Config Porta.2 = Input : Ta1 Alias Porta.2
Config Porta.3 = Input : Ta2 Alias Porta.3

do
debounce irs,0,sub_stat,sub
debounce ta1,0,sub_stat,sub
debounce ta2,0,sub_stat,sub
loop

sub_stat:
if irs = 0 then
blabla
end if
...
return

In der sub_stat wollte ich halt auswerten, welcher Eingang denn überhaupt betroffen ist, an Stelle einer eigenen SUB für jeden Eingang.

Emulator:
Das ist schade. Ich habe BASCOM vorhin zum Spaß mal auf einem P300 mit WIN2k installiert. Das läuft da annähernd eben so schnell wie hier auf meiner großen Kiste, wenn ich den LCD-Emu nicht öffne. Im Umkehrschluss stellt sich mir dann natürlich die Frage, warum die Macher von BASCOM da offensichtlich eine Bremse eingebaut haben resp. auf Echtzeitanzeigen bei Verwendung von echt schnellen Maschinen verzichten. Aber nun gut; gehört ja nicht hier her...

python_rocks
18.10.2009, 18:58
kein in meinen Augen brauchbares Tutorial
Hallo!

Ob brauchbar oder nicht, das müssen andere entscheiden.

http://halvar.at/elektronik/kleiner_bascom_avr_kurs/

mfg
Gerold
:-)

M*I*B
18.10.2009, 19:04
... jau, schaut gut aus; ist gespeichert. Danke dir!

for_ro
18.10.2009, 19:09
Die Aliase musst du auf PinA.1 usw. setzen, wenn du Werte einlesen willst.
Zum Simulator: Ich glaube nicht, dass irgendein PC im Moment in der Lage
ist, die schnellen Zustandänderungen eines µC in Echtzeit zu zeigen. Noch weniger sind Menschen dazu in der Lage zu erkennen, was da vor sich geht.
Die Hauptbremse ist übrigens die Ausgabe in dem Programmfenster, wo der Befehlspointer hin und her springt. Wenn du das Fenster minimierst, geht da richtig die Post ab.
Die echte HW Simulation hört bei größeren Sachen sowieso recht schnell auf. Komplexe Signale wie 1-wire ode so kannst du gar nicht simulieren.
Ich sehe den Hauptsinn darin, bestimmte Passagen eines Programms zu debuggen und dafür habe ich so ziemlich alles an Bord, was ich benötige.

guenter1604
18.10.2009, 20:23
Hallo Micha,

hiermit habe ich angefangen:

www.rowalt.de

dremler
18.10.2009, 20:28
ich habe auch das buch von rowalt und bin sehr zufrieden:)

Bammel
18.10.2009, 20:48
da kann ich mich auch nur anschließen das buch ist top

M*I*B
18.10.2009, 21:55
... jo, danke Kinnaz; ist auf den Wunschzettel geschrieben ;)

M*I*B
19.10.2009, 16:25
@for_ro u.a.:
Ich habe die Nummer mit dem PCINTx mal in Angriff genommen, aber irgendwie klappt das nicht; zumindest nicht im Simulator ...

Ich habe so getan:


Pcmsk0.0 = 1 : Pcmsk0.1 = 1 : Pcmsk0.2 = 1 : On Pcint0 Isr_input
Enable Interrupts

... blabla ...

Isr_input:
Debounce Irs , 0 , Sub_input , Sub
Debounce Ta1 , 0 , Sub_input , Sub
Debounce Ta2 , 0 , Sub_input , Sub
Return

... blabla ...

Im Simulator erreicht der nimmernicht die ISR_input, egal was ich mache. Ist da was verquer oder kann das der Simulator nur nicht?

In dem Zusammenhang noch eine Frage: Es gibt doch bestimmt die Möglichkeit, den jetzt - Zustand eines PIN direkt abzufragen, also ohne Umweg über Register oder so?!? Dann würde ich mir die Sache einfacher machen und den jetzt- Zustand der PIN's via Timer0 in eine Byte- Variable kopieren und das Debouncing dort machen...

Sauerbruch
19.10.2009, 17:42
Also, erstmal muss ich mich den Aussagen zum Buch von Roland Walter uneingeschränkt anschließen (auch wenn´s schon auf Deinem Wunschzettel steht :-) )

In Deinem PCINT-Code hast Du vergessen, den Pinchange-Interrupt auch freizugeben. Alle Interrupt-Routinen werden nur dann ausgeführt, wenn nicht nur die globale Interrupt-Freigabe erfolgt ist (enable Interrupts), sondern auch diejenige des speziellen Interrupts. In Deinem Fall also "Enable PCINT0". Der Tiny84 hat nämlich 2 Pinchange-Interrupts: PCINT0 fasst die Eingänge PCINT0...7 zusammen, und PCINT1 die Eingänge PCINT8...11.

Das gleiche gilt übrigens auch für Timer-Interrupts. "Enable timerX" aktiviert mitnichten den Timer als solches, sondern nur den Interrupt im Falle eines Timer-Überlaufes.

Die einzelnen Bits im PCMSK-Register kannst Du übrigens auch "am Stück" setzen:

PCMSK0 = &B00000111 ("&B" heißt binär)
oder
PCMSK0 = 7 (das gleiche in dezimal)


Es gibt doch bestimmt die Möglichkeit, den jetzt - Zustand eines PIN direkt abzufragen, also ohne Umweg über Register oder so?!?

Die einzelnen Bits der PIN-Register sind die Eingangszustände an den jeweiligen Anschlüssen - einfacher als über dieses Register geht´s also nicht!! Liegt am PinA0 ein H an, ist das Register PINA = 1. Liegt das H am Eingang A2, ist PINA = 4. Sind die Pins A1-A3 alle H, wäre PINA = 7.

Du kannst natürlich den Zustand der Eingangspins "konservieren", indem Du einer Byte-Variable den momentanen Wert des PINA-Registers zuweist.


Config Zahl as byte
Zahl = PINA
...
...

Dann wäre der momentane Status gespeichert, auch wenn sich in der Zwischenzeit etwas an den Eingängen ändert. Aber die direkteste Möglichkeit der Abfrage ist das Überprüfen entweder einzelner Bits des PINA-Registers (oder gleich des ganzen PINA-bytes).

Viel Spaß noch beim "simulieren" :-)

Daniel

M*I*B
19.10.2009, 18:58
](*,) ](*,) ](*,)

Logisch! Hab ich glatt übersehen; bei dem Timer hab ich es ja auch explizit eingeschaltet :-b Das war jetzt echt Betriebsblind oder so ;)

Nun hab ich es mal eingeschaltet, aber den Simulator juckt das nicht. Ich werde es noch mal in echt ausprobieren, sobald ich einen Tiny84 hier vor mir habe, um festzustellen, ob das tatsächlich nur am Simulator liegt.
Derweil werde ich mal in Verbindung mit der zweiten Frage bezüglich direkter Abfrage via PINx was anderes probieren; kann nicht schaden und übt ;)

Also wenn ich das jetzt richtig verstanden habe, betrifft die Abfrage mit PINx.y immer den echten Zustand der Pins, mit PORTx.y den der Register, oder? oder?

Da drängt sich mir eine weitere Frage auf:
An PINA.0 hängt ein Helligkeitssensor und auf den Eingang ist ADC(0) aktiv. PINA.1, .2 und .3 sind im Grunde Taster (L-Aktiv).
Was ist denn dann PINA, wenn auf dem ersten BIT der ADC läuft? Wird das BIT bei der Abfrage ignoriert und als 0 oder 1 gewertet oder ist der Zustand undefiniert? Darüber habe ich keine Aussagen im Datenblatt finden können ...

Naj, ich probiere es halt mal...

Sauerbruch
19.10.2009, 19:29
Also wenn ich das jetzt richtig verstanden habe, betrifft die Abfrage mit PINx.y immer den echten Zustand der Pins, mit PORTx.y den der Register, oder? oder?

Nicht ganz :-)

An die "echten" Pins (im Sinne des kleinen Anschlussbeinchens) kommst Du unmittelbar definitiv nicht ran!

Diese kleinen silbernen Beinchen sind entweder mit dem PIN-Register verbunden (in Richtung Beinchen -> Register) oder mit dem PORT-Register (in umgekehrter Richtung Register -> Beinchen). Entschieden wird das ganze über das DDR-Register (Data Directory Register). Steht ´ne 1 drin, ist der Anschluss ein Ausgang (PORT -> Anschluss); ist das DDR-Bit 0, ist der Anschluss als Eingang geschaltet (Anschluss -> PIN). Dies ist übrigens der Normalzustand nach dem Einschalten, einen Anschluss muss man also nicht extra als Eingang konfigurieren. Das ist er zunächst mal ganz von alleine.

Bei jedem Taktimpuls wird also entweder der "echte" Zustand am Anschluss in´s PIN-Register übernommen, oder aber der Zustand im PORT-Register auf den Anschluss gegeben; je nach DDR-Bit.

Wenn ein Anschluss als Eingang konfiguriert ist, ist das dazugehörige PORT-Bit nicht ganz unbeteiligt: Wird es auf H gesetzt, ist der interne PulUp-Widerstand für diesen Eingang aktiviert. Das kann eine sehr hilfreiche Angelegenheit sein.

Mit dem Befehl GETADC(x) wird der korrespondierende Anschluss mit dem AD-Wandler verbunden. Die Verbindung zum PIN-Register und vom PORT-Register sind dann unterbrochen. Du kannst das PORT-bit zwar setzen oder das PIN-bit abfragen - aber das ergibt keinen Sinn, weil der Anschluss nur dem ADC-Wandler gehört.

Ist es jetzt etwas klarer?

M*I*B
19.10.2009, 19:34
... jau ;) Jetzt hat es geklingelt im Oberstübchen! Vielen Dank für deine Geduld!

Besserwessi
19.10.2009, 21:13
Schon eine gute Erklärung. Beim ADC Eingang aber noch nicht ganz korrekt:
Dir Port-funktion bleibt auch dann aktiv, wenn der Pin als ADC Eingang definiert ist. Die PIN Funktion (Digitaler Eingang) kann, und sollte man über ein extra Register abschalten. Beim Mega?8 ist das das Register DIDR0.

Es ist nur so, das es selten sinnvoll ist die digitalen Funktionen zu nutzen, wenn man den ADC nutzt. Man sollte dann den Pin als Einang definieren, und die Eingangsfunktion ausschalten.

M*I*B
21.10.2009, 19:16
... so ihr netten Leutz :-b

Dank eurer Hilfe ist mir der Einstig in BASCOM doch recht flott von der Hand gegangen.
Inzwischen bin ich fertig mit dem Code; zumindest läuft er im Simulator wie erwartet =D>
Sicherlich gibt es an dieser und jener Stelle noch Möglichkeiten, den Code intelligenter zu gestalten und Abläufe zu optimieren, aber Rom ist auch nicht an einem Tag erbaut worden...

Ein paar Fragen nicht direkt in diesem Zusammenhang hätte ich aber noch abschließend zu diesem Thread:

1. Konstanten und Variablen kann ich ja auch ins EEPROM schreiben an Stelle des FLASH... Wann resp. unter welchen Umständen macht das Sinn?

2. Ich möchte dieses System irgendwann mal in ein 1wire- Netz einbinden, aber als Slave. In der Hilfe zu BASCOM habe ich zum Betrieb als Slave nichts finden können, auch nicht darüber, ob der/jeder AVR, der von Haus aus für 1wire ausgelegt ist, wo und ob es überhaupt eine UID gibt zur Identifikation auf dem Bus; ok, man könnte z.B. einen DS2401 an den AVR hängen, aber schöner wäre es natürlich, wenn das nicht nötig wäre...

Bammel
21.10.2009, 20:17
ich kann dir "nur" auf deine erstefrage antworten. das schreiben in den eeprom macht "nur" dann sin wenn die daten auch bei einem reset den µC beibehalten werden. dies amcht auch auch nur bei variabeln sinn... konstatnten sind ja eh festgelegt

M*I*B
22.10.2009, 17:20
.. ok, kapiert ;)
Also brauche ich das, um nachträglich z.B. per Tasten geänderte Werte vor Stromausfällen o.ä. zu sichern (wenn ich es richtig verstanden habe)

Genau dafür möchte ich es auch im Code einsetzen; da mach ich nämlich so was ...

Aber irgendwie klappt das nicht... folgendes Beispiel- Konstrukt:



Const E0 = 15
Const E1 = 300
...
Dim Z1 As Eram Word
Z1 = E1 'Default laden
...
'Setup: Jeder Tastendruck erhöht Z1
Z1 = 15
Tastenabfragen:
...
Z1 = Z1 + E0
...
GOTO Tastenabfragen
Bei der Zeile Z1 = Z1 + E0 bekomme ich dann ein "Invalid Datatype" ?!?

Ziel der Aktion ist, beim allerersten Start bestimmte Variablen mit den Defaultwerten aus den Konstanten zu füllen. Beim fertigen System kann man über eine Tastenkombination in den Setup- Modus gelangen und dort die mit den Defaults belegten Variablen über Tastendrücke selber einstellen...

guenter1604
22.10.2009, 17:30
Gaaaanz böse ;-)

Grundsätzlich NIE ein Eeprom in einer Schleife beschreiben, das macht es nicht lange mit. Am Besten nur nach Bedieneraktion.

Guck dir mal den Befehl Writeeeprom und Readeeprom an.

Gruß Günter

Sauerbruch
22.10.2009, 17:31
Meines Wissens kann man mit ERAM-Variablen nicht direkt rechnen. Ich hab´s zumindest immer so gelöst, dass ich mir eine "normale" Variable im SRAM definiert habe, sie mit der entsprechenden ERAM-Variablen gleichgesetzt und mit ihr weitergerechnet habe.

Außerdem sind die ERAM-Speicherplätze auch nicht unenedlich oft beschreibbar. Auch wenn´s 10- oder 100.000 mal geht - wenn man den ERAM einmal pro Sekunde beschreibt, ist er statistisch gesehen in gut einem Tag hin...

M*I*B
22.10.2009, 18:16
... ah, ok. Gleich wieder 2 Sachen dazu gelernt: Nicht "böse" zum Eram sein und direkt rechnen darf man damit auch nicht.

Dann muss ich mal den Code entsprechend umstricken, so das ich zum einen nur nach einem Reset die Daten aus dem Eram lese und den Variablen zuweise und zum anderen alle geänderten Variablen einsammle und erst nach dem kompletten Setup ins Eram schreibe. Das lässt sich m.E. ja gut mit einem Array lösen, welches man ja direkt ins Eram schreiben resp. lesen kann (oder?).

Nachtrag:
Wenn ich das richtig sehe, ist Lesen längst nicht so schädlich wie Schreiben für das EEprom, oder?
Dann könnte ich ja beim Übertragen der Daten zum AVR gleich die Defaults ins EE schreiben mit ...

$eeprom
Data 300 , 3600 , 256 , 512 , 5 , 60 , 300 , 30 , 300 , 16 , 3
$data ... und nach Definition eines Array mit z.B. Dim Prog(11) As Word via Readeeprom prog() mit den Werten aus dem EE füllen ... oder?!?

Bammel
22.10.2009, 19:14
jap genau lesen kan man es meines wissens nach "so oft man will" nur die schreibzyklen sind begrenzt