PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Universale Timerfunktion



Vinter
09.03.2007, 15:42
Salut,

haette gern eine Timerfunktion, der ich einen float-Wert uebergeben kann und die mir dann x Sekunden wartet, also universal fuer 0.0001 .. 65535 sec zu verwenden ist. Am PC schaff ich das auch problemlos, die Werte werden anscheinen einwandfrei gesetzt, nur am AVR gibts eine Endlosschleife...

Code folgt:


uint8_t prescalerValues[] = PRESCALER_VALUES;
uint8_t timerValues[] = TIMER_VALUES;

#define WAIT 1

uint8_t mode = 0;
uint8_t overflow = 0;

ISR ( _VECTOR(5) ) {

TCCR2 = 0;

if ( mode == WAIT ) overflow = 1;

}

void waitTime(float time) {

mode = WAIT;

uint8_t ctr;
for (ctr = 0; ctr < 5; ctr++) {

for (time; (uint8_t) time > 0; time--) {

TCNT2 = 65535 - timerValues[ctr];
TCCR2 = prescalerValues[ctr];
while ( !overflow ) {}
overflow = 0;
TCCR2 = 0;

}

time *= 10;

}

mode = 0;

}
void initTimers() {

TIMSK |= ( 1 << TOIE2 );
sei();

}


Aufzurufen einfach im Sinne

initTimers();
wait(n.m);

PRESCALER_VALUES und TIMER_VALUES beschreiben die Ticks, die der Timer fuer einen bestimmten Prescaler ablaufen muss, um 1, 0.1, 0.01 etc sec zu brauchen; das wird dann (int) time mal wiederholt und auf die naechste Nachkommastelle weitergerueckt.
Frage ich TOV2 direkt ab, funktionierts uebrigens genauso wenig.

Gruss und Danke im Voraus,
David

SprinterSB
09.03.2007, 16:26
overflow ist flüchtig. Schau dir in einem C-Buch/Tutorial an, was das Schlüsselwort 'volatile' bewirkt!

Anststt _VECTOR(5) solltest du den Namen der ISR verwenden und nicht irgendwelche magischen Zahlen oder internen Makros.

Wenn TOV2 nicht per Polling funktioniert hast du den Timer nicht korrekt initialisiert.

Im übrigen solltest du überlegen, wie du warten kannst, ohne deine komplette Anwendung lahmzulegen ;-) (Währed du wartest geht nix anderes mehr).

bL1nK
09.03.2007, 16:29
also ich kann dir jetzt überhaupt nicht folgen?

stell halt den timer so ein das er alle 10ms kommt und im TOV0 lässt du dann ne variable dekrementieren und wenn die bei 0 ist machst was in der hautschleife



volatile uint8_t ovrcount;

int main
{
//init timer, prescaler, interrupts

ovrcount = 0x0F;
while (1)
{
if (!ovrcount)
{
//zeit abgelaufen
}
}
}


ISR (SIG_OVERFLOW0)
{
if ( ovrcount != 0)
ovrcount--;
}

Banzai
26.03.2007, 21:25
Hallo Leutz,

ich bin mal wieder am verzweifeln...

Kann mir jemand sagen was an diesem Code nicht stimmt (Code für RN-Control 1.4 ATMega32, also LED's auf PORTC ).


#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER2_COMP_vect)
{
PORTC = ~PORTC; // umschalten
}

int main(void)
{
DDRC = 0xFF;
PORTC = 0x0F; // alles aus

TCCR1A = (1<<COM1A1) | (1<<COM1A0);
TCCR1B = (1<<CS12) | (1<<WGM12);

OCR1A = 0xFFFF;

TIMSK |= ( 1 << OCIE1A );

sei();

while(1);
}

Die Hinweise hier im Forum, die Wissenseite, auf www.mikrocontroller.net, die Hilfe auf der Robotik-Hardware-CD und auch das #*@#+* Datenblatt haben mir nicht geholfen. Jedenfalls komme ich nicht weiter....

Banzai


PS: Kann man nicht einen 'Banzai-stellt-dumme-Fragen'-Thread aufmachen, in dem schlaue Leute einem geistig abwesenden Schwachsinnigen wie mir die Dinge einfach erklärt?

SprinterSB
26.03.2007, 21:33
Du aktivierst eine Timer1-IRQ, implementierst aber für die ISR einer Timer2-IRQ.

Banzai
26.03.2007, 23:42
Auf die Stirnhauvorlauterdummheit!
Den Baum vor lauter Wald nicht seh (oder war das andersherum... egal )

Danke!!!!!

Banzai

Banzai
27.03.2007, 08:19
Hallo erstmal,

ich hab zwar jetzt den TIMER2_COMP_vect für den Timer1 geändert und das Vergleichsregister OCR1A mit 3000dez geladen, aber es geht immer noch nicht.

Der Java-Timer-Calculator-Link auf den Wissenseiten ist irgendwie tot und mir hat sich die Berechnung der Werte um einen Interrupt in einer bestimmten Zeit z.B. 1 Sekunde aufzurufen noch nicht erschlossen.

Klar, irgendwie die µC-Clock (ich denke mal das Quarz, wenn kein externer Zeitgeber angeschlossen ist) durch den Prescaler. In meinem Fall die 16000000Hz / 256 = 62500Hz, also Schwingungen pro Sekunde... oder?

Wenn ich jetzt 0xF424 ( 62500 ) in das OCR1A lade, müsste doch nach einer Sekunde ein Timer Compare Match Interrupt ausgelöst werden, oder sehe ich das Falsch (OCR1A ist doch 16bit breit, kann also bis 0xFFFF, 65535dez aufnehmen )??? Der CTC (WGM12) ist ja auch eingeschaltet.
Was kann jetzt noch sein (ausser mein µC ist anders als andere oder das RN-Control ist ein RN-Machtnix)???

Gleich noch eine Frage hinterher: Kann man im AVR-Studio 4.x mit Interrupts 'simuliert' debuggen?

thx4help

Banzai

SprinterSB
27.03.2007, 08:36
Zeig mal den Code.

Hast du das Wiki-Beispiel in den C-Quellen (Hallo welt...) mal angeschaut? Da ist ne Formel für die Berechnung drin.

AVR-Studio weiß ich net, ist mir zu klotzig und mit Similieren findet man eh nur Fehler, die man komfortabler mit Brain v0.9 findet.

Banzai
27.03.2007, 14:42
thx Sprinter

der Code...


#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_COMP_vect)
{
PORTC = ~PORTC; // umschalten
}

int main(void)
{
DDRC = 0xFF;
PORTC = 0x0F; // alles aus

TCCR1A = (1<<COM1A1) | (1<<COM1A0);
TCCR1B = (1<<CS12) | (1<<WGM12);

OCR1A = 0x3000;

TIMSK |= ( 1 << OCIE1A );

sei();

while(1);
}

Der Wiki-Tip ist gut, da die Artikel schon etwas wild gestreut sind und man nach 10x Seitenblättern irgendwie den Anschluss verpasst.

OK... wo kriege ich Brain V0.9, wenn meine Version bei V0.3 stehengeblieben ist und das updaten so unheimlich schwer fällt ;o)

