Im Beispiel wundert mich die hohe Taktfrequenz von 2kHz, die dann ein
sichtbares blinken ergibt.
Die CPU Frequenz kann nur durch maximal 2¹⁶ für die SMs dividiert werden.
Ohne hinein geschaut zu haben, wird die sich ergebende Blinkfrequenz auf delays ›[n]‹ für 0<=n<=31 in PIOASM zurück zu führen sein.
die PIO-Frequenz auf 1MHz stellt? Eigentlich müsste es ja besser sein, die Frequenz auf Maximum zu stellen, weil dann die Quantisierung der Frequenzen am kleinsten ausfällt. Ich könnte mir nur vorstellen, dass man bei 1MHz etwas Strom spart.
die PIO-Frequenz auf 1MHz stellt? Eigentlich müsste es ja besser sein,
die Frequenz auf Maximum zu stellen, weil dann die Quantisierung der
Frequenzen am kleinsten ausfällt. Ich könnte mir nur vorstellen, dass
man bei 1MHz etwas Strom spart.
Nö, der Rest läuft ja volle Pulle. Man kann die halbe Periode ja auf 1µs einstellen.
Das Beispiel hat aber durchaus Arduino Qualität.
Buzzer direkt an die GPIOs
Ein wildes Durcheinander von import … und from … import … Statements
Bei der gewünschten Frequenz muss man wohl die Hälfte ins FIFO schütten
Selbst dann passt sie nicht, da der Overhead nicht berücksichtigt wird.
Trotzdem gut geeignet als abschreckendes Beispiel. ;-)
Bei der gewünschten Frequenz muss man wohl die Hälfte ins FIFO
schütten
Wieso das?
Da steht doch
1
pull(noblock)
2
mov(x, osr)
d.h. da wird nicht auf einen vollen FIFO gewartet sondern der alte Wert aus dem OSR koppiert, wenn keine Werte im FIFO sind. Man kann die Frequenz also asynchron setzten, wie es am Schluss gemacht wird:
1
play(500)
2
time.sleep(1)
3
play(1000)
4
time.sleep(1)
5
play(0)
Siehe Datenblatt
1
3.4.7.2. Operation
2
3
A nonblocking PULL on an empty FIFO has the same effect as MOV OSR, X. The program can either preload scratch register X with a suitable default, or execute a MOV X, OSR after each PULL NOBLOCK, so that the last valid FIFO word will be recycled
Bei der gewünschten Frequenz muss man wohl die Hälfte ins FIFO
schütten
Wieso das?
Weil man sonst etwa die halbe Frequenz erhält.
Der Ersteller des Scripts hat wohl nie geprüft ob die am GPIO ausgegebene Frequenz der gewünschten entspricht.
Obwohl, bei einem Piezo-Plättchen, könnte es sich schon nach der gewünschten Frequenz anhören.
Bei der gewünschten Frequenz muss man wohl die Hälfte ins FIFO
schütten
Wieso das?
Weil man sonst die halbe Frequenz erhält.
Der Ersteller des Scripts hat wohl nie geprüft ob die am GPIO
ausgegebene Frequenz der gewünschten entspricht.
Obwohl, bei einem Piezo-Plättchen, könnte es sich schon nach der
gewünschten Frequenz anhören.
Stefan hat's schon richtig beschrieben.
Für eine volle Periode braucht's zwei Polaritätswechsel. Hier findet pro PIO Rundlauf nur einer statt, ergo halbe Frequenz.
Richtig wäre es, wenn man die PIO Frequenz auf 2MHz setzen würde, und beim sm.put() den erheblichen Offset der restlichen PIOASM Befehle subtrahieren würde.
Aber selbst dann wäre es falsch, denn der y_jmp loop braucht eine ›0‹ im Register für einen Durchlauf, oder ›n-1‹ für ›n‹ Durchläufe.
Aber das Gute ist, zumindest einige Programmzeilen sind fehlerfrei. ;-)
PIO mit vollem CPU Takt laufen lassen.
Alles andere ergibt keinen Sinn.
Im ›put‹ keine ›//‹ Division mit inhärentem round down, sondern:
sm.put(round(machine.freq()/freq/2) - offset)
Die Play Funktion ist ebenfalls fehlerhaft, sie stoppt den Ton bei ›0‹ nicht, sondern erzeugt (bei ›0‹) die Periode ca 2³²/F_CPU und bestromt den Ausgang für längere Zeit kontinuierlich.
Die Play Funktion ist ebenfalls fehlerhaft, sie stoppt den Ton bei ›0‹
nicht, sondern erzeugt (bei ›0‹) die Periode ca 2³²/F_CPU und bestromt
den Ausgang für längere Zeit kontinuierlich.
Da hast du Recht, das konnte ich auf dem Oszilloskop beobachten. Ich vermute, man kann den PiPico direkt in einen UKW-Sender verwandeln, einfach in dem man eine Antenne an den Pin hängt.
Die State-Machine in diesem Beispiel ist recht einfach, allerdings erfolgt die Abfrage des Zählerstandes als "Code Injection" und braucht daher extra Zeit. Die Frage ist, ob hier Zählerwerte verloren gehen könnten. Ich vermute eher nicht, wenn die zu zählende Frequenz deutlich kleiner als die Loopfrequenz der Zustandsmaschine ist.
Das Ziel ist, den Zähler an den Frequenzgenerator von vorher anzuschließen. Am einfachsten erscheint es mir, einfach den gleichen Pin zu verwenden und die beiten Zustandsmaschinen gleichzeitig laufen zu lassen.
1
import rp2
2
from machine import Pin
3
import time
4
5
# PIO program to count pulses on an input pin
6
@rp2.asm_pio()
7
def pulse_counter():
8
label("loop")
9
wait(0, pin, 0) # Wait for pin to go low
10
wait(1, pin, 0) # Wait for pin to go high (rising edge)
11
jmp(x_dec, "loop") # Decrement x and jump to loop (counts pulses)
Die Play Funktion ist ebenfalls fehlerhaft, sie stoppt den Ton bei ›0‹
nicht, sondern erzeugt (bei ›0‹) die Periode ca 2³²/F_CPU und bestromt
den Ausgang für längere Zeit kontinuierlich.
Da hast du Recht, das konnte ich auf dem Oszilloskop beobachten. Ich
vermute, man kann den PiPico direkt in einen UKW-Sender verwandeln,
einfach in dem man eine Antenne an den Pin hängt.
Ich würde es zwar so wohl nicht machen, aber angelehnt an das Beispiel…
(Falls ich mich nicht verzählt habe ;-) )
1
#!/python
2
# vim: fileencoding=utf-8: ts=4: sw=4: expandtab:
3
frommachineimportfreqascpufreq
4
fromrp2importPIO,StateMachine,asm_pio
5
fromtimeimportsleep_ms
6
7
@rp2.asm_pio(sideset_init=PIO.OUT_LOW)
8
deftoggle():
9
wrap_target()
10
pull(noblock)# 1 (neue Daten)OSR oder X──▶OSR
11
mov(x,osr)# 1
12
mov(y,x).side(1)# 1
13
label("loop1")
14
jmp(y_dec,"loop1")# n+1
15
mov(y,x).side(0)[2]# 3 symmetrisch machen
16
label("loop2")
17
jmp(y_dec,"loop2")# n+1
18
wrap()
19
20
defplay(freq):
21
iffreq:
22
# Bei höchster Frequenz nicht negativ werden lassen.
23
sm.put(max(0,round(cpufreq()/freq/2)-4))
24
sm.restart()# Falls ohne warten bei extrem niedriger Frequenz gewünscht
25
sm.active(1)
26
else:
27
sm.active(0)# Sonst beträgt (bei ›0‹ die Periode ca. 2³¹/F_SM
28
sm.exec('nop().side(0)')# Ausgang auf spezifizierten Pegel bringen
29
30
sm=rp2.StateMachine(0,toggle,sideset_base=25)# LED zum Test (Pin() ist hier unnötig)
Ich würde es zwar so wohl nicht machen, aber angelehnt an das
Beispiel…
Welchen Tipp hättest du, es besser zu machen?
Kleine Tabelle (2^n Größe) mit gewünschter ›Waveform‹ füllen. Per DMA mit Ringsize ›n‹ entweder einen der >=acht PWM slices oder eine der >=acht StateMachines mit variablem duty-cycle ansteuern. Klingt angenehmer. Aber für ein Rechteck mit duty:50% geht's so auch.
Nebenbei: In meinem offensichtlich zu hastig veröffentlichen Code haben sich zwei copy'n'paste Artefakte versteckt. Zeilen 7,30. Die ›rp2.‹ können natürlich weg.
In meinem offensichtlich zu hastig veröffentlichen Code haben
sich zwei copy'n'paste Artefakte versteckt. Zeilen 7,30. Die ›rp2.‹
können natürlich weg.
Da ist mir nicht klar, was du meinst.
Da ich ein Rechtecksignal brauche, habe ich das Programm mal korrigiert. Ich denke, die Zyklenkorrektur muss 6 betragen:
1
#!/python
2
# vim: fileencoding=utf-8: ts=4: sw=4: expandtab:
3
4
importrp2
5
frommachineimportPin
6
fromrp2importPIO
7
importtime
8
frommachineimportfreqascpufreq
9
10
# Define a PIO assembly program that toggles the output pin at a controllable rate
11
@rp2.asm_pio(out_init=[PIO.OUT_LOW])
12
defecho():
13
wrap_target()# define the start of the main loop of the PIO program.
14
mov(pins,isr)# [1] Output current ISR value to the pin (initially LOW)
15
mov(isr,invert(isr))# [1] Toggle ISR between 0 and 1 for pin toggling
16
pull(noblock)# [1] Try to pull new data from FIFO (non-blocking)
17
mov(x,osr)# [1] Store new delay count (or reuse old one if no new data)
18
mov(y,x)# [1] Copy to Y register for countdown
19
label("loop")
20
jmp(y_dec,"loop")# [1] Decrement Y until 0 – creates delay
21
wrap()# Loop back to start
22
23
# Create a state machine (0) using the PIO program, output on GPIO16
24
sm=rp2.StateMachine(0,echo,out_base=Pin(16))
25
26
# Activate the state machine (start running)
27
sm.active(1)
28
29
# Function to set the output frequency (tone)
30
defplay(freq):
31
iffreq:
32
# Compute the delay count from CPU frequency and tone frequency
33
# cpufreq()/freq/2 is half the period in CPU cycles
34
sm.put(max(0,round(cpufreq()/freq/2)-6))# Send delay count to PIO program
35
else:
36
sm.put(0)# Send 0 to stop toggling
37
sm.active(0)# Deactivate the state machine (silence output)
Nach Bereinigung der imports hatte sich dort mittels copy'n'paste error Folgendes verewigt:
1
@rp2.asm_pio(sideset_init=PIO.OUT_LOW)
2
sm = rp2.StateMachine(0, toggle, sideset_base=25)
Da ich aber bereits selektiert importiert hatte:
1
from rp2 import PIO, StateMachine, asm_pio
sollten die Zeilen in:
1
@asm_pio(sideset_init=PIO.OUT_LOW)
2
sm = StateMachine(0, toggle, sideset_base=25)
also ohne ›rp2.‹ davor abgeändert werden. Es wird nur deshalb keine Exception geworfen, da µPy insgeheim beim Start schon ›machine‹ und ›rp2‹ automagisch importiert.
Da bei deiner gezeigten Version noch mehrere Varianten importiert werden,
also Autoimport rp2, manueller import rp2, selektierter import PIO,usw. isses jedoch egal, welche der Arten man benutzt.
Sechs sieht mir auf Anhieb ganz gut aus.
Aber bedenke, nach einem play(0) ist das Ding ohne erneutes sm.active(1) tot wie ein Papagei.
Und der erste sm.active(1) nach StateMachine erzeugt etwas unkontrolliertes/uninitialisiertes. Erst der erstmalige play() Aufruf setzt den Schleifenzähler korrekt.
Noch eins: Wenn der play(0) im ungünstigen Zeitpunkt kommt, dann kann der Ausgang mit einer 50:50 Chance auf High bleiben, was man möglicherweise nicht wirklich will.
Da ich ein Rechtecksignal brauche, habe ich das Programm mal korrigiert.
Ich denke, die Zyklenkorrektur muss 6 betragen:
So wie das Programm jetzt aussieht passt 6.
Das sieht man mit einem Oszilloskop oder Frequenzzähler sofort, wenn man bei play() einen so hohen Wert eingibt, dass sm.put(0) aufgerufen wird.
Bei 125MHz CPU Takt erhält man damit etwa 10,42MHz am GPIO, also 125MHz/12.
Wenn man die beiden Zeilen
mov(pins, isr)
mov(isr, invert(isr))
durch die eine Zeile
mov(pins, invert(pins))
ersetzt kommt man auf max. 12,5MHz am GPIO.
also ohne ›rp2.‹ davor abgeändert werden. Es wird nur deshalb keine
Exception geworfen, da µPy insgeheim beim Start schon ›machine‹ und
›rp2‹ automagisch importiert.
Ah, danke.
Stefan K. (stk)
18.10.2025 10:59
So wie das Programm jetzt aussieht passt 6.
Das sieht man mit einem Oszilloskop oder Frequenzzähler sofort, wenn man
bei play() einen so hohen Wert eingibt, dass sm.put(0) aufgerufen wird.
Bei 125MHz CPU Takt erhält man damit etwa 10,42MHz am GPIO
Das ist eine gute Idee. Ich hatte das Signal mit einem Frequenzzähler bei 1kHz gemessen und es sah erst mal gut aus. Aber an die Grenze zu gehen, ist natürlich besser.
Interessant, dass man nur bis ca. 12MHz bei SysClk=150Mhz kommt. Darüber hatte ich gar nicht nachgedacht, weil mich eher die Genauigkeit der Frequenzen im Audiobereich interessiert haben.
Aber für das weiter oben angedachte Experiment als UKW Sender währen natürlich 108MHz interessanter. Ob man wohl die PLL in Mikropython schnelle genug für die FM-Modulation umkonfigurieren könnte?
Interessant, dass man nur bis ca. 12MHz bei SysClk=150Mhz kommt.
18.75MHz mit dem weiter oben gezeigten PIO Programm.
Ist aber komplett sinnbefreit, da die Abstufung astronomisch groß wird.
Die maximal mögliche erzeugbare Frequenz beträgt ½·SM_F.
sideset(1)
sideset(0)
in wrap() gewickelt.
Interessant, dass man nur bis ca. 12MHz bei SysClk=150Mhz kommt.
18.75MHz mit dem weiter oben gezeigten PIO Programm.
Ist aber komplett sinnbefreit, da die Abstufung astronomisch groß wird.
Die maximal mögliche erzeugbare Frequenz beträgt ½·SM_F.
sideset(1)
sideset(0)
in wrap() gewickelt.
Das ist so nicht ganz richtig. Das ist, was man maximal als Rechteck-Grundwelle erzeugen kann.
Mit klugen Tricks ist es aber sehr wohl möglich, basierend darauf ein (wenn auch ziemlich schmutziges) UKW-FM-Signal zu erzeugen. Man nutzt halt aus, dass Rechtecke sehr viele Oberwellen enthalten.
Das ist so nicht ganz richtig. Das ist, was man maximal als
Rechteck-Grundwelle erzeugen kann.
Es müsste mehr gehen. Einfach die PIO nur den Pin togglen lassen und die
PIO mit Systemtakt laufen lassen. Dann den Systemtakt auf 216MHz.
Leute! Jetzt aber mal STOPP! Ihr bewegt euch im Bereich der Flugnavigation. Muss das sein? Die Russen hauen schon in weiten Arealen die GNSS Navigation kaputt.
Bist du Amateurfunker? Wie viel Leistung kann den so ein Raspi-Pin
abstrahlen?
Nein, bin ich nicht. Ich weiß aber auch nicht was da hinten noch alles dran hängt.
Und die Flugfunknavigation, Localizer, Glidepath, VOR, … stören, auch wenn nur möglicherweise, da ist meine Toleranzschwelle noch nicht einmal ein Epsilon über 0.
Das mag damit zusammen hängen, dass man sich da oben recht gerne gerade in IMC auf die Geräte verlassen und nicht zu einer Statistik werden möchte.
Ich versuche, die Länge eines Pulses zu messen, aber es sieht so aus, als wenn die PIO das Eingangssignal ignoriert. Nach ca.32 Sekunden läuft der Zähler über, dann kommt jeweils ein Wert.
Eigentlich sollte das Programm ganz einfach funktionieren: Auf eine 1/0 Flanke an PIN16 warten und dann solange zählen, bis der Pegel wieder auf 1 springt. Es will aber einfach nicht funktionieren. Weis jemand, warum?
1
#!/python
2
# vim: fileencoding=utf-8: ts=4: sw=4: expandtab:
3
4
importrp2
5
frommachineimportPin
6
importtime
7
8
######### PROGRAMm funktioniert nicht !!! ####################
Man kann ja z.b. keine Konstanten >31 direkt ins X-Register laden. Außerdem scheint der Jump über den Testpin nur auf High-Werte zu funktionieren. Aus diesem Grunde habe ich nur die Low-Periode gemessen und dann einfach x2 genommen. Das Ergebnis kann man nicht unbedingt als genau bezeichnen. Hier mal für 1kHz:
1
>>> %Run -c $EDITOR_CONTENT
2
cpufreq: 125000000
3
f= 1000.032 Hz
4
f= 1000.032 Hz
5
f= 1000.032 Hz
6
f= 1000.032 Hz
7
f= 1000.032 Hz
8
f= 1000.032 Hz
9
f= 1000.032 Hz
10
f= 1000.032 Hz
11
f= 1000.032 Hz
Ich vermute, es liegt an der unscharfen Flanke, weil ich den Funktionsgenerator mit 3.3kOhm angeschlossen habe.
Möglich … Unwahrscheinlich.
Verstand würde implizieren, dass man sich mit der momentanen Situation um den größeren Bereich ›baltic sea‹ vertraut macht und Informationen diesbezüglich sammelt. Und da wir uns über Aviation unterhielten, wäre das wohl der maßgebende Bereich. Mit ein wenig Glück fände derjenige sogar eine oder mehrere offizielle Webseiten, auf denen dies ständig dokumentiert wird.
ad1: Ich mach's noch leichter. Einfach mal ›EASA GPS outage‹ versuchen.
Ich versuche, die Länge eines Pulses zu messen, aber es sieht so aus,
als wenn die PIO das Eingangssignal ignoriert. Nach ca.32 Sekunden läuft
der Zähler über, dann kommt jeweils ein Wert.
Mal etwas Themen-bezogenes. Du Kennst das "Erratum/Errata 9" für den PI Pico 2?
Hat mir, trotz externer Pulldown-Beschaltung, sporadisch Fehler bei der Auswertung eines Eingangssignals beschert. Ich musste auf den PI Pico zurückgreifen. Eine neue Chip-Version des PI Pico 2 (A4) ist als Chip schon verfügbar - aber habe ich bisher nicht als Developement-board verfügbar gesehen.
Mal etwas Themen-bezogenes. Du Kennst das "Erratum/Errata 9" für den PI
Pico 2?
Das ist ein guter Hinweis. Für die bisherigen Experimente habe ich einen RP20240 benutzt. Heute morgen habe ich mal den selben Micropython-Frequenzzähler wie oben ohne Änderung auf einem RP2350 laufen lassen. Es hat auch funktioniert, nur die Frequenzauflösung war etwas besser, weil der RP2 etwas schneller läuft.
Wie man oben sieht, ist der Pin aber als Pull-Up konfiguriert. Auf den ersten Blick habe ich keine Ausreißer gesehen.
Durch die Codezeilen
1
# wait for rising edge
2
wait(0, pin, 0)
3
wait(1, pin, 0)
kann man nur jede zweite Welle messen. Ich mal versucht, diese Synchronisation weg zu lassen, aber dann wird die Messung ziemlich verrauscht. Das liegt aber wahrscheinlich am langsamen lesen des FIFOs durch die Python-Loop, die dann die PIO bremst.
Falls sich deine Beobachtung auch beim Konfiguration als Pull-Up bestätigen würde, müsst man man einen Langzeitversuch machen und die Daten über ein paar Minuten aufzeichnen.
Wenn man den Pin (input) mit weniger als 8kΩ ansteuert, tritt dieser Fehler nicht auf. Selbst bei höchsten Frequenzen im 100MHz Bereich kann man noch, wie hier, einen 160Ω Widerstand in Serie zwischen /input/ und /output/ legen.
Habe das ganze Zeug sowohl auf RP2040 als auch auf RP2350 getestet und völlig problemlos laufen.
Der geschilderte Fehler tritt nur bei hochohmiger Ansteuerung auf, wenn weniger als ca. 100µA bei low Pegel aus dem /input/ fließen können.
ad1:
Diese Ausgaben der Messungen hier kommen direkt aus dem RP2350:
Falls sich deine Beobachtung auch beim Konfiguration als Pull-Up
bestätigen würde, müsst man man einen Langzeitversuch machen und die
Daten über ein paar Minuten aufzeichnen.
Wäre vielleicht sinnvoll - aber ein Zurück auf den PI Pico tuts auch. Anbei ein Bild in welchem ich Taktsignale (gelb) auswerte - und bei Erkennen ausgebe (grün). Der Fehler ist sporadisch, aber im Kontext (ich werte Signale zur Display-Steuerung aus) mehr als störend.
Micropython ist für das Programmieren der PIO unglaublich praktisch, weil der Syntax viel einfacher als für C ist.
Um die maximale Geschwindigkeit zu erreichen, ist aber C unvermeidlich.
Mich wundert dass noch keiner einen Konverter geschrieben hat, um Micropython PIO-Code in C umzuwandeln so wie es hier gebraucht wird: https://wokwi.com/tools/pioasm
Um die maximale Geschwindigkeit zu erreichen, ist aber C unvermeidlich.
Wenn man wirklich maximale Geschwindigkeit erreichen will, ist Assembler unvermeidlich. Braucht man aber fast nie, genauso wenig wie C.
Ich selbst habe in den letzten Jahren nur eine Handvoll C-module für µPy geschrieben. Die waren dann aber auch wirklich ziemlich extrem.
Alles andere kann man durch vernünftige Programmierung abfrühstücken. Wenn man sich eingehend mit dem System beschäftigt.
Nur – im Sinne von ausschließlich – mit µPy geschrieben:
IRQs pro Sekunde irgendwo im hohen fünf, niedrigen sechs-stelligen Bereich.
Monitoransteuerung inkl. Grafik- und Fensterroutinen.
Signalerzeugung und Frequenzmessung bis in den drei-stelligen MHz Bereich.
Logic-Analyser 16 Kanäle
Audio-Signalerkennung und Auswertung
Ich such' mal ein oder zwei Videos heraus.
ad1: Direkt mit dem Clever-Telefon vom Eizo 22" Monitor
Bisschen komprimiert, bei der Originalgröße käme ich hier auf die Strafbank.
Die Datei heißt eigentlich µPy4.mp4, ist aber von der Foren-SW verändert worden. Abspielbar mit mpv,vlc,mplayer,smplayer
Wenn man wirklich maximale Geschwindigkeit erreichen will, ist
Assembler unvermeidlich. Braucht man aber fast nie, genauso wenig wie C.
Du brauchst die hohe Geschwindigkeit zum Beispiel IMMER dann wenn du Energieprobleme hast. Es ist ein Unterschied ob deine Kiste 2Monate oder 2Jahre mit einer Batterie laeuft. Oder auch wenn die Energie begrenzt ist wegen Solarzelle oder Feldbus. Oder einfach wenn du kommerziell unterwegs bist weil es bedeutet das du mit derselben (preislich) Hardware wie die Konkurrenz viel mehr Funktionalitaet hast.
Zum basteln zuhause ist es sicher oft egal! Aber sobald deine Ansprueche darueber hinaus gehen ist C/C++ im Embeddedbereich selbstverstaendlich.
Programmierung in Assembler dagegen ist in der Tat sehr exotisch/selten geworden. Es ist aber immer noch notwendig es zu koennen damit du bei komplexen Problemen auf Assemblerlevel debuggen kannst. Auch nicht jeden Tag, aber so 1x im Jahr kommt das vor. Das ist dann manchmal der Tag an dem du einen Bugreport an den Compilerhersteller schreiben kannst. Ich meine irgendeiner muss ja die Bugs finden oder? :-)
Du brauchst die hohe Geschwindigkeit zum Beispiel IMMER dann wenn du
Energieprobleme hast.
Wer Energieprobleme hat, nutzt ganz sicher keinen Pico (oder nur wenn's gar nicht anders geht). Die Dinger sind nun wirklich nicht für Batteriebetrieb ausgelegt.
Programmierung in Assembler dagegen ist in der Tat sehr exotisch/selten
geworden.
Wenn die ersten drei erlernten Sprachen Maschinencode/Assembler waren, dann empfindet man das als völlig natürlich. Natürlich schreibt man heute kein komplettes Programm in Assembler, nur die Routinen wo es massig Umpf braucht.
Hatte ich erwähnt, das µPy ganz nebenbei einen Assembler eingebaut hat? ;-)
Und so ein Bild auf dem Monitor kann man mit µPy übrigens auch erzeugen.
Wenn man's richtig macht. Ohne Assembler und ohne C übrigens.
Da habe ich viel über Video-Formate gelernt.
Muss man allerdings – wie bei dem gezeigten Video auch – alles, wirklich alles, selbst programmieren. Nix Schublade auf und module importieren.
Wenn die ersten drei erlernten Sprachen Maschinencode/Assembler waren,
dann empfindet man das als völlig natürlich.
Ich hab mal MCS48, MCS51, Z80, ST6, Saturn, ESRH, 6502 und 68k Assembler gelernt. Trotzdem wuerde ich nicht sagen das ich heute ARM oder Risc/V mal eben gut also sinnvoll in Assembler programmieren kann. Irgendwas hinschludern das geht, ja, aber programmieren ist was anderes! Wo man es genau drauf hat um wirklich noch besser wie ein Compiler zu sein. Das ist nicht mal eben so gemacht. Deshalb ist es ja auch weitestgehend ausgestorben.
Micropython ist für das Programmieren der PIO unglaublich praktisch,
weil der Syntax viel einfacher als für C ist.
Was ich bislang als Code so gesehen habe, scheint mir doch recht gewöhnungsbedürftig ;-)
Syntax hin oder her: wenn es schnell gehen soll, muß man genau wissen, was man eingibt, und da helfen ein Blatt Papier und eigene Kopfarbeit enorm - bei mir zumindest.
Die PIOs habe ich mir mit einer IAR-IDE in C programmiert. Damit kann man ganz elegant zur Laufzeit eine PIO starten und stoppen, einzelene Befehle von C aus ausführen lassen und beim Debuggen das PIO-Programm manuell verändern.
Für größere PIO-Programme könnte man per DMA auch die Befehle aus einer Tabelle ausführen lassen oder eine PIO zur Laufzeit umprogrammieren.
Aber gut, wohl etwas speziell das Ganze.
Wie man im Code sieht, kann man die SDK-API benutzen.
Ich habe den angehängten PIO-Code, der dem Micropython-Code entspricht mit dem Onlineassembler assemblieren lassen: https://wokwi.com/tools/pioasm
Leider hängt es noch irgendwo ..