Forum: Mikrocontroller und Digitale Elektronik Anfänger Frage


von Erik Werner (Gast)


Lesenswert?

Hallo

Ich habe Anfänger Frage:
Kann man Timer so Programmiren dass Timer mehr als 0,52s sein kann:
1
int main(void) 
2
{
3
WDTCTL = WDTPW | WDTHOLD;  // Stop watchdog timer
4
TA0CCR0 = 62499;
5
TA0CTL = TASSEL_2 | ID_3 | MC_1 | TAIE;// SMCLK, /8, Up mode, Interrupts ein
6
P1DIR |= (1<<6);
7
_bis_SR_register(GIE | CPUOFF);
8
}
9
10
#pragma vector=TIMER0_A1_VECTOR
11
__interrupt void TIMER0_A1_ISR(void)
12
13
{
14
P1OUT ^= (1<<6);
15
TA0CTL &= ~TAIFG;
16
}

TAnCCR0 = t ∙ fclk/ Vorteiler – 1 = 0,5 s ∙ 1 MHz / 8 – 1 = 62499 max. 
kann man 2^16 (65536= 0.52s)reinschreiben. Was wäre wenn ich brauche 
Timer= 20s?

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Erik Werner schrieb:
> Was wäre wenn ich brauche Timer= 20s?
Du zählst in deiner Timer-ISR mit deinem 0,5s Timer bei jedem Aufruf 
eine Variable um 1 hoch. Wenn du einen bestimmten Wert erreicht hast, in 
diesem Fall 40, lässt du deinen Controller tun, was er alle 20s tun soll 
und setzt die Variable wieder auf 0. Damit kannst du jede beliebig lange 
Zeit erzeugen.

mfg.

von Erik Werner (Gast)


Lesenswert?

Wert erreicht hast, in
> diesem Fall 40, lässt du deinen Controller tun, was er alle 20s tun soll
> und setzt die Variable wieder auf 0. Damit kannst du jede beliebig lange
> Zeit erzeugen.

Was hst du mit 40 gemeint? In meinem fall zählt MC TA0CCR0 = 
62499;(0.5s)und dann wird ISR gelöst.Die frage ist wie kann man TA0CCR0 
mehr als 65536= 0.52s
machen?

von Spaßmacher (Gast)


Lesenswert?

Wenn der INT ausgelöst wird erhöhst Du eine vorher definierte Variable 
um 1. Willst Du nun mehr als 0,5s haben, z.B. 2s, dann vergleichst Du 
die Variable in der main() einfach mit 4. Sobald die Variable 4 ist sind 
2s um und Du kannst in eine Funktion springen. Vor dem Sprung solltest 
Du aber noch die Variable wieder auf 0 setzten.

von Thomas E. (thomase)


Lesenswert?

Erik Werner schrieb:
> Was hst du mit 40 gemeint? In meinem fall zählt MC TA0CCR0 =
> 62499;(0.5s)und dann wird ISR gelöst.Die frage ist wie kann man TA0CCR0
> mehr als 65536= 0.52s
> machen?
Mehr als 65535 geht nicht. 65536 passt schon nicht mehr ins 
16-Bit-Register und wird zu 0. Also, der Zähler fängt wieder von vorne 
an.

Wenn du längere Zeiten haben willst, musst du in der ISR eine Variable 
hochzählen. Bei jedem ISR-Aufruf, der in diesem Fall alle 0,5s 
stattfindet, wird diese Variable um 1 erhöht. Wenn du also 20s haben 
willst, zählst du bis 40. Das sind dann 40 halbe Sekunden. Brauchst du 
eine Minute zählst du 120 halbe Sekunden. Bei einer Stunde sind das dann 
7200. Das kannst du treiben, bis du nicht mehr unter den Lebenden 
weilst. Dem Controller ist das egal. Der zählt einfach nur +1 bei jedem 
Aufruf der ISR. Jede halbe Sekunde.
Nach 1000 Jahren ist er bei 63.113.904.000.

So macht man das immer mit langen Zeiten. Die Register, also die 
Timercounter, sind nur für relativ kurze Zeiten direkt zu verwenden.

Wobei man für solche Zeiten zumeist keinen 16-Bit-Timer "verschwendet", 
sondern einen 8-Bit-Timer nimmt und diesen auch deutlich schneller 
laufen lässt. Z.B. mit 1/100s. Dann ist er nach 1000 Jahren bei 
3.155.695.200.000.

mfg.

: Bearbeitet durch User
von Erik Werner (Gast)


Lesenswert?

es währe leichter  _delay_cycles() benutzen.Statdessen will ich während 
Arbeit von  Timer strom zu messen.

von ich (Gast)


Lesenswert?

#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)

{
P1OUT ^= (1<<6);
TA0CTL &= ~TAIFG;

zaehler++;
if (zaehler > 20)
{
zaehler=0;
Tu was immer der TO will;
}







}

von Erik Werner (Gast)


Lesenswert?

ich schrieb:
> #pragma vector=TIMER0_A1_VECTOR
> __interrupt void TIMER0_A1_ISR(void)
>
> {
> P1OUT ^= (1<<6);
> TA0CTL &= ~TAIFG;
>
> zaehler++;
> if (zaehler > 20)
> {
> zaehler=0;
> Tu was immer der TO will;
> }
>
> }

Geht nicht!

von Erik Werner (Gast)


Lesenswert?

#include <msp430.h>
int zaehler=0;
int main(void)

{
WDTCTL = WDTPW | WDTHOLD;  // Stop watchdog timer

TA0CCR0 = 62499;
TA0CTL = TASSEL_2 | ID_3 | MC_1 | TAIE;// SMCLK, /8, Up mode, Interrupts 
ein
P1DIR |= (1<<6);
_bis_SR_register(GIE | CPUOFF);

}

#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)

{


TA0CTL &= ~TAIFG;
zaehler++;
if (zaehler > 20)
{
zaehler=0;
P1OUT ^= (1<<6);
//_delay_cycles(500);

}
}


so geht aber gut

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.