Ja das stimmt, ich hab einen wichtigen Abschnitt wirklich eben erst gelesen.
Also das "Update of OCRx at" gibt es, weil man den OCRx-Wert in manchen Fällen
double-buffered hat. Wenn man OCR1A als TOP-Wert in einem Modus benutzt und ihn im
laufenden Programm ändern will, weil man eine andere Frequenz braucht etc. und man ihn
kleiner machen will, aber der Zähler (TCNT) grade über der neuen TOP-Grenze ist, wäre die
Grenze nach dem Umsetzten weg und er würde bis FFFF zählen. Das double-buffered bedeutet,
dass es eine Kopie von der OCR1A gibt, die der Zähler als TOP benutzt und wenn man
OCR1A ändert, hat man TOP damit noch gar nicht verändert. Die Zahl in OCR1A wird erst beim
nächsten Erreichen von "Update of OCRx at" in die (wichtigere) Kopie kopiert.
(Und wenn man beim 16bit Timer ICR1 statt OCR1A benutzt und ihn ändert kann es aber doch
passieren, dass man dem Zähler für den aktuellen Durchlauf die Obergrenze wegnimmt und er
bis FFFF durchläuft, weil die ICR1 nicht double-buffered ist)
Dann werden TOV und der Compare Match Interrupt von OCR1A nur beide gleichzeitig im Mode 7
ausgelöst?
Ich hab mir mal die iotn2313.h angeguckt.
Hier gibt es einige gleichwertige Benennungen, was man vielleicht wissen sollte.
16bit Timer:
OCR1 == OCR1A für den 16bit Zugriff
OCR1L == OCR1AL für den 8bit Zugriff auf den niederwertigen Teil
OCR1H == OCR1AH für den 8bit Zugriff auf den höherwertigen Teil
Für den B-Ausgang gibts hingegen keine Schreibweise ohne das B
OCR1B für den 16bit Zugriff
OCR1BL für den 8bit Zugriff auf den niederwertigen Teil
OCR1BH für den 8bit Zugriff auf den höherwertigen Teil
Auf TCNT kann ebenfalls über einen 16bit oder zwei 8bit Zugriffe geschrieben werden
TCNT1 für den 16bit Zugriff
TCNT1L für den 8bit Zugriff auf den niederwertigen Teil
TCNT1H für den 8bit Zugriff auf den höherwertigen Teil
Ebenso gilt für das ICR
ICR1 für den 16bit Zugriff
ICR1L für den 8bit Zugriff auf den niederwertigen Teil
ICR1H für den 8bit Zugriff auf den höherwertigen Teil
TCCR1A/TCCR1B/TCCR1C 8bit
8bit Timer:
Keine Überraschungen. Es gibt nur die 8bit-Register..
OCR0A 8bit
OCR0B 8bit
TCNT0 8bit
TCCR0A/TCCR0B 8bit
Inzwischen hab ichs hinbekommen Timer0 zu starten und damit eine LED zum faden zu bringen, und zwar so:
Code:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int main (void)
{
/* Fast PWM an Timer0. Benutzt werden soll nur OCR0A. Die LED/der Port OC0A soll beim
Erreichen von OCR0A aktiviert weden und beim Overflow wieder aus gehen.
In der while(1)-Schleife wird immer 12ms gewartet und dann OCR0A um eins erhöht.
(Bzw. wenn grade angefadet werden soll, um eins verringert)
*/
TCCR0A = (1 << COM0A1) | (1 << COM0A0) | (1 << WGM00) | (1 << WGM01);
//Set on Compare Match, clear on Overflow Fast-PWM (Mode 3 Tab.40 S.75)
/* ist doch zu langsam
TCCR0B = (1 << CS02) | (1 << CS00);
//Prescaler auf CPU/1024 -> langsamer gehts nicht (Tab.41 S. 77)
*/
TCCR0B = (1 << CS01);
//Prescaler auf CPU/8 -> perfekt^^
OCR0A = 1; //Startwert, pendelt dann zwischen 0..255
DDRB = (1 << PB2); //pin PB2 auf Ausgang (das ist OC0A)
uint8_t direction=0; //0->OCR0A raufzählen 1-> OCR0A runterzählen
while(1){
_delay_ms(12);
if(direction==0){
OCR0A += 1;
if(OCR0A==254)
direction=1;
}else
if(direction==1){
OCR0A -= 1;
if(OCR0A==1)
direction=0;
}
}
}
Eigentlich gar nicht so schwer wenn man denn ein bisschen Durchblick hat. Als nächstes werd ich versuchen den Verlauf angenehmer zu Timen, dann muss ich Transistoren finden, die schon bei Versorgung mit Pinspannung (wenn der mit 2 AA Batterien betrieben wird) ohne Widerstand alles durchlassen. (Damit ich steuern welche LED das PWM-Signal bekommt) Und anschließend, wie das Ganze mit einem kleinen Motor funktioniert. Denn mein Plan ist es ein kleines Elektroauto zum Fahren und Leuchten zu bringen.
Wieso liest man überall, dass Phasen-Korrekte PWM am Besten für eine Motorsteuerung sein soll?
Im Prinzip macht doch eine Fast-PWM das Selbe, nur das diese wohl schneller umschalten kann (da man bei
der Phasen Korrekten ja nur eine Umschaltung pro Timerdurchlauf hat und bei der Fast PWM zwei).
Lesezeichen