Ich frage mich, ab welchem AVR sich lohnt, in C zu programmieren (Speichergröße, Stack usw.)
Das hängt immer davon ab wieviel Platz du noch übrig hast... ich würde es immer erst in C versuchen, wenns nicht passt versuchen den Code in C zu komprimieren und erst dann in Assembler programmieren Die C Compiler sind allerdings schon recht gut, also wirst du es in Assembler auch nicht viel kleiner bekommen. Da lohnt sich vielleicht ein größerer µC :P
Zumindest sollte der AVR internen Ram haben. Und dann kann man davon ausgehen, dass ein C-Programm durchaus doppelt so viel Programmspeicher verbraucht. Je nachdem.
@ChristophK: Auszuschließen für C, Bascom, etc. sind alle Controller ohne SRAM, da diesen der Speicher für Stapel und Variablen fehlt. Die 32 Register reichen meist auch für einfache Dinge nicht aus. Da sind z.B. AT90S1200, ATTiny 11, 12, 15, 28. Ab ATTiny 2313 wird es auch mit C interessant. Assembler empfiehlt sich ebenfalls unabhängig von der Controllergröße für zeitkritische Anwendungen, da dabei die Ausführungsgeschwindigkeit für jeden Befehl bekannt ist. Sind nur kleine Teile zeitkritisch, C und Assembler lassen sich mischen. ( s. WinAVR-Dokumentation ) Gruss Jadeclaw.
@Jadeclaw:
>Ab ATTiny 2313 wird es auch mit C interessant.
OK, das wollte ich fast wissen. Da bin ich mit ATTiny2313 also gerade so
an der Grenze.
ChristophK wrote: > @Jadeclaw: >>Ab ATTiny 2313 wird es auch mit C interessant. > > OK, das wollte ich fast wissen. Da bin ich mit ATTiny2313 also gerade so > an der Grenze. Der C-Freund meidet ASM sogut er kann. Er erklärt RAM-lose AVRs zu Schrott und empfiehlt überdimensionierte Controller. Der ASM-Freund meidet C und arbeitet gern auf kleineren überschaubaren AVRs. Der BASCOM-Freund meidet C, ASM, Dokumentationen und Datenblätter. Die Wahrheit wird irgendwo dazwischen liegen und ist für Jeden etwas anders. Mach's also so, wie Du (Du, Deine Person) am besten zurecht kommst. MfG, BlauBär
>Kann man denn bestimmte AVRs von vorn herein ausschließen? Kommt darauf an, welchen Compiler du benutzt. Der gcc unterstützt nur AVRs mit SRAM, d. h. einen AT90S1200 kannst du nicht verwenden. Von Imagecraft gibt es einen Compiler, der auch für AVRs ohne SRAM geeignet ist. Klar ist, dass du in diesem Fall aber keine großen Sachen machen kannst.
>Die C Compiler sind allerdings schon recht gut, also wirst du es in >Assembler auch nicht viel kleiner bekommen. [ ] Du hast schon mal in C programmiert. [ ] Du hast schon mal in ASM programmiert. [ ] Du hast mal den vom C-Compiler erzeugten Code angesehen.
>>Die C Compiler sind allerdings schon recht gut, also wirst du es in >>Assembler auch nicht viel kleiner bekommen. >[X] Du hast schon mal in C programmiert. >[X] Du hast schon mal in ASM programmiert. >[X] Du hast mal den vom C-Compiler erzeugten Code angesehen. Ich stimm dem oberen Zitat zu... Wenn man die Optimierung im AVR-GCC einschaltet, dann kommen da doch manchmal Sachen raus, die man selbst nicht bemerkt hätte. Gerade bei größeren Projekten mit vielen Variablen und so zeuch ist man mit einem Assembler-Projekt doch mal schnell überfordert beim Optimieren. Bei manchen Sachen muss man halt wissen, dass man eine Funktion besser _inline_ und/oder _static_ macht...
Der WINAVR benötigt internen RAM, also kann man alles ab dem ATtiny13 in C programmieren. Die Attiny12, 15 sollte man eh nicht mehr für Neuentwicklungen nehmen. Und wenns im ATtiny13 knapp wird, kann man ja auf ATtiny25/45/85 upgraden, der Preisunterschied ist für den Bastler unerheblich. Für größere Sachen ist die ATmega48/88/168 Serie geeignet. Der ATtiny2313 ist heikel, für den gibts keine direkte Upgrademöglichkeit (außer AT89LP4052). Peter
Wer in C Müll programmiert darf sich nciht wundern wenn da ein sehr großer Code mit viel Rambedarf rauskommt. Auch C Programmieren will gelernt sein , ein Buch lesen reicht da nciht. Ist das C Program gut, dann erzeugt der Compiler einen Code der effizienter und schneller ist, als alles was 99 % aller Assemblerfreaks so von sich geben.
Ralph wrote: > Auch C Programmieren will gelernt sein , ein Buch lesen reicht da nciht. Dem stimme ich voll zu. > Ist das C Program gut, dann erzeugt der Compiler einen Code der > effizienter und schneller ist, als alles was 99 % aller Assemblerfreaks > so von sich geben. Das stimmt. Ich glaube nur nicht, dass 99% aller C-Programmierer das können. Daher halte ich C (alleine) nicht für die Lösung aller AVR-Probleme. MfG, Blaubär, der auf C verzichtet.
bascom-looser wrote:
> C = Müll
Troll' hier nicht 'rum, das ist mein Job. Geh' ins Bascom-Forum, die
brauchen noch Leutz wie Dich.
MfG, BlauBär, der auch auf Bascom verzichtet.
Ralph wrote: > Ist das C Program gut, dann erzeugt der Compiler einen Code der > effizienter und schneller ist, als alles was 99 % aller Assemblerfreaks > so von sich geben. Kommt drauf an. Ich behaupt einfach mal, dass meine Inline Assembler Programme etwa 10-500% schneller sind als der Code, den AVR-gcc erzeugt. Das liegt ganz einfach daran, dass der Compiler z.B. nicht weiß wie groß eine Variable werden kann, und daher meist mit größeren Datentypen rechnet als eigentlich notwendig ist. Ein Compiler rechnet so wie es mathematisch korrekt ist. Allerdings ist dies oftmals nicht notwendig. Nimmt man Rundungsfehler usw. in kauf, ergeben sich oftmals neue Optimierungsmöglichkeiten. Außerdem nutzt der Compiler nicht alle Befehle (wie z.B. fmul) aus.
Benedikt was du schreibst macht deutlich das du NICHT weißt wie man seinen Compiler im Griff hat und wie man ein C Programm effektiv schreibt. Der Compiler verwendet den Datentyp den der Programmierer mit seiner Definition bestimmt, und keinen anderen. Nichts anderes machst du bei Assembler, nur DA machst du es. Ein sinnvolles CAST vor/in einer Berechnung hilft da wahre Wunder. Wer natürlich in C alles mit FLOAT berechnet, statt Integer zu benutzen bekommt eine trügerische Genauigkeit zu immensen Kosten ( Ram, Rom, Laufzeit). Als Beispiel: Multipliziere mit oder dividiere durch 1000 ==> hoher Bedarf an Ram, Rom, Laufzeit Nutze dazu 1024 ==> Ram, Rom, Laufzeit fast nichts Dazu gehört eine sinnvolle Scalierung der Werte.
> Der Compiler verwendet den Datentyp den der Programmierer mit seiner > Definition bestimmt, und keinen anderen. Nicht ganz. Wenn es ein Standard C Compiler ist und die beteiligten Datentypen kleiner als "int" sind, dann muss die Rechung formell als "int" durchgeführt werden. Vorschrift. Manchmal muss er das auch wirklich (z.B. bei i+1 < n), manchmal merkt er dass es einfacher geht und manchmal merkt er es auch nicht.
Ralph wrote: > Benedikt was du schreibst macht deutlich das du NICHT weißt wie man > seinen Compiler im Griff hat und wie man ein C Programm effektiv > schreibt. Wenn du meinst... Dann stell mal bitte deine optimale Lösung vor, um z.B. auf einem ATmega8 eine 16bit Zahl möglichst effizient und mit hinreichender Genauigkeit mit dem konstanten Faktor 1.234 zu multiplizieren. Das Ergebnis sollte wieder eine 16bit Zahl sein. Der Faktor ergibts sich halt so und dient dazu einen 12bit ADC Messwert anzupassen. Das ist ein wunderbares Beispiel in dem DU beweisen kannst, dass DU den Compiler im Griff hast. Ich bin schon gespannt wie du das löst. Ich benötige dazu <25 Takte...
Ralph wrote:
> Benedikt was du schreibst macht deutlich das du NICHT weißt...
Von Benedikt habe ich schon viel Source gesehen und der ist gut aus
meiner Sicht.
Ich denke nicht das Benedikt das so meinte wie's bei Ralf rüberkam.
Auch ich meine der Mensch, mit ausreichend Zeit, wird in ASM Code
schreiben können der mindestens 50% kleiner und 200% schneller ist als
der Code eines Compilers. Sollte man eine andere Annahme treffen so
behauptet diese Person in meinen Augen das sein geliebter C Compiler
intelligenter ist als er selber. Noch ist ein Compiler eine dumme
Maschine die der Mensch erdacht hat. Also alles worauf ein Compiler als
Optimierung kommt wird ein Mensch besser können. Und das ganz unabhängig
von der Komplexität des programmes, also auch ein Program mit 1 Million
C Source Zeilen kann ein Mensch in Assembler weitaus besser kodieren.
ABER! die liebe Zeit. Der Compiler als Maschine kann wie jede Maschine
seine Aufgabe viel schneller als ein Mensch erledigen. Und das ist der
springende Punkt, der Mensch hat Compiler erschaffen damit sie ihm Zeit
einsparen und das tun sie auch. Das heist aber eben nicht das der
Compiler besser wäre als ein erfahrener ASM Programmierer.
Speziell in Bezug auf den GCC kann ich aus Erfahrung mit zwei meiner
Bibliotheken sagen das man ohne großes ASM Können den erzeugten Code um
50% Speicher reduzieren und um 200% performanter machen kann.
Die Frage ist nur ob ein um 50 Cent teuerer Prozessor mit doppeltem Takt
und doppeltem Speicher die langwierige Arbeit in Assembler auf einem 50
Cent preiswerteren Chip rechtfertigt.
Gruß Hagen
@benedikt: Dann könntest du ja mal diesen Thread befruchten: Beitrag "16 bit Div durch 100 bei AVR Mega32" Ist eine Multiplikation mit 0.01 Aber bitte <25 Takte ;-)
Was ist für dich eine hinreichende Genauigkeit ?? Wenn du mit 1.234 multiplizierst bekommst du eine FLOAT Operation, Elend viel Resourcenbedarf ohne eine FPU. multipliziere das so : ( prinzip, je nachgenauigkeit reicht auch 512 , 256 128,...) 1. #define FAKTOR (U16)1.234 * 1024 2. X = (U16)((U32)Wert * Faktor)/1024) ==> Integeroperation Wenn du weißt das in der Multiplikation Wert * Faktor der Wert IMMER kleiner als 65535 bleibt, dann kannst du das (U32) durch (U16 )ersetzen und den Compiler dazu zwingen mit einer U16 zu rechnen. U16 = unsigned 16 Bit U32 = unsigned 32 Bit Ich kenne jetzt nicht die Assemblerefehle des AVR, kann dir also da keine Vergleichsrechnung anbieten. Ich kenne die Compiler auf denen ich unterwegs bin, nur ein AVR ist nicht dabei. Also spezifiche AVR sachen hab ich keine Info's zu. Aber von Prinzip sind die Compiler da alle identisch. Ich arbeite mit 8051 auf Keil µVision und TMS 470 mit Compiler von TI. Poste mal bitte den Code mit deinen <25 Takten, inklusive Kommentaren, würde mir das gerne mal ansehen. Und wenn es geht lass meinen Vorschlag mal übersetzen und sag mir wieviel Takte der AVR Compiler draus macht.
Benedikt K. wrote: > Dann stell mal bitte deine optimale Lösung vor, um z.B. auf einem > ATmega8 eine 16bit Zahl möglichst effizient und mit hinreichender > Genauigkeit mit dem konstanten Faktor 1.234 zu multiplizieren. Das > Ergebnis sollte wieder eine 16bit Zahl sein. Der Faktor ergibts sich > halt so und dient dazu einen 12bit ADC Messwert anzupassen. > > Das ist ein wunderbares Beispiel in dem DU beweisen kannst, dass DU den > Compiler im Griff hast. Ne, das ist dann nur ein Beispiel, wie gut Du die Aufgabe umstellen kannst, bevor Du sie in Code umsetzt. Mit C vs. Assembler hat das absolut nichts zu tun, es geschieht ja schon in Deinem Kopf, vor dem Code hinschreiben. Wenn man die direkte Umsetzung mit 1.234 als float Zahl nimmt, dann dauerts auch in Assembler lange. Zeig also einfach mal Deine Lösung in Assembler oder als Pseudosprache, damit man gleiche Ausgangsbedingungen hat. Die C Umsetzung wird vielleicht einige wenige Zyklen länger sein, aber nie 500%. Peter
Wieder mal ein schönes Beispiel wie ein Thread in C vs. ASM ausartet, pubertäres Gehabe. Ein guter Programmierer, zumindestens wenn er sich mit MC's beschäftigt, beherscht beides und weis, wann was angebracht ist. Die Diskussion über C dreht sich eher um Standardisierung. Es wird heutzutage in der Regel C verlangt, ist nunmal so. Die Fülle an Controllern und C Compilern trägt dem Rechnung. Der GCC mag ne Gurke sein, dennoch sollte man den Leuten die das Ding zum MC Compiler verbiegen, dankbar sein. >> Auch C Programmieren will gelernt sein , ein Buch lesen reicht da nicht. So ist es ! Das Gleiche gilt für Assembler. >> Der C-Freund meidet ASM sogut er kann. Er erklärt RAM-lose AVRs zu >> Schrott und empfiehlt überdimensionierte Controller. >> Der ASM-Freund meidet C und arbeitet gern auf kleineren überschaubaren >> AVRs. Und der Profi beherscht beides und kann unterscheiden was wann Sinn macht. In diesem Sinne, viel Spaß beim bla. bla.
Joe wrote: > Wieder mal ein schönes Beispiel wie ein Thread in C vs. ASM ausartet, > pubertäres Gehabe. Leider. :-( > Und der Profi beherscht beides und kann unterscheiden was wann Sinn > macht. Amen. Gruss Jadeclaw.
Es gibt 3 Lösungen, zwei in C, eine in Assembler: Die C Lösung: wert=ADC+ADC/4-ADC/64; Ganz ohne float, 32bit usw. Wenn man es nachrechnet, dann ergibt das in etwa (abgesehen von den Rundungsfehlern bei der Division) wert=ADC*1,234; Zeit: etwa 40 Takte, Speicherplatz: 28 Bytes Das funktioniert mit jeder noch so krummen Zahl: 1024->5,000mV ergibt einen Faktor von 4,8828125: wert=4*ADC+ADC-ADC/8+ADC/128; Die Lösung mit dem casten auf long benötigt 90 Bytes und viele Takte, da der Compiler das ganze als 32bit x 32bit->32bit rechnet. Und dies kann man meines Wissens nach durch casts nicht besser hinbekommt. Dadurch benötigt der Compiler etwas über 100 Takte. Assembler Lösung: clr null clr var32 clr var33 mul var10,var20 mov var31,r1 mul var10,var21 add var31,r0 adc var32,r1 mul var11,var20 add var31,r0 adc var32,r1 adc var33,null mul var11,var21 add var32,r0 adc var33,r1 mov r22, var31 mov r23, var32 mov r24, var33 clr r25 Im Prinzip eine 16bit x 16bit -> 32bit Multiplikation, bei der das niederwertigste Byte direkt weggelassen wird und die anderen Bytes nachrücken. Diese Funktion würde mit ADC und 1.234*256 als Parameter aufgerufen werden. Diese Lösung habe ich mir gebaut, um die 32bit Operationen zu vermeiden, die vor allem bei AVRs ohne Hardware Multiplizierer etwas über 500 Takte benötigen. Diese Routine ohne Multiplizierer benötigt etwa 170 Takte, das sind immerhin etwa 1/3 von der 32bit Version. Bei Controllern ohne Division ist die oberste Version eindeutig die schnellste. Allerdings muss der Faktor zur Compilezeit schon bekannt sein, und der Programmierer muss sich Gedanken machen und die einzelnen Faktoren ausrechnen.
Joe hat recht. Lassen wir die Diskussion über Vor und Nachteile von C oder Assembler an der Stelle sein. Kommen wir zurück zur Anfangsfrage. 1. Sieh nach welche AVR Version vom Compiler unterstützt wird. 2. Überlege welche Sprache du verwenden willst und such den dazu passenden µC aus
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.