ATtiny2313 PWM/ Timer ausprogrammieren
Ich beschäftige mich erst seit kurzem mit dem 2313 und verstehe immer noch nicht ganz welche Register man wie setzten muss um einen Timer zu intialisieren, diesem einen PWM-Port zuzuweisen etc. Zwar hab ich mir schon viele Seiten dazu durchgelesen, bekomme aber immer noch keine Ordnung in das TCC/TNC/OCR-Gewirr.
Die grundsätzlichen Zusammenhänge (also was CTC, den Prescaler und so angehen) hab ich schon verstanden, es fehlen mir nur gute/einfache Beispielprogramme anhand derer man einmal für jedes Timer/PWM-Feature einmal sieht wies angewendet wird.
Mit dem was ich bisher verstanden hab, habe ich jetzt mal versucht soein Konstrukt, was eigentlich alles die Hardware des Chips erledigen kann, "per Hand" selber zu schreiben.
Mein Ziel ist es (vorerst) alles soweit zu verstehen und auf den Chip zu kriegen, dass vier angeschlossene LEDs nacheinander an/aus faden.
Mein src sieht folgendermaßen aus (erstmal nur mit einer LED). Das Problem ist, dass ich nur ein kurzes Blitzen der LED sehe, dann eine Sek. Pause, dann wieder ein Blitzen. Was stimmt da nicht?
Code:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
uint16_t table[256] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6,
6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11,
11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 31, 32, 33, 35, 36, 38, 40, 41, 43, 45,
47, 49, 52, 54, 56, 59, 61, 64, 67, 70, 73,
76, 79, 83, 87, 91, 95, 99, 103, 108, 112,
117, 123, 128, 134, 140, 146, 152, 159, 166,
173, 181, 189, 197, 206, 215, 225, 235, 245,
256, 267, 279, 292, 304, 318, 332, 347, 362,
378, 395, 412, 431, 450, 470, 490, 512, 535,
558, 583, 609, 636, 664, 693, 724, 756, 790,
825, 861, 899, 939, 981, 1024, 1069, 1117,
1166, 1218, 1272, 1328, 1387, 1448, 1512,
1579, 1649, 1722, 1798, 1878, 1961, 2048,
2139, 2233, 2332, 2435, 2543, 2656, 2773,
2896, 3025, 3158, 3298, 3444, 3597, 3756,
3922, 4096, 4277, 4467, 4664, 4871, 5087,
5312, 5547, 5793, 6049, 6317, 6596, 6889,
7194, 7512, 7845, 8192, 8555, 8933, 9329,
9742, 10173, 10624, 11094, 11585, 12098,
12634, 13193, 13777, 14387, 15024, 15689,
16384, 17109, 17867, 18658, 19484, 20346,
21247, 22188, 23170, 24196, 25267, 26386,
27554, 28774, 30048, 31378, 32768, 34218,
35733, 37315, 38967, 40693, 42494, 44376,
46340, 48392, 50534, 52772, 55108, 57548,
60096, 62757, 65535};
int main (void)
{
// Pin 1 von Port A (PA1) als Ausgang schalten
DDRA = (1 << PA1);
int count=0;
int arrayindex;
int OCRzahl=table[0];
int ledstatus=0;//0 aus, 1 an
while(1){
for(arrayindex=0;arrayindex<256;arrayindex++)//alle 256 helligkeitsschritte
{
for(count=0;count<65540;count++)//entspricht einem timerdurchlauf
{
if(count==0)//am anfang die led einschalten
{
ledstatus=1;
PORTA |= (1 << PA1); //led an
}
if(ledstatus==1 && count > OCRzahl)//bei erreichen der OCRzahl die
{ //led ausschalten
ledstatus=0;
PORTA &= ~(1 << PA1); //led aus
}
}
_delay_ms(12);//warten bis die led das nächste mal aufblitzen soll
OCRzahl=table[arrayindex];//zeit nach der die led das nächste mal aus geht
}
_delay_ms(500);
//runterfaden
for(arrayindex=256;arrayindex>0;arrayindex--)//alle 256 helligkeitsschritte
{
for(count=0;count<65540;count++)//entspricht einem timerdurchlauf
{
if(count==0)//am anfang die led einschalten
{
ledstatus=1;
PORTA |= (1 << PA1); //led an
}
if(ledstatus==1 && count > OCRzahl)//bei erreichen der OCRzahl die
{ //led ausschalten
ledstatus=0;
PORTA &= ~(1 << PA1); //led aus
}
}
_delay_ms(12);//warten bis die led das nächste mal aufblitzen soll
OCRzahl=table[arrayindex];//zeit nach der die led das nächste mal aus geht
}
_delay_ms(500);
PORTA |= (1 << PA1); //nur um zu sehen ob überhaupt
_delay_ms(500); //irgentwas "lebt", falls große fehler im code sind
PORTA &= ~(1 << PA1);
_delay_ms(500);
}
}
Das Array soll 256 CTC-artige Abbruchzahlen enthalten. Das PWM-hochgezähle übernimmt die 65k-Schleife. Also wird die LED angeschaltet, die for-Schleife zählt los und bei erreichen der CTC-Zahl wird sie ausgeschaltet. Das, so war es gedacht, sollte ein kurzes Aufblitzen der LED erzeugen. Dann wird 12ms gewartet und es folgt das nächste, etwas längere Aufblitzen.
Die Zahlen im Array hab ich von einer anderen Seite mit Beispielprogramm. Die Werte wurden über eine bestimmte Formel aufgerechnet und sollen das faden möglichst linear aussehen lassen (das menschliche Auge funktioniert irgentwie mehr logarithmisch oder so).
Eigentlich finde ich von der Idee her alles richtig^^
Bisher hatte ich nur mit ARM-µCs zu tun. Aber weiter als bis zu den Interrupts sind wir in der Schule noch nicht gekommen. Timer hatten wir auch schon, aber das war mehr soeine Busy-Waiting-Geschichte.