PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Eigenen Timer in der RP6ControlLib.c ergänzen



WarChild
02.05.2008, 01:38
Hi,

ich wollte einen Timer erstellen, der schneller als die standard timer arbeitet.

Der Timer 1 ist schließlich noch frei, also habe ich mal einfach drauf losprogrammiert, um einen 5us-Timer zu erzeugen
Der Prescaler ist 1 und der Preloader ist 175 (255-80).
(1/16MHz)*80 = 5us

soweit zur Theorie, aber in der Praxis funzt es nicht.
Meine Erfahrung mit Timern ist gleich 0.


volatile uint16_t fast_timer;

ISR (TIMER1_COMP_vect)
{
fast_timer++;
TCNT2 = 175; // Nachladen
}

void setFastTimer(uint16_t time)
{
fast_timer = time;
}

uint16_t getFastTimer(void)
{
return fast_timer;
}

//...weiter unten in initRP6Control() habe ich außerdem noch folgendes ergänzt:

// Timer 1 - creates an interupt every 5us (is free for your application!)

TCCR1 |= (0 << CS12) | (0 << CS11) | (1 << CS10); //Count frenquenzy set to 16MHz
TCNT1 = (175); //preloader
TIMSK |= (1<<TOIE2);


Vielleicht könnt ihr mir sagen was ich da falsch gemacht habe?
Ich habe die Funktionen ähnlich der Stopwatches gehalten, aber beim übersetzen kommt folgende Fahlermeldung:

Compiling: ../../RP6Lib/RP6control/RP6ControlLib.c
avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=../../RP6Lib/RP6control/RP6ControlLib.lst -I../../RP6Lib -I../../RP6Lib/RP6control -I../../RP6Lib/RP6common -std=gnu99 -MD -MP -MF .dep/RP6ControlLib.o.d ../../RP6Lib/RP6control/RP6ControlLib.c -o ../../RP6Lib/RP6control/RP6ControlLib.o
../../RP6Lib/RP6control/RP6ControlLib.c:749: warning: 'TIMER1_COMP_vect' appears to be a misspelled signal handler
../../RP6Lib/RP6control/RP6ControlLib.c: In function 'initRP6Control':
../../RP6Lib/RP6control/RP6ControlLib.c:924: error: 'TCCR1' undeclared (first use in this function)
../../RP6Lib/RP6control/RP6ControlLib.c:924: error: (Each undeclared identifier is reported only once
../../RP6Lib/RP6control/RP6ControlLib.c:924: error: for each function it appears in.)
make: *** [../../RP6Lib/RP6control/RP6ControlLib.o] Error 1

> Process Exit Code: 2
> Time Taken: 00:00


vielen Dank für eure Hilfe

mfg WarChild

s.o.
02.05.2008, 06:42
Hallo,

ich bin mal so frei und unterstreiche dir die Fehlermeldungen:
appears to be a misspelled signal handler bzw. 'TCCR1' undeclared.
Auf gut deutsch will dir der Compiler sagen, dass du die Vars nicht deklariert hast. Aber ich denke eher, dass Du die <avr/io.h> nicht eingebunden hast.

Grüße

Michael

WarChild
02.05.2008, 11:10
aber weshalb funktionieren die anderen Timer aus der RP6ControlLib.h ??
Sieht ansonsten alles richtig aus???

mfg WarChild

WarChild
03.05.2008, 13:01
Also ich habe auch die io.h included, aber es bleibt der gleiche Fehler.
Die Standard Timer0 und Timer2 funktionieren ja auch, aber arum meiner nicht???

hier nochmal der minimal veränderte Code.


ISR (TIMER0_COMP_vect)
{
// Blocking delay (100µs):
delay_timer++;

// All 1ms based timing stuff
if(ms_timer++ >= 10) { // 10 * 100µs = 1ms
// 16bit Stopwatches:
if(stopwatches.watches & STOPWATCH1)
stopwatches.watch1++;
if(stopwatches.watches & STOPWATCH2)
stopwatches.watch2++;
if(stopwatches.watches & STOPWATCH3)
stopwatches.watch3++;
if(stopwatches.watches & STOPWATCH4)
stopwatches.watch4++;
if(stopwatches.watches & STOPWATCH5)
stopwatches.watch5++;
if(stopwatches.watches & STOPWATCH6)
stopwatches.watch6++;
if(stopwatches.watches & STOPWATCH7)
stopwatches.watch7++;
if(stopwatches.watches & STOPWATCH8)
stopwatches.watch8++;

// Sound generation timing:
if(controlStatus.beep) {
if(sound_timer < 1) { // sound_timer * 1ms
TCCR2 = 0;
controlStatus.beep = false;
}
else
sound_timer--;
}

ms_timer = 0;
}
}

