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!
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
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 :-)
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
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];
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.