Moin,
hier kommt ein Follow-Up zu meinem Beitrag [0]. Weil ich seit kurzem mit
STM8 Controllern herumspiele, dachte ich mir es wäre doch ganz nett,
dieses Projekt vom AVR auf den STM8 zu portieren. Was soll ich sagen:
das ging viel leichter als erwartet. Das liegt sicher auch daran, daß
der STM8 genügend PWM-Kanäle hat, um die PWM komplett in Hardware zu
machen.
Schaltbild:
1
TSOP STM8S103F3
2
34136 Evalboard
3
.-----. .------------.
4
| 3|----+-[100R]--|3.3V 5V|-------------.
5
| 2|-. | | | |
6
| 1|-)--)---------|PA1 PD4|--|<--[150R]-+ red
7
'-----' | | | | |
8
| = 100nF | PD3|--|<--[220R]-+ green
9
| | | | |
10
'--+---------|GND PA3|--|<--[150R]-' blue
11
'------------'
Das Evalboard ist bei mir ebay Nummer 171907337886, die LED sind 5mm
Typen von Pollin, dito der TSOP34136. Der ganze Krempel steckt derzeit
auf einem Breadboard, als Programmer dient ebay Nummer 121507212413.
Aber auch ein STLINK V1 von einem STM8 Discovery funktionierte.
Die Hardware ist ziemlich geradezu. Der TSOP wird aus der auf 3.3V
stabilisierten Betriebsspannung des STM8 versorgt (auf dem Evalboard ist
dafür ein LT1117-3.3 verbaut). Die LED werden L-aktiv gegen 5V
getrieben, das hauptsächlich deswegen weil dann die Wahl der
Vorwiderstände (für 10mA) etwas entspannter abläuft als gegen 3.3V.
An Software braucht man den SDCC [1]. Bei mir in Version 3.5.0 (ab 3.4.0
wird der STM8 unterstützt, allerdings offenbarte ein Blick auf den von
3.4.0 generierten Assemblercode gar grausliches; ich empfehle also
dringend den SDCC 3.5.0+ zu verwenden, der geht gut). Ferner braucht man
stm8flash [2], make und (optional, zur Neu-Erzeugung der PWM-Tabelle)
Perl. Linux-Nutzer haben das alles an Bord bzw. können es über das
System-Packagemanagement nachinstallieren.
Die beigelegte stm8s.h wurde aus der STM8S Standard Peripheral Library
von ST in Verbindung mit [3] erzeugt (plus ein paar manuelle Edits). Für
die prinzipielle Funktion verweise ich auf den Vorgängerthread [0].
Noch ein paar Notizen:
- beim Eintritt und Verlassen der irmp_ISR() schalte ich die User-LED
auf dem Board (PB5) ein bzw. aus. Damit kriegt man einen ungefähren
Eindruck, wieviel Zeit der µC im Interrupt-Handler verbringt.
- im Prinzip würde die Sache auch mit 8MHz Systemtakt funktionieren.
Allerdings kann der STM8 jetzt 250 Helligkeitsstufen (statt 208 beim
AVR) auflösen. Und damit die Lichtprogramme auch schnell ablaufen
können, habe ich einfach den Systemtakt auf das Maximum von 16MHz
gestellt, was dann gut 240Hz PWM-Frequenz ergibt. Wer hat, der kann ;)
- die notwendigen Änderungen an IRMP habe ich als separates diff File
angehängt. Falls der Patch wegen Zeilenendungen nicht applied - sorry,
aber DOS Zeilenendungen nerven einfach. Deswegen ist das eine meiner
ersten Aktionen, das gerade zu rücken.
- der gesamte Code belegt 3333 Byte von 8KB Flash und 57 Bytes von 1KB
RAM. Da ist also noch Luft. Es erstaunt mich etwas, daß der STM8 damit
kaum mehr Programmspeicher verbraucht als der ATmega8. Obwohl der STM8
vergleichsweise spartanisch ausgestattet ist. Und der SDCC ein viel
minimalistischerer Compiler ist als der (avr-)gcc.
Happy Hacking!
[0] Beitrag "noch ein AVR Moodlight"
[1] http://sdcc.sourceforge.net/
[2] https://github.com/vdudouyt/stm8flash
[3] https://github.com/gicking/SPL_2.2.0_SDCC_patch
Hallo,
hier kommt eine neue Software-Version. Was hat sich geändert:
- das Makefile wurde mächtig aufgebohrt und kann jetzt 'make depend'
- es wird nur noch ein Timer-Interrupt verwendet
- Master-Clock und CPU-Clock wurden verringert auf das nötige Minimum
- man kann jetzt zur Compilezeit zwischen zwei Fernbedienungen wählen
- Unmengen Bugfixes
Auch die Änderungen an IRMP habe ich nochmal überarbeitet. Die sind
jetzt final (wenn Frank nicht noch was auszusetzen hat ;)
Außerdem habe ich noch ein kleines Tool dazugepackt (lirc2irmp.zip) mit
dem man eine Fernbedienung die man in LIRC (http://www.lirc.org/) erfaßt
hat auch für IRMP verwenden kann:
1
lirc2irmp.pl xyz.lirc >xyz.h
funktioniert zwar nur für das NEC Protokoll, aber etwas anderes brauchte
ich bisher auch nicht.
Für alle Anwender von SDCC noch eine Warnung: der Code wird vom derzeit
neuesten SDCC Release (3.5.0) nur dann korrekt übersetzt, wenn man mit
"--max-allocs-per-node 1000" übersetzt. Sonst verhakelt sich SDCC in der
Schachtelung aus case/if/if in moodlight_remote(). Sobald ich einen
kurzen Testcase gefunden habe der das Problem demonstriert, werde ich
einen Bug reporten. Ehrlich gesagt steige ich durch den von SDCC
generierten Assemblercode noch nicht durch. Ich kann aber sehen daß er
nicht funktioniert.
Ich will an dem Projekt noch ein bißchen feilen. Z.B. will ich die
Fernbedienungscodes aus dem Programm werfen und im EEPROM speichern.
Dann kann man die Fernbedienung wechseln ohne das Programm neu zu
compilieren. Und man soll auch mehrere Fernbedienungen verwenden können
sollen. Dazu suche ich noch Feedback:
Beitrag "Umfrage: welche IR-Protokolle nutzt ihr mit IRMP?"
Axel S. schrieb:> Ich will an dem Projekt noch ein bißchen feilen. Z.B. will ich die> Fernbedienungscodes aus dem Programm werfen und im EEPROM speichern.> Dann kann man die Fernbedienung wechseln ohne das Programm neu zu> compilieren. Und man soll auch mehrere Fernbedienungen verwenden können> sollen. Dazu suche ich noch Feedback:> Beitrag "Umfrage: welche IR-Protokolle nutzt ihr mit IRMP?"
Da würde mich schon mal vorab das Design interessieren. Das ist manchmal
spannender als Details der Implementierung.
Ich habe in einer Neuauflage von
http://www.mystrobl.de/Plone/basteleien/weitere-bulls-and-cows-mastermind-implementationen/mm-v1821/mastermind-solver-mit-led-streifen-und-ir-fernbedienung
, in der die Fernbedienungscodes auch noch hart verdrahtet waren, das so
gelöst, daß die drei Knöpfe, die ich da brauche (+,-,ENTER) in der Form
protocol, address, command im EEPROM gespeichert werden. Es gibt zwar
eine Vorbelegung, jedoch läßt sich jede Fernbedienung, deren Protokoll
enabled ist, anlernen, indem zunächst irgend eine Taste zwölf mal
hintereinander gedrückt wird (ohne Wiederholungsflag) und dann die
nächsten drei Tastendrücke mit passendem Protokoll und passender Adresse
als die o.a. Funktionen im EEPROM gespeichert werden. Funktioniert
erstaunlich gut, jedenfalls besser als vorherige Versuche mit
Tastenfolgen.
Die wesentliche Idee dabei war, nach dem Triggern durch genügend viele
gleiche Tastendrücke zunächst sofort zu signalisieren "hab's gemerkt",
dann aber eine Totzeit von ca. 1 s einzulegen und erst dann "warte auf
ersten Tastendruck" usw. zu signalisieren. Auf diese Weise kommt es
auf das Abzählen der Tastendrücke nicht an, man morst einfach so lange,
bis eine Reaktion kommt und wartet dann auf die Aufforderung zum ersten
Tastendruck usw.
Mehrere Fernbedienungen zu unterstützen wirft die Frage auf, wie man
alte angelernte wieder los wird, ohne das zu kompliziert zu machen.
Eine Tastenkombination "vergiss mich" erfordert, daß die zu vergessende
Fernbedienung noch verfügbar ist. Dann lieber Verwaltung in einem
Ringpuffer (älteste werden jeweils überschrieben) und eine Kombination
"alles vergessen".
Hi Axel,
Axel S. schrieb:> hier kommt ein Follow-Up zu meinem Beitrag [0]. Weil ich seit kurzem mit> STM8 Controllern herumspiele, dachte ich mir es wäre doch ganz nett,> dieses Projekt vom AVR auf den STM8 zu portieren.
Vielen Dank für den IRMP-Port auf STM8 - und danke für das diff-File :-)
Sehr schön gemacht: das passt perfekt. Ich habe Deine Änderungen
eingearbeitet und als IRMP-Version 2.9.6 hochgeladen. Den IRMP-Artikel
habe ich aktualisiert.
P.S.
Planst Du auch noch eine Portierung von IRSND? ;-))
Frank M. schrieb:> Vielen Dank für den IRMP-Port auf STM8 - und danke für das diff-File :-)
Nichts zu danken. Ich bin froh, daß ich etwas zurückgeben konnte für
dein schnuckeliges IRMP Projekt :D
> Sehr schön gemacht: das passt perfekt. Ich habe Deine Änderungen> eingearbeitet und als IRMP-Version 2.9.6 hochgeladen. Den IRMP-Artikel> habe ich aktualisiert.
Ich habe noch zwei kleine Anmerkungen zu meinem Patch.
+ IRMP_GPIO_STRUCT->DDR &= ~(1<<IRMP_BIT); // pin is input
10
#else // AVR
11
IRMP_PORT &= ~(1<<IRMP_BIT); // deactivate pullup
12
IRMP_DDR &= ~(1<<IRMP_BIT); // set pin to input
Hier sollte man vielleicht die Reihenfolge der Operationen umkehren.
Also den Pin erst als Eingang setzen und dann den Pullup einschalten.
Denn sonst kann es unter ungünstigen Umständen dazu kommen daß der Pin
für ein paar Dutzend Nanosekunden als Ausgang einen H-Pegel treibt. OK,
dazu muß der Benutzer ihn erst manuell als Ausgang konfiguriert haben.
Default nach Reset ist Input.
Das ist leider nicht so generisch wie es sein könnte. Das Headerfile
heißt nur für die STM8Sxxx und STM8AFxxx so. Für die STM8Lxxx und
STM8ALxxx heißt es "stm8l15x.h". Der Name ist dämlich gewählt, weil der
STM8L Port der Standard Periperal Library keineswegs nur für STM8L15x
paßt, sondern auch für STM8L05x und weitere. Viel besser wäre "stm8l.h"
gewesen ...
Auf jeden Fall hat man etwas extra Arbeit, wenn man einen STM8L
verwenden will. Am einfachsten kopiert man wohl die stm8l15x.h unter dem
Namen stm8s.h in sein Projekt.
> P.S.> Planst Du auch noch eine Portierung von IRSND? ;-))
Nicht in den nächsten Tagen. Aber man soll niemals nie sagen :)
Axel S. schrieb:> Hier sollte man vielleicht die Reihenfolge der Operationen umkehren.> Also den Pin erst als Eingang setzen und dann den Pullup einschalten.
Okay, habe ich geändert. Kommt dann aber erst mit der nächsten Version,
da ich diese "Unschönheit" als unkritisch ansehe.
> Das ist leider nicht so generisch wie es sein könnte. Das Headerfile> heißt nur für die STM8Sxxx und STM8AFxxx so. Für die STM8Lxxx und> STM8ALxxx heißt es "stm8l15x.h".
Das ist schade. Gibt's da keine Preprozessor-Konstante, die man abfragen
könnte, um den genauen Typ des Prozessors abzufragen?
>> Planst Du auch noch eine Portierung von IRSND? ;-))> Nicht in den nächsten Tagen. Aber man soll niemals nie sagen :)
Klar. So etwas macht man erst, wenn man es selbst auch braucht.
Frank M. schrieb:> Axel S. schrieb:
...
>> Das ist leider nicht so generisch wie es sein könnte. Das Headerfile>> heißt nur für die STM8Sxxx und STM8AFxxx so. Für die STM8Lxxx und>> STM8ALxxx heißt es "stm8l15x.h".>> Das ist schade. Gibt's da keine Preprozessor-Konstante, die man abfragen> könnte, um den genauen Typ des Prozessors abzufragen?
Jein. Die SPL erfordert, daß man ein #define mit dem genauen Typ der MCU
anlegt, weil sie abhängig davon die SFR structs an der für jene MCU
gültigen Adresse plaziert.
Man könnte jetzt also die komplette Liste der MCU abfragen die in
stm8s.h respektive stm8l15x.h abgehandelt werden. ca. so:
1
#if defined (STM8S208) || defined (STM8S207) || defined (STM8S105) || \
2
defined (STM8S103) || defined (STM8S903) || defined (STM8AF52Ax) || \
3
defined (STM8AF62Ax) || defined (STM8AF626x) || defined (STM8S007) || \
4
defined (STM8S003) || defined (STM8S005) || defined (STM8AF622x)
5
6
# include "stm8s.h"
7
8
#elif defined (STM8L15X_MD) || defined (STM8L15X_MDP) || defined (STM8L15X_HD)
9
10
# include "stm8l15x.h"
11
12
#else
13
# error "unknown STM8 mcu!"
14
#endif
Finde ich allerdings ziemlich häßlich. Und falls(?) ST irgendwann mal
eine neue MCU in die STM8 Familie aufnimmt, paßt es natürlich nicht
mehr.
Axel S. schrieb:> Finde ich allerdings ziemlich häßlich.
Wenn man sich die ganzen Preprocessor-Statements im IRMP-Source näher
anschaut, dann ist das sowieso schon hässlich[1]. Also ich hätte nichts
dagegen, das genau so einzubauen.
[1]
Frank M. schrieb:> Wenn man sich die ganzen Preprocessor-Statements im IRMP-Source näher> anschaut, dann ist das sowieso schon hässlich[1]. Also ich hätte nichts> dagegen, das genau so einzubauen.
[x] make it so!
Wobei, warte mal noch bis ich das eingebaut habe und bestätigen kann daß
es durch den Compiler läuft.
Kurzbericht:
Ein STM8S103-board von Pollin mit einer RGB-LED zusammengesteckt, das
ganze Projekt in die kostenlose, aber begrenzte IAR-workbench gezogen,
alle IRMP-Bezüge entfernt, weil kein IR-Empfänger zur Hand, beim ersten
Compilieren über die Binärdarstellung ("0b00001010") gestolpert, IAR
kennt diese nicht, in Hex ("0x0A") umgeschrieben ... läuft sofort.
Nach Fertigstellung eines STM8S103 mit dieser Technologie:
Beitrag "~1€ ARM-Cortex-M0 (STM32)-Bord selbstgestrickt"
wollte ich noch mein moodlight-Galerie zeigen, siehe angehängte Fotos.
Leider ist heute das Licht ganz schlecht ...