seeYa

SprinterSB
27.03.2007, 15:53
Das sollte beim Übersetzen mindestens eine Warnung geben, weil du einen ungültigen SIGNAL-Name verwendest.

https://www.roboternetz.de/wissen/index.php/Fallstricke_bei_der_C-Programmierung#Warnung_ignoriert



/* Interrupt vectors */

/* External Interrupt Request 0 */
#define INT0_vect _VECTOR(1)
#define SIG_INTERRUPT0 _VECTOR(1)

/* External Interrupt Request 1 */
#define INT1_vect _VECTOR(2)
#define SIG_INTERRUPT1 _VECTOR(2)

/* External Interrupt Request 2 */
#define INT2_vect _VECTOR(3)
#define SIG_INTERRUPT2 _VECTOR(3)

/* Timer/Counter2 Compare Match */
#define TIMER2_COMP_vect _VECTOR(4)
#define SIG_OUTPUT_COMPARE2 _VECTOR(4)

/* Timer/Counter2 Overflow */
#define TIMER2_OVF_vect _VECTOR(5)
#define SIG_OVERFLOW2 _VECTOR(5)

/* Timer/Counter1 Capture Event */
#define TIMER1_CAPT_vect _VECTOR(6)
#define SIG_INPUT_CAPTURE1 _VECTOR(6)

/* Timer/Counter1 Compare Match A */
#define TIMER1_COMPA_vect _VECTOR(7)
#define SIG_OUTPUT_COMPARE1A _VECTOR(7)

/* Timer/Counter1 Compare Match B */
#define TIMER1_COMPB_vect _VECTOR(8)
#define SIG_OUTPUT_COMPARE1B _VECTOR(8)

/* Timer/Counter1 Overflow */
#define TIMER1_OVF_vect _VECTOR(9)
#define SIG_OVERFLOW1 _VECTOR(9)

/* Timer/Counter0 Compare Match */
#define TIMER0_COMP_vect _VECTOR(10)
#define SIG_OUTPUT_COMPARE0 _VECTOR(10)

/* Timer/Counter0 Overflow */
#define TIMER0_OVF_vect _VECTOR(11)
#define SIG_OVERFLOW0 _VECTOR(11)

/* Serial Transfer Complete */
#define SPI_STC_vect _VECTOR(12)
#define SIG_SPI _VECTOR(12)

/* USART, Rx Complete */
#define USART_RXC_vect _VECTOR(13)
#define SIG_USART_RECV _VECTOR(13)
#define SIG_UART_RECV _VECTOR(13)

/* USART Data Register Empty */
#define USART_UDRE_vect _VECTOR(14)
#define SIG_USART_DATA _VECTOR(14)
#define SIG_UART_DATA _VECTOR(14)

/* USART, Tx Complete */
#define USART_TXC_vect _VECTOR(15)
#define SIG_USART_TRANS _VECTOR(15)
#define SIG_UART_TRANS _VECTOR(15)

/* ADC Conversion Complete */
#define ADC_vect _VECTOR(16)
#define SIG_ADC _VECTOR(16)

/* EEPROM Ready */
#define EE_RDY_vect _VECTOR(17)
#define SIG_EEPROM_READY _VECTOR(17)

/* Analog Comparator */
#define ANA_COMP_vect _VECTOR(18)
#define SIG_COMPARATOR _VECTOR(18)

/* 2-wire Serial Interface */
#define TWI_vect _VECTOR(19)
#define SIG_2WIRE_SERIAL _VECTOR(19)

/* Store Program Memory Ready */
#define SPM_RDY_vect _VECTOR(20)
#define SIG_SPM_READY _VECTOR(20)

Banzai
28.03.2007, 00:20
MANY THX!

Jetzt klappts (auch mit dem Interrupt)

Eine Compiler-Warnung hätte mich ja stutzig hemacht, aber da kommt nix....

Entweder ist das doppelt und falsch belegt, oder der Compiler prüft den Wert nicht... muss ich noch schauen.

Somit steht einer erfolgreichen Timer-Programmierung nichts mehr im Wege, denk ich mal!

Vielen Dank für die Hilfestellung!


banzai