Guten Abend,
da es mich interessiert, wie viel man mit wenig Ressourcen machen kann,
möchte ich demnächst ein paar kleinere Projekte mit Mikrocontrollern,
die in Flash- und RAM-Größe sehr beschränkt sind, umsetzen. Speziell hab
ich mir da den PIC 10F220 ausgesucht. Programmiert werden soll er mit
dem PicKit3 und der IDE + C-Compiler von Microchip (Assembler möchte ich
mir nicht antun).
Meine Frage ist nun: Kann man mit 16Byte und dem 8-bit Timer einen
UA[R]T programmieren (zumindest sendend)? Theoretisch bräuchte man nicht
mehr als eine ISR in der die Pins getoggelt werden, so viel RAM dürfte
das nicht benötigen, oder?
Was mich ebenfalls noch interessieren würde, ist, ob sich mit den
beschränkten Ressourcen auch eine Software-I2C Lösung implementieren
ließe? Vom Flash her dürfte das imho kein Problem sein, aber ich weiß
nicht, ob das RAM dafür reicht? Die Funktionalität des I2C-Systems würde
ich auf mehrere Funktionen aufteilen, wenn man davon ausgeht, dass nach
dem Rausspringen aus einer Funktion der RAM, der in der Funktion
benötigten Variablen, freigegeben wird, könnte das klappen, oder? Wie
genau überprüfen ich die Machbarkeit eines Projektes? Bei AVRs teilt
einem avrdude mit, wie viel Flash das Programm benötigt, über die
RAM-Auslastung wird allerdings nichts gesagt. Bekommt man in der
Microchip IDE irgendwie mit, wie viel RAM gerade in Benutzung ist, oder
merkt man das erst, wenn der Controller nicht mehr funktioniert bzw.
komische Dinge macht?
Eine weitere Projektidee wäre das Ansteuern diverser WS2822...
Grüße
Max
Max M. schrieb:> Kann man mit 16Byte und dem 8-bit Timer einen UA[R]T programmieren
Natürlich.
> Software-I2C
Das auch. Bei begrenzten Daten (z.B. TempSensor DS1820) kann man soagr
Daten übernehmen und dann per UART wieder raussenden.
> Wie genau überprüfen ich die Machbarkeit eines Projektes?
Programm erstellen und gucken wie gross es wird ?
Max M. schrieb:> Bekommt man in der> Microchip IDE irgendwie mit, wie viel RAM gerade in Benutzung ist
Im LST File steht doch, welche RAM Zellen belegt sind
MEMORY USAGE MAP ('X' = Used, '-' = Unused)
0000 : XXXX------------ ---------------- XXXXXXXXXXXXXXXX
XX--------------
All other memory blocks unused.
Program Memory Bytes Used: 22
Program Memory Bytes Free: 32746
Eine Auswertung eines 433MHz Funkempfängers und Steuerung eines
Garagentors mit Endschaltern, Handbedienung und Überstromerkennung passt
jedenfalls rein. Der Sender natürlich auch.
Eine Uhr mit Wecker auch, wahlweise eine Stoppuhr oder ein
Rückwärtstimer.
Ein Thermometer mit besagten DS1820 und LCD Glas auch, müsste sogar für
einen Thermostaten reichen wenn simpler on/off Regler reicht.
Reicht es zur Steuerung eines GSM Moduls um Rufnummern zu wählen und
Sprache durchzuschalten, oder GPS Lokation als SMS zu übertragen ? Hängt
wohl im wesentlichen davon ab, wie viele Bytes man zur Authentifizierung
speichern muss, nur die 4-stellige PIN dann reicht es jedenfalls.
>Speziell hab ich mir da den PIC 10F220 ausgesucht.>Programmiert werden soll er mit dem PicKit3 und der IDE + C-Compiler von
Mit 16 Byte RAM ist da wohl nix mehr gross mit C-Compiler.
>(Assembler möchte ich mir nicht antun).
Dann such dir nicht so einen unterbelichteten Schrott
als Controller aus.
Max M. schrieb:> Theoretisch bräuchte man nicht> mehr als eine ISR in der die Pins getoggelt werden, so viel RAM dürfte> das nicht benötigen, oder
Minimum sind der Program Counter und das Statusregister.
Max M. schrieb:> wenn man davon ausgeht, dass nach> dem Rausspringen aus einer Funktion der RAM, der in der Funktion> benötigten Variablen, freigegeben wird, könnte das klappen, oder?
Lokale Variablen werden auf dem Stack oder in den Registern angelegt.
Die sind nach dem Verlassen der Funktion immer wieder frei. Wenn du
allerdings eine Funktion aus einer anderen heraus aufrufst, kommen deren
Variablen natürlich noch oben drauf.
Max M. schrieb:> wie viel RAM gerade in Benutzung ist, oder> merkt man das erst, wenn der Controller nicht mehr funktioniert bzw.> komische Dinge macht
Globale und statische Variablen liegen grundsätzlich im RAM. Die kannst
du zur Not auch selbst zusammenzählen. In den Funktionen mußt du die
Pushs und Pops zählen. Jedes Push zählt ein Byte rauf, jedes Pop eins
runter. Dazu kommen noch der PS, also meistens 2 Bytes und das
Statusregister.
Max M. schrieb:> da es mich interessiert, wie viel man mit wenig Ressourcen machen kann,> möchte ich demnächst ein paar kleinere Projekte mit Mikrocontrollern,> die in Flash- und RAM-Größe sehr beschränkt sind, umsetzen. Speziell hab> ich mir da den PIC 10F220 ausgesucht. Programmiert werden soll er mit> dem PicKit3 und der IDE + C-Compiler von Microchip (Assembler möchte ich> mir nicht antun).
So ein Blödsinn.
Das ist wie: "ich möchte herausfinden, mit wie wenig Mitteln ich in der
Wildnis überleben kann. Dazu habe ich mir ein Waldgebiet ausgesucht.
Jetzt muß ich nur noch meinen Induktionsherd irgendwie angeschlossen
bekommen (Kochen über dem offenen Feuer will ich mir nicht antun)."
Mit C geht bei 16 Byte RAM genau gar nichts. Mit Assembler durchaus.
Mit Assembler kommt man notfalls sogar ganz ohne RAM aus, wenn man alle
Variablen in Registern unterbringt. Das klassische Beispiel ist die
Melodieklingel mit einer zweistelligen Anzahl Liedern, bestehend aus
einer Z80 CPU, einem EPROM und ein paar Gattern/Flipflops [1].
Auf dem Papier sieht der PIC10 ganz gut aus mit seinen 32 Registern und
sogar einem Hardware-Stack. Da mußte man auf dem Z80 noch ohne auskommen
und Register hatte man nur 2x 8. Andererseits ist der PIC Befehlssatz
... gewöhnungsbedürftig. Aber gut, du hast ihn dir selber ausgesucht.
Hättest ja auch einen ATtiny12 oder so nehmen können ...
Ansonsten verstehe ich die Frage nicht. Leg doch einfach los. Du wirst
schon sehen, was geht und was nicht. Aber mit Star-Allüren a'la "ich
will mir nicht die Hände mit Assembler dreckig machen" wirst du so oder
so nicht weit kommen.
[1] siehe z.B. hier
http://eb-harwardt.jimdo.com/8-bit-technik/melo-5-leiterplatten-vorhanden/
Max M. schrieb:> Programmiert werden soll er mit> dem PicKit3 und der IDE + C-Compiler von Microchip (Assembler möchte ich> mir nicht antun).
Dann such Dir einen größeren µC aus. Diese Konfigration schreit gradezu:
"Programmierung nur mit Assembler sinnvoll".
Außerdem sind da selbst zum LED Blinken kaum Pins übrig. Das ist eine
für SOT23-6 gedachte Minimalst-Version die nix kosten darf und schön
klein ist.
Spannend.... Hab ich das Datenblatt richtig verstanden, der hat einen
fixen Stack mit Platz für 2 Rücksprungadressen (und ohne Stack Pointer)?
Heisst das, man könnte bei C nur mit globalen Variablen arbeiten? Oder
kann der Compiler das irgendwie umgehen?
Auf jeden Fall eine Herausforderung, das Ding... ;)
http://ww1.microchip.com/downloads/en/DeviceDoc/40001270F.pdf
Rasputin schrieb:> man könnte bei C nur mit globalen Variablen arbeiten? Oder> kann der Compiler das irgendwie umgehen?
Ja. Der HiTech-Compiler weiss, welche Funktionen von wo aufgerufen
werden und legt die lokalen Variablen so übereinander, dass sie sich
nicht zerstören aber möglichst effektiv wiederverwendet werden.
Daher keine Rekursion und keine Funktionspointer-Funktionen, die zur
Rekursion führen können (Funktionspointer sind aber prinzipiell erlaubt)
Kleiner als 12F675 (64 Byte RAM/1 kWorte Flash/128 byte EEPROM)
tue ich mir und dem XC8/Pro nicht an.
Groesser als 16F684/16F886 aber auch nicht.
Dafuer gibt es dann doch besseres...
holger schrieb:> Dann such dir nicht so einen unterbelichteten Schrott> als Controller aus.
Was soll diese unqualifizierte Aussage?
Hast du dir schon mal die Frage gestellt warum solche kleine Controller
produziert werden?
Nun gut.Wenn also der PIC10F220 deiner Meinung nach unterbelichteter
Schrott ist was ist dann wohl erst ein einzelner Transistor - die
groesste Kacke aller Zeiten oder was?
Hast du dir schon mal die Frage gestellt warum solche kleine Controller
produziert werden?
Warum wird das gemacht, wenn es günstigere und gleichzeitig
leistungsstärkere gibt?
So vor etwa 25 Jahren hatte ich RFID Leser mit PIC16C71 gebaut und
verkauft.
Der hatte auch nicht mehr RAM. Natürlich in Assembler programmiert.
Da war man noch mit jedem Bit per du.
Einigen Schreibern ist offenbar das Wort "wirtschaftlich" halt fremd.
Für einen Einsteiger, und so verstehe ich die Worte zwischen den Zeilen,
ist diese Herausforderung eher ein Hindernis.
Das ist übrigens einer der Gründe für den Arduino gewesen, aber das ist
wieder ein anderes Politikum.
Also @Max, tue Dir selbst einen Gefallen und kauf' einen PIC mit mehr
RAM....
>da es mich interessiert, wie viel man mit wenig Ressourcen machen kann,>möchte ich demnächst ein paar kleinere Projekte mit Mikrocontrollern,
Eine Zeit lange habe ich einen Attiny13 in C-programmiert ( 1 KFlash, 64
Byte Ram ).
Das geht relativ gut in C.
Danke für eure hilfreichen Antworten. Vllt. eine naive Frage, aber warum
kann man den genannten PIC nicht mit der IDE in C programmieren bzw.
warum ist mit Assembler ein größerer Funktionsumfang möglich als mit C?
Liegt. es an den Header-Dateien die man z.B für die ISRs importieren
müsste (wobei die eigentlich im Flash landen). Der Overhead von C müsste
doch hauptsächlich im Flash stattfinden, oder?
Am besten faengst du mal mit dieser Maschine an. Und mit ASM. Dort den
gesammten Befehlssatz plus die zugehoerige Architektur, Register usw
verinnerlichen. Dann heraussuchen, welche Operationen moeglichst RAM
sparend ausgefuehrt werden. Einfach Probieren.
Plus einfache analog Operationen. zB wie mach ich einen 10..12Bit ADC &
DAC, kann ich einen Teddy plaerren lassen, ..
solche Machinen werden gerne fuer Projekte mit ultra hohen Stueckzahlen,
dh groesser als 1 million, eingesetzt. Dafuer werden auch noch 4 bit
Maschinen eingesetzt.
Vor einigen Jahren waren die globalen Stueckzahlen bei den 4 Bit
Maschinen ein Stueck groesser wie die der 8 Bitter. Es gibt Leute, die
Leben ganz gut mit genau solchen Anwendungen. Rechne : Bei 10 Millionen
Stueck 2 Cent sparen macht auch schon 200'000.
Solche spartanisch ausgerüsteten MCs sind nur was für extrem
kostensensitive Anwendungen mit riesen Stückzahlen, wo die
Entwicklungskosten (Zeit) egal sind.
Ich hab damals mit dem ATtiny12/15 experimentiert, die Programmierung
war ein Albtraum. Am schlimmsten war der Hardwarestack. Ich schreibe
gerne modular, da kommt man mit einem nur 3 Level Hardwarestack
überhaupt nicht aus. Ich hab notgedrungen ein Pseudocall-Macro
geschrieben, damit die Programme übersichtlich bleiben.
Ich hab für mich als kleinsten sinnvollen MC den ATtiny25 festgelegt.
Falls es mal klemmt, kann man den einfach auf den ATtiny85 (512Byte RAM)
pimpen.
Max M. schrieb:> Danke für eure hilfreichen Antworten. Vllt. eine naive Frage, aber> warum> kann man den genannten PIC nicht mit der IDE in C programmieren bzw.> warum ist mit Assembler ein größerer Funktionsumfang möglich als mit C?> Liegt. es an den Header-Dateien die man z.B für die ISRs importieren> müsste (wobei die eigentlich im Flash landen). Der Overhead von C müsste> doch hauptsächlich im Flash stattfinden, oder?
Ich würds einfach ausprobieren. Dann wirst du das schon sehen. Du kannst
in MPLABX immer noch auf Assembler umsteigen.
Mach einen Trockenauf - nimm den XC8-Compiler, setz ein Blink-Beispiel
auf und lass es durchrattern.
Dann siehst du ja, ob der Compiler das da reinbringt.
Ich tipp mal drauf, dass man damit schon was machen kann, auch mit C.
Für geschätzte 90% der Projekte hier reicht das (LED blinken lassen).
Was schon klar sein muss: Mit Assembler ist man da natürlich besser dran
;-)
Für C und Minimalisten würde ich den PIC12F1840 empfehlen. Der hat auch
nur 8 Haxen, hat aber komforatbel Flash und satt Periperie. Damit kann
man schon richtig was anfangen.
Eine richtige Herausforderung ist aber immer die Anzahl an Pins bei dem
Teil.
Max M. schrieb:> Danke für eure hilfreichen Antworten. Vllt. eine naive Frage, aber warum> kann man den genannten PIC nicht mit der IDE in C programmieren bzw.> warum ist mit Assembler ein größerer Funktionsumfang möglich als mit C?
Das letztere hat überhaupt niemand gesagt. Und C geht (vielleicht mit
Ausnahme einiger Spezial-Compiler) deswegen nicht, weil es auf
Architekturen mit einer Mindest-Größe an RAM zugeschnitten ist.
Ein C-Compiler erwartet z.B. einen Stack, der nicht nur Rücksprung-
adressen, sondern auch Funktionsparameter aufnehmen kann. Ein C-Compiler
hält Variablen im RAM und lädt sie nur zur Optimierung mal für längere
Code-Abschnitte in Register. Eine Variable rein im Register geht oft nur
für lokale Variablen.
> Der Overhead von C müsste> doch hauptsächlich im Flash stattfinden, oder?
Es liegt nicht am Overhead, sondern an ABI Design-Entscheidungen. Wenn
man z.B. Parameter- und Returnwert-Übergabe ausschließlich in Registern
macht, dann braucht man kein RAM für einen Stack. Wenn man die Variablen
bezüglich Anzahl und Größe so einschränkt, daß sie alle in Register
passen, dann braucht man kein RAM für Variablen. Allerdings kriegt man
so keinen vollwertigen C-Compiler, denn etliche gültige Programme wird
man damit einfach nicht übersetzen können.
Am Ende läuft es darauf hinaus, daß man das bißchen Funktionalität, das
man mit einem derartig abgespeckten C-Compiler erzeugen kann, auch
gleich in Assembler schreiben kann. Womit wir wieder beim Anfang wären.
Und bevor du fragst: Assembler hat das Problem nicht, weil es da kein
starres ABI gibt. Wie du Werte an Funktionen übergibst, kannst du machen
wie du lustig bist. Wenn du keinen Stack hast, kannst du halt kein
CALL/RET (oder wie immer das auf der jeweiligen Architektur heißt)
benutzen. Und um die Anordung deiner Variablen in RAM und/oder Registern
mußt du dich auch alleine kümmern.
Ich habe mal eine DCF-77 Uhr mit einem µC ganz ohne RAM in Assembler
programmiert. Der hatte nur relativ viele Register (wie AVR's) und genau
ein Register für die Rücksprungadresse der ISR.
Heute würde ich das nie wieder tun, damals hatte ich es als Gehirnsport
empfunden. Was tut man nicht alles sinnloses, einfach nur weil man es
kann?
Max M. schrieb:> Der Overhead von C müsste> doch hauptsächlich im Flash stattfinden, oder?
Nein, der Programmspeicher ist meistens überhaupt nicht das Problem.
Aber, nur zum Beispiel, man könnte ewig so weitermachen: in Assembler
bestimmt der Programmierer, was beim Aufruf einer Funktion auf dem Stack
abgelegt ist und wie tief die Aufrufe verschachtelt sind. Bei C ist eine
Prozedur wie etwa printf natürlich kein einfacher Aufruf, sondern die
ruft andere, einfachere Prozeduren usw. auf und dein Stack ist
übergelaufen ohne dass du weisst warum, von Variablen mal ganz
abgesehen.
Stefan schrieb:> Für den, der weiß was er tut, ist da C kein Problem.
Unbestritten, man kann auch ein C-Programm bis in den letzten Aufruf
analysieren. Nur ist es dann auch nicht bequemer als Assembler, und für
die Probleme muss man dann ja auch noch Abhilfe schaffen. Da bleibe ich
lieber gleich bei Assembler und habe alles im Griff (hoffentlich).
Teilweise habe ich es auch schon umgekehrt gemacht: ein
Assemblerprogramm mit geringstem Resourcenverbrauch geschrieben, das
eine einzelne C-Funktion aufruft, etwa für eine Fliesskommarechnung.
Aber da muss man wirklich wissen was man tut.
Ein Anfänger wie der TO kann sich natürlich sagen, interessiert mich
alles nicht, soll der Compiler machen. Aber dann ist der Ansatz mit
einem Kleinstcontroller natürlich völlig falsch, er sollte gleich einen
Arm mit haufenweise Rom und Ram nehmen. Allerdings wird er dann nie
etwas über die internen Details wisssen, aber das Knowhow stirbt sowieso
aus.
Georg
Georg schrieb:>> doch hauptsächlich im Flash stattfinden, oder?>> Nein, der Programmspeicher ist meistens überhaupt nicht das Problem.> Aber, nur zum Beispiel, man könnte ewig so weitermachen: in Assembler> bestimmt der Programmierer, was beim Aufruf einer Funktion auf dem Stack> abgelegt ist und wie tief die Aufrufe verschachtelt sind. Bei C ist eine> Prozedur wie etwa printf natürlich kein einfacher Aufruf, sondern die> ruft andere, einfachere Prozeduren usw. auf und dein Stack ist> übergelaufen ohne dass du weisst warum, von Variablen mal ganz
Wer auf DEM Gerät printf() benutzt, der gehört nackt ausgepeitscht.
Vermutlich belegt das alleine 180% vom Flash.
Speziell string-Funktionen sind auf PICs sehr ineffizient. snprintf()
und Konsorten verwende ich nur, wenn ich Devices wie PIC24 mit 128k
Flash habe und Projekte mit vielen String-Operationen. Bei µC mit <4k
tut man gut daran, sowas "händisch" zu machen. Was auch in C
hervorragend klappt.
Wer so wenig Stack hat, überlegt sich jeden Funktionsaufruf sowieso
doppelt. Hoffentlich.
Axel S. schrieb:> Ein C-Compiler erwartet z.B. einen Stack, der nicht nur Rücksprung-> adressen, sondern auch Funktionsparameter aufnehmen kann.
Naja, das stimmt so für die PIC-Compiler halt nicht. Es gibt dort keinen
Stack im herkömmlichen Sinne, sondern der Compiler für diese PICs
analysiert die komplette Aufrufhirarchie. Ist zwar rückwärts durch die
Brust ins Auge, der geschreibene Code ist aber wirklich ANSI-C wie auf
"normalen" Maschinen, nur ohne Rekursion.
Der wahr Grund für Assembler bei so kleinen µC ist eher die
Herausforderung. Um wirlich das letzte Bit zu sparen wird C
komplizierter als Assembler, da ich nicht nur schreiben muss, was ich
möchte, sondern auch so, dass der Compiler es auf die gewünschte Weise
tut.
Ihr kennt sicher das Poormans Oszilloskop auf PIC12-Basis. Aus 1kB ROM
und 64 Byte RAM zaubert er ein Oszilloskop mit Monitorausgabe und
Menüführung.
http://www.dos4ever.com/uscope/uscope_e.html#youtube
Ich habe vor einigen Jahren ein Projekt mit dem PIC10F222, dem etwas
größeren Bruder des PIC10F220, geleitet. Es ging um einen
Akkucontroller, bei dem es dem Management auf Centbeträge ankam. Er
sollte die vorhandene diskrete Schaltung aus mehreren Komparatoren,
Flipflops etc. ersetzen. Gelinde gesagt war die Entwicklung mühsam. Im
Prinzip schien der Chip für den Zweck gut geeignet, kleines SOT-26
Gehäuse, niedrige Betriebsspannung bis hinunter zu 2V, integrierter AD
Wandler mit Spannungsreferenz.
Die Tücken offenbarten sich dann während des Entwicklungsprozesses: Von
den 4 Portpins des Winzlings waren 3 durch den Programmieradapter
belegt, so dass kein In-Circuit Debugging möglich war. Wir haben dann
vom Microchip einen Adapter bekommen, der einen größeren Pic (ich weiss
nicht mehr, welcher) enthielt und den 10F220 emulierte. Programmiert
wurde in Assembler, wobei das Banking des Programmspeichers Probleme
bereitete. Funktionsaufrufe von der oberen in die untere Hälfte des
Programmspeichers und umgekehrt sind mangels genügend Adressbits nicht
direkt möglich.
Laut Datenblattsollte der XC8-Compiler aber funktionieren.
Die unangenehmste Überraschung war jedoch die starke Streuung der
Spannungsreferenz, die eine Einzelkalibrierung der Bauteile nötig
machte. Ohne EEPROM oder selbstprogrammierbares Flash ist das ziemlich
aufwändig. Der Kostenvorteil war damit auch wieder dahin.
Bezeichnenderweise hat Microchip sich geweigert, eine
Genauigkeitsspezifikation für diese Referenz anzugeben.
Fazit: Anfängern würde ich von dieser Art Minimalcontrollern abraten und
wenn nicht ganz zwingende Gründe dagegen sprechen, einen größeren PIC
wählen.
Toxic schrieb:> Hast du dir schon mal die Frage gestellt warum solche kleine Controller> produziert werden?
Weil die Leute ihn kaufen. Vermutlich um sportliche Wettbewerbe im
Ressourcensparen auszutragen. Auch wenn er doppelt so viel kostet wie
ein Controller mit 20 mal soviel RAM und 8 mal soviel Flash.
Verkauf ihn mir für < 8ct und wir reden nochmal drüber.
Achim S. schrieb:> Axel S. schrieb:>> Ein C-Compiler erwartet z.B. einen Stack, der nicht nur Rücksprung->> adressen, sondern auch Funktionsparameter aufnehmen kann.>> Naja, das stimmt so für die PIC-Compiler halt nicht. Es gibt dort keinen> Stack im herkömmlichen Sinne, sondern der Compiler für diese PICs> analysiert die komplette Aufrufhirarchie. Ist zwar rückwärts durch die> Brust ins Auge, der geschreibene Code ist aber wirklich ANSI-C wie auf> "normalen" Maschinen, nur ohne Rekursion.
Das kann ich mir ehrlich gesagt nicht vorstellen. Ein C-Compiler, der
keine Rekursion kann, ist doch sicher aus der Spezifikation, oder?
Ansonsten kann ich mir schon vorstellen, daß die verkorkste^W spezielle
Architektur der 8-Bit PICs Auswirkungen auf Design-Entscheidungen bei
den C-Compilern und insbesondere dem ABI hatte. Ist ja auch kein Zufall,
daß es nie [1] einen open-source C-Compiler für diese Architektur gab.
[1] ok, fast. SDCC kann seit einiger Zeit auch PIC. Keine Ahnung, ob das
taugt. Ich halte von 8-Bit PICs vor allem eins: Abstand.
Max M. schrieb:> da es mich interessiert, wie viel man mit wenig Ressourcen machen kann,
[...]
> (Assembler möchte ich mir nicht antun).
Und schon komplett als Looser geoutet. Es gibt nunmal theoretisch und
praktisch keinen besseren Weg, Resourcen maximal effizient zu nutzen als
eben die optimierte Programmierung in Assembler. Ob dir das paßt oder
nicht, spielt gegenüber der Allgewalt der Gesetze der Informatik sowas
von keine Rolle...
D.h.: bestenfalls kannst du mit höheren Programmiersprachen
Gleichstand mit einer optimierten Asm-Lösung erreichen. In aller Regel
wirst du aber ein suboptimales Ergebnis erzielen. Das ist kein Problem,
so lange reichlich Resourcen vorhanden sind, aber eben gerade dann ein
Problem, wenn genau das nicht der Fall ist, also genau in deinem
Ziel-Szenario...
Deswegen: Du bist einfach nur DUMM, wenn du den einzig zielführenden
Weg von vornherein kategorisch ausschließt...
Axel S. schrieb:> Das kann ich mir ehrlich gesagt nicht vorstellen. Ein C-Compiler, der> keine Rekursion kann, ist doch sicher aus der Spezifikation, oder?
Doch das geht sehr gut, z.B. beim Keil C51 Compiler.
Da der 8051 viele Operationen im RAM ausführen kann, wurde dadurch der
Code sehr kompakt und schnell.
Der 8051 kann aber auch PUSH/POP, d.h. man kann Funktionen auch als
reentrant deklarieren. Das geht allerdings zu Lasten der Codedichte und
Ausführungszeit.
http://www.keil.com/support/man/docs/c51/c51_le_reentrantfuncs.htm
c-hater schrieb:> Deswegen: Du bist einfach nur DUMM, wenn du den einzig zielführenden> Weg von vornherein kategorisch ausschließt...
Wichtig ist doch, dass er nicht dümmer ist als du.
Olmau schrieb:> Wichtig ist doch, dass er nicht dümmer ist als du.
Aber das ist er ja leider. Denn ich ziehe diesen Weg bei
Resourcenknappheit immer in Betracht, zumindest als Alternative zur
Aufweitung der Resourcen durch Verwendung eine anderen Hardware.
Ich wähle dann, was unterm Strich günstiger kommt. So geht man an die
Sache heran, wenn man nicht dumm ist...
So kann man aber nur an die Sache herangehen, wenn man sich nicht das
Gehirn von vornherein zunagelt. Genau das ist der springende Punkt!
c-hater schrieb:> So kann man aber nur an die Sache herangehen, wenn man sich nicht das> Gehirn von vornherein zunagelt.
Das kommt mir irgendwie bekannt vor. Du wohnst nicht zufällig in
Katzelsried?
Axel S. schrieb:> Ansonsten kann ich mir schon vorstellen, daß die verkorkste^W spezielle> Architektur der 8-Bit PICs Auswirkungen auf Design-Entscheidungen bei> den C-Compilern und insbesondere dem ABI hatte.
Axel, du bist ein AVR-Mann und als solcher verstehst du die PIC-Welt
nicht bzw. willst sie nicht verstehen. Kannst du ja machen, es gibt für
jeden Geschmack eine µC-Architektur.
Die Architektur der kleinen PIC's ist nämlich überhaupt nicht verkorkst,
sondern auf einfaches und dabei effizientes Assembler-Programmieren hin
optimiert - und nicht für C als Programmiersprache. Wer nen Horizont
hat, der direkt hinter C endet, für den sind die PIC's nicht.
Die kleinen PIC's sind NICHT für große Systeme gedacht, sondern für all
die kleineren Anwendungen, die man im Allgemeinen nicht wahrnimmt.
So ein Winzig-PIC im SOT23-5 fällt fast nirgendwo auf, er kann dennoch
Protokolle umsetzen, Peripherie betreiben, Codenummern liefern, ne Menge
kleinere Aufgaben erledigen und das recht stromsparend - eben alles,
wofür ein dickerer µC schlichtweg übertrieben oder nicht anwendbar wäre.
Ich selber programmiere solche kleinen PIC's schon seit vielen Jahren -
und das in Assembler. Wer sowas nicht kann, sondern nix anderes als C
kennt, ist bei den PIC's im verkehrten Film - da hilft ihm auch keine
große Klappe. Mir fällt da ein angeregter Zähler-Disput zwischen 40 MHz
AVR und >100 MHz PIC ein..
..Aber lassen wir das mal. Das Folgende hingegen hast du sehr schön
formuliert. Man sollte es dem TO ruhig nochmal zu lesen geben:
> Das ist wie: "ich möchte herausfinden, mit wie wenig Mitteln ich in der> Wildnis überleben kann. Dazu habe ich mir ein Waldgebiet ausgesucht.> Jetzt muß ich nur noch meinen Induktionsherd irgendwie angeschlossen> bekommen (Kochen über dem offenen Feuer will ich mir nicht antun)."
Eben.
W.S.
Peter D. schrieb:> Doch das geht sehr gut, z.B. beim Keil C51 Compiler.> Da der 8051 viele Operationen im RAM ausführen kann, wurde dadurch der> Code sehr kompakt und schnell.
Lob den C51 mal nicht in den Himmel, der kann schon ganz schöne Böcke
schießen die unangenehm auffallen wenn Flash oder Rechenzeit knapp wird.
Versuch zum Beispiel mal ein uint32_t um 8 bit (ein Byte!) nach rechts
zu schieben. Oder von 0x1ffff auf null zu zählen. Oder schreib eine
Funktion die einen Pointer als Argument hat foo(uint16_t* bar) und ruf
sie auf. Oder teile ein uint32_t mit den / Operator durch eine
konstante(!) Zweierpotenz. Und dann wirf einen Blick in den erzeugten
Code um rauszufinden wohin grad wieder mit einem Schlag eine
dreistellige Zahl von Bytes verschwunden ist und was er da für Kapriolen
dreht (brauchst nen separaten Disassembler um das Elend zu bewundern
weil der Linker kann das Zeug was er selber erzeugt oder dazulinkt nicht
in sein Listing schreiben). Man merkt schon deutlich daß da vor 20
Jahren (als er noch vergleichsweise toll war) die Entwicklung
eingeschlafen ist, verglichen mit heutigen Compilern auf anderen
Architekturen. Von dem C89 Sprachstandard möcht ich jetzt gar nicht erst
anfangen. Es dauert wahrscheinlich nicht mehr lange und der SDCC hat ihn
überholt.
holger schrieb:> Dann such dir nicht so einen unterbelichteten Schrott> als Controller aus.
Da kreischt schon wieder einer der keine Ahnung von der Materie hat.
Max M. schrieb:> PIC 10F220
Das ist einer meiner Lieblingstypen neben dem PIC10F322 und dem
PIC12F1572.
Der PIC ist billiger als ein NE555.
Wenn eine Blaue LED an 3V ein und ausschalten will und sie auch noch
Dimmbar sein soll ist der PIC genau richtig.
Bernd K. schrieb:> Lob den C51 mal nicht in den Himmel, der kann schon ganz schöne Böcke> schießen die unangenehm auffallen wenn Flash oder Rechenzeit knapp wird.
Ich kann da nicht klagen, Flash oder CPU-Zeit wurden bei mir nie knapp.
Ich hab allerdings hauptsächlich 8 oder 16Bit Variablen verwendet und
float bzw. 32Bit nur sparsam. Ein deutlicher Codezuwachs ergibt sich
immer nur beim ersten Aufruf einer neuen Lib-Funktion. Danach kostet es
nur noch einen weiteren Call.
Mein größtes 8051-Projekt ist über viele Jahre auf 48kB angestiegen, da
ist also noch Luft bis 64kB. Ich bin der vierte, der an diesem Programm
gearbeitet hat, d.h. es ist nicht sonderlich effizient geschrieben.
Daran habe ich auch den großen Vorteil von C erkannt, daß dadurch
mehrere an einem Projekt erfolgreich weiter arbeiten können.
Assembler ist dagegen nur für Einzelkämpfer geeignet. Wenn da der
Entwickler die Firma verläßt und es erweitert werden muß, wird es weg
geschmissen und komplett neu angefangen (in C natürlich).
Max M. schrieb:> da es mich interessiert, wie viel man mit wenig Ressourcen machen kann,...
Okay, das soll wohl heißen: spielend*, jedoch nicht aus wirtschaftlichen
Interesse.
> (Assembler möchte ich mir nicht antun).
Diese Entscheidung ist ein zusätzlich gewähltes freiwilliges Handikap
(Vgl. Boxen mit einem Arm auf dem Rücken).
> Meine Frage ist nun: Kann man mit 16Byte und dem 8-bit Timer..> einen UA[R]T programmieren> eine Software-I2C Lösung implementieren> Ansteuern diverser WS2822...
Also all diese Funktionen mit Assembler: kein Problem
In C: naja, es würde definitiv grenzwertig: manches wird gar nicht
implementierbar sein, manches nur mit bestimmten Compilern, (bzw mit
entsprechenden Compileroptionen), und alles geht nur mit entsprechender
Auslegung des Quellcodes auf entsprechend wenig RAM-Bedarf.
Wenn das der entsprechende Nerfenkitzel ist...
Rein wirtschaftlich würde man von vornherein entweder einen anderen
Controller oder Assembler wählen.
Achja: auch bei den AVRs gibts solche "hochgerüsteten Transistoren"
*Entwicklungsprozess "Spielen".
W.S. schrieb:> Ich selber programmiere solche kleinen PIC's schon seit vielen Jahren -> und das in Assembler. Wer sowas nicht kann, sondern nix anderes als C> kennt, ist bei den PIC's im verkehrten Film - da hilft ihm auch keine> große Klappe. Mir fällt da ein angeregter Zähler-Disput zwischen 40 MHz> AVR und >100 MHz PIC ein..FALSCH
Der xmega kann seine Timer mit PLL auf 128 MHz betreiben, und zwar alle.
Ansonsten hast du Recht. C-Programmierer bringens einfach nicht, wenn es
drauf ankommt.
Max M. schrieb:> (Assembler möchte ich mir nicht antun).
Auf einem STM32 wird man fast nie so tief einsteigen.
Assembler war für allgemeine Aufgaben schon vor 25 Jahren out.
Was mich nicht daran gehindert hat, in Spezialfällen trotzdem darauf
zurückzugreifen.
Bei stark begrenzten Ressourcen
(Platz/Zeit/Energie/Bauraum/Serienkosten) hat Maschinensprache den
Vorteil, dass man als Entwickler direkt steuern kann, wie diese
eingesetzt werden.
Beispiel 1 - Thema Speicher - Tiny10 im SOT23-6 Gehäuse, welcher
pinkompatibel zum PIC10F200 ist:
Diesen Tongenerator haben wir hier im Forum schonmal behandelt:
http://www.harerod.de/applications_ger.html#TQ10_melody
Beispiel 2 - Thema Speicher und Rechenzeit:
Die schwebende Eisenkugel ist schon ein wenig anspruchsvoller. Die
Abbildung eines Regelalgorithmus' mit Integerarithmetik in
Maschinensprache ist schon etwas weniger komfortabel, als mit Labview,
dafür ist der Materialeinsatz einen Tick geringer:
http://www.harerod.de/applications_ger.html#xmasball2012
Beispiel 3 - Thema Rechenzeit und Energieverbrauch:
Bei dieser Anwendung war die Stückzahl für ASIC noch zu gering, deswegen
kommt hier ein PIC16F57 zum Einsatz. Der arbeitet hier mit 8192Hz
Befehlstakt und multiplext das LCD und misst nebenbei noch ein wenig
Zeit:
http://www.harerod.de/applications_ger.html#allTimerMax M. schrieb:> Meine Frage ist nun: Kann man mit 16Byte und dem 8-bit Timer einen> UA[R]T programmieren (zumindest sendend)?> Was mich ebenfalls noch interessieren würde, ist, ob sich mit den> beschränkten Ressourcen auch eine Software-I2C Lösung implementieren> ließe?
Mann kann! Denn echte Programmierer meiden Pascal...
http://www.pbm.com/~lindahl/real.programmers.html
Marcus H. schrieb:> Max M. schrieb:>> Meine Frage ist nun: Kann man mit 16Byte und dem 8-bit Timer einen>> UA[R]T programmieren (zumindest sendend)?>> Was mich ebenfalls noch interessieren würde, ist, ob sich mit den>> beschränkten Ressourcen auch eine Software-I2C Lösung implementieren>> ließe?> Mann kann!
Naja, für UART und I2C braucht man in der Regel noch einen Datenpuffer
und dafür ist bei 16Byte einfach kein Platz mehr.
Für die UART nehme ich mindestens je 30 Byte Sende-/Empfangspuffer,
damit man kürzere Texte ein- bzw. ausgeben kann.
Und z.B. bei nem DS1307 (I2C-RTC) braucht man mindestens 8 Byte Puffer,
um die Zeit konsistent lesen bzw. schreiben zu können.
Man müßte die Strings/Daten "on the fly" basteln bzw. auswerten, was ein
sehr unübersichtliches Programm ergibt (riesiges unentwirrbares
Codeknäuel statt einfacher einzelner Module).
Und wie schon gesagt, hat man als nächstes Problem bei der modularen
Programmierung den viel zu kleinen HW-Stack.
Z.B. meine LCD-Lib hat allein schon einen Callingtiefe von 4.
http://www.avrfreaks.net/forum/tutc-lcd-tutorial-1001
Peter D. schrieb:> Und wie schon gesagt, hat man als nächstes Problem bei der modularen> Programmierung den viel zu kleinen HW-Stack.
Der SRAM-Stack und General Purpose Registersatz - das sind genau die
Punkte, warum der AVR deutlich komfortabler als der PIC zu programmieren
ist.
Modulare Programmierung ist Teil des Gesamtkonzepts einer
"wirtschaftlichen Entwicklungleistung". Jedoch wird man in dieser
Kampfklasse wohl keinen HAL zwischenschieben wollen, oder? ;)
Peter D. schrieb:> [8051]> Ich kann da nicht klagen, Flash oder CPU-Zeit wurden bei mir nie knapp.
Ich schon, denn bei mir wird es immer knapp. Es kommt drauf an was Dich
dazu antreibt den zu verwenden. Der Hauptgrund bei mir der mich heute
zwingt mich mit 8051 zu beschäftigen ist daß ein EFM8BB1 von Silabs
deutlich weniger als 30ct kostet. Dies geht jedoch damit einher daß man
leider nur noch 2kB Flash hat, da herrscht beklemmende Enge schon wenn
man nur damit anfängt über die angedachten Features zu diskutieren.
Sobald ich aber die größeren Varianten mit 4 oder 8kB ins Auge fasse
verschwindet der Preisvorteil schnell, Arm fängt bei ~50ct an.
Bernd K. schrieb:> Es kommt drauf an was Dich> dazu antreibt den zu verwenden.
Mit dem Einsatz wurde 1995 angefangen, vorwiegend Philips und die damals
brandneuen Flash 8051 von Atmel.
Die DACs und ADCs waren 12/14Bit, d.h. alle Daten waren 16bittig. Keil
war wohl auch der Meinung, wer 32Bit benutzt, dem kommt es auf die
Optimierung nicht so sehr an und der nimmt nen dicken 8051 mit viel
PROM.
Bei 1, 8 und 16Bit Variablen war der Keil extrem effektiv.
> Der SRAM-Stack und General Purpose Registersatz - das sind genau die> Punkte, warum der AVR deutlich komfortabler als der PIC zu programmieren> ist.
Das ist etwa so falsch wie die Aussage eines Buchautors ueber
den PIC-Befehl SUBWF/SUBWL der "falsch herum" subtrahieren wuerde.
Der hat es einfach nicht verstanden. Du ja uebrigens auch nicht...
Peter D. schrieb:> Assembler ist dagegen nur für Einzelkämpfer geeignet. Wenn da der> Entwickler die Firma verläßt und es erweitert werden muß, wird es weg> geschmissen und komplett neu angefangen (in C natürlich).
Das glauben eben nur Leute, die Assembler nicht beherrschen. Ich habe da
(neben vielen anderen Sachen) von meinem Vorgänger ein in Stückzahlen
verkauftes HC12-Werk übernommen. Ich hatte selber vorher niemals Kontakt
mit diesen Motorola-µC-Teilen. Aber ich war trotzdem in der Lage,
innerhalb von nur zwei Tagen eine vom Kunden gewünschte Änderung
einzupflegen. Hat mich nur den Download von ein paar PDFs gekostet und
einige Stunden Lektüre dieser Dokumente und der Quelltexte meines
Vorgängers. Assembler ist halt i.A. eine einfache und leicht
verständliche Sprache ohne jegliche bösen Fallstricke, wie sie dieses
Drecks-C nur allzu reichlich bereit hält...
Den Assembler-Dialekt eines neuen Controllers kann man üblicherweise in
wenigen Stunden vollständig lernen (für lesende Anwendung und um
"leichte" Änderungen daran vornehmen zu können, um aktiv optimalen Code
programmieren zu können, braucht man natürlich deutlich mehr Zeit).
Für C hingegen braucht man mindestens einige Wochen, wenn nicht Monate,
um es auch nur vollständig lesen zu können. Vor allem dann, wenn da ein
"C-Crack" am Werk war. Einer von den Blinden Wichsern, die glauben, dass
eine besonders geringe Zahl von Zeichen im Quelltext besonders schnellen
Code erzeugt...
c-hater schrieb:> Aber ich war trotzdem in der Lage,> innerhalb von nur zwei Tagen eine vom Kunden gewünschte Änderung> einzupflegen.
Das ist ja großartig, du Held.
Peter D. schrieb:> Und wie schon gesagt, hat man als nächstes Problem bei der modularen> Programmierung den viel zu kleinen HW-Stack.
Ach Peter, du kommst genauso wie Axel nicht heraus aus deiner AVR- und
C-Denkweise. Das ist alles. Folglich kannst du auch keine Probleme der
Art lösen, wie sie typisch und passend sind für solche kleinen PIC's.
Mal ne kleine Erklärung:
Der HW-stack in den PIC's ist ausschließlich für Rücksprungadressen und
NICHT für Argumente aller Art. Die CPU hat gar kein Register und
arbeitet normalerweise mit den RAM-Zellen und den HW-Registern direkt
oder über das W-Register, was nur teilweise ein echter Akku ist.
UP-Calls gehen dank HW-Stack in effektiv nur 2 Takten (Inclusive
Call-Befehl selbst). Selbst das indirekte Arbeiten mit RAM und
HW-Registern über das "Register 0" geht ohne zusätzlichen Takt.
Das ist eben alles anders, als du es vom AVR her gewohnt bist. Aber
gerade deswegen kann man mit dieser Architektur in Assembler sehr viel
mehr machen als mit vielen anderen Architekturen. Man muß sich aber
drauf einlassen - sonst wird das Ganze nix.
Und da scheiden sich die Geister.
Heutige Dünnbrettbohrer wollen dediziert NICHT sich mit HW und
HW-bezugenem wie Assembler befassen müssen - ist mit zuviel
Gehirnanstrengung verbunden. Eben nicht wirklich selbst potent sein,
sondern das Bumsen einer Library anheim stellen - ist bequemer.
W.S.
Thomas E. schrieb:> Das ist ja großartig, du Held.
Findest du? Ich finde das normal. Hätte ich bei einem einigermaßen
normal formuliertem C-Programm natürlich ganz genauso machen können.
Bräuchte dazu nichtmal C zu lernen, denn das kann ich bereits deutlich
besser als die Mehrheit der Leute, die sich selber als "C-Programmierer"
einstufen...
Genau das ist der Punkt. Einen C-Programmierer stelle ich nur ein (bzw.
gebe meine Zustimmung dazu), wenn er auch nachweist, dass er für
mindestens eine relevanten Zielarchitektur die Assemblersprache aktiv
beherrscht. Tut er das nicht, kann man meiner Erfahrung nach getrost
davon ausgehen, dass er auch kein C kann, sondern nur Wichsvorlagen aus
dem Netz notdürftig zusammenleimen kann. Insbesondere ist er dann nicht
zu einer qualifizierten Fehlersuche auf Maschinenebene in der Lage. Was
bei C auf Grund der Mankos der Sprache nunmal zwingend erforderlich
ist...
Jemand, der kein Assembler kann, kann nicht programmieren. Schon gar
keine MCUs und PUNKT.
Das heisst nicht, dass man jeden Scheiss in Assembler schreiben muss.
Ich hätte jetzt wirklich keine Lust, einen JPG-Encoder in ASM zu
realisieren, aber das wäre die logische Konsequenz, wenn ich unbedingt
JPG brauche und C nicht anfassen will. Mein B0SS würde mich feuern, wenn
ich wochenlang an einer ASM JPG Lib sitzen würde. Auf die Frage, warum
ich nicht einfach eine vorhandene Lib eingesetzt hätte, hätte ich in der
Tat auch keine Antwort.
Andersrum funktioniert es aber auch. Wenn mir ein Bewerber sagt, er
kennt die MCUs, die wir verwenden in- und auswendig und dann sagt, er
kann kein ASM, dann kennt er die MCU auch nicht. Dann kennt er GAR keine
MCU richtig. Fertig und tschüss. Nächster.
Ich sehs schon kommen und nehme es gleich vorweg. Ein ARM ist für mich
keine MCU mehr, wie ich sie bei der Argumentation von vorhin im Kopf
habe.
Ich rede hier nur von PICs, AVRs, etc.
(Wobei der ASM-Befehlssatz eine PICs ein Argument für C ist hrhrhr)
ASM Superprofi schrieb:> (Wobei der ASM-Befehlssatz eine PICs ein Argument für C ist hrhrhr)
Wobei man durchaus zwischen PIC12/16, PIC18, PIC24/dsPIC und PIC32
unterscheiden sollte, denn die haben ziemlich unterschiedliche
Befehlssätze.
W.S. schrieb:> Mal ne kleine Erklärung:> Der HW-stack in den PIC's ist ausschließlich für Rücksprungadressen und> NICHT für Argumente aller Art.
In der Codesammlung findest Du Beispiele von mir mit dem ATtiny12
(3-Level-HW-Stack). In der Not kann man einiges damit machen. Aber stolz
bin ich darauf nicht, mich damit abgequält zu haben. Das waren nur
Spielereien, keine professionellen Projekte.
Ich will mich voll auf die Aufgabe konzentrieren können und nicht auch
noch auf den Stack aufpassen müssen und Unterfuntionen kopieren, statt
sie zu callen.
Alter Schwede, hier sind ja wieder Kaliber unterwegs. Früher dachte ich
mein eignes Tun sei grenzwertig weil ich lieber einen USB-Stack from
scratch schreibe als den SDK-bloat des Herstellers zu verwenden, weil
ich meinen eigenen Startupcode schreibe und eigene Treiber für alles.
Aber solche ASM-Superprofis wie hier mit derart schrägen Vorstellungen
und Prioritäten und derartiger Selbstüberschätzung würden ein
ernsthaftes Problem mit mir bekommen. Man kann nämlich alles übertreiben
und wenn der Code aufgrund solcher selbstverliebter ASM Trottel und
inkompetenter C-Verweigerer zum unwartbaren ASM-Spaghetti verkommt dann
wäre Schluss mit lustig.
Bernd K. schrieb:> Aber solche ASM-Superprofis wie hier mit derart schrägen Vorstellungen> und Prioritäten und derartiger Selbstüberschätzung würden ein> ernsthaftes Problem mit mir bekommen. Man kann nämlich alles übertreiben> und wenn der Code aufgrund solcher selbstverliebter ASM Trottel und> inkompetenter C-Verweigerer zum unwartbaren ASM-Spaghetti verkommt dann> wäre Schluss mit lustig.
du verkennst womöglich die Aussagen
ich bin auch ein Chef und wenn ich zu eintscheiden habe ob ein
C-Programmierer eingestellt wird und dieser mir nichtmal beantworten
kann was z.B. ein Carry-Flag ist, gechweige denn wie man damit eine
effiziente Zählschleife baut, dann darf der gut gepflegte
Wichtigtuer-Bengel mit seinem gepflegten Hippster-Rauschebart gerne
seinen schmucken, weißen Laptop mitsamt seiner interaktiven Präsentation
wieder einpacken und abdampfen, egal wieviel ach so tolle
Open-Source-Tools er angeblich gebaut hat.
Die Unterschiede zwischen den Assembler-Sprachen verschiedener
Prozessoren sind sowieso nicht kriegsentscheidend, ob die Grundbefehle
nun LD, MOV, ROT, SHIFT oder sonstwie heissen hat man bei halbwegs
normaler geistiger Beweglichkeit schnell drauf, viel entscheidender ist
das Wissen darüber, welche Bits man in welchem Control-Register setzen
muss, damit serielles Senden oder eine ADC-Messung so läuft wie sich das
der Programmierer vorstellt - und das ist bei Assembler oder C genau
dasselbe Problem. Da muss man halt im Zweifelsfall tatsächlich mal das
Manual lesen.
Georg
Axel S. schrieb:> Max M. schrieb:>> da es mich interessiert, wie viel man mit wenig Ressourcen machen kann,>> möchte ich demnächst ein paar kleinere Projekte mit Mikrocontrollern,>> die in Flash- und RAM-Größe sehr beschränkt sind, umsetzen. Speziell hab>> ich mir da den PIC 10F220 ausgesucht. Programmiert werden soll er mit>> dem PicKit3 und der IDE + C-Compiler von Microchip (Assembler möchte ich>> mir nicht antun).>> [...]>> Mit C geht bei 16 Byte RAM genau gar nichts. [...]
Das von anderen, insbesondere von Gästen solche uninformierten Aussagen
kommen - geschenkt. Aber bei dir bin ich dann doch enttäuscht.
Natürlich ist der mit C programmierbar. Neben dem Microchip CX8 gibt es
auch den CC5X von Knudsen Data.
Klar, dass man mit einem 10F220 kein Atomkraftwerk steuern kann. Noch
nicht mal ein "Apfelmännchen" lässt sich damit nicht berechnen.
Trotz dem ist der Witzling durchaus verwendbar.
Ich hab selbst schon den 10F200 verwendet, und eine recht komplexe
Steuerung für einen kleinen Tester umgesetzt, die den Speicher bei
weitem nicht ausgereizt hat. Beschaltung 1 Einganssignal, 1 LED, 1
Piezo-Scheibe, 1 Taster, 1 Steuerausgang. Wer jetzt denkt ... uhhh ...
das sind aber 5! - LED und Taster hingen an einem I/O-Pin. Das Programm
konnte unterschiedliche Tastendrücke erkennen, optische und Tonsignale
erzeugen, und den Tester automatisch selbst abschalten, und hat den
Programmspeicher vom 10F200 nur zur Hälfte belegt, beim RAM war's wohl
noch weniger.
Also ja, da geht was.
Ehrhardt schrieb:> Bernd K. schrieb:>> Aber solche ASM-Superprofis wie hier mit derart schrägen Vorstellungen>> und Prioritäten und derartiger Selbstüberschätzung würden ein>> ernsthaftes Problem mit mir bekommen. Man kann nämlich alles übertreiben>> und wenn der Code aufgrund solcher selbstverliebter ASM Trottel und>> inkompetenter C-Verweigerer zum unwartbaren ASM-Spaghetti verkommt dann>> wäre Schluss mit lustig.>> du verkennst womöglich die Aussagen>> ich bin auch ein Chef und wenn ich zu eintscheiden habe ob ein> C-Programmierer eingestellt wird und dieser mir nichtmal beantworten> kann was z.B. ein Carry-Flag ist, gechweige denn wie man damit eine> effiziente Zählschleife baut, dann darf der gut gepflegte> Wichtigtuer-Bengel mit seinem gepflegten Hippster-Rauschebart gerne> seinen schmucken, weißen Laptop mitsamt seiner interaktiven Präsentation> wieder einpacken und abdampfen, egal wieviel ach so tolle> Open-Source-Tools er angeblich gebaut hat.
So wie du dich echauffierst, verkennst du womöglich die Problematik.
Der Maßstab ist nicht, ob jemand C-Programmierer ist, sondern auf
welchem Gebiet er SW entwickelt. Der Eine schreibt Anwendungsprogramme
für den PC, der nächste Gerätetreiber, andere wiederum SW für
Microcontroller. Nicht jeder kann deswegen zwangsläufig auch das andere.
Aber C ist bestens dafür geeignet, guten Code selbst für kleinste
Microcontroller zu schreiben. Dafür gibt es extra angepasste Compiler,
und man kann jeder Zeit in C zwecks Optimierung Assemblercode einbetten.
Aber meist ist der vom Compiler generierte Code besser als es die
C-Hater wahrhaben wollen. C-Code ist zudem schneller zu erstellen und
leichter zu pflegen, insbesondere wenn man wechselnd auf
unterschiedlichen Hardwareplattformen arbeiten muss. Die Verwendung von
C ist also kein Indikator. Schlechten Code kann man wirklich in jeder
Sprache fabrizieren, auch in Assembler.
Michael L. schrieb:> Also ja, da geht was.
Der Punkt ist: mit Assembler geht immer noch ein wenig mehr. Schlimmer
noch: nur allzu oft überspringt man damit genau den Unterschied zwischen
"geht nicht" und "geht doch".
Natürlich kann man das oft auch mit viel Gefrickel mit unlesbarem
inline-Assmbler, Linkerscripts und weiß der Fuchs was für Tricks der
konkrete Compiler für das konkrete Target bietet hinkriegen. Aber warum
kompliziert, wenn es auch einfach, natürlich und direkt geht?
Das ist doch völliger Schwachsinn! Nur C-dioten bestehen darauf, das
unbedingt mit den Werkzeugen ihren kleinen, beschränkten Welt abbilden
zu wollen. Sie sind einfach unfähig zu begreifen, dass sie mit der
Anwendung all dieser Tricks im Endeffekt die einzige Daseinsberechtigung
ihrer Sprache vollkommen ad absurdum führen. Denn das Ergebnis ist
genauso wenig portabel wie nativer Assemblercode. Und obendrein mit an
Sicherheit grenzender Wahrscheinlichkeit immer noch weniger effizient
als das Werk eines echten Assemblerprogrammierers...
Also: purer Schwachsinn in höchster Potenz. Sinnlose Verschwendung von
Mannjahren an Entwicklungszeit.
c-hater schrieb:> Michael L. schrieb:>>> Also ja, da geht was.>> Das ist doch völliger Schwachsinn! Nur C-dioten [...]>> Also: purer Schwachsinn in höchster Potenz. Sinnlose Verschwendung von> Mannjahren an Entwicklungszeit.
Dein Vater hätte besser einen Kondom benutzt.
Max M. schrieb:> Danke für eure hilfreichen Antworten. Vllt. eine naive Frage, aber warum> kann man den genannten PIC nicht mit der IDE in C programmieren bzw.> warum ist mit Assembler ein größerer Funktionsumfang möglich als mit C?> Liegt. es an den Header-Dateien die man z.B für die ISRs importieren> müsste (wobei die eigentlich im Flash landen). Der Overhead von C müsste> doch hauptsächlich im Flash stattfinden, oder?
Weil du in Assembler viel mehr tricksen kannst als in C möglich wäre und
diese Tricks, die sparen natürlich Speicherplatz.
Der C Compiler aber, der muss nach Schema F compilieren, sein einziger
Vorteil ist nur der, das der Code leichter portierbar ist und der
Compiler alle OpCodes kennt und daher besser optimieren kann, aber
letzteres gilt nur dann, wenn die CPU selbst komplex ist.
Bei einem kleinen µC ist das aber nicht der Fall, das ist schließlich
keine moderne High End CPU wie man sie bei Intel oder AMD basierten PCs
vorfindet.
Solche kleinen µC sind überschaubar und was überschaubar ist, das kann
der Mensch besser optimieren als ein Compiler.
Meine Empfehlung, nimm den billigsten MSP430 für ca. 36 Cent bei
Digikey, der bietet immerhin schon 128 Bytes RAM und 512 Bytes
Flashspeicher.
Außerdem ist dieser µC deutlich moderner und auch noch vom
Stromverbrauch super sparsam.
Die Diskussion entwickelt sich wie immer: diejenigen, die Assembler
nicht beherrschen, erklären C zur Lösung für alle Probleme der Welt und
prügeln auf die Assemblerprogrammierer ein. Die Assemblerprogrammierer
prügeln auf die C-Fanatiker ein, weil die garkeine Ahnung haben was im
Prozessor tatsächlich passiert. Und wer wie ich schon immer beides
benutzt, je nach Anforderung, und meistens auch zugleich in einem
Projekt, bekommt doppelt so viele Prügel, nämlich von beiden Seiten.
Was bringt die ganze Diskussion? Absolut nichts. Es muss eh jeder seine
eigenen Probleme lösen, und solche Dreckschleudern wie c-hater helfen
weder Anfängern noch Fortgeschrittenen.
Georg
Thomas E. schrieb:> Das ist ja großartig, du Held.
Es gibt halt Leute, die ihr Handwerk tatsächlich beherrschen. Dass dann
Nichtskönner sofort reflexartig mit solchen Hassausbrüchen antworten,
ist traurig, aber nicht überraschend.
Georg
Georg schrieb:> Thomas E. schrieb:>> Das ist ja großartig, du Held.>> Es gibt halt Leute, die ihr Handwerk tatsächlich beherrschen. Dass dann> Nichtskönner sofort reflexartig mit solchen Hassausbrüchen antworten,> ist traurig, aber nicht überraschend.>> Georg
Was willst du denn?
Du tust ja gerade so, als könntest du das beurteilen.
Und wie so oft bei solchen Threads hat sich der TO schon lange
"abgemeldet" und kringelt sich vor lachen ob der Schlammschlacht von
Egomanen hier im Forum.
Schade eigentlich, so kurz vor dem "Fest der Liebe" sollten wir doch
alle etwas netter zueinander sein.
Schöne Feiertage!
Georg schrieb:> Die Assemblerprogrammierer> prügeln auf die C-Fanatiker ein, weil die garkeine Ahnung haben was im> Prozessor tatsächlich passiert.
Es gibt noch eine dritte Fraktion und die bekommt den Job: Es sind
diejenigen die eine hervorragende Ahnung davon haben was im Prozessor
passiert, die bei Bedarf auch zwölf Zeilen ASM entziffern können wenn es
drauf ankommt und die genau *DESHALB* wissen daß sie 99% der
anfallenden Programmiertätigkeit auf dem µC lieber in C oder C++ als in
ASM betreiben sollten, weil sie die Nachteile beider Welten gesehen und
daraufhin zielsicher das geringere Übel gewählt haben.
sadfsdf schrieb:> Und wie so oft bei solchen Threads hat sich der TO schon lange> "abgemeldet" und kringelt sich vor lachen ob der Schlammschlacht von> Egomanen hier im Forum.>> Schade eigentlich, so kurz vor dem "Fest der Liebe" sollten wir doch> alle etwas netter zueinander sein.
Hat doch schon was gebracht: der nä. Post, nachdem ich C++ geschrieben
habe, spricht vom Fest der Liebe ... ;-)
> Und wie schon gesagt, hat man als nächstes Problem bei der modularen> Programmierung den viel zu kleinen HW-Stack.
Diese minimal-µC ohne RAM sind sicher nur für ganz kleine Anwendungen
gedacht. Was will man da mit Modulen anfangen?
Man kann sich das Leben auch selbst verkomplizieren.
Wenn ich eine Schubkarre brauche, dann kaufe ich eine Schubkarre =
simple Blechschwanne mit zwei Griffen und einem Rad drunter. Sicher kann
man die Schubkarre auch durch eine modulare Baumaschine ersetzen, aber
das würde ich ohne guten Grund nicht tun.
Thomas E. schrieb:> Was willst du denn?> Du tust ja gerade so, als könntest du das beurteilen.
Du kannst nicht beurteilen, ob er das beurteilen kann oder nicht.
Aber egal, die Frage war: was kann man mit 16Byte an RAM machen ?
Die Antwort ist: nicht viel in C, bedeutend mehr in ASM.
Bei 16Byt RAM fängt man gar nicht erst mit C an. Die ganze dazu
nötige Gehirnakrobatik, um mit 16Byte überhaupt ein einigermassen
sinnvolles Programm zum Laufen zu bringen, lohnt sich doch eh
nicht. Das hat man mit ASM viel schneller hingekriegt.
Und das es Leute gibt die so etwas kaufen, um damit anzufangen,
werde ich niemals begreifen.
So etwas nimmt man als Sensor/Aktor und dann ist aber auch Schluss.
Und dafür war es wahrscheinlich auch gedacht, also ASM von vorn-
herein, kein C.
Ende.
Der Haupsächliche Einsatz laut Microchip: Timer, Logik und PLDs in
größeren Systemen. Natürlich kann man die Dinger auch für kleinere stand
allone Projekte einsetzen und mittels C den Inhalt drauf quetschen. Die
Flexibilität ist aber bei ASM ungleich höher. Und ja, wer in C proggt
solte auch ASM können und den mc kennen.
Hach, das geht ja wieder ab wie Schmitts Katze. :-D
Immer diese Lobpreisungen des jeweils beherrschten Hammers als
ultimatives Werkzeug. Da weiß ich nie, ob ich lachen oder Mitleid haben
soll.
Und am lautesten melden sich jeweils die zu Wort, die zur entsprechenden
Problematik grad die geringste Ahnung haben. Der Blinde schwätzt über
die Nutzlosigkeit von Farbe, der Taube verachtet den Gesang. Oder um es
mit aktuellen Worten zu formulieren: Man hält seine regentropfen-kleine
Filterblase für den Ozean.
"Mit 16 Byte geht kein C"
Ja klar, und die Hersteller entsprechender Compiler hätten besser gut
daran getan, mal vorher bei euch Klugscheißern nachzufragen, ebenso die
ganzen Leute, die mit diesen Compilern tagtäglich arbeiten.
Einstein hatte den Finger drauf:
"Die Majorität der Dummen ist unüberwindbar und für alle Zeiten
gesichert."
Max M. schrieb:> da es mich interessiert, wie viel man mit wenig Ressourcen machen kann,> möchte ich demnächst ein paar kleinere Projekte mit Mikrocontrollern,> die in Flash- und RAM-Größe sehr beschränkt sind, umsetzen. Speziell hab> ich mir da den PIC 10F220 ausgesucht.
Sowas ist, bei Massenproduktion, ein zeigemäßer Ersatz für ein kleines
Relais-, NE555- oder TTL-Grab, das mit einigen OPVs gewürzt sein kann.
Nicht mehr und auch nicht weniger.
Bei kleineren Stückzahlen: Besseren µC mit mehr Ram und mehr Pins
einsetzen, das schont die Nerven!
Marc V. schrieb:> Aber egal, die Frage war: was kann man mit 16Byte an RAM machen ?> Die Antwort ist: nicht viel in C, bedeutend mehr in ASM.
Knapp daneben: Korrekte Antwort: nicht viel in C, kaum mehr in ASM.
Etwas Hiernschmalz beim Programmeren ist aber hilfreich, mit einem 8-bit
Festkomma µC sollte man 32bit Gleitkomma-Berechnungen tunlichst
vermeiden.
Zurückhaltung bei Funktionsaufrufen, passende Variablendeklaration und
Vermeidung sinnlos Verschachtelter oder Aufgeblasener Funktionen ist
ebenfalls sinnvoll.
Marc V. schrieb im Beitrag #4832187:
> Michael L. schrieb:>> "Mit 16 Byte geht kein C">> Hat keiner gesagt.
Stimmt.
Z.B. ich habe nur gesagt, daß es für serielle Protokolle recht knapp
werden wird, da die oft paketorientiert arbeiten, was man viel einfacher
auf Arrays abbilden kann.
Die C-Hater sollten sich mal anschauen, wie gute Compiler arbeiten. Die
Compilerbauer sind ja keine Anfänger und können da mehrere Mannjahre
investieren. Nicht ohne Grund sind professionelle Compiler kein
Schnäppchen und trotzdem keine Ladenhüter.
Man kann oftmals in C mehr aus einem knappen RAM machen, als in
Assembler. Ein Compiler kann einfach einen Calling-Tree erstellen und
Variablen überlagern. In Assembler wäre das sehr aufwendig und man geht
lieber weniger effektiv mit dem RAM um.
Auch einen limitierenden HW-Stack kann ein Compiler gut verstecken. Man
schreibt modular und der Compiler inlined dann einfach die Funktion an
den 10 Stellen, wo sie aufgerufen wird. Kostet eben mehr Flash, als ein
echter Stack.
Als ich den Schritt von Assembler zu C wagte, wurden die Programme
schneller und brauchten weniger Flash. Davor hätte ich auch 1000 Eide
geschworen, daß es genau umgekehrt sein muß. Und vor allem konnte man
sie sauschnell schreiben im Vergleich zu Assembler.
Ich kann Assembler Output lesen, aber ob das unbedingt eine
Voraussetzung für einen guten Programmierer sein muß, auf dieses schmale
Brett würde ich mich nicht stellen.
Ich kann sogar PIC-Assembler lesen, aber das ist wirklich der mit
Abstand umständlichste Assembler, der mir untergekommen ist.
Z.B. bei INCFSZ brauchte ich lange, um alle seine Feinheiten verstehen.
Wie man in Posts lesen kann, ging das aber nicht nur mir so.
Peter D. schrieb:> Z.B. bei INCFSZ brauchte ich lange, um alle seine Feinheiten verstehen.
Manchmal scheint es mir so als hätte ich in all meinen PIC Jahren gar
nichts kapiert. (Gar nicht gemerkt, dass es da "Feinheiten" gibt ;-)
Peter D. schrieb:> In der Codesammlung findest Du Beispiele von mir mit dem ATtiny12
...
> Ich will...nicht auch..> noch auf den Stack aufpassen müssen und Unterfuntionen kopieren, statt> sie zu callen.
CALLEN...
(do you speak britisch? yes, a paar broken.."
Peter, lass es BITTE! Du bist gedanklich immerzu bei den AVR's und C und
nicht bei den PIC's und Assembler.
Da sind erhebliche Unterschiede - und offensichtlich UNÜBERBRÜCKBAR. Du
hast ja nichtmal das verstanden, was ich geschrieben habe.
Natürlich ruft man auch bei den kleinen PIC's Unterprogramme mit CALL
auf und verläßt sie mit RETURN. Aber man packt eben keine Argumente in
den Stack, denn der liegt völlig außerhalb von Datensegment und
Codesegment.
Ich geb dir mal nen Ausschnitt (nur zum Draufgucken):
1
HexOut24:
2
MOVFADC_roh+2,W
3
CALLHexaus
4
MOVFADC_roh+1,W
5
CALLHexaus
6
MOVFADC_roh,W
7
8
;Hexa-AusgabevonW
9
Hexaus:MOVWFHudl;merken
10
SWAPFHudl,W;Hi-NibblenachW
11
ANDLW15
12
ADDLW246;ab10-->Carry
13
SKIPNC
14
ADDLW7
15
ADDLW48-246+256
16
CALLSayIt
17
MOVFHudl,W;Hi-NibblenachW
18
ANDLW15
19
ADDLW246;ab10-->Carry
20
SKIPNC
21
ADDLW7
22
ADDLW48-246+256
23
GOTOSayIt
Das sind Ausgaberoutinen für Hexa-Zahlen: 4, 8 und 24 Bit in Assembler
für PIC16F8xx oder so. Wundere dich nicht, daß es hier keine RETURN's zu
sehen gibt. Die sind bei sinnvoller Anordnung der Funktionen oftmals
nicht nötig, wohl aber in manchen Fällen das Sparen mit Returnadressen
im Stack.
Es ist eben ne andere Welt als AVR.
W.S.
W.S. schrieb:> für PIC16F8xx oder so. Wundere dich nicht, daß es hier keine RETURN's zu> sehen gibt. Die sind bei sinnvoller Anordnung der Funktionen oftmals> nicht nötig, wohl aber in manchen Fällen das Sparen mit Returnadressen> im Stack.
Ich wundere mich aber.
Jeder CALL Befehl macht vorher ein PUSH von PC+1 auf den Stack.
Wenn es kein RETURN gibt, kann dein Programm niemals dort zurückkehren
von wo diese Routine aufgerufen wurde.
Also, machen möchtegern Programierer nachträglich einen Sprung
irgendwo vor einen RETURN und glauben, das wäre besonders klug oder
sogar genial.
Ich nenne so etwas dumm und Spaghetticode.
Die einzig richtige Lösung hat Peter aber schon genannt:
Peter D. schrieb:> Auch einen limitierenden HW-Stack kann ein Compiler gut verstecken. Man> schreibt modular und der Compiler inlined dann einfach die Funktion an> den 10 Stellen, wo sie aufgerufen wird. Kostet eben mehr Flash, als ein> echter Stack.
> Wenn es kein RETURN gibt ...
Ganz sicher gibt es ein return, das steht am Ende des nicht gezeigten
SayIt.
Über das Gewicht der Einsparung lässt sich allerdings in der Tat
trefflich streiten.
> So wäre es besser und kürzer.
Richtig, und so hat er es mit seinem Hexaus ja gemacht, es geht aber
eben immer nur einmalig. Und was daran PIC-spezifisch sein soll, bleibt
mir unverständlich.
W.S. schrieb:> Da sind erhebliche Unterschiede - und offensichtlich UNÜBERBRÜCKBAR. Du> hast ja nichtmal das verstanden, was ich geschrieben habe.
Nö, Du hast es nicht verstanden. Nochmal, die alten ATtiny12 hatten
einen HW-Stack, ganz genau wie die kleinen PICs. Und deshalb mußte ich
höllisch aufpassen, eine Callingtiefe von 3 nicht zu überschreiten, bzw.
2, wenn man Interrupts verwendete. Er war daher genauso eklig zu
programmieren, wie die PICs mit nur 2-level HW-Stack.
W.S. schrieb:> CALLEN...> (do you speak britisch? yes, a paar broken.."
Ja, Programmierer callen, pushen, returnen, jumpen, moven usw. In der
Regel versteht das auch jeder sofort.
S. Landolt schrieb:>> So wäre es besser und kürzer.> Richtig, und so hat er es mit seinem Hexaus ja gemacht, es geht aber> eben immer nur einmalig. Und was daran PIC-spezifisch sein soll, bleibt> mir unverständlich.
Es ist nicht sein Hexaus, genauso macht man es z.B. bei AVR und der
LCD-Ausgabe. SWAP Nibble, CALL, SWAP Nibble, durchfallen...
Mir ist auch nicht ganz klar was daran so PIC-spezifisch sein soll.
Mir ist gerade aufgefallen, dass der PIC10F220 zwar einen Timer hat,
aber keinen Overflow-Interrupt (bzw. gar keine Interrupts). Das macht
das Programmieren nicht angenehmer. Ich werde versuchen, mich in den PIC
Assembler einzuarbeiten. Aktuell ist Assembler (programmieren) auch
Thema im Studium, von dem her kann es eh nicht schaden. Danke für die
vielen Antworten.
Peter D. schrieb:> Als ich den Schritt von Assembler zu C wagte, wurden die Programme> schneller und brauchten weniger Flash. Davor hätte ich auch 1000 Eide> geschworen, daß es genau umgekehrt sein muß. Und vor allem konnte man> sie sauschnell schreiben im Vergleich zu Assembler.
Das sagt etwas über deine Fähigkeiten in Assembler aus.
Wie schon gesagt, auf so kleinen Dingern sind die Funktionen der CPU
überschaubar und der Mensch kriegt bessere Ergebnisse in Assembler hin
als der C Compiler, allerdings gilt das natürlich nicht, wenn der Mensch
nen schlechten Code schreibt.
Da ist der Mensch nämlich dann das schlechteste Glied, aber theoretisch
dem Compiler überlegen.
Erst dann, wenn die CPU nicht mehr überschaubar ist, liegt der Compiler
ganz vorne.
Letzteres gilt bei so allen modernen Intel und AMD x64 CPUs, allerdings
nicht für solche kleinen µC mit ner Handvoll überschaubarer Opcodes und
16 Byte RAM.
> Ich kann sogar PIC-Assembler lesen, aber das ist wirklich der mit> Abstand umständlichste Assembler, der mir untergekommen ist.> Z.B. bei INCFSZ brauchte ich lange, um alle seine Feinheiten verstehen.> Wie man in Posts lesen kann, ging das aber nicht nur mir so.
Deswegen habe ich weiter oben einen MSP430 empfohlen. PIC ist von
vorgestern und dann auch noch ein 8 Bitter, der MSP430 ist schon 16 Bit
und mit so etwas wie segmentiertem RAM oder Bankwechsel muss man sich
bei dem auch nicht herumärgern.
Warum also so uralte CPU Architekturen einsetzen, wenn es schon längst
bessere gibt?
Der erste Fehler beginnt nicht erst bei der verwendeten Sprache, sondern
bei der Wahl der Hardware.
Geron schrieb:> Der erste Fehler beginnt nicht erst bei der verwendeten Sprache, sondern> bei der Wahl der Hardware.
Und die Hardware sollte man erst wählen, wenn man ein Projekt hat,
welches man realisieren will. Zuerst einen uC auswählen und dann ein
Projekt dafür suchen ist schon schwierig aber ich nehme mal an der
Threadstarter hatte irgendwas im Hinterkopf.
Max M. schrieb:> Was mich ebenfalls noch interessieren würde, ist, ob sich mit den> beschränkten Ressourcen auch eine Software-I2C Lösung implementieren> ließe? Vom Flash her dürfte das imho kein Problem sein, aber ich weiß> nicht, ob das RAM dafür reicht? Die Funktionalität des I2C-Systems würde> ich auf mehrere Funktionen aufteilen, wenn man davon ausgeht, dass nach> dem Rausspringen aus einer Funktion der RAM, der in der Funktion> benötigten Variablen, freigegeben wird, könnte das klappen, oder?
Da bei so kleinen PICs das Debuggen ohne Debug-Header nicht sinnvoll
ist, einfach das Programm schreiben und mit dem Simulator überprüfen. Da
sieht man sofort wieviele Resourcen verbraucht werden. Kaufen muss man
auch noch nichts. Das kann warten, bis man eine Vorstellung bekommen
hat, ob eine Realisierung überhaupt möglich ist.
Geron schrieb:>> schneller und brauchten weniger Flash. Davor hätte ich auch 1000 Eide>> geschworen, daß es genau umgekehrt sein muß. Und vor allem konnte man>> sie sauschnell schreiben im Vergleich zu Assembler.>> Das sagt etwas über deine Fähigkeiten in Assembler aus.Bestimmt nicht.
Guck dir mal die vom C-Compiler erzeugten Listings an.
Da sind manchmal Tricks drin, da fragt man sich warum man nicht
selber draufgekommen ist und ob man wirklich so dumm ist...
Interrupts können zu jedem beliebigen Zeitpunkt feuern, welche Register
will man da sichern - AVR hat 32 davon - alle ?
Wenn man ein nur einigermassen kompliziertes Programm in ASM schreibt,
müssen die benutzten Register und die geänderten Variablen irgendwo
verfolgt und festgehalten werden.
Ich habe mir sogar seinerzeit ein Programm geschrieben, das nur dazu
diente, benutzte Register und Änderungen in ASM-Listings zu verfolgen.
CALL und RCALL rausgesucht - Routine gefunden - RET gefunden - benutzte
Register dazwischen ausgegeben.
Ging natürlich mit modularem Programmaufbau wunderbar, aber dann
kamm die Entscheidung bei bedingtem Sprung, Labels, etc...
Ich gab auf und behielt nur den CALL/RCALL Zweig und den benutze ich
heute noch.
Geron schrieb:> Erst dann, wenn die CPU nicht mehr überschaubar ist, liegt der Compiler> ganz vorne.
Deine Aussage zeugt nur davon auf welchem Schwierigkeitsgrad bzw.
Niveau sich deine Programme befinden.
Peter D. schrieb:> Und deshalb mußte ich> höllisch aufpassen, eine Callingtiefe von 3 nicht zu überschreiten, bzw.> 2, wenn man Interrupts verwendete. Er war daher genauso eklig zu> programmieren, wie die PICs mit nur 2-level HW-Stack.
Na, das ist ja mal ne seltene Übereinstimmung.
Aber schreib nicht so generalisierend. Ganz alte PIC's hatten keinen
Interrupt - ist aber schon 25 Jahre her. Die "normalen" kleinen PIC's
(16Fxxx) haben zumeist 8 Stack-Plätze, manche neueren auch mehr. Es sind
nur die ganz winzigen PIC's, die weniger haben - aber das kann man ja
auch einsehen: so ein winziger 6-Beiner mit 512 Programmschritten ist
eben nur für ganz kleine Vorhaben vorgesehen und da braucht man i.All.
auch weniger Stacktiefe.
Nochwas zu dem geposteten Quell-Ausschnitt: Das war zum Angucken, wie
sowas bei den PIC's aussehen kann - und nicht zum Behaupten, daß
Prinzipien, die man zwar in Assembler, aber eben NICHT in C machen kann,
als solche PIC-spezifisch wären. Zu sowas gehören auch Operationen
über's carry, also Schieben, Rotieren usw. Wer den Lampe-Jorke-Wengel
mal gelesen hat weiß, wie effektiv sowas bei kluger Planung sein kann
(Z80).
Ich kenne Leute, die zwar von PIC's keine Ahnung haben, aber dennoch im
Brustton allertiefster Überzeugung sagen "ich wüßte nicht, warum ich so
einen PICNICHT in C programmieren sollte."
Max M. schrieb:> Mir ist gerade aufgefallen, dass der PIC10F220 zwar einen Timer hat,> aber keinen Overflow-Interrupt (bzw. gar keine Interrupts). Das macht> das Programmieren nicht angenehmer.
Wenn du erst noch anfangen willst, dann greife zuerst lieber zu einem
PIC16F... und nicht zu allererst zu einem der ganz winzigen Typen.
Laß dir das geraten sein.
Und schau dir verschiedene PIC-Assembler an, denn manche haben ne
gefälligere Syntax als die Originale von Microchip.
W.S.
Marc V. schrieb:> Interrupts können zu jedem beliebigen Zeitpunkt feuern, welche Register> will man da sichern - AVR hat 32 davon - alle ?>> Wenn man ein nur einigermassen kompliziertes Programm in ASM schreibt,> müssen die benutzten Register und die geänderten Variablen irgendwo> verfolgt und festgehalten werden.
nanana..
Mal ganz ruhig: Man weiß ja wohl, was für Register man im
Interrupthandler zu benutzen gedenkt. Und da wir hier nicht bei AVR
sind, sondern bei den PIC's, muß man sich um die dort üblichen
Verdächtigen kümmern: W und Status und je nach PIC und Anwendung ggf.
FSR und Bank.
Das war's.
Bei dem "nur einigermassen kompliziertes Programm in ASM" handelt es
sich um eine Chimäre - konkret wird die Aussage nur dann, wenn man sie
auf eine bestimmte CPU-Architektur bezieht. Alles durcheinanderwürfeln
und generös von "in Assembler" reden, gilt nicht.
Bei Registermaschinen macht man das normalerweise so, daß man die in
einem Unterprogramm benutzten Register zuvor auf dem Stack rettet - bis
auf diejenigen, die nach eigener Konvention zum beliebigen Benutzen
deklariert sind.
Das trifft auf die kleinen PIC's aber nicht zu, wenn man mal von W
absieht.
Also bitte keine derartigen Verallgemeinerungen.
W.S.
W.S. schrieb:> Bei Registermaschinen macht man das normalerweise so, daß man die in> einem Unterprogramm benutzten Register zuvor auf dem Stack rettet
Welche wären das? Beim 8051 und den Cortex A/R nimmt man in Assembler
erst mal die anderen Registerbänke her und braucht meist gar keinen
Stack. Und bei den Cortex M werden ja bei Interrupts automatisch
bestimmte Register auf den Stack geschoben, was dann DIE Fehlerquelle
für den Hardfault ist.
Marc V. schrieb:> Interrupts können zu jedem beliebigen Zeitpunkt feuern, welche Register> will man da sichern - AVR hat 32 davon - alle ?
Was für ein Unsinn - wozu Register sichern, die in der ISR garnicht
verändert werden? Das sind aber nun wirklich allerprimitivste
Grundlagen, die jeder Assembler-Programierer wissen MUSS.
Georg
Geron schrieb:> Das sagt etwas über deine Fähigkeiten in Assembler aus.
Der Schuß ging ins Leere.
Schau Dir einfach mal die alten Assemblerbeispiele (8051, AVR) von mir
an.
Max M. schrieb:> Schade, dass man 2 Register nicht direkt vergleichen kann sondern diese> Umwege gehen muss
Kennst du nen µC, wo man zwei Variablen im RAM direkt miteinander
vergleichen kann?
Bei den kleinen PIC's geht es eben nur etwa so:
1
MOVFVariable1,W
2
XORWFVariable2,W;oderwermagSUBWF...
3
SKIPZ
4
GOTOsonstwohin
Ach ja, so ist das mit verschiedenen Assemblern:
movfw cmpVal
ist so ein Fall, den ich nicht mag. Ist nicht Standard und mit movwf
leicht zu verwechseln. Man kann es mit einem garstigen Assembler dem
Programmierer auch künstlich schwer machen.
W.S.
Max M. schrieb:> [...]> Ich weiß nun nicht, inwiefern die 2 Programme vergleichbar sind,> allerdings belegt das C-Programm 31% des RAMs und 7% des Flashes.
Du musst dir einfach mal den ASM-Output des C-Compilers anschauen.
Davon gabesehen ist der XC8 als kostenlose Version nicht unbedingt die
beste Wahl, weil Microchip da die meiste Optimierung abgeschaltet hat.
Böse Zungen würden wohl sogar behaupten, dass der Code-Output künstlich
aufgebläht wird. Daher ist der freie CC5X für die kleinen PICs i.d.R.
besser geeignet.
Max M. schrieb:> Kann es sein, dass der PIC10F200 die Pins gar nicht so schalten kann,> dass I2C direkt möglich ist (Open-Drain)?
Kann es sein, dass Dir wirklich die Basics fehlen? Entweder zu I2C oder
zu µControllern? Open Drain wird durch DRR=1/0 mit PIN=0 realisiert.
Max M. schrieb:> delay:> movfw cmpVal ;copy content from 11h to 12h> movwf cmpReg> movfw incrReg> subwf cmpReg ;subtract counter value> btfsc STATUS,2 ;check if compare and increment value are equal> goto endDelay> incf incrReg> goto delay> endDelay> retlw 0
Das ist so ziemlich der umständlichste Delay-Loop, den ich je gesehen
habe...
Man könnte sowas auch völlig ohne RAM-Speicher machen, und viel kürzer!
1
;---------------- Delay Unterprogramm
2
;Aufruf mit Delay-Wert in W, verzögert um W*4 +3 Zyklen
Thomas E. schrieb:> Man könnte sowas auch völlig ohne RAM-Speicher machen, und viel kürzer!
Der Simulator zeigt bei mir, dass 0% vom RAM genutzt wird? Ehrlich
gesagt weiß ich gar nicht, wie ich in Assembler explizit den RAM
adressiere... Danke für deine Delay-Funktion, hatte da etwas Tomaten auf
den Augen.
Uuuups - sorry, sehe gerade, daß die Sache einen kleinen Haken hat: der
PIC10F200 hat gar keinen ADDLW-Befehl (der 10F32x schon)!
Also doch mit einer RAM-Speicherzelle:
1
;---------------- Delay Unterprogramm
2
;Aufruf mit Delay-Wert in W, verzögert um W*3 +4 Zyklen
Max M. schrieb:> Der Simulator zeigt bei mir, dass 0% vom RAM genutzt wird? Ehrlich> gesagt weiß ich gar nicht, wie ich in Assembler explizit den RAM> adressiere...
Im "relocatable mode" wird die RAM Nutzung auch in MPLABX angezeigt.
Im "absolute mode" wo man mit EQU irgendwelche Namen durch Adressen
ersetzten lassen kann wird ja kein Speicherplatz reserviert.
Schau mal in den Ordner mit den Templates:
.../microchip/mplabx/v3.50/mpasmx/templates
Die für "relocatable" sind im Ordner .../templates/Object
Marc V. schrieb:> Geron schrieb:>>> schneller und brauchten weniger Flash. Davor hätte ich auch 1000 Eide>>> geschworen, daß es genau umgekehrt sein muß. Und vor allem konnte man>>> sie sauschnell schreiben im Vergleich zu Assembler.>>>> Das sagt etwas über deine Fähigkeiten in Assembler aus.>> Bestimmt nicht.> Guck dir mal die vom C-Compiler erzeugten Listings an.> Da sind manchmal Tricks drin, da fragt man sich warum man nicht> selber draufgekommen ist und ob man wirklich so dumm ist...
Dir fällt nicht einmal auf, dass das in dem Kontext nicht einmal ein
Argument ist.
Denn es ist nicht allgemeingültig, du machst sogar den Fehler und
schließt in dem Fall sogar von dir auf die Frage, ob der Mensch besser
sein kann als der Compiler bei Überschaubaren CPU Architekturen.
Als Mensch kannst du veränderlichen Code programmieren, das wird ein
normaler Compiler nicht machen.
Das allein ist schon eine Möglichkeit um mit knappen Platz umzugehen.
> Interrupts können zu jedem beliebigen Zeitpunkt feuern, welche Register> will man da sichern - AVR hat 32 davon - alle ?
Das kann man so pauschal nicht beantworten und das weißt du auch. Es
kommt auf den konkreten Anwendungsfall an und wie dein Code aussieht.
Zumal man sich jetzt darüber streiten kann, ob 32 Register für eine
überschaubare CPU sprechen und darum geht es ja.
>> Geron schrieb:>> Erst dann, wenn die CPU nicht mehr überschaubar ist, liegt der Compiler>> ganz vorne.>> Deine Aussage zeugt nur davon auf welchem Schwierigkeitsgrad bzw.> Niveau sich deine Programme befinden.
Nein, meine Aussage ist im Gegensatz zu deiner allgemeingültig.
Oder soll ich jetzt aus deiner Antwort deuten, das du dieser Aussage
widersprichst?
Der Compiler ist nur so schlau, wie ihn der Mensch programmiert hat und
ja, Compilerbauer die das Hauptberuflich machen, sind schlau, es ist
extrem wahrscheinlich dass die schlauer sind als du und der andere, bei
dem ich auf seine Assemblerfähigkeiten hingewiesen habe, aber selbst bei
denen kommt es vor, dass sie Optimierungsmöglichkeiten in Assembler
kennen, die sie im Compiler nur schlecht umsetzen können.
Und schon hast du einen Fall, wo der Compiler nicht gut sein kann.
Marc V. schrieb:> ....
Noch etwas:
Das ganze kannst du dir wie folgende Funktion forstellen:
f=(1/x^2) wobei für x nur der positive Wertebereich gilt.
Auf der Y-Achse hast du dann die Komplexität der CPU abgebildet
und auf der X-Achse die Anzahl an Leuten, die die mithalten können.
Nach diesem Beitrag: http://www.edaboard.com/thread114417.html
kann man einen Pin Open-Drain schalten, in dem ich die entsprechenden
Bits im TRIS-Register setze. Wenn ich einen Pin low schalten möchte,
muss ich das gesamte TRIS-Register neu schreiben. Damit würde ich
automatisch auch den Zustand des 2. Pins überschreiben, d.h. ich muss
vorher überprüfen, welchen Zustand der andere Pin hat. Das geht aber
nicht, da laut Datenblatt das TRIS-register "write-only" ist, wie löst
man das?
Max M. schrieb:>> Ich weiß nun nicht, inwiefern die 2 Programme vergleichbar sind,> allerdings belegt das C-Programm 31% des RAMs und 7% des Flashes.
Guck dir einfach den Maschinencode an, den der Compiler aus dem C Code
backt.
Dann kannst du das auch vergleichen.
Max M. schrieb:> Wenn ich einen Pin low schalten möchte,> muss ich das gesamte TRIS-Register neu schreiben. Damit würde ich> automatisch auch den Zustand des 2. Pins überschreiben, d.h. ich muss> vorher überprüfen, welchen Zustand der andere Pin hat. Das geht aber> nicht, da laut Datenblatt das TRIS-register "write-only" ist, wie löst> man das?
Wenn man das nicht wissen kann, muss man es sich wohl irgendwo merken.
Wenn sich nur ein Pin änndert, dann sollte man es aber eigentlich
wissen..
.
Geron schrieb:> ja, Compilerbauer die das Hauptberuflich machen, sind schlau, es ist> extrem wahrscheinlich dass die schlauer sind als du und der andere, bei> dem ich auf seine Assemblerfähigkeiten hingewiesen habe, aber selbst bei
Da du dich selbst aus dem Vergleich rausgenommen hast, nehme ich an,
dass du dich für ungemein schlau hältst.
Sagen wir es mal so:
Peter D. (der andere) kann bestimmt besser in Assembler programmieren
als du.
Und ich habe mehr von ASM-Programmierung vergessen, als du jemals
lernen wirst.
Das hat aber nichts mit schlau oder dumm zu tun - ein Mensch kann ganz
einfach nicht alles wissen, alles am besten machen und immer als Erster
auf beste Lösungen kommen.
Und was ist von der ganzen Sache halte, habe ich schon geschrieben:
Marc V. schrieb:> Bei 16Byt RAM fängt man gar nicht erst mit C an. Die ganze dazu> nötige Gehirnakrobatik, um mit 16Byte überhaupt ein einigermassen> sinnvolles Programm zum Laufen zu bringen, lohnt sich doch eh> nicht. Das hat man mit ASM viel schneller hingekriegt.> Und das es Leute gibt die so etwas kaufen, um damit anzufangen,> werde ich niemals begreifen.>> So etwas nimmt man als Sensor/Aktor und dann ist aber auch Schluss.> Und dafür war es wahrscheinlich auch gedacht, also ASM von vorn-> herein, kein C.>> Ende.
W.S. schrieb:> Kennst du nen µC, wo man zwei Variablen im RAM direkt miteinander> vergleichen kann?MSP430; Beispiel aus dem Handbuch:
1
CMP.B EDE,TONI ; MEM(EDE) = MEM(TONI)?
2
JEQ EQUAL ; YES, JUMP
Die Selbstbeweihräucherung lautet wie folgt:
> The CPU incorporates features specifically designed for modern> programming techniques such as calculated branching, table processing,> and the use of high-level languages such as C. The CPU can address the> complete address range without paging.>> The CPU features include:> • RISC architecture with 27 instructions and 7 addressing modes.> • Orthogonal architecture with every instruction usable with every> addressing mode.> • Full register access including program counter, status registers,> and stack pointer.> • Single-cycle register operations.> • Large 16-bit register file reduces fetches to memory.> • 16-bit address bus allows direct access and branching throughout> entire memory range.> • 16-bit data bus allows direct manipulation of word-wide arguments.> • Constant generator provides six most used immediate values and> reduces code size.> • Direct memory-to-memory transfers without intermediate register> holding.> • Word and byte addressing and instruction formats.
Und dann kann man natürlich darüber streiten, was "RISC" eigentlich
bedeutet ...
Marc V. schrieb:> Geron schrieb:>> ja, Compilerbauer die das Hauptberuflich machen, sind schlau, es ist>> extrem wahrscheinlich dass die schlauer sind als du und der andere, bei>> dem ich auf seine Assemblerfähigkeiten hingewiesen habe, aber selbst bei>> Da du dich selbst aus dem Vergleich rausgenommen hast, nehme ich an,> dass du dich für ungemein schlau hältst.>> Sagen wir es mal so:> Peter D. (der andere) kann bestimmt besser in Assembler programmieren> als du.> Und ich habe mehr von ASM-Programmierung vergessen, als du jemals> lernen wirst.
Du kannst eine Diskussion nicht gewinnen, in dem du mich, der die andere
Seite vertritt, persönlich angreifst. Das dies ausgesprochen dumm von
dir ist, erwähne ich hiermit explizit.
>> Das hat aber nichts mit schlau oder dumm zu tun - ein Mensch kann ganz> einfach nicht alles wissen, alles am besten machen und immer als Erster> auf beste Lösungen kommen.
Noch einmal, wir sprachen von überschaubaren CPUs.
Geron schrieb:> Du kannst eine Diskussion nicht gewinnen, in dem du mich, der die andere> Seite vertritt, persönlich angreifst. Das dies ausgesprochen dumm von> dir ist, erwähne ich hiermit explizit.
Ich habe dich bestimmt nicht persönlich angegriffen, ganz im Gegensatz
zu dir, sowohl in oben zitiertem Satz als auch vorher:
>> ja, Compilerbauer die das Hauptberuflich machen, sind schlau, es ist>> extrem wahrscheinlich dass die schlauer sind als du und der andere,>> bei dem ich auf seine Assemblerfähigkeiten hingewiesen habe,
Als ich erwähnt habe, dass Peter besser Assembler kann als du und
dass ich mehr davon vergessen habe etc... - das ist ganz einfach die
Wahrheit und kein Angriff, ob du es wahrhaben willst oder nicht.
Und dass du dich aus dem obigen Vergleich mit Compiler rausgenommen
hast und dich durch obige Behauptung gleich angegriffen fühlst, zeugt
nur davon, dass dein Ego weitaus grösser als deine Kenntnisse ist und
diese bei weitem übersteigt.
>> Das hat aber nichts mit schlau oder dumm zu tun - ein Mensch kann ganz>> einfach nicht alles wissen, alles am besten machen und immer als Erster>> auf beste Lösungen kommen.>> Noch einmal, wir sprachen von überschaubaren CPUs.
Was hat meine Behauptung damit zu tun, ob eine CPU überschaubar ist
oder nicht ?
Max M. schrieb:> Also Assembler ist schon lustig :D> 8% des Flash vom PIC10F200 sind mit diesem Programm belegt:>
...
> Edit: Ich hab mal versucht, das ganze in C nachzumachen:>>
1
>#include<xc.h>
2
>#define_XTAL_FREQ4000000
3
>voidmain(void){
4
>TRISGPIO=0x00;
5
>while(1){
6
>GPIO|=(1<<0);
7
>__delay_ms(1);
8
>GPIO&=~(1<<0);
9
>}
10
>}
11
>
>> Ich weiß nun nicht, inwiefern die 2 Programme vergleichbar sind,> allerdings belegt das C-Programm 31% des RAMs und 7% des Flashes.
Also weniger Flash, keine Enge im RAM und ich als *nicht-PICler kann's
sofort verstehen. Was spricht gegen den "Universal-Assembler.
*lesen kann ich rudimentär, aber es muß nicht sein.
Marc V. schrieb:> Geron schrieb:>> Du kannst eine Diskussion nicht gewinnen, in dem du mich, der die andere>> Seite vertritt, persönlich angreifst. Das dies ausgesprochen dumm von>> dir ist, erwähne ich hiermit explizit.>> Ich habe dich bestimmt nicht persönlich angegriffen, ganz im Gegensatz> zu dir, sowohl in oben zitiertem Satz als auch vorher:>>> ja, Compilerbauer die das Hauptberuflich machen, sind schlau, es ist>>> extrem wahrscheinlich dass die schlauer sind als du und der andere,>>> bei dem ich auf seine Assemblerfähigkeiten hingewiesen habe,
Der Kontext ist hier Assembler. Es macht schon einen Unterschied ob man
eine Generelle Aussage trifft:
Compilerbauer können besser Assembler als der typische 08/15
Programmierer. Und das dem so ist, ergibt sich aus dem Kontext, weil die
schließlich die Compiler entwickeln und daher die Maschine und Assembler
in und auswenig kennen und kennen müssen und man dafür auch nur die
besten auf dem Markt nimmt. Der einfache Programmierer kriegt den Job
erst gar nicht.
Daraus ergibt sich übrigens auch, wärst du darin gut, dann wärst du
beruflich selbst Compilerbauer.
Das Angebot ist aber klein und die Stellen sind begehrt, das ist so wie
Jetpilot werden zu wollen und deswegen nimmt man da auch nur die besten.
Im Gegensatz zu einer Aussage wie:
"Peter und ich können besser Assembler als du."
Zumal du hier nicht einmal weißt, wer ich bin.
Also, der einzige der hier beleidigt hat, warst du.
> Als ich erwähnt habe, dass Peter besser Assembler kann als du und> dass ich mehr davon vergessen habe etc... - das ist ganz einfach die> Wahrheit und kein Angriff, ob du es wahrhaben willst oder nicht.
Das ist keine Wahrheit, weil dir dafür die Informationen fehlen.
Du müsstest dazu nämlich mich kennen. Es ist somit sogar eine Lüge, weil
du mich nicht kennst.
> Und dass du dich aus dem obigen Vergleich mit Compiler rausgenommen> hast und dich durch obige Behauptung gleich angegriffen fühlst, zeugt> nur davon, dass dein Ego weitaus grösser als deine Kenntnisse ist und> diese bei weitem übersteigt.
Ich habe mich rausgenommen, weil ich kein Compilerbauer bin und es für
meine generelle Aussage auch nicht wichtig wäre.
>>>> Das hat aber nichts mit schlau oder dumm zu tun - ein Mensch kann ganz>>> einfach nicht alles wissen, alles am besten machen und immer als Erster>>> auf beste Lösungen kommen.>>>> Noch einmal, wir sprachen von überschaubaren CPUs.>> Was hat meine Behauptung damit zu tun, ob eine CPU überschaubar ist> oder nicht ?
Eine überschaubare CPU kann man kennen, man kann sie auch gut
programmieren, eben weil sie überschaubar ist.
Ich hatte mal den AVR LS1200 oder so, der hatte glaub kein gar RAM und
nur 1200 byte code. Und trotzdem konnte ich einen FSK generator
reinschreiben. Abhaengig von einem Pin konnte der auf einem anderen Pin
die eine oder andere Frequenz im 50kHz (51kHz & 55kHz) Bereich
rauslassen.
Max M. schrieb:> Nach diesem Beitrag: http://www.edaboard.com/thread114417.html>> kann man einen Pin Open-Drain schalten,
Ich hoffe Du bist Dir bewusst, dass es nur ein "pseudo" Open-Drain ist.
Ich habe es nicht extra geschrieben, aber er funktioniert nur, wenn die
Spannung am µC >= die vom I2C-Device ist.
> in dem ich die entsprechenden> Bits im TRIS-Register setze. Wenn ich einen Pin low schalten möchte,> muss ich das gesamte TRIS-Register neu schreiben. Damit würde ich> automatisch auch den Zustand des 2. Pins überschreiben, d.h. ich muss> vorher überprüfen, welchen Zustand der andere Pin hat. Das geht aber> nicht, da laut Datenblatt das TRIS-register "write-only" ist, wie löst> man das?
In der Regel nimmt man ein Shadow-Register, das man jeweils bearbeitet
und nachher ins TRIS schreibt. Aber auch das wiederspricht natürlich der
sportlichen Herausforderung nach möglichst wenig Speicher.
So wirklich kleinste µC verwendet man privat nur wegen der Sportlichen
Herausforderung. Ansonsten nimmt man zumindest die größte Variante einer
Bauform.
Dampf T. schrieb:> Ich hatte mal den AVR LS1200 oder so, der hatte glaub kein gar RAM und> nur 1200 byte code.
Der AT90S1200 ist ja der Uropa der AVR.
Etwa 30 Register hat der nur.
Für viele einfache Sachen reicht der völlig.
Auf dem STK-500 ist der u.a. für die ser. Kommunikation zuständig.
michael_ schrieb:> Der AT90S1200 ist ja der Uropa der AVR.> Etwa 30 Register hat der nur.
Der Z80 hat garkein RAM und viel weniger Register, trotzdem gabe es
viele Schaltungen ohne externen RAM-Baustein. Sowas erfordert halt
Nachdenken beim Programmierer, was seitdem aus der Mode gekommen ist.
Georg
Achim S. schrieb:> So wirklich kleinste µC verwendet man privat nur wegen der Sportlichen> Herausforderung. Ansonsten nimmt man zumindest die größte Variante einer> Bauform.
Nicht übertreiben, man kann die Anforderungen durchaus realistisch
abschätzen und die Auswahl entsprechend treffen. Den letzten Cent muss
man aber nicht sparen wollen.
Bei der Bauform würde ich aber auch nicht sparen, ein paar pins als
Reserve schaden auch nicht. Etwa wenn man merkt, dass der interne
Oszillator doch nicht genau genug ist und man, entgegen der Planung,
doch einen Quarz braucht. Oder man hat noch irgendwas andres vergessen.
Auch bei Serienfertigung: Neuere Firmwareversionen sind im zweifelsfall
immer größer wie die vorhergehende. Wenn Kundenseitige Updates
vorgesehen sind: Ausreichend Speicher einplanen.
Diese sind für bestimmte Anwendungen ganz nett, nicht so toll ist ist
das heikle icsp speziell wenn man die Sensoren im laufenden Betrieb
calibrieren muss.
Hitech C funktioniert recht gut darauf, wurde von Microchip aber
totgekauft und gibt es nicht mehr downzuladen mit eingeschalteter
Optimierung soweit ich weiss.
Eventuell in Archiven.
Ohne baseline ASM libs und macros such dir einen anderen chip. 256 flash
und 16 byte RAM, ein counter +wdt. Eigentlich müsste es ein die shrinked
12f509 sein mit ADC sowie top row flash emulated eeprom.
X8c basiert auf hitech 18c Compiler, war nicht sonderlich gut. Ich bezog
mich auf den 12c/16c/17c (lite) Compiler wo die volle Optimierung
eingeschaltet war sowie peephole optimizer und auf 2k Rom/Flash begrenzt
war, dafür aber gratis, auch für kommerzielle Projekte.
Ich hab mehrere Funktionen, in denen ich den gleichen Labelnamen
verwende, nun bekomme ich beim kompilieren folgende Fehlermeldung:
1
Address label duplicated or different in second pass
Auch local:
1
;SCL is GP0
2
;SDA is GP1
3
SCLHigh:
4
local sdaHigh,sdaLow,updateTris
5
movfw SDA
6
movwf tmp
7
decf tmp
8
btfsc STATUS,2 ;check if Z-Flag is set
9
goto sdaHigh ;if so, SDA is currently High
10
goto sdaLow ;otherwise, SDA is low
11
sdaHigh
12
movlw 03h ;SCL and SDA are high
13
goto updateTris
14
sdaLow
15
movlw 01h ;only SCL is high
16
goto updateTris
17
updateTris
18
tris 6 ;update TRIS register
19
movlw 01h
20
movwf SCL ;SCL is now high
21
retlw 0
schafft da keine Abhilfe, der Fehler ändert sich nur von:
1
Address label duplicated or different in second pass (updateTris)
in
1
Address label duplicated or different in second pass (_0updateTris)
Hat jemand eine Idee, wie man das löst (abgesehen von jedes mal neue
Labels zu verwenden)? Kann man Labels irgendwie explizit im Kontext der
eigenen Funktion definieren?
Max M. schrieb:> Kann man Labels irgendwie explizit im Kontext der> eigenen Funktion definieren?
Soweit ich weiß, kennt MPASM keine lokalen Labels in "Funktionen" - er
kennt nicht mal Funktionen in dem Sinn, wie z.B. C.
Lokale Labels gibt es nur modulweise, bei relocatable Code. Dann
müsstest Du für jede Deiner Funktionen in ein separates Sourcefile
schreiben. Das dürfte sich bei Deinen paar Programmzeilen aber nicht
lohnen - denk Dir lieber unterschiedliche Labelnamen aus.
Max M. schrieb:> Hat jemand eine Idee, wie man das löst
Selbstverständlich: Deklariere NIEMALS ein Label oder sonstigen Namen
zweimal, sondern nimm jedesmal einen anderen Namen. Das ist doch
eigentlich einleuchtend - oder?
In deinem Beispiel sehe ich auch keine "Markierungen", wo ein lokaler
Block beginnt und wo er endet. Folglich dürfte zu vermuten sein, daß
"local" dann eben für die gesamte Quelle gilt, womit die
Assembler-Ausschrift erklärlich ist - auch wenn ich deinen Assembler
nicht näher kenne. Ich benutze nämlich seit langem meinen eigenen.
Nochwas: dein Beispiel sieht mit sehr goto-lastig aus, überdenke nochmal
deinen Ansatz: Ich würde für Tris ein halbes RAM-Byte opfern, das sieht
mir günstiger aus.
W.S.
chris schrieb:> Hitech C funktioniert recht gut darauf, wurde von Microchip aber> totgekauft und gibt es nicht mehr downzuladen mit eingeschalteter> Optimierung soweit ich weiss.> Eventuell in Archiven.
Der Link auf der Hi-Tech Seite hat gestern nicht funktioniert.
Heute geht es anscheinend (wieder).
http://www.htsoft.com/downloads/archive.php
ftp://Compilers-RO:C0mP!0511@ftp.microchip.com/
Ist es möglich, den grau markierten Bereich (das ist anscheinend der
RAM) auch als Register zu benutzen (abgesehen davon, wenn man den
relocateable Mode benutzt)?
Wenn ich versuche, in meinem Programm da was reinzuschreiben, bekomme
ich die Fehlermeldung:
Danke!
Ich versuche gerade, eine Funktion zu schreiben, die ein Byte als
I2C-Datenpaket sendet. Aktuell scheitert die Funktion daran, dass ich
nicht weiß, wie ich testen kann, ob eine Variable negativ ist (bzw. 255
bzw. -1 ist). Bis zum letzten Durchlauf (wenn nicht mehr nach rechts
geschoben wird) funktioniert alles, ich ziehe von meiner Zählervariable
(tmp) "1" ab, das Register wird 255 aber an den Flags ändert sich
nichts. Wie erkenne ich nun, dass ich im negativen Bereich bin?
1
;sends Byte which is stored in i2cDat Register
2
SendByte:
3
movlw 07h
4
movwf tmp
5
step movfw tmp
6
movwf tmp2
7
movfw i2cDat
8
movwf tmp3
9
movfw tmp
10
incf tmp ;do some stuff to create zero bit if necessary
11
decf tmp
12
sru btfsc STATUS,2 ;check if tmp is already zero (last step)
13
goto extrBit ;if so, don't shift right anymore
14
bcf STATUS,0 ;clear carry bit to shift unsigned
15
rrf tmp3,1 ;shifted values are now in tmp3
16
decf tmp2
17
btfss STATUS,2 ;chechk if zero
18
goto sru ;shift if not zero
19
extrBit
20
movfw tmp3 ;move shifted value to work register
21
andlw 01h ;extract first bit
22
movwf tmp2 ;contains now single bit
23
decf tmp2 ;decrement
24
btfsc STATUS,2 ;check if zero (was 1 before then)
25
goto setSDA ;if, set SDA high
26
goto resetSDA ;otherwise, set SDA low
27
setSDA
28
call SDAHigh
29
goto clk
30
resetSDA
31
call SDALow
32
goto clk
33
clk
34
call SCLHigh ;create a clock cycle
35
36
movlw 015h
37
movwf tmp2
38
call delay
39
40
call SCLLow
41
bcf STATUS,0 ;clear carry from previous operations
Max M. schrieb:> Aktuell scheitert die Funktion daran, dass ich> nicht weiß, wie ich testen kann, ob eine Variable negativ ist (bzw. 255> bzw. -1 ist).
Eine negative Zahl erkennt man am gesetzten MSB (Bit 7). Testen kann man
das dann leicht z.B. mit
1
...
2
btfsc tmp,7
3
goto tmp_is_negative
4
...
oder
1
...
2
btfss tmp,7
3
goto tmp_is_positive
4
...
Schleifenzähler macht man aber meistens besser so:
Max M. schrieb:> extrBit> movfw tmp3 ;move shifted value to work register> andlw 01h ;extract first bit> movwf tmp2 ;contains now single bit> decf tmp2 ;decrement> btfsc STATUS,2 ;check if zero (was 1 before then)> goto setSDA ;if, set SDA high> goto resetSDA ;otherwise, set SDA low> setSDA> call SDAHigh> goto clk> resetSDA> call SDALow> goto clk> clk
warum so kompliziert? Diese goto-Orgien sind ja grausam! Ebenfalls
grausam finde ich, die Statusbits mit Nummern anzusprechen, statt z.B.
mit "Z" oder "C", und als Ziel der Operation "0" oder "1" zu schreiben,
statt "W" oder "F".
Ich schlage vor, diesen Programmteil durch
Wir verwenden pic 12f509 für die Steuerung des Test im Ofen sowie
diversen Langzeittests.
derzeit werden max 16 bytes verwendet.
Was angeschlossen ist:
1 io IRIG J-14 signal + error flag
1 inp dmm rs232, reset line
2 in/out rs232 MUX, kann zu mehreren Geräten gemuxt werden. Dmm Netzteil
LCR ...
1 out scl
1 io OC sda oder rs232
Relay oder IC MUX wie auch Temperatursensoren werden über i2c gesteuert.
Sieht so aus, als wäre I2C doch nicht ganz so einfach, durch den
begrenzten Hardware-Stack kann ich das Programm nicht so strukturieren
wie ich gerne möchte. Wenn ich jeden Funktionsaufruf von "SendCommand"
durch den in der Funktion enthaltenen Code ersetze, lande ich schnell
bei 100% Flashauslastung.
Hat jemand einen Tipp, wie man die Initialisierung des SSD1306 in den
Flash reinbekommt?
Ich bin bereits erstaunt, dass das bis jetzt überhaupt reinpasst und das
sogar noch 24% vom Flash übrig sind! Wäre Platz für eine
Rücksprungadresse mehr würde es, denke ich, funktionieren. Mein
bisheriger Code (Achtung: Lang):
1
#include <p10f200.inc>
2
3
trisShadow EQU 11h
4
tmp EQU 12h
5
i2cDat EQU 13h
6
tmp2 EQU 14h
7
tmp3 EQU 15h
8
i2cCmd EQU 16h
9
10
org 0x00
11
movlw 0Fh
12
movwf trisShadow
13
14
main
15
call I2CStart
16
movlw 0aeh
17
movwf i2cCmd
18
call SendCommand
19
call I2CStop
20
21
call I2CStart
22
movlw 0d5h
23
movwf i2cCmd
24
call SendCommand
25
call I2CStop
26
27
call I2CStart
28
movlw 080h
29
movwf i2cCmd
30
call SendCommand
31
call I2CStop
32
33
call I2CStart
34
movlw 0A8h
35
movwf i2cCmd
36
call SendCommand
37
call I2CStop
38
39
call I2CStart
40
movlw 03F
41
movwf i2cCmd
42
call SendCommand
43
call I2CStop
44
45
call I2CStart
46
movlw 0D3h
47
movwf i2cCmd
48
call SendCommand
49
call I2CStop
50
51
call I2CStart
52
clrf i2cCmd
53
call SendCommand
54
call I2CStop
55
56
call I2CStart
57
movlw 04h
58
movwf i2cCmd
59
call SendCommand
60
call I2CStop
61
62
call I2CStart
63
movlw 08dh
64
movwf i2cCmd
65
call SendCommand
66
call I2CStop
67
68
call I2CStart
69
movlw 014h
70
movwf i2cCmd
71
call SendCommand
72
call I2CStop
73
74
call I2CStart
75
movlw 020h
76
movwf i2cCmd
77
call SendCommand
78
call I2CStop
79
80
call I2CStart
81
movlw 001h
82
movwf i2cCmd
83
call SendCommand
84
call I2CStop
85
86
call I2CStart
87
movlw 0a1h
88
movwf i2cCmd
89
call SendCommand
90
call I2CStop
91
92
call I2CStart
93
movlw 0c8h
94
movwf i2cCmd
95
call SendCommand
96
call I2CStop
97
98
call I2CStart
99
movlw 0dah
100
movwf i2cCmd
101
call SendCommand
102
call I2CStop
103
104
call I2CStart
105
movlw 12h
106
movwf i2cCmd
107
call SendCommand
108
call I2CStop
109
110
call I2CStart
111
movlw 081h
112
movwf i2cCmd
113
call SendCommand
114
call I2CStop
115
116
call I2CStart
117
movlw 0cfh
118
movwf i2cCmd
119
call SendCommand
120
call I2CStop
121
122
call I2CStart
123
movlw 0d9h
124
movwf i2cCmd
125
call SendCommand
126
call I2CStop
127
128
call I2CStart
129
movlw 0f1h
130
movwf i2cCmd
131
call SendCommand
132
call I2CStop
133
134
call I2CStart
135
movlw 0dbh
136
movwf i2cCmd
137
call SendCommand
138
call I2CStop
139
140
call I2CStart
141
movlw 40h
142
movwf i2cCmd
143
call SendCommand
144
call I2CStop
145
146
call I2CStart
147
movlw 0a4h
148
movwf i2cCmd
149
call SendCommand
150
call I2CStop
151
152
call I2CStart
153
movlw 0a6h
154
movwf i2cCmd
155
call SendCommand
156
call I2CStop
157
158
call I2CStart
159
movlw 0afh
160
movwf i2cCmd
161
call SendCommand
162
call I2CStop
163
164
goto main
165
166
;delay funktion
167
delay:
168
decfsz tmp2
169
goto delay
170
retlw 0
171
172
;SDA = GP0
173
;SCL = GP1
174
SCLHigh:
175
movlw 02h
176
iorwf trisShadow,1
177
movfw trisShadow
178
tris 6
179
retlw 0
180
181
;SDA = GP0
182
;SCL = GP1
183
SCLLow:
184
movlw 0dh
185
andwf trisShadow,1
186
movfw trisShadow
187
tris 6
188
retlw 0
189
190
;SDA = GP0
191
;SCL = GP1
192
SDAHigh:
193
movlw 01h
194
iorwf trisShadow,1
195
movfw trisShadow
196
tris 6
197
retlw 0
198
199
;SDA = GP0
200
;SCL = GP1
201
SDALow:
202
movlw 0eh
203
andwf trisShadow,1
204
movfw trisShadow
205
tris 6
206
retlw 0
207
208
;generates a I2C Start Condition
209
I2CStart:
210
call SDALow
211
call SCLLow
212
retlw 0
213
214
;generates a I2C Stop Condition
215
I2CStop:
216
call SCLHigh
217
call SDAHigh
218
retlw 0
219
220
;sends Byte which is stored in i2cDat Register
221
SendByte:
222
movlw 07h
223
movwf tmp
224
step movfw tmp
225
movwf tmp2
226
movfw i2cDat
227
movwf tmp3
228
incf tmp ;do some stuff to create zero bit if necessary
229
decf tmp
230
sru btfsc STATUS,2 ;check if tmp is already zero (last step)
Max M. schrieb:> Wenn ich jeden Funktionsaufruf von "SendCommand"> durch den in der Funktion enthaltenen Code ersetze, lande ich schnell> bei 100% Flashauslastung.
Mach ne Schleife draus, die die einzelnen Bytes aus ner Tabelle (retlw)
liest.
Peter D. schrieb:>> Mach ne Schleife draus, die die einzelnen Bytes aus ner Tabelle (retlw)> liest.
Danke für deine Antwort, leider verstehe ich nicht ganz, was du meinst.
Ich hab nicht genügend RAM um die Bytes der Initialisierung (24) zu
speichern.
Volker S. schrieb:> 10f32x nehmen? (8-Level Stack, LAT Register, Interrupt...)
Das wäre doch zu einfach :)
> Das wäre doch zu einfach :)
Und immer noch nicht richtig.
Zwischen setSDA und setSCL ist kein delay. -> I2C-Spezifikation lesen.
Besonders von dem Target.
decf + btfss + goto -> siehe decfsz
Diese überoptimierte Programmierung nur wegen 20ct Einkaufspreises
bringt doch nichts. Lieber den 10F322 nehmen und mit C starten.
Max M. schrieb:> Wenn ich jeden Funktionsaufruf von "SendCommand"> durch den in der Funktion enthaltenen Code ersetze,
Ich halte es auch für keine gute Idee, beim Abflachen der
Call-Hierarchie von oben anzufangen, also da, wo dein Unterprogramm am
häufigsten aufgerufen wird. Dadurch multipliziert sich die Codegröße
natürlich entsprechend. Machst Du die Hierarchie im Unterprogramm
flacher, wird der Code vom Unterprogramm aber nur einmal länger.
Das mit der Schleife bietet sich natürlich an und macht den Code
kompakter und übersichtlicher. Du musst die Bytes für die
Initialisierung nicht im RAM speichern - dort liegt nur der
Schleifenzähler. Die Daten stehen in einer Tabelle im Programmspeicher,
etwa so:
1
ReadTable
2
addwf PCL,F
3
retlw DATA0
4
retlw DATA1
5
retlw DATA2
6
retlw DATA3
7
retlw DATA4
8
retlw DATA5
Um einen Wert aus der Tabelle zu lesen, wird ein "call ReadTable" mit
der Indexnummer der Daten in W ausgeführt. Wichtig wäre bei dieser Art
von Tabelle, daß die Daten nicht über eine 256 Words Codegrenze gehen
(wg. Übertrag von PCL-PCH), aber beim 10F200 besteht da naturgemäß keine
Gefahr.
Du benützt 3 calllevel wobei nur 2 verfügbar sind. SCL wird
normalerweise als reiner output angesteuert, in so einem Falle, das
vereinfacht vieles.
Also einfach bsf i2c_scl anstelle von call scl-high.
#define i2c_scl i2c_scl_port,i2c_scl_bit
Für SDA
Movlw tris_val
Btfsc tmp3,0
Xorlw i2c_sda_bit
Tris i2c_sda_port
Delay 66 US
Movlw 0x16
Movwf tmp2
Decfsz tmp2
Goto $-1
Danke für eure Antworten, da ist viel Input dabei den ich so erstmal
nicht verstehe.
neuer PIC Freund schrieb im Beitrag #4845291:
> Zwischen setSDA und setSCL ist kein delay. -> I2C-Spezifikation lesen.> Besonders von dem Target.
Meinst du in der SendByte Funktion? So:
1
extrBit
2
btfsc tmp3,0
3
call SDAHigh ;if is '1', set SDA high
4
btfss tmp3,0
5
call SDALow ;otherwise, set SDA low
6
7
;hier delay?
8
call SCLHigh ;create a clock cycle
9
10
movlw 015h
11
movwf tmp2
12
call delay
13
14
call SCLLow
15
decf tmp
16
btfss tmp,7 ;check if not negative
17
goto step ;if so, return to top
18
retlw 0
neuer PIC Freund schrieb im Beitrag #4845291:
> decf + btfss + goto -> siehe decfsz
Ist das auch in der SendByte - Funktion? Decfsz bedeutet, dass der
nächste Befehl übersprungen wird, wenn im Statusregister das Zero-Bit
gesetzt ist, ansonsten wird dekrementiert? Es erscheint mir sinnvoller,
wenn es die negierte Version davon gäbe, es wird also der nächste Befehl
übersprungen, wenn es nicht Zero ist. Ansonsten bringt mir das doch
nicht viel? Ich verstehe nicht, wie ich das hier sinnvoll implementieren
kann, vielleicht kannst du mir einen Tipp geben?
Thomas E. schrieb:> Die Daten stehen in einer Tabelle im Programmspeicher,> etwa so:
Danke, ich wusste nicht, dass es so etwas gibt. Ich verstehe nicht, was:
1
addwf PCL,F
macht. Laut der Doku addiert addwf den Inhalt des W-Registers mit
einem beliebigen anderen Register. Warum genau aus Register 15 und was
muss da drinn stehen? 0F liegt zudem noch in einem nicht
implementierten Bereich des PIC10F200.
pic schrieb:> SCL wird> normalerweise als reiner output angesteuert, in so einem Falle, das> vereinfacht vieles.
Das ist doch nicht mehr I2C konform, dachte ich? Ist nicht jeder Pin
Open-Drain und eben nicht push-pull?
pic schrieb:> Also einfach
Das was danach steht, verstehe ich nicht mehr.
Max M. schrieb:> Decfsz bedeutet, dass der> nächste Befehl übersprungen wird, wenn im Statusregister das Zero-Bit> gesetzt ist, ansonsten wird dekrementiert?
Nein - ganz anders! Bitte guck Dir nochmal die Beschreibung des Befehls
im Datenblatt an. Das Z-Flag wird durch diesen Befehl gar nicht
beeinflusst, und decrementiert wird immer, unabhängig vom Z-Flag.
1
loop
2
decfsz temp,F
3
goto loop
decrementiert also temp solange in der Schleife, bis temp=0 erreicht
wird.
Max M. schrieb:> Ich verstehe nicht, was:> addwf PCL,F>> macht. Laut der Doku addiert addwf den Inhalt des W-Registers mit> einem beliebigen anderen Register.
Eben - es addiert W auf den Programmzähler (bzw. auf die unteren 8 Bits
davon), das Ergebnis ist ein berechneter Sprung vorwärts um W
Programmspeicherstellen.
> Warum genau aus Register 15 und was> muss da drinn stehen? 0F liegt zudem noch in einem nicht> implementierten Bereich des PIC10F200.
Da ist nirgendwo ein "Register 15" im Spiel! Falls Du das ",F" so
interpretierst: Bitte beschäftige Dich noch etwas mit den Grundlagen zu
Deinem Controller! Hinter dem Komma steht das Ziel der Operation, das
entweder "W" für das W-Register sein kann, oder "F" für das angegebene
Register im Register-"F"ile. In diesem Fall soll also das Ergebnis der
Addition nicht im W-Register, sondern im PCL landen, deshalb ",F"
Du kannst auch ",0" statt ",W" schreiben und ",1" statt ",F",
offensichtlich im Gegensatz zu Dir, der Du ja auch lieber die
Status-Flags mit Nummern, statt mit Namen bezeichnest, finde ich
symbolische Bezeichnungen aber besser lesbar, als solch nichtssagende
Nummern.
Max M. schrieb:> Ich verstehe nicht, was:> addwf PCL,F>> macht. Laut der Doku addiert addwf den Inhalt des W-Registers mit> einem beliebigen anderen Register. Warum genau aus Register 15 und was> muss da drinn stehen? 0F liegt zudem noch in einem nicht> implementierten Bereich des PIC10F200.
Hier wird der Wert in W zum Wert im Register PCL addiert. Nach dem Komma
steht das Ziel an dem das Ergebnis gespeichert wird, das kann W für WREG
oder F für file (also hier PCL) sein.
PCL, also Program Counter low Byte zeigt auf diese Weise auf einen
Tabelleneintrag, von dem aus mit retlw ein Wert im WREG zurückgegen
wird.
Funktioniert allerdings nur wenn die Tabelle keine Page-Grenze
überschreitet sonst kommt Blödsinn raus.
Max M. schrieb:> pic schrieb:>> SCL wird>> normalerweise als reiner output angesteuert, in so einem Falle, das>> vereinfacht vieles.>> Das ist doch nicht mehr I2C konform, dachte ich? Ist nicht jeder Pin> Open-Drain und eben nicht push-pull?
In der Tat wäre das nicht konform. Deshalb macht man das tunlichst
nicht. Es würde dann nämlich nur noch mit solchen Slaves funktionierten
die garantiert keinen Gebrauch von Clock-Stretching machen, da fallen
dann schon mal so gut wie alle Slaves weg die I²C auf einem µC
implementieren, denn die ziehen üblicherweise nach jedem Byte den Takt
solange auf Low bis die Interruptroutine kommt und sagt "is OK, habs
gelesen, kannst ACK geben und den Takt wieder loslassen".
Es gab mal eine Zeit, da quetschten sich ein Dutzend Leute in eine
Telefonzelle, um sich und der Welt etwas zu beweisen. Telefonieren stand
dabei nicht im Vordergrund, weshalb kein praktischer Nutzen bestand.
Heute gibt es kaum noch geschlossene Telefonzellen, also weicht man
offenbar ersatzweise auf Zwerg-Mikrocontroller aus und versucht, damit
Dinge zu erledigten, für die sie weder gedacht noch auch nur annähernd
geeignet sind. Und um dem die richtige Würze zu geben, verwendet man
dafür einen µC, den man nicht versteht.
Immerhin ist das weniger lebensgefährlich.
Clock stretching, es gibt viele CPU welche dies nicht können, angefangen
von Microchip bis zu RPI. Zudem wird hier iic langsam gefahren,
15.15kbit/s was dazu beiträgt dass iic device welches clock stretching
benutzen trotzdem an einem Master ohne clock stretching support
funktioniert.
Der call level ist ein Problem, es gibt nur zwei call ebenen. Solltest
du verzweifelt sein, gibt es ein SW stack mit mehr call/return ebenen,
ansonsten einfach code besser planen.
Auch sollten 8bit Argumente nur in W dem Unterprogramm über geben werden
und nicht schon vorher in einer Hilfe variable abgespeichert werden,
dies braucht man nur wenn mehr als 8bit über geben wird.
A. K. schrieb:> Und um dem die richtige Würze zu geben, verwendet man> dafür einen µC, den man nicht versteht.
Mit irgendwas muss man doch anfangen? Ich weiß nicht, was daran schlimm
ist, wenn man etwas nicht versteht? Ich habe vor, dieses Projekt
durchzuziehen, danach verstehe ich den PIC10F200 hoffentlich
einigermaßen.
pic schrieb:> Auch sollten 8bit Argumente nur in W dem Unterprogramm über geben werden> und nicht schon vorher in einer Hilfe variable abgespeichert werden,
Hm, nur muss ich dann in der Funktion den Wert aus dem W-Register
trotzdem im RAM speichern da sonst z.B. logische Operationen nur bedingt
möglich sind. Der PIC hat zudem keinen Stack auf den man die
Übergabeparameter schieben kann so dass sich theoretisch jedes Register
in irgendeiner Unterfunktion ändern kann wenn man nicht aufpasst.
Deswegen hab ich ein Register für die wichtigsten Sachen definiert. Das
würde ein effizienter Compiler sicher anders machen, aber bevor ich
jedes Register so effizient wie möglich nutze, versuche ich erstmal, das
Programm zum laufen zu kriegen.
pic schrieb:> Clock stretching, es gibt viele CPU welche dies nicht können, angefangen> von Microchip bis zu RPI.
Der Bus Pirate mit seinem zu Fuss programmierten I2C auch nicht. Wobei
mir nicht ganz klar ist, was daran so schwierig ist.
Wobei die Hardware-Module für I2C es normalerweise können, zumindest
theoeretisch. Auch der RasPi-SoC hat das eigentlich vorgesehen, nur ist
die Implementierung ein Schuss ins Knie.
Max M. schrieb:> Mit irgendwas muss man doch anfangen? Ich weiß nicht, was daran schlimm> ist, wenn man etwas nicht versteht? Ich habe vor, dieses Projekt> durchzuziehen, danach verstehe ich den PIC10F200 hoffentlich> einigermaßen.
Das ist ja auch durchaus in Ordnung, nur sollte man das Teil am Anfang
nicht gleich bis auf das letzte Bit ausquetschen wollen.
Max M. schrieb:> Mit irgendwas muss man doch anfangen?
Mikrocontroller dieser untersten Kategorie aller 8-Bit µC sind
hauptsächlich auf dem Markt, um im Masseneinsatz einfachste Logik- und
Timerfunktionen zu implementieren. Beispielsweise an Stelle eines '555.
Anwendungen, wo der letzte Cent interessant ist, und das 6-Pin Gehäuse.
Wer damit I2C ansteuert, der muss sich schon fragen lassen, ob es ihm
wirklich um eine Lösung geht. Oder darum, in voller Absicht etwas im
Grunde sinnloses zu tun. Dieser µC hat eine für Open Drain ungeeignete
Portstruktur (ohne LAT Register ist das haarig) und erlaubt nur extrem
eingeschränkte Nutzung von Unterprogrammen. Kaum ein anderer nicht schon
antiker 8-Bit PIC hat diese Einschränkungen.
Max M. schrieb:> Hm, nur muss ich dann in der Funktion den Wert aus dem W-Register> trotzdem im RAM speichern
W zur Über- und Rückgabe von Parametern zu verwenden, ist üblich.
Es ist aber bzgl. Codegröße auch effizienter, z.B. am Anfang einer
Subroutine einmal movwf einzubauen, als bei X Aufrufen der Subroutine
X-mal vor jedem call einen movwf-Befehl einzufügen.
Apropos antik: Diese PIC10 sind im Grunde experimentelle Archäologie,
ein Ausflug mit einer Zeitmaschine in die allerersten Jahre der
Mikrocontroller.. Der Core ist in seiner Funktionalität nahezu identisch
mit dem des ersten aller PICs, dem PIC1650 von 1977. Was nicht heisst,
dass der Core von damals so genial gewesen sei, dass die Zeit ihm nichts
anhaben kann.