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
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
>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
Max M. schrieb: > Speziell hab ich mir da den PIC10F220 ausgesucht Ein EFM8BB1 mit immerhin 512B RAM kostet weniger und ist auch in C ordentlich programmierbar. > Assembler möchte ich mir nicht antun PIC10F220 geht nur in Assembler. Beitrag "v0.9 Update - ARM Cortex support" > Ansteuern diverser WS2822 Da würde sich eher ein LPC810 DIP8 anbieten, wegen dem State Configurable Timer, auch wenn der teurer ist. Beitrag "v0.9 Update - ARM Cortex support"
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.
Lothar schrieb: > PIC10F220 geht nur in Assembler. Nein, sogar sehr gut mit Oshonsoft-Compiler! Gruss Chregu
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?
Hallo, der Chip kann mehr, ist nur per Configbits auf 16 Byte. 16 Byte ist eher Marketing, ich würde mit Microchip mal den Preis verhandeln,... Seppel
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
holger schrieb: > it 16 Byte RAM ist da wohl nix mehr gross mit C-Compiler. Für den, der weiß was er tut, ist da C kein Problem.
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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!
Axel S. schrieb: > Ich halte von 8-Bit PICs vor allem eins: Abstand. Da bin ich aber froh, da kommen wir uns nicht in die Quere. MfG Klaus
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.
:
Bearbeitet durch User
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#allTimer 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! 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
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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
Bernd K. schrieb: > 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 Grade bei dem lässt sich in Assembler einiges mehr rausholen darum ist z.B. die "Standard" BLDC Regelung für Multicopter in Assembler programmiert: http://fpv-racer.net/blheli-s-firmware-for-busybee-esc-aikon-sefm-30a-dys-xs20a-dys-xs30a/
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.
:
Bearbeitet durch User
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.
Thomas E. schrieb: > Du tust ja gerade so, als könntest du das beurteilen Das ist garnicht nötig, du outest dich mit solchen Posts ja selber. Georg
Das scheint mir jetzt der richtige Zeitpunkt zu sein, um C++ ins Spiel zu bringen ;-)
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.
Hallo wir haben ja nicht 1969. du bist auf den Holzweg, wen du Nichts machen möchtest da fange erst gar nicht damit an.
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 | MOVF ADC_roh+2,W |
3 | CALL Hexaus |
4 | MOVF ADC_roh+1,W |
5 | CALL Hexaus |
6 | MOVF ADC_roh,W |
7 | |
8 | ; Hexa-Ausgabe von W |
9 | Hexaus: MOVWF Hudl ; merken |
10 | SWAPF Hudl,W ; Hi-Nibble nach W |
11 | ANDLW 15 |
12 | ADDLW 246 ; ab 10 --> Carry |
13 | SKIP NC |
14 | ADDLW 7 |
15 | ADDLW 48-246+256 |
16 | CALL SayIt |
17 | MOVF Hudl,W ; Hi-Nibble nach W |
18 | ANDLW 15 |
19 | ADDLW 246 ; ab 10 --> Carry |
20 | SKIP NC |
21 | ADDLW 7 |
22 | ADDLW 48-246+256 |
23 | GOTO SayIt |
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.
> Sparen mit Returnadressen im Stack. Dies ist aber nicht PIC-spezifisch; damit spare ich auf einem AVR vor allem die 7 Takte für rcall & ret.
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.
:
Bearbeitet durch User
> 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.
S. Landolt schrieb: > Ganz sicher gibt es ein return, das steht am Ende des nicht gezeigten > SayIt. Ja.
1 | ADDLW 7 |
2 | ADDLW 48-246+256 |
3 | ; GOTO SayIt |
4 | SayIt: |
So wäre es besser und kürzer.
> 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.
:
Bearbeitet durch User
Max M. schrieb: > Mir ist gerade aufgefallen, dass der PIC10F220... Nimm doch wenigstens einen 10F32x.
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 PIC NICHT 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.
Also Assembler ist schon lustig :D 8% des Flash vom PIC10F200 sind mit diesem Programm belegt:
1 | #include <p10f200.inc> |
2 | |
3 | incrReg EQU 10h |
4 | cmpVal EQU 11h |
5 | cmpReg EQU 12h |
6 | |
7 | org 0x00 |
8 | call outputGPIOs |
9 | |
10 | main bsf GPIO,0 ;set GP0 to 'HIGH' |
11 | |
12 | movlw 00ah ;set '10' in register 11h |
13 | movwf cmpVal |
14 | |
15 | call delay ;wait 10 incrementations |
16 | bcf GPIO,0 ;set GPO to 'LOW' |
17 | goto main |
18 | |
19 | outputGPIOs: |
20 | movlw 00h |
21 | tris 6 ;set all pins as output [@TRISIO] |
22 | retlw 0 |
23 | |
24 | delay: |
25 | movfw cmpVal ;copy content from 11h to 12h |
26 | movwf cmpReg |
27 | movfw incrReg |
28 | subwf cmpReg ;subtract counter value |
29 | btfsc STATUS,2 ;check if compare and increment value are equal |
30 | goto endDelay |
31 | incf incrReg |
32 | goto delay |
33 | endDelay |
34 | retlw 0 |
35 | |
36 | END |
Schade, dass man 2 Register nicht direkt vergleichen kann sondern diese Umwege gehen muss :( Edit: Ich hab mal versucht, das ganze in C nachzumachen:
1 | #include <xc.h> |
2 | #define _XTAL_FREQ 4000000
|
3 | void main(void) { |
4 | TRISGPIO = 0x00; |
5 | while(1){ |
6 | GPIO |= (1<<0); |
7 | __delay_ms(1); |
8 | GPIO &=~(1<<0); |
9 | }
|
10 | }
|
Ich weiß nun nicht, inwiefern die 2 Programme vergleichbar sind, allerdings belegt das C-Programm 31% des RAMs und 7% des Flashes.
:
Bearbeitet durch User
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 | MOVF Variable1,W |
2 | XORWF Variable2,W ; oder wer mag SUBWF... |
3 | SKIP Z |
4 | GOTO sonstwohin |
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.
Kann es sein, dass der PIC10F200 die Pins gar nicht so schalten kann, dass I2C direkt möglich ist (Open-Drain)?
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.
:
Bearbeitet durch User
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 |
3 | delay |
4 | addlw -1 |
5 | btfss STATUS,Z |
6 | goto delay |
7 | retlw 0 |
Max M. schrieb: > GPIO |= (1<<0); Bei deinen nächsten Versuchen in "C" probier doch mal
1 | GPIObits.GPIO0 = 1; |
Wahrscheinlich geht auch einfach
1 | GP1 = 1; |
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.
:
Bearbeitet durch User
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 |
3 | delay |
4 | movwf counter |
5 | delay_lp |
6 | decfsz counter,F |
7 | goto delay_lp |
8 | retlw 0 |
Ha, und es gibt doch eine Möglichkeit, keinen wertvollen RAM-Inhalt für den Delay-Loop zerstören zu müssen:
1 | Delay |
2 | xorwf 0x10,F ;Inhalt von W und Speicher (z.B. Adresse 0x10) |
3 | xorwf 0x10,W ;austauschen |
4 | xorwf 0x10,F |
5 | |
6 | DelayLoop |
7 | decfsz 0x10,F |
8 | goto DelayLoop |
9 | |
10 | movwf 0x10 ;original Inhalt restaurieren |
11 | retlw 0 |
:
Bearbeitet durch User
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
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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_FREQ 4000000 |
3 | > void main(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.
Geron und Mark, setzt doch bitte eure Diskussion irgendwo anders fort.
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.
:
Bearbeitet durch User
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.
chris schrieb: > Hitech C funktioniert recht gut darauf, wurde von Microchip aber > totgekauft und gibt es nicht mehr downzuladen... Heißt jetzt xc8.
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: > ;SCL is GP0 > ;SDA is GP1 > SCLHigh: -- snip --- > retlw 0 Ich würde sagen, der obige Code ließe sich auch einfach so schreiben:
1 | #define SCL 0 ;SCL is GP0 |
2 | #define SDA 1 ;SDA is GP1 |
3 | |
4 | SCLHigh |
5 | movf GPIO,W ;read current level (SDA) -> W |
6 | iorlw 1<<SCL ;set SCL-bit |
7 | andlw 1<<SCL | 1<<SDA ;keep other bits 0 (GPIO pins = output) |
8 | tris GPIO ;-> emulate open drain output |
9 | retlw 0 |
Und wegen evtl. Clock Stretching würde ich die Routine erst verlassen, wenn SCL auch tatsächlich auf high gegangen ist:
1 | .... |
2 | tris GPIO ;-> emulate open drain output |
3 | btfss GPIO,SCL |
4 | goto $-1 |
5 | retlw 0 |
:
Bearbeitet durch User
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:
1 | Invalid RAM location specified. |
Schon mal in's Datenblatt geschaut? Da steht "unimplemented". Was das wohl bedeuten?
Danke, lesen sollte man können :( Trotzdem versteh ich nicht, wo denn nun der RAM ist (also die 16Byte)?
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 |
42 | decf tmp |
43 | btfss STATUS,0 ;check if not carry [doesn't work] |
44 | goto step ;if not, return to top |
45 | retlw 0 |
Hat da jemand eine Idee?
:
Bearbeitet durch User
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:
1 | movlw 8 ;initialize loop counter |
2 | movwf counter |
3 | loop |
4 | <(body of loop)> ;done 8 times... |
5 | decfsz counter,F |
6 | goto loop |
7 | ... |
:
Bearbeitet durch User
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
1 | extrBit |
2 | btfsc tmp3,0 |
3 | call SDAHigh |
4 | btfss tmp3,0 |
5 | call SDALow |
6 | clk |
zu ersetzen.
Obacht: I2C auf einem PIC ohne LAT Register ist etwas tricky. Siehe Datasheet 5.4.1 BIDIRECTIONAL I/O PORTS.
Normalerweise sieht der code so ähnlich aus: ; Send the byte currently in W, most significant bit first I2CSendByte MOVWF i2cdata MOVLW .8 I2CSendByteLoop MOVWF i2ccnt CALL DataHigh RLF i2cdata,F BTFSS STATUS,C CALL DataLow CALL ClockToggle DECFSZ i2ccnt,W GOTO I2CSendByteLoop RETLW 0
1 | ; Send the byte currently in W, most significant bit first |
2 | I2CSendByte |
3 | MOVWF i2cdata |
4 | MOVLW .8 |
5 | I2CSendByteLoop |
6 | MOVWF i2ccnt |
7 | CALL DataHigh |
8 | RLF i2cdata,F |
9 | BTFSS STATUS,C |
10 | CALL DataLow |
11 | CALL ClockToggle |
12 | DECFSZ i2ccnt,W |
13 | GOTO I2CSendByteLoop |
14 | RETLW 0 |
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) |
231 | goto extrBit ;if so, don't shift right anymore |
232 | bcf STATUS,0 ;clear carry bit to shift unsigned |
233 | rrf tmp3,1 ;shifted values are now in tmp3 |
234 | decf tmp2 |
235 | goto sru ;shift if not zero |
236 | extrBit |
237 | btfsc tmp3,0 |
238 | call SDAHigh ;if is '1', set SDA high |
239 | btfss tmp3,0 |
240 | call SDALow ;otherwise, set SDA low |
241 | |
242 | call SCLHigh ;create a clock cycle |
243 | |
244 | movlw 015h |
245 | movwf tmp2 |
246 | call delay |
247 | |
248 | call SCLLow |
249 | decf tmp |
250 | btfss tmp,7 ;check if not negative |
251 | goto step ;if so, return to top |
252 | retlw 0 |
253 | |
254 | ;send a command to SSD1306 Display |
255 | ;command is read from i2cCmd register |
256 | SendCommand: |
257 | movlw 078h |
258 | movwf i2cDat |
259 | call SendByte ;SSD1306 I2C Address |
260 | clrf i2cDat |
261 | call SendByte ;send 0x00 for a command |
262 | movfw i2cCmd |
263 | movwf i2cDat |
264 | call SendByte ;send command |
265 | retlw 0 |
266 | |
267 | END |
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.
Max M. schrieb: > Hat jemand einen Tipp, 10f32x nehmen? (8-Level Stack, LAT Register, Interrupt...)
:
Bearbeitet durch User
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 :)
:
Bearbeitet durch User
> 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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.