Hallo,
hab beim Setzen der Fusebits einen Fehler gemacht, ich denke dass ich
das ganze auf externen Takt gelegt hatte -> hab aber einen Quarz dran.
Hab hier einen ähnlichen Beitrag gesehen. Da stand dass man einen Takt
mit einem anderen uC erzeugen kann (in meinem Fall: Mega328). Dazu
toggle ich einfach einen Ausgang. Jedoch funktioniert da ganze i.wie
nicht.
nimm als externen Takt einen Fertigen OSC. (kannste aus
alter Grafikkarte,Mainboard, etc. ausschlachten)
i hab einen 8 Mhz dafuer, das mit dem µC ist verm.
zu langsam da der Takt meines wissens 4x hoeher
sein muss als der Clk des Programmers
(ps. unn am richtigen Pin anschliessen)
vlG
Charly
Max Neu schrieb:> hab beim Setzen der Fusebits einen Fehler gemacht, ich denke dass ich> das ganze auf externen Takt gelegt hatte -> hab aber einen Quarz dran.
[...]
> avrdude.exe: set SCK frequency to 8000 Hz> avrdude.exe: warning: cannot set sck period. please check for usbasp> firmware update.
Das dürfte das Problem sein. Dein extern eingespeister Takt ist
vermutlich relativ gering, ganz sicher, wenn da wirklich ein
Arduino-Program per Bitbanging PB0 wackeln läßt. Irgendwie habe ich da
was mit unglaublichen 100 Takten für jede Portänderung in Erinnerung,
d.h.: dein externer Takt würde nur ca. ein 1/200 des
Arduino-Systemtaktes betragen, also nur etwa 80kHz.
Der ISP-Takt muß noch unter 1/4 dieses Taktes liegen, das hast du wohl
auch erkannt, denn du sagst ja avrdude, daß du 8kHz haben willst, was
ungefähr 1/10 und damit ausreichend gering wäre.
Das Problem ist bloß, daß dein Programmer das offensichtlich nicht
beherrscht, wie das Log von avrdude ja eindeutig aussagt.
Am einfachsten löst du das Problem, indem du auf dem Arduino ein
richtiges Programm laufen läßt und nicht diesen Arduino-Gammel. Ein
richtiges Programm kann einen Pin sehr viel schneller wackeln lassen,
bis zu 1/2 des Systemtaktes sind möglich (mittels Timer im CTC- oder
FastPWM-Mode), ohne Hardwarehilfe, nur mittels Code ist immerhin je nach
konkretem AVR noch 1/3 oder wenigstens 1/4 des Systemtaktes möglich.
an c-hater:
weiß nicht was du genau meinst, deswegen hier das kleine Programm
1
DDRB=0b11111111;
2
3
while(1){
4
PORTB=0b00000000;
5
PORTB=0b11111111;
6
};//END WHILE
das Ergebnis siehe Bild 1. Außer der angezeigten Frequenz ist da noch
1,143MHz die sich abwechseln, ka wieso (also 1MHz, 1,143MHz, 1MHz, ...)
Hatte AVRDUDE auf 93,75kHz eingestellt, was aber nicht geholfen hatte.
Als Test: mit dem Atmega644 läuft alles.
an Charly:
hab sowas leider nicht da. Werde ich mir aber zulegen, ist eine gute
Idee.
an gvs:
das muss ich mir mal in alle Ruhe durchlesen.
Viele Dank
Beste Grüße
Max
"warning: cannot set sck period. please check for usbasp firmware
update."
Erst neuere Versionen von usbasp können slow-sck...
FW-Update des usbasp....
Max Neu schrieb:> weiß nicht was du genau meinst, deswegen hier das kleine Programm>>
1
DDRB=0b11111111;
2
>
3
>while(1){
4
>PORTB=0b00000000;
5
>PORTB=0b11111111;
6
>};//END WHILE
Das ist eigentlich nicht, was ich meinte. Das ist immerhin schon fast
sowas wie ein richtiges Programm. Kein Arduino-Gammel, nur noch
C-Gammel. An nicht hinreichender Frequenz kann es hier nicht mehr
liegen.
Aber dein Oszillogramm sagt es ja schon: Tastverhältnis lausig,
Frequenzkonstanz lausig. Frequenz zu niedrig (allerdings hoch genug für
die Anwendung).
C ist Dreck, denn das ist mindestens für das lausige Tastverhältnis
verantwortlich. Korrigieren kannst du es nur durch den Einsatz von
Assembler. (NOPs zwischen den beiden Schreibzugriffen auf die Ports).
Das müßte man de facto direkt in Assembler natürlich genauso mit NOPs
erledigen, aber da sieht man schon am Code selber, daß das nötig sein
wird, das ist da der Vorteil.
Möglicherweise wäre aber noch eine andere Variante drin. Neuere AVR
können den Pin alleine toggeln (Ausgabe einer 1 für das entsprechende
Bit auf das PIN-Register). Damit wärest du erstmal alle Sorgen bezüglich
des Tastverhältnisses los. Ich weiß bloß nicht, ob der in deinem Arduino
verbaute AVR das kann. Genannt hattest du ihn bisher nicht, oder hab'
ich das überlesen?
Die zu geringe Frequenz hingegen liegt nicht direkt an C, sondern daran,
daß du damit nicht umgehen kannst. Hier ist offensichtlich die
Optimierung des Compilers nicht eingeschaltet, deswegen ist der Scheiß
so langsam. Denn so einen primitiven Code wie diese Minischleife kann
sogar C optimal umsetzen. Wenn man es denn zuläßt...
Das größte Problem dürfte allerdings die Frequenzkonstanz sein. Und der
Mangel an selbiger liegt definitiv nicht an C. Möge der Compiler auch
noch so beschissenen Code generieren, wird dieser doch immer die gleiche
Laufzeit erfordern. Wenn wie hier imemr mal wieder was anderes
rauskommt, sind da noch irgendwelche Interrupts im Spiel.
Also: Entweder alles interrupterzeugende Zeug aus der Arduino-Anwendung
entfernen oder die Takterzeugung an einen Timer delegieren, der sich
nicht von MCU-Interrupts in seiner Tätigkeit stören läßt.
hallo,
hab nun einen externen Takt mit 20kHz angeschlossen, leider auch hier
ohne erfolg. Usbasp wurde auch auf den neusten Stand gebracht.
Die Ausgabe ist:
Ich hab's nun endlich.
Die Lösung:
1. USBASP updaten!!!
2. Atmega328p mit dem Programm: (ohne Dalays gings bei mir nicht)
1
DDRB=0b11111111;
2
while(1){
3
PORTB=0b11111111;
4
_delay_us(1);
5
PORTB=0b00000000;
6
_delay_us(1);
7
}
Dadurch entsteht eine Frequenz am PortB von 363,6kHz (Bild "CLOCK_PB")
3. Richtig beschalten (Masseverbindung nicht vergessen)
4. AvrDude Frequenz bremsen mit B100 (Benutztes Programm siehe
überschrift und Bild "Einstellung_1")
5. Auf Quarz umstellen und fertig!
Vielen Dank für die Hilfen,
Danke
Max
holger schrieb:> @c-hater>> Ist dir dein geistiger Dünnschiss den du da dauernd> absonderst nicht schon selber peinlich?
Öhm, nein. Ich halte es nämlich nicht für solchen. Du scheinbar auch
nicht, sonst hättest du dich vielleicht bemüht, irgendwelche der von mir
gemachten Aussagen mit FAKTEN zu entkräften.
Im übrigen ist ja inzwischen vom TO die Lösung geposted wurden. Auch
wenn der wahrscheinlich nicht wirklich kapiert hat, warum das die Lösung
war, bestätigt sie doch JEDE meiner Aussagen. :)
Er hat nämlich durch seine Delays dafür gesorgt, daß die erzeugte
Taktfrequenz ein akzeptables Tastverhältnis und einen akzeptablen Jitter
bekommen hat. Auf beides als wahrscheinliches Problem hatte ich mehr als
ausdrücklich hingewiesen.
Weil es es aber mit den beschränkten Mitteln dieses unsäglichen
C-Gammels gemacht hat, mußte er damit leben, daß die erzeugte Frequenz
dadurch nochmals erheblich weiter gesackt ist.
Was ihn dann aber immerhin doch endlich dazu bewegt hat, den ebenfalls
von mir als Schlüssel zum Problem reposteten Auszug aus dem avrdude-Log
ernst zu nehmen.
Also: wo siehst du da den Dünnschiß, wenn die böse Realität alle meine
Aussagen so vorteilhaft bestätigt?
Dein Problem ist einfach nur, daß du C-only-Schwachmat bist. Die leiden
oft an solchen Verzerrungen der Wahrnehmung der Realität. Ich hingegen
bin Allrounder, kann u.a. auch C und weiß deshalb sehr genau, wo die
Schwächen dieser Sprache sind, was es mir natürlich stark erleichtert,
bei jeder passenden Gelegenheit darauf herumzuhacken. Und ich geniesse
das wirklich. Das ist meine ganz persönliche Rache dafür, daß ich viel
zu oft dazu gezwungen werde, in dieser Scheißsprache zu programmieren.
Und dieser Druck resultiert nunmal zu einem großen Teil daher, daß es
einfach viel zu viele dieser C-only-Schwachmaten gibt. Mit meinen
militanten Beiträgen will ich ein kleines bissel dafür sorgen, daß es
vielleicht wenigstens nicht noch schlimmer wird.
Jaja, ich bin nur ein einzelner kleiner Mann, deshalb muß ich mich mit
kleinen Zielen begnügen...
Max Neu schrieb:> DDRB=0b11111111;>> while(1){> PORTB=0b00000000;> PORTB=0b11111111;> };//END WHILE
Hallo Max,
das verschobene Tastverhältnis deines Selbstbautakts war ja wohl das
Problem. Deine spätere Lösung hat das Problem immer noch, nur
abgeschwächt durch die Verlangsamung.
Wie man am Logikanalyser im ersten Versuch schön sehen kann, dauert
PORTB=0b00000000 genau 0.125μs, also genau einen CPU-Takt bei 8MHz (dein
Selbstbauarduino läuft ja mit 8Mhz?). Der folgende Befehl
PORTB=0b11111111 dauert natürlich ebenfalls genau einen CPU-Takt, also
0.125μs. Wo bleiben dann die restlichen 6 Takte a 0.750μs? Anscheinend
werden die durch die Sprungbefehle der while()-Schleife verbraten!
Wenn du ein sauberes Rechteck produzieren möchtest, dann heisst es
tatsächlich, wie @c-hater immer so schön ausführt,
Maschineninstruktionen unter die Lupe nehmen und CPU-Zyklen abzählen. Du
kannst dazu mit objdump die von der Arduino-IDE erzeugte .elf-Datei
disassemblieren.
Max Neu schrieb:> Außer der angezeigten Frequenz ist da noch> 1,143MHz die sich abwechseln, ka wieso (also 1MHz, 1,143MHz, 1MHz, ...)
Einer der Gründe für solchen Jitter könnte die Arduino-Bibliothek sein,
die einen Interrupt auf Timer0 programmiert um als Uhr für delays zu
dienen. Für ein ganz sauberes 50%/50% Rechteck müsstest du vorher mit
cli() oder noInterrupts() (ist genau dasselbe) alle Interrupts
abschalten.
Eine ganz andere Möglichkeit, die ich manchmal nutze, ist die CKOUT-Fuse
auf dem Hilfs-AVR zu benutzen. Der dadurch ausgegebene Takt ist recht
schnell und gut für solche Fälle geeignet.
HTH.
LG, Sebastian