Tag an alle,
ich habe gerade etwas langeweile und durchstöber mal das Internet nach
allem möglichen zu µCs.
Dabei sind mir einige Fragen gekommen:
- Welche heute gängigen 8Bit µC-Familien gibt es?
Ich habe "nur" die 8051er, PICs und AVRs gefunden
- zu den PICs: Ist es möglich, externen Speicher anzuschließen?
- zu den AVRs: Ich programmiere gerne rekursiv und nutze dafür beim 8051
auch gerne Pointer, die incrementiert bzw. drecrementiert werden.
Das klappt auch ganz gut, da der 8051 ja mind. 9Pointer hat.
Wie macht man sowas beim AVR mit "nur" drei Pointern oder beim PIC?
Im Netz hab ich trotz langer Suche nichts weiter gefunden.
Danke schonmal für eure Hilfe, meine Langeweile zu tilgen,
MC
zur 2: Eigentlich kannst du an alles was frei programmierbar ist
externen speicher anschließen.
zu 3: Was meinst du mit Pointern? imho so viel wie der speicher fasst?
bei rekursiver programmierung ist doch ehr der Stack ausschlaggebend??
Genau weiß ichs net aber der fasst bestimmt 8 Adressen, ehr mehr.
EDIT2: Aus dem datenblatt:
During interrupts and subroutine calls, the return address Program
Counter (PC) is stored on the
Stack. The Stack is effectively allocated in the general data SRAM, and
consequently the Stack
size is only limited by the total SRAM size and the usage of the SRAM.
>man hat doch soviele Pointer wie ins RAM passen
Ich kenn mich mit den AVRs zwar nicht so gut aus, aber ich dachte, der
hat nur die drei Pointer X,Y,Z.
>bei rekursiver programmierung ist doch ehr der Stack ausschlaggebend??
Ich hab mich verschrieben. Ich meinte nicht rekursiv. Das wäre ja
selbstaufrufend. Ich programmiere gerne in Schleifen, wo z.B. mehrere
Speicehrstellen sortiert werden. Anstatt eine lange Abfrage aller
Speicherstellen zu machen, lade ich mir zwei Pointer und frage diese in
einer Schleife ab. Am Ende der Schleife wird jeder Pointer auf die
nächsten Stellen gesetzt und die Schleife läuft aufs neue durch...
MC wrote:
> - zu den AVRs: Ich programmiere gerne rekursiv und nutze dafür beim 8051> auch gerne Pointer, die incrementiert bzw. drecrementiert werden.
Von rekursive Algorithmen auf Mikrocontrollern mit einem entsprechend
kleinen Stack ist wohl eher abzuraten, vor allem wenn eine hohe
Rekursionstiefe zu erwarten ist. Dann lieber den geschlossenen Ansatz
waehlen.
@Michael G.:
Danke für deinen Rat, ich hatte mich lediglich verschrieben. Ich meinte
etwas anderes (siehe oben). Natürlich werde ich auf einem µC keine
rekursiven Programme laufen lassen.
Hi
>Ich programmiere gerne in Schleifen, wo z.B. mehrere>Speicehrstellen sortiert werden.
Und was machst du, wenn das in einem Programm überhaupt nicht notwendig
ist?
Seit wann ist es relevant, was der Programmierer gern programmiert?
MfG Spess
MC wrote:
> Ich kenn mich mit den AVRs zwar nicht so gut aus, aber ich dachte, der> hat nur die drei Pointer X,Y,Z.
Klar, manchmal kann man mehr Pointer brauchen als die 3. Insgesamt ist
das aber nicht schlecht. Man hat 32 Register, und einen Befehl, der 16
Bit zwischen den Register transportiert.
Welche sind denn die 9 Pointer vom 8051? Für 8bit Adressen kommen mir 2
in den Sinn (R0,R1), für 16bit Adressen regulär einer (2-3 in manchen
Derivaten). Auf 9 komme ich da eigentlich nur, wenn ich die R0+R1 aller
4 Registersätze zusammenaddiere, was sich IMHO nur für's Fälschen der
Statistik eignet.
MC wrote:
> Ich programmiere gerne in Schleifen, wo z.B. mehrere> Speicehrstellen sortiert werden. Anstatt eine lange Abfrage aller> Speicherstellen zu machen, lade ich mir zwei Pointer und frage diese in> einer Schleife ab.
Du brauchst also nur 2 Pointer gleichzeitig, d.h. von den dreien ist
sogar noch einer übrig.
Und mit MOVW kannst Du bequem ein anderes Registerpaar in die Pointer
laden.
Peter
Das war doch nur ein Beispiel. Wenn es nicht erforderlich ist, z.B. zig
Werte zu sortieren, dann mach ich das doch auch nicht.
>Seit wann ist es relevant, was der Programmierer gern programmiert?
Ich finde, dass ein Hobby-Programmierer sich nicht nach irgendwelchen
Richtlinien, Standards oder dergleichen zu richten hat. Er kann doch so
programmieren, wie er will, oder nicht? Und dementsprechend kann er sich
seine Plattform zum prgorammieren doch auch aussuchen/zurechtschustern.
Eine Familie, die nicht ganz so gängig aber doch einigermassen verfügbar
ist, und dir vielleicht gefallen könnte: Zilog Z8 Encore. Hat 256
Pointer für kurze und 128 Pointer für lange Adressen.
Bei deiner Vorliebe für Pointer würde ich um die PICs in ihrer 8 Bit
Ausprägung einen Bogen machen. Könnte ein Kulturschock werden ;-).
>Du brauchst also nur 2 Pointer gleichzeitig, d.h. von den dreien ist>sogar noch einer übrig.
In meinem Beispiel schon. Ich denke mal wieder zu viel. Ihr kennt
natürlich nicht meine Programme. Also, ein Beispiel:
Ich habe einen 8Kanal Dimmer mit Fading und Soft-PWM. Für das Fading
frage ich in einer Schleife über zwei Pointer den SOLL und den IST-Wert
ab und gleiche diese stückweise aneinander an. In der gleichen Schleife
frage ich ab, ob der momentane IST-Wert auf einem extra Stapelspeicher
für den Soft-PWM schon vorhanden ist. Das geschiet wieder über zwei
Pointer. Wenn dass alles fertig ist, sortiere ich die für den Soft-PWM
abgelegten Werte noch der Größe nach. Das mache ich deshalb, weil dann
der Soft-PWM sich den nächsten Auslösepunkt berechnen kann.
>Und mit MOVW kannst Du bequem ein anderes Registerpaar in die Pointer>laden.
Das würde bedeuten, wenn ich ausschließlich mit Pointern in R0 bis R31
arbeite, könnte ich 14 16Bit Pointer realiseren (X,Y,Z würden dann ja an
sich wegfallen, da dort ja immer andere Pointer reingeladen werden).
Externen Speicher kann man immer anschliessen, wenn die Pins reichen.
Wenn du damit allerdings meinst, externes RAM so anschliessen zu können,
dass er direkt als Datenspeicher adressiert werden kann: viele der PICs
haben schon ziemliche Mühe, auch nur den internen Speicher halbwegs
erträglich adressieren zu können.
>Zilog Z8 Encore
Danke für den Tip. Werd ich mir mal ansehen.
>Könnte ein Kulturschock werden ;-)
Hab mir die mal grob in nem tutorial zu Gemüte geführt. Ich glaub die
wären erst ab den dsPICs interessant. Aber das ist noch nicht mein
Anforderungsbereich.
Andreas Kaiser wrote:
> Welche sind denn die 9 Pointer vom 8051? Für 8bit Adressen kommen mir 2> in den Sinn (R0,R1), für 16bit Adressen regulär einer (2-3 in manchen> Derivaten). Auf 9 komme ich da eigentlich nur, wenn ich die R0+R1 aller> 4 Registersätze zusammenaddiere, was sich IMHO nur für's Fälschen der> Statistik eignet.
Nö, fälschen tut man da nichts.
Die 8051 haben oft nur 256 Byte internes SRAM, da reichen 8Bit-Pointer
aus. Z.B. habe ich mal dem I2C-Interrupt und dem UART-Interrupt eigene
Registerbänke zugewiesen und damit hatten sie ihre eigenen FIFO-Pointer
ohne Register umladen zu müssen. Ich hatte also 6 Datenpointer benutzt.
Die 8051 mit zusätzlichen XRAM haben 2..8 XRAM-Pointer, was aber nicht
so der Brüller ist, da sie alle als DPTR benutzt werden müssen. Man muß
also mit DPTR-Select dazwischen umschalten.
Nützlich sind beim 8051 auch die 2 Codepointer. In Interrupts ist der
Tabellenzugriff mit PC als Basisadresse schön codesparend.
Peter
Peter Dannegger wrote:
> aus. Z.B. habe ich mal dem I2C-Interrupt und dem UART-Interrupt eigene> Registerbänke zugewiesen und damit hatten sie ihre eigenen FIFO-Pointer> ohne Register umladen zu müssen. Ich hatte also 6 Datenpointer benutzt.
Ok, wenn man Interrupts mitrechnet, dann akzeptiere ich diese
Kalkulation. Das ist definitiv ein Schwachpunkt der bisherigen AVRs.
Allerdings hatte ich den Eindruck, dass der Fragesteller die alle im
Hauptprogramm verwenden will. Und da kommt mir diese Rechnung etwas
seltsam vor.
Umschaltbare DPTRs sind freilich nicht viel einfacher als hin- und
hertransportierte AVR Register.
>dass der Fragesteller die alle im>Hauptprogramm verwenden will
Nein, eben nicht. Da habe ich mich falsch ausgedrückt. Ich benutze im
Hauptprogramm momentan einen Pointer (könnten auch zwei o. Drei sein,
bin mir da im momment nicht ganz sicher). In der ISR des INT0 benutze
ich vier Pointer und in der ISR des Timer0 nochmal einen Pointer.
Die will ich nicht alle durch push und pop sichern, also wechsle ich
immer die Registerbänke.
Und weil mir mal langweilig war, wollte ich mal wissen, wie das anderswo
abläuft.
MC wrote:
>>dass der Fragesteller die alle im>>Hauptprogramm verwenden will> Nein, eben nicht. Da habe ich mich falsch ausgedrückt.
Drueck Dich mal richtig aus... ;)
MC wrote:
> Die will ich nicht alle durch push und pop sichern, also wechsle ich> immer die Registerbänke.
Dann wird dir Z8e liegen. Soviel Registerbänke à 16 Register wie RAM
vorhanden ist, und ein priorisierter Interrupt Controller.
Hab mir bei Zilog den Z8e mal angesehen. Das ist ja doch gar nicht so
schlecht, Herr Specht! Aber ich glaube, ich würde nur die "großen"
Z86x4... nehmen, da die auch externen Speicher adressieren können (auch
über die vieeelen internen Pointer;-).
Aber weiß jemand, wo ich die bekommen kann? Angelika hat nur die
kleineren Varianten.
rscomponents
Wusste garnicht, dass R überhaupt welche hat. Die paar die dort unter
Zilog als Z8 drinstehen sind die alten Z8 und OTP, d.h. kein Flash-ROM.
Ich glaub hier stimmt so einiges nicht. Nur weil der AVR 3 Indexregister
hat, heißt das nicht, dass man unter C nur 3 Variablen mit Pointern
anlegen kann. Pointer sind ganz normale Variablen, die im Falle des AVRs
16 Bit breit sind. Sie können genau so im RAM liegen, wie Integer oder
Floats. Die Indexregister sind nur wichtig, wenn man auf Arrays
zugreifen will. Und wenn du nur ein Array von A nach B kopieren willst,
reichen 2 Indexregister völlig aus.
Simon S. wrote:
> zur 2: Eigentlich kannst du an alles was frei programmierbar ist> externen speicher anschließen.
Das stimmt so nicht ganz. Prinzipiell kann man überall externen Speicher
anschließen. Aber bei Prozessoren ohne herausgeführtes Speicherinterface
muss man selbiges über normale I/O Pins realisieren.
Das hat 1. den Nachteil dass es oft langsamer ist, als würde es direkt
vom Prozessor adressiert werden und 2. kann der Speicher nicht in den
regulären (vorhandenen) Adressraum eingeblendet werden. Taugt also somit
nicht wirklich zur Programmierung unter C (ohne Krücken).
MC wrote:
>>Und mit MOVW kannst Du bequem ein anderes Registerpaar in die Pointer>>laden.> Das würde bedeuten, wenn ich ausschließlich mit Pointern in R0 bis R31> arbeite, könnte ich 14 16Bit Pointer realiseren (X,Y,Z würden dann ja an> sich wegfallen, da dort ja immer andere Pointer reingeladen werden).
Quark. Du kannst so viele Pointer im RAM halten, wie du möchtest. Nur in
dem Moment, wo du den Pointer dereferenzieren willst, MUSS(!) der
Pointer im X,Y,Z Register liegen, damit der Prozessor auch eben diese
Dereferenzierung durchgeführt werden kann. Ansonsten ist es völlig Wumpe
wo der Pointer liegt.
Ich kenn mich mit AVRs zwar nicht so aus, aber:
wie soll ich die denn da bitte reinbekommen? Das geht doch nur über den
Umweg der 32 Register, oder nicht? Und was mache ich mit meinem evtl.
schon vorhandenen Pointer, ohne den zu überschreiben? Den muss ich dann
auch wieder sichern,....
ja, es geht den "Umweg" über die Register, aber ist das etwa ein
Problem?
Wenn Du in C programmierst macht das der Compiler für dich, und wenn du
in Assembler programmierst und dann mit 32 Pointern gleichzeitig
arbeitest na denn Prost Mahlzeit, viel Spaß hätte ich damit nicht!
MC wrote:
> Ich kenn mich mit AVRs zwar nicht so aus, aber:> wie soll ich die denn da bitte reinbekommen?
Wen willst du wo rein bekommen?
> Das geht doch nur über den> Umweg der 32 Register, oder nicht?
Die Indexregister sind Teil der 32 Register! Jeweils zwei der 32
Register ergibt das X, Y oder Z Register.
> Und was mache ich mit meinem evtl.> schon vorhandenen Pointer, ohne den zu überschreiben? Den muss ich dann> auch wieder sichern,....
Du siehst das irgendwie falsch. Die Pointer sind dauerhaft im RAM und
werden in dem Moment, wo man sie dereferenziert (*, [] in C) in ein X, Y
oder Z Register geladen.
Ansonsten könntest du ja genau so gut sagen "Was ist wenn ich 40 Stück 8
Bit Integer habe. Die können ja gar nicht auf einmal in den Registern
bleiben. Die müssen ja immer gesichert werden, wenn ein anderer der 40
Werte in ein Register hereingeladen werden soll."
Walter wrote:
> ja, es geht den "Umweg" über die Register, aber ist das etwa ein> Problem?> Wenn Du in C programmierst macht das der Compiler für dich, und wenn du> in Assembler programmierst und dann mit 32 Pointern gleichzeitig> arbeitest na denn Prost Mahlzeit, viel Spaß hätte ich damit nicht!
Erzähl doch kein Unfug. Was für einen Umweg über Register? X, Y und Z
sind Register!
Ich möchte mal einigen Vermutungen entgegentreten:
> viele der PICs haben schon ziemliche Mühe, auch nur den internen> Speicher halbwegs erträglich adressieren zu können.
Aus welchem Jahr stammt Dein Wissen?? - Es ist bereits 2008, die Welt
hat sich in den letzten Jahrzehnten verändert! (Schau Dir z.B. ruhig mal
die PIC18Fxxxx an.)
> 2. kann der Speicher nicht in den regulären (vorhandenen) Adressraum> eingeblendet werden.
Genau das geht mit vielen PICs.
rrrrr wrote:
>> viele der PICs haben schon ziemliche Mühe, auch nur den internen>> Speicher halbwegs erträglich adressieren zu können.>> (Schau Dir z.B. ruhig mal die PIC18Fxxxx an.)
Hab ich, ist mir bekannt. Drum steht da ja auch "viele der PICs".
Sonderlich begeistert bin ich von der Methode allerdings nicht, mit der
Microchip das bei den PIC18 gedeichselt hat.
Bitte nicht schlagen, ich versuche nur, eure Aussagen zusammenzufassen:
- der AVR besitzt drei 16Bit Pointer X,Y,Z innerhalb der 32 Register
- man kann mit movw in die jeweiligen Registerpaare andere der 32
Register
laden
- man kann die Pointer im RAM ablegen und dann immer in X,Y,Z kopieren
Habe ich das jetzt richig verstanden?
MC wrote:
> Bitte nicht schlagen, ich versuche nur, eure Aussagen zusammenzufassen:> - der AVR besitzt drei 16Bit Pointer X,Y,Z innerhalb der 32 Register> - man kann mit movw in die jeweiligen Registerpaare andere der 32> Register> laden> - man kann die Pointer im RAM ablegen und dann immer in X,Y,Z kopieren>> Habe ich das jetzt richig verstanden?
Um dich zu beruhigen. Sobald dein C-Programm etwas größer wird und du
irgendwo (egal wo eigentlich) einen Pointer benutzt (also
dereferenzierst), wird der Compiler genau das machen. Er wird den
Pointer aus dem RAM holen und in in einem der Indexregister
dereferenzieren. Das ist durchaus üblich und gängig.
Nur wenn der Compiler feststellt, dass eine lokale Variable eh ein
Pointer ist und sonst nix anderes da ist, wird er die lokale Variable
möglicherweise direkt in einem Indexregister "anlegen".
Bei globalen Pointern geht das nur, wenn das Indexregister sonst nicht
gebraucht wird.
Beide Fälle sind eher selten (Fall 1 ist vielleicht realistisch).
Aber der Compiler wird da schon relativ schnell ans kopieren kommen.
Andreas Kaiser wrote:
> Simon K. wrote:>>> Sobald dein C-Programm etwas größer wird>> Wer solche Fragen stellt, der programmiert nicht in C sondern in> Assembler.
Ahso ;) Durch das Wörtchen "Pointer" bin ich zuerst auf C gekommen.
Ich bins nochmal.
Ich habe mir die eZ8 sowie die Z8Encore mal angesehen. Vorallem die
Z8Encore Familie ist ja doch gar nicht so schlecht! Aber sehe ich das
richtig, dass die Z8Encore Controller keinen ext. Datenspeicher
adressieren können?