Bascom BASCOM ; Erste Schritte zum Ausprobieren

Ischarwaiting prüft, ob ein Zeichen durch den UART empfangen wurde
Ich habe mir dieses und auch andere Begriffe in der "AVR-Hilfe" angesehen und die Beschreibung dazu von Goggle übersetzen lassen. Aber auch die in der AVR-Hilfe müssen schon einige Grundkenntnisse vorhanden sein. Zu dem UART kommt jetzt auch noch USCRA dazu. Also ich verstehe nur noch Bahnhof.
Schau Dir mal die 1.Seite in diesem Forum an, wie Cassio dem Jordy die Funktionen beibringt. Cassio schreibt einen Programmcode mit ausführlicher Erklärung. Da kommt auch der Code

CodeBox BascomAVR
If Flag = 1 Then                                            'Wenn FLAG eine EINS hat, dann....
   For I = 1 To 3                                           'Zähle I von 1 bis 3
      Led_7 = Ein                                           'LED 7 einschalten
      Waitms 250                                            'Warten
      Led_7 = Aus                                           'LED 7 ausschalten
      Waitms 250                                            'Warten
   Next I                                                   'gehe wieder zu FOR
      Flag = 0
Else
End If
mit dem ich etwas experimentieren kann um ihn zu verstehen.
 
Die Namensgebung der Befehle ist auch manchmal etwas irreführend, grade wenn das Casing (Groß/Kleinschreibung) nicht passt.
Ischarwaiting = IsCharWaiting = Is Char Waiting => Ist ein Zeichen empfangen worden und steht zur Abarbeitung bereit?

Die Auswertung der seriellen Daten sollte (hier) nur dann erfolgen wenn Daten da sind, sonst sind Befehle wie Input und InbutBin blockend, sprich das Programm wird angehalten solange bis Daten eingegangen sind. Daher setz mal den Bereich Zeile 2 - 18 aus #117, also der Eingabeteil, in eine extra If wo du IsCharWaiting abfragst.
 
Ich weiß nicht ob Bascom das so frisst (bin zu lange raus), aber:


CodeBox BascomAVR
If Ischarwaiting() = 1 Then
   ...
End If


Oder etwas unschöner (aus der Hilfe):


CodeBox BascomAVR
Dim A As Byte

A = Ischarwaiting()
If A = 1 Then
   ...
End If
 


CodeBox BascomAVR
$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32
$baud = 19200

Dim Zeichen As String * 1

Config Timer1 = Pwm , Prescale = 1024 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down

Rot Alias Portd.7                                           'Name für Portbit des Beines
Config Rot = Output                                         'LED ist Ausgang
Rot = 1                                                     'high Pegel
Gruen Alias Portc.3
Config Gruen = Output
Gruen = 1

Do
If Ischarwaiting() = 1 Then
   Inputbin Zeichen
   If Zeichen = "1" Then
      Rot = 1
      Print "Led An"
   Elseif Zeichen = "0" Then
      Rot = 0
      Print "Led Aus"
   Elseif Zeichen = "t" Then
      Toggle Rot
      Print "Toggle Led"
   Elseif Zeichen = "?" Then
         If Rot = 0 Then
            Print "Led ist aus"
         Elseif Rot = 1 Then
            Print "Led ist an"
         End If
   End If
End If

   If Tifr.tov1 = 1 Then
      Toggle Gruen
      Set Tifr.tov1
   End If
Loop
End

Ist das so richtig?
 
Sieht soweit gut aus, probieren kann ich es grade leider nicht.
 
Ich weiß nicht ob Bascom das so frisst (bin zu lange raus),
Also...
If Ischarwaiting() Then meckert er an (sowas in der Art geht im Visual Studio, oder?)
If Ischarwaiting() = 1 Then schluckt der Compiler zumindest, ob das auch das gewünschte Resultat liefert ist auszuprobieren.
Variable = Ischarwaiting() If Variable = 1 Then geht definitiv

Alternativ kannst Du natürlich auch selbst das RXC-Bit abfragen (Ischarwaiting macht wie gesagt nix anderes)
If USCRA.RXC = 1 Then

Wie in #120 angedeutet ist nach Ischarwaiting aber auch sinniger, Inkey statt Inputbin zu verwenden - Inkey liest einfach den Inputbuffer aus (egal ob überhaupt was drinnsteht; Inputbin wartet solange bis das RXC-Bit gesetzt ist, und liest dann.

mit Ischarwaiting und Inputbin würdest Du also bei jedem Schleifendurchlauf prüfen ob was eingegangen ist (Ischarwaiting), wenn was eingegangen ist (If), würdest Du mit Inputbin nochmal warten bis was eingegangen ist (das ist klar - es wird aber trotzdem nochmal geprüft), und dann erst das Zeichen auslesen lassen.

Alternativ kannst Du auch hier statt Inputbin oder Inkex selbst den Empfangspuffer auslesen lassen - in Deinem Fall ist das das UART Data Register (UDR)
Zeichen = UDR
 
