Forum: Compiler & IDEs Software-Timer beim ATmega168


von Sven K. (skoehler)


Lesenswert?

Als Anfänger hätte ich gern etwas Nachhilfe: Ich möchte beim ATmega168 
in C einen Software-Timer implementieren. Wer ist bereit, mir dazu 
kompetente Hinweise zu geben? Ich erwarte nicht, dass mir jemand den 
kompletten Code liefert!

von mork (Gast)


Lesenswert?

Was genau meinst Du mit Software-Timer?

Wenn das mehrere Timer sein sollen, die aber nur mit einem Hw-Timer 
laufen, dann kann ich Dir das im Anhang geben.
Mit System_Init() initialisiert man Timer0. Mit SetTimer setzt man einen 
Sw-Timer. Der erste Parameter dabei ist die Dauer zwischen 2 
Software-IRQs in ms, der zweite ein Zeiger auf eine void-Funktion ohne 
Parameter. Die Funktion selbst liefert ein Handle vom Typ int auf den 
Softwaretimer, welches gebraucht wird, um den Timer zu löschen. Die 
Funktion KillTimer(int) löscht den entsprechenden Timer bei Übergabe des 
Handles.
z.b.:
1
int h;
2
3
void mach()
4
{
5
  static int count;
6
        count++;
7
  printf("1 sek um!/n");
8
  if(count>10) KillTimer(h); 
9
}
10
11
int main()
12
{
13
  System_Init();
14
  h=SetTimer(1000,&mach);
15
  while(1);
16
  return 0;
17
};

MfG Mark

von Karl H. (kbuchegg)


Lesenswert?

Was verstehst du unter einem 'Software Timer'.

Ein Timer ist ganz einfach eine Variable, die
regelmässig hochgezählt wird. Bei erreichen von
bestimmten Zählerständen kann eine Funktionalität
ausgelöst werden.

Ergo; Im einfachsten Fall
ist ein 'Software Timer'

int main()
{
  unsigned char Timer;

  while(1)
    Timer++;
}

Ich denke aber nicht, dass du das im Sinn hattest :-)

von Peter D. (peda)


Lesenswert?


von Mark .. (mork)


Lesenswert?

Irgendwie klappt bei mir das Anhängen von Dateien nicht, also schick ich 
den oben erwähnten Code so:
1
#define Used_Timers 8
2
typedef void (*function) (void);
3
unsigned int SwTimer[Used_Timers],OCR[Used_Timers];
4
function TimerISR[Used_Timers];
5
6
7
void System_Init()
8
{
9
  TCCR0=3|(1<<WGM01);      //Prescale=64
10
  OCR0=(F_CPU/64)/1000;    //jede ms ein Interrupt
11
  TIMSK|=(1<<OCIE0);
12
  int i;
13
  for(i=0;i<Used_Timers;i++)
14
  {
15
    OCR[i]=0;
16
    SwTimer[i]=0;
17
  };
18
  sei();
19
}
20
21
ISR(TIMER0_COMP_vect)
22
{
23
24
  int i;
25
  for(i=0;i<Used_Timers;i++)
26
  {
27
    if(OCR[i]!=0)
28
    {
29
      if(SwTimer[i]>=OCR[i])
30
      {
31
        SwTimer[i]=0;
32
        TimerISR[i]();
33
      }
34
      else
35
      SwTimer[i]++;
36
    }
37
  }
38
}
39
40
int SetTimer(unsigned int OCRtmp,function to_exe)
41
{
42
  //suchen nach freiem Timer
43
  int handle;
44
  for(handle=0;handle<Used_Timers;handle++)
45
  {
46
    if((OCR[handle])==0)
47
    {
48
      OCR[handle]=OCRtmp;
49
      TimerISR[handle]=to_exe;
50
      return handle;
51
    };
52
  };
53
  return -1;
54
}
55
56
void KillTimer(int TimerID)
57
{
58
  SwTimer[TimerID]=0;
59
  OCR[TimerID]=0;
60
}

MfG Mark

von Sven K. (skoehler)


Lesenswert?

Besten Dank für den Code! Genau das hatte ich gemeint.

von Karl H. (kbuchegg)


Lesenswert?

Mach aber anstelle der 3 einzelnen Arrays
eine Struktur und erst davon dann ein Array.

struct Timer {
  unsigned int Timer;
  unsigned int OCR;
  function TimerISR;
};

struct Timer SWTimers[Used_Timers];

von Werner A. (homebrew)


Angehängte Dateien:

Lesenswert?

Ich hab mal das ganze für den Mega168 zusammengefasst.
Generell funktioniert das ganze, nur stimmt die Zeit von 1 Sekunde nicht 
richtig. Ich komme irgendwie auf 10 Sekunden.
Ich benutze den internen Oszillator mit 8 MHz und der Teiler 8 ist 
eingeschaltet.
Kann da vielleicht mal jemand drüber schauen?

Danke
  Werner

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.