Hallo erstmal.
Ich bin gerade dabei von der gut vorgekauten Arduino-IDE auf Atmelstudio
umzusteigen.
Die ersten Hürden konnte ich noch gut überwinden und verstehen, doch nun
die Erste die ich zwar überwunden habe aber nicht verstehe.
Da ich viel mit Arduino gemacht habe, laufen meine ersten schritte auf
einem Arduino-uno (ATMega328).
Nun war nach den ersten timer und pwm versuchen der Wunsch geweckt auch
ein LED blinken ohne delay zu bauen. Hier erstmal der Code der sogar
funktioniert.
1
#define F_CPU 16000L
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
5
uint64_tmillis=0;
6
uint64_tlast;
7
uint64_tmicros;
8
uint64_tpos;
9
intmain(void)
10
{
11
DDRB=0b00100000;
12
PORTB=0b00010000;
13
DDRD=255;
14
PORTD=0;
15
TCCR0A=0b10000011;
16
TCCR0B=(1<<CS00);
17
TIMSK0=0b00000001;
18
sei();
19
while(1)
20
{
21
OCR0A=0;
22
if(micros-last>1000000){
23
last=micros;
24
PORTB^=(1<<5);
25
}
26
}
27
}
28
ISR(TIMER0_OVF_vect){
29
micros+=16;
30
}
Nun das Problem.
Wenn ich die Zeile mit "OCR0A = 0;" aus der while schleife schiebe oder
lösche, blinkt PB5 nicht mehr. und trotz der 0 leuchtet die LED am Pin
(PD6) an dem die Waveform ausgegeben wird ganz schwach.
Habe ich hier was falsch verstanden oder ist das die komplett falsche
Herangehensweise?
Ok danke klappt. und auch verstanden. :)
Das muss ich dann bei jeder anderen Variablen machen die ich außerhalb
der main verändere und in der main verarbeiten möchte?
und gibt es in meinem Code groben Optimierungsbedarf?
und woher kommt das "Glimmen" der LED an PD6?
#define F_CPU 16000L scheint mir verkehrt zu sein, der Prozessor läuft
wohl eher mit 16MHz.
Bei den Registerzuweisungen sollte man sich schon eine einheitliche
Schreibweise angewöhnen, das bringt Übersichtlichkeit.
Die uint64_t Variablen könnte man sich sparen in dem man den Prescaler
erhöht z.B. 64, und den CTC statt dem PWM Modus wählt.
Da die Led im Code selber geschaltet wird bietet sich CTC sowieso an.
PD6 ist der OC0A Pin der PWM...
Danke Für die Schreibweisentipps.
die LED will ich später noch in verschiedenen Dimmstufen leuchten
lassen.
deswegen fast PWM.
mich wundert nur das wenn ich "OC0A = 0" mache die LED trotzdem etwas am
"glimmen" ist.
Sören G. schrieb:> while (1)> {> OCR0A = 0;> if(micros - last > 1000000){> last = micros;> PORTB ^= (1<<5);> }> }
Hallo, frage Dich bitte mit welcher Zahl die Differez (micros - last)
verglichen wird.
Dass
1
PB5=5
ist, weißt Du, es liest sich besser, dies umzuschreiben.
1
DDRB=0b00100000;PORTB=0b00010000;
Neu
1
DDRB=(1<<PB5);PORTB=(1<<PB5);
Ich nutze eine noch etwas andere Funktionalität, die Defines.
1
#define LED (1<<PB5)
Dadurch wird der Ausdruck noch leserlicher:
1
DDRB=LED;PORTB=LED;
Dass kann man weiter Abstrahieren, so dass dies möglich wird:
Sören G. schrieb:> mich wundert nur das wenn ich "OC0A = 0" mache die LED trotzdem etwas am> "glimmen" ist.
Ich hoffe das ich mich nun nicht hineinsetze, aber ich meine des der Pin
im nicht invertierten Modus für sehr kurze Zeit eingeschaltet wird.
Abhilfe sollte da der invertierte Modus schaffen, welcher (glaube dann
allerdings keine maximale "helligkeit" mehr zuläßt)
Set OC0A on Compare Match, clear OC0A at BOTTOM,
(inverting mode). Für Fast PWM Modus.
Die alte Initialisierung nur nochmal falls die obere unverständlich
seien sollte
1
TCCR0A=0b10000011;
wäre das selbe wie
1
TCCR0A=(1<<COM0A1)|(1<<WGM01)|(1<<WGM00);
Clear OC0A on Compare Match, set OC0A at BOTTOM,
(non-inverting mode) Für Fast PWM Modus.
So Pi mal Daumen, ist ungetestet. Es gibt bestimmt eine deutlich
bessere, fachlich versiertere, Erklärung.
Sören G. schrieb:> if(micros - last > 1000000) {> last = micros;> ...> ...> }
Hallo,
nur so nebenbei. Den Codeausschnitt hättest du in der Arduino IDE auch
mit micros() oder millis() erledigen können. Das nur zur reinen Info.
> Da ich viel mit Arduino gemacht habe, laufen meine ersten schritte auf> einem Arduino-uno (ATMega328).
Korrektur: Atmega328P - "P" nicht das du das falsche Datenblatt
verwendest
Weitermachen. :-)
Karl M. schrieb:> Ich nutze eine noch etwas andere Funktionalität, die Defines.>
1
#define LED (1<<PB5)
>> Dadurch wird der Ausdruck noch leserlicher:>
1
DDRB=LED;PORTB=LED;
Bis hier hin komm ich noch mit.
> Dass kann man weiter Abstrahieren, so dass dies möglich wird:>
1
LED_DDR=1;LED=1;
Da wirds für mich interessant, weil ich grad keine Ahnung hab wie ich
das mit nem einfachen #define machen soll.
Veit D. schrieb:>nur so nebenbei. Den Codeausschnitt hättest du in der Arduino IDE auch>mit micros() oder millis() erledigen können. Das nur zur reinen Info.
Jap weiss ich, aber da ich die Arduinoumgebung gerade verlassen habe,
steht mir diese nützliche Funktion leider nicht zur Verfügung und muss
sie selbst bauen.
@ Holger
ich werds mal probieren.
Bei dem entlehnten Verb "coden" dreht sich mir immer der Magen um, weil
ich da an was anderes denke. Steht zwar auch so im Wictionary, doch
[ck]odieren oder coding erscheint mit irgendwie natürlicher, wobei koten
(s.o.) natürlich auch ein natürlicher Vorgang ist ;-)
Wilhelm M. schrieb:> Bei dem entlehnten Verb "coden" dreht sich mir immer der Magen um, weil> ich da an was anderes denke. Steht zwar auch so im Wictionary, doch> [ck]odieren oder coding erscheint mit irgendwie natürlicher, wobei koten> (s.o.) natürlich auch ein natürlicher Vorgang ist ;-)
Mit den Jahren und dank vieler junge Kollegen (jeder Bauart), hab ich
eine gewisse Milde gegenüber Neuzeitsprech entwickelt. Sprachliche
Korrektheit kann man ja immer noch in den Bereichen verlangen, in denen
es wirklich wichtig ist. Z.B. weil Compiler nicht so rücksichtsvoll
sind.
Wir waren schließlich auch nicht besser ;-)
Gut das wir alle einen Verstand haben und Wörter auch im Kontext
verstehen...
Sören G. schrieb:> Da wirds für mich interessant, weil ich grad keine Ahnung hab wie ich> das mit nem einfachen #define machen soll.
Ok da sind wir stehen geblieben....
Sören G. schrieb:>> Da wirds für mich interessant, weil ich grad keine Ahnung hab wie ich>> das mit nem einfachen #define machen soll.
Du bemerkst jetzt dass das Arduino Framework gar nicht so blöd ist. Denn
#define ist dafür ein klarer Rückschritt. In C scheinbar nicht anders
möglich. Ich empfehle dir bleibe bei C++, baue dir Klassen usw., dann
kannste das ähnlich wie mit dem Arduino Framework machen.
Wenn du unbedingt #define möchtest lese dir das AVR Tutorial hier im
Forum durch. Als Einstieg ein Bsp. ...
Was du vielleicht auch machen kannst ist folgendes. Atmel Studio mit
https://www.visualmicro.com/ Plugin. Du stehst damit nicht völlig auf
verlorenen Posten. Kannst weiterhin das Arduino Framework nutzen und
baust Stück für Stück eigenen Klassen bis du das Arduino Framework
vielleicht nicht mehr benötigst, falls das dein Ziel sein sollte. Man
kann aber auch weiterhin das Arduino Framework nutzen und nur das selbst
neu schreiben was einem vielleicht stört. Das bleibt jeden selbst
überlassen.