Programm Code #125
Gruen toggelt. Ich denke mal an nach Timervorgabe.
Rot arbeitet nach den If Bedingungen ohne Gruen zu beeinflussen.
 
Denn funktioniert es ja jetzt :)
Oder?

:offtopic:
If Ischarwaiting() Then meckert er an (sowas in der Art geht im Visual Studio, oder?)
Jupp. Zumindest wenn Ifcharwaiting eine Funktion ist die Boolean (Bit in Bascom) zurück gibt.
 
Ja, es funktioniert.
Ich denke mal, dass ich auf diese Art an mein Ziel kommen könnte. Wie? Noch keine Ahnung.
 
):offtopic:
Zumindest wenn Ifcharwaiting eine Funktion ist die Boolean (Bit in Bascom) zurück gibt.
Ischarwaiting liefert "irgendwas Numerisches", 'ne Zahl... also Byte, word, integer, Long,... aber keine Fließkommazahlen.
If kann aber auch bits (boolean) selbst nicht verarbeiten - die Bedingung muß immer ein Vergleich enthalten.
(Also If USCRA.RXC then geht nicht, If USCRA.RXC = 1 Then geht.

Back to Topic...

Gruen toggelt. Ich denke mal an nach Timervorgabe.
Rot arbeitet nach den If Bedingungen ohne Gruen zu beeinflussen.
Damit haben wir erfolgreich zwei verschiedene Teilprogramme quasi-gleichzeitig zu laufen - beide arbeiten korrekt.

Ersetze mal bitte Inputbin durch Inkey - funktioniert zwar beides, aber Inputbin prüft nochmal das RXC-Bit, was ja nach Ischarwaiting nicht mehr/nochmal nötig ist. Außerdem muß Zeichen dann ein Byte sein (Zeile 8)

So, der Timer läuft ja eigentlich im PWM, und das wollen wir letztendlich auch nutzen. Für die grüne LED haben wir den Timer mithilfe des Prescalers (Vorteilers) gedrosselt. Unser PWM würde ähnlich flackern, wie die grüne LED...
Der Vorteiler soll wieder auf 64 zurück, trotzdem soll Gruen noch irgendwie sichtbar blinken (ohne daß wir irgendwelche Waits verwenden:stop:)
'Ne Idee?
Wenn der Prescaler auf 64 gesetzt wird, läuft der Timer sechzehn mal so schnell wie jetzt. Wenn es mit derselben Frequenz blinken soll, darf nur bei jedem sechzenhten Timerüberlauf getoggelt werden.
Man könnte die Timerüberläufe zählen, und nur jeden sechzehnten (oder was auch immer) Überlauf nutzen
 
Lass dich davon nicht verwirren, es ist im Endeffekt genau das was Ischarwaiting macht, nur halt mit den Hardware-Namen statt einer Bascom Funktion. Das war ja auch eher Off-Topic, also abseits vom Thema, zwischen uns beiden.
USCRA ist das Register der Hardware für die serielle Schnittstelle (USART), Control & Status. RXC ist das Bit darin was besagt dass ein Byte empfangen wurde und verarbeitet werden kann, oder eben nicht.
 
Inputbin durch Inkey
Bascom Fehlermeldung : Unknow statement [INKEY ZEICHEN]


CodeBox BascomAVR
Dim Zeichen As Byte

Config Timer1 = Pwm , Prescale = 1024 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down

Rot Alias Portd.7
Config Rot = Output
Rot = 1
Gruen Alias Portc.3
Config Gruen = Output
Gruen = 1

Do
If Ischarwaiting() = 1 Then
   Inkey Zeichen
 
Inkey hat 'ne andere Syntax, schau Dir mal die Hilfe dazu (Cursor auf Inkey() und F1 drücken) an, insbesondere auch das Example...
 
Ich kann damit nichts anfangen und
Ich hatte ja schon mal versucht, das zu erklären... nochmal...

Stell Dir mal vor, Du wärst die ALU, der eigentliche Rechenkern des Controllers.
Du sitzt an Deinem Schreibtisch, und hast nur 32 Speicherzellen vor Dir, In diese kannst Du irgendwas reinschreiben, Du kannst mit ihnen Rechenoperationen und Vergleiche durchführen usw.
Diese Zellen sind Deine Rechenregister - in höheren Sprachen wie zB C aber auch Bascom sind die zwar weniger interessant, aber die ALU muß alle Operationen auf diesen Registern (dem Schreibtisch) durchführen.
Im Flur hast Du jetzt 'n großen Schrank, wo Du Rechenergebnisse ablegen und holen lassen kannst (Deine SekretärInnen heißen Load und Store).
Das ist der Speicher, der SRAM - damit kannst Du jetzt zwar schon einiges anfangen, aber hast keinen Blick und keinen Einfluß auf Deine Umwelt.
Die Peripherie.
Dazu steht außerdem ein großes Panel neben dem Schreibtisch, wo alle möglichen Sachen angezeigt werden können (Lampen/Fähnchen, Zählwerke) und wo Du alles mögliche einstellen kannst (Schalter, Taster). Das sind die I/O-Register. Der Mega8 hat 61 davon. Jedes dieser Register wird durch ein Byte realisiert. Einige Funktionen benötigen nur ein einzelnes Bit in einem Register, manche mehrere, manche ein ganzes Register, und manche sogar mehrere Register.
Diese Register - Dein Panel - stellen also Deine Schnittstelle - Schnittstellen - zur Außenwelt dar.
Hier liest Du den Zählerstand des Timers ab, legst fest ob ein Bein Eingang oder Ausgang sein soll, veranlaßt den UART irgendein Zeichen zu senden - ALLES was in irgendeiner Form zwischen dem Controllerkern und seiner Umwelt (Peripherie) ausgetauscht wird, geht durch diese Register.

Wie ich bereits sagte, ist Bascom 'ne Hochsprache. Der Controller versteht kein Bascom oder C, der versteht nur Maschinencode. Deine Hochsprache übersetzt aber Deinen Hochsprachencode in Maschinencode, und der Hochsprachencode kann mehr oder weniger maschinennah sein.
Der höher abstrahierte Code muß natürlich am Ende genau denselben Maschinencode erzeugen wie der maschinennahe (wenn er dieselbe Funktion erfüllen soll).
In Bascom bist Du aber nicht zwingend auf die Verwendung hoch abstrahierter Instruktionen/Funktionen angewiesen, sondern hast außerdem auch den Zugriff auf die I/O-Register (das Panel). Wenn es in Bascom also keine Funktion für irgendwas gibt, was der Controller könnte (oder diese uns nur nicht bekannt ist), kann man das unter Bascom trotzdem über die Register selbst lösen.

Ischarwaiting prüft also, ob der Empfangspuffer des UART leer ist oder nicht. Und zwar einfach indem das UART Receive Complete Bit im Statusregister A des UART ausgelesen wird. Dieses zeigt direkt an, ob ungelesene Daten im Empfangspuffer liegen.
Statt Ischarwaiting auf das Panel blicken zu lassen, kannst Du das auch selbst tun.
Der resultierende Maschinencode wird ähnlich sein.

Manche solcher Bascom-Instruktionen sind recht simpel (Ischarwaiting zB), andere können recht komplex und umfassend sein ('ne Fließkommazahl in einen entsprechenden String umwandeln)

bleib einfach bei Ischarwaiting...
 
Die Blinkfrequenz der LED.
Die Blinkt im derzeitigen Code mit der halben PWM-Frequenz des Timers.
Ursprünglich hattest Du da mit Prescaler=64 'ne PWM-Frequenz von 8000000Hz/64/510=245Hz. Die PWM-LEDs würden also nicht flimmern.
Wir hatten für die Blink-LED jetzt den Prescaler auf 1024 hochgesetzt, also die PWM-Frequenz durch sechzehn geteilt.
80000000Hz/1024/510=15,3Hz -> die LED toggelt, also blinkt sie mit etwa 7,6Hz.

Als nächste Etappe würde ich den Timer als PWM nutzen wollen, und deswegen den Prescaler wieder auf 64 zurücksetzen. Die Blink-LED würde dann natürlich auch mit der sechzehnfachen Frequenz blinken, also mit etwa 122Hz (genau, die hälfte der oben errechneten 245Hz PWM-Frequenz).

Aber wenn ich die 245Hz so sehe...
Vielleicht sollte man mit Blick auf Dein eigentliches Ziel lieber gleich versuchen, aus den TOVs (245Hz) 'ne Frequenz von etwa einem Hz zu generieren. Indem man durch 256 teilt (wären 0,96Hz - die Blink-LED sollte dann mit etwa 0,5Hz blinken)...
Also:
Mit Prescaler=64 ist die Bedingung in Zeile 40 mit einer Frequenz von 245Hz wahr, viel zu oft.
Wir wollen, daß die Grüne Led dann nicht jedesmal getoggelt wird, sondern nur jedes 256ste mal.

Du siehst, daß das ganze wie ein Getriebe mit Untersetzung, ein Uhrwerk läuft?
Angetrieben vom Systemtakt als Motor geht's mit Untersetzung (Prescaler) auf den Timer Der ist ein weiteres Zahnrad, welches mit Seinen Überläufen den If-Block ab Zeile 40 antreibt. Im If-Block wird durch das toggeln nochmal halbiert, aber wir brauchen jetzt vor dem Toggeln ein weiteres Zahnrad, welches nochmal durch 256 teilt.

'ne Idee?
 
If Tifr.tov1 = 1 Then
Wenn ich verstehen würde, was diese Zeile genau macht, ja vielleicht. So aus dem Stehgreif würde ich sagen, anstatt =1 nehme ich einfach =256.
Das geht natürlich nicht, weil ich solche Experimente schon probiert habe. Allerdings mit 16.
Wie gesagt, mit den Registern kann ich noch nicht umgehen.
Eine Idee hätte ich noch, mit einer For...Next Schleife könnte man auch bis 256 zählen lassen und dann das TIFR.TOV1=1 ausführen lassen.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)