/*################################################# #########################################
OWN TIMER ADDITION
################################################## ##########################################*/

volatile uint16_t fast_timer;

ISR (TIMER1_COMP_vect)
{
fast_timer++;
TCNT1 = 175; // Nachladen
}

void setFastTimer(uint16_t time)
{
fast_timer = time;
}

uint16_t getFastTimer(void)
{
return fast_timer;
}
//...weiter Unten in void initRP6Control(void)
/*################################################# #########################################
OWN TIMER ADDITION
################################################## ##########################################*/

volatile uint16_t fast_timer;

ISR (TIMER1_COMP_vect)
{
fast_timer++;
TCNT1 = 175; // Nachladen
}

void setFastTimer(uint16_t time)
{
fast_timer = time;
}

uint16_t getFastTimer(void)
{
return fast_timer;
}


Bitte helft mir!!!

mfg WarChild

Dirk
06.05.2008, 17:13
Hallo WarChild,

mit dieser Timer-Einstellung kannst du einen Interrupt 200kHz (5us) erreichen:

// Timer 1 - creates an interupt every 5us (is free for your application!)

TCCR1A = (0 << COM1A1)
| (0 << COM1A0)
| (0 << COM1B1)
| (0 << COM1B0)
| (0 << FOC1A)
| (0 << FOC1B)
| (0 << WGM11)
| (0 << WGM10);
TCCR1B = (0 << ICNC1)
| (0 << ICES1)
| (0 << WGM13)
| (1 << WGM12)
| (0 << CS12)
| (1 << CS11)
| (0 << CS10);
OCR1A = 9; // about 200kHz (5us)
// Enable output compare A match interrupts:
TIMSK |= (1 << OCIE1A);

Die ISR sieht dann z.B. so aus:

ISR (TIMER1_COMPA_vect)
{
fast_timer++;
}

Erwarte aber nicht zu viel von dem Code! Da du eine 16-Bit-Variable genommen hast, läuft die schon nach 1/3 Sekunde über!
Zusätzlich belastet der Interrupt ordentlich: Der M32 hat gerade 80 Takte bis er schon wieder in die ISR gezwungen wird!

Was willst du mit einem so schnellen Zähler machen?

Gruß Dirk

WarChild
16.05.2008, 19:30
Ich möchte synchron 18 servos ansteuern.
wenn ich eine auflösung von 5us habe, kann ich die 180° drehung mit ungefähr 300 schritten auflösen. Und weil es ein timer ist, beeinflusst die große Anzahl der anzusteuernden servos den Impuls nicht.
ich hatte es bereits mit einer sleep funktion zu lösen versucht, jedoch addiert sich zu den sleep zeiten auch noch die schaltzeiten der pins die Impulslänge. d.h. der letzte servo bekam, aufgrund der verzögerung durch das abschalten der 17 servos zuvor einen zu langen Impuls, sodass die Stellungen sehr vom soll abwichen. Mehr als drei servos kann ich damit nicht gleichzeitig ansteuern.
Also vielen dank für deine mühen.

mfg Warchild

PS: kannst du ein buch empfehlen, dass die atmega (oder Atmel) programmierung ohne umfassendes hintergrundwissen in der microcontrollerprogramierung verständlich rüber bringt?
C und C++ kann ich eigentlich recht gut. Abgesehen von zeigern, da verhaue ich mich gerne mal.

Dirk
16.05.2008, 21:08
@WarChild:

... kannst du ein buch empfehlen, dass die atmega (oder Atmel) programmierung ohne umfassendes hintergrundwissen in der microcontrollerprogramierung verständlich rüber bringt?
Weil jeder andere Voraussetzungen mitbringt, kann man nicht EIN gutes Buch empfehlen.
Die wesentlichen Bücher werden aber hier ...
https://www.roboternetz.de/wissen/index.php/Buchvorstellungen
... gut vorgestellt.

Gruß Dirk