Funktionaufruf

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
SeriK00
Beiträge: 34
Registriert: Fr Mai 15, 2009 12:15 pm

Funktionaufruf

Beitrag von SeriK00 » Mo Jul 20, 2009 6:20 pm

Guten Abend,

ich programmiere zwar auf den uController, aber ich denke ihr könnt mir hier helfen.
Die Funktion void timers_start( void ) __irq wird jede ms aufgerufen.
Dabei werde alle timer im array dekrementiert.
Bei erreichen von 0 bei einem bestimmten Timer wird eine bestimmte Funktion aufgerufen.
Für jeden Timer eine spezielle.
Wenn Timer0 = 0 ist dann wird function0 aufgerufen.
Das Problem ist, dass diese Funktion ständig aufgerufen wird, da void timers_start jede ms aufgerufen wird.
Wie kann ich es realisieren, dass die function0 nur 1 mal aufgerufen wird.

Vielen dank im Voraus.

Code: Alles auswählen

void timers_start( void ) __irq
{
	unsigned char i;
	lauf++;
		
	for (i=0; i<10; i++)
	{
	 	if (timer[i].t_time == 0)
		{
 		     if (timer[0) == 0 )
	              {
                          call function0;
                      }

		}
		else
		{
		 	timer[i].t_time--;
		}
	}
	T0IR = 1;                               	// Clear interrupt flag
	VICVectAddr = 0; 
}
Windows XP Prof
Visual Studion 2005
Keil µVision 3

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Funktionaufruf

Beitrag von cloidnerux » Mo Jul 20, 2009 7:02 pm

Wie kann ich es realisieren, dass die function0 nur 1 mal aufgerufen wird.
Bau dir ncoh eine variable ein

Code: Alles auswählen

char/int funktion0_aufgerufen = 0;
Die setzt du auf 1 wenn funktion0 aufgerufen wird und baust dir ncoh eine Abfrage in das if ein:

Code: Alles auswählen

if (timer[0) == 0 && funktion0_aufgerufen == 0)
Dann solte das klappen.
Du kannst auch alle 8-Bits des Chars für jeweils 1 Funktion nutzen.
Auf dem µC solltest du das Bitschubsen ja gewohnt sein ;)
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Funktionaufruf

Beitrag von Dirty Oerti » Mo Jul 20, 2009 8:29 pm

Hm, setzt du timer.t_time denn auch wieder auf einen anderen Wert als 0, nachdem die Funktion ein erstes mal aufgerufen wurde..?
Übrigens:

Du solltest die Funktion in das Struct timer mit einbauen, dann musst du keine riesen switch/if Anweisung einbauen..

Code: Alles auswählen

typedef struct  {
   Timer timer;
   void (*function) (int argument);
} new_Timer;

//...

new_Timer nt;
nt.function = /* Zeiger auf ieine Funktion */
nt.function(5);
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

SeriK00
Beiträge: 34
Registriert: Fr Mai 15, 2009 12:15 pm

Re: Funktionaufruf

Beitrag von SeriK00 » Mo Jul 20, 2009 9:07 pm

Vielen Dank für die hilfreiche Beiträge.

Ich setze timer.t_time bei der Initialisierung auf einen bestimmten Wert.
Wie mache ich das richtig mit der Funktion in der Struktur?

1. Bei der Initialisierung muss ich der Struktur einen Pointer übergeben?
und weiter?
wie mache ich das den genau?
Für eine Erklärung wäre ich sehr dankbar.

Bei der Funktion:
void timers_start( void ) __irq
ist das prog schneller wenn ich else ifs benutze?


Code: Alles auswählen

//Timer Struktur
typedef struct Timers 
{
	unsigned int 	t_time;
	unsigned char 	t_type;
	unsigned char 	flag;
   	void (*function) (int argument);
}TIME_TYPE;

//Initialisierung der Timer
void timers_set ( void )
{
	memset ( &timer, 0, sizeof (timer));
	timer[0].t_time = 1000;
	timer[0].t_type = PERIODIC;
	timer[0].flag = 	TRUE;
	timer[0].function = 
	timer[1].t_time = 5000;
	timer[1].t_type = PERIODIC;
	timer[1].flag = 	TRUE;
	timer[1].function = 

....
...
}

//ISR Timer wreden incrementiert und beim erreichen von 0 wird funktion aufgerufen
void timers_start( void ) __irq
{
	unsigned char i;
	lauf++;
		
	for (i=0; i<MAX_TIMERS; i++)
	{
	 	if (timer[i].t_time == 0)
		{
			if (timer[i].t_time == FALSE && timer[i].flag == TRUE)
			{
				timer[i].flag = FALSE;
				timer[0].function();//call_func_1();
			}
//			else if (timer[1].t_time == 0 && timer[1].flag == 1)
//			{
//				timer[1].flag = 0;
//				call_func_1();
//			}
//			else if (timer[2].t_time == 0 && timer[2].flag == 1)
//			{
//				timer[2].flag = 0;
//				call_func_1();
//			}
//			else if (timer[3].t_time == 0 && timer[3].flag == 1)
//			{
//				timer[3].flag = 0;
//				call_func_1();
//			}
//			else if (timer[4].t_time == 0 && timer[4].flag == 1)
//			{
//				timer[4].flag = 0;
//				call_func_1();
//			}
//			else if (timer[5].t_time == 0 && timer[5].flag == 1)
//			{
//				timer[5].flag = 0;
//				call_func_1();
//			}
//			else if (timer[6].t_time == 0 && timer[6].flag == 1)
//			{
//				timer[6].flag = 0;
//				call_func_1();
//			}
//			else if (timer[7].t_time == 0 && timer[7].flag == 1)
//			{
//				timer[7].flag = 0;
//				call_func_1();
//			}
//			else if (timer[8].t_time == 0 && timer[8].flag == 1)
//			{
//				timer[8].flag = 0;
//				call_func_1();
//			}
//			else if (timer[9].t_time == 0 && timer[9].flag == 1)
//			{
//				timer[9].flag = 0;
//				call_func_1();
//			}	
		}
		else
		{
		 	timer[i].t_time--;
		}
	}
	T0IR = 1;                               	// Clear interrupt flag
	VICVectAddr = 0; 

//Funktion von Timer0
void call_func_1 ( void )
{
 
}
}
Windows XP Prof
Visual Studion 2005
Keil µVision 3

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Funktionaufruf

Beitrag von Kerli » Mo Jul 20, 2009 9:51 pm

SeriK00 hat geschrieben:1. Bei der Initialisierung muss ich der Struktur einen Pointer übergeben?
und weiter?
wie mache ich das den genau?
Für eine Erklärung wäre ich sehr dankbar.
Genau. Du kannst mit dem Adressoperator auch Zeiger auf Funktionen erhalten, also zb so:

Code: Alles auswählen

timer[0].function = &call_func_1;
Beim Aufrufen der Funktion musst du dann gleich wie bei Variablen auch den Dereferenzierungsoperator einsetzen:

Code: Alles auswählen

(*timer[0].function)();//call_func_1();
Du musst aber aufpassen dass alle Funktionen von denen du die Zeiger speicherst die gleiche Signatur haben, also zb void (*function)(int argument).
SeriK00 hat geschrieben:ist das prog schneller wenn ich else ifs benutze?
Ein switch sollte immer schneller sein da der Compiler da normalerweise noch optimieren kann und nicht jedes mal einen neuen Vergleich durchführen muss. Außerdem macht es deinen Code lesbarer. Bei dir ist das aber eigentlich egal, da du dir durch die Funktionszeiger das ganze sowieso ersparst und die Funktionen gleich in der Schleife aufrufen kannst.

Code: Alles auswählen

for (i=0; i<MAX_TIMERS; i++)
   {
       if (timer[i].t_time == 0)
      {
         if( timer[i].flag )
         {
            timer[i].flag = FALSE;
            timer[i].function();
         }
      }
    }
Achja und warum überprüfst du denn den Timer zuerst auf 0 und dann gleich noch auf FALSE?
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Funktionaufruf

Beitrag von Dirty Oerti » Mo Jul 20, 2009 10:00 pm

Ich setze timer.t_time bei der Initialisierung auf einen bestimmten Wert.


Und GENAU DA liegt meiner Ansicht nach der Fehler.
Du setzt t_time am Anfang z.B. auf 10, dann wird runtergezählt, bis t_time bei 0 ist, dann wird die Funktion aufgerufen.
Soweit so gut.
Aber beim nächsten Durchlauf steht t_time ja immer noch auf 0.
Folge: Die Funktion wird wieder aufgerufen.

Setz nach dem Funktionsaufruf t_time doch mal auf z.B. 200.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

SeriK00
Beiträge: 34
Registriert: Fr Mai 15, 2009 12:15 pm

Re: Funktionaufruf

Beitrag von SeriK00 » Di Jul 21, 2009 3:22 am

Die Funktion wird nicht aufgerufen, da ein das Flag auf 0 gesetzt wird.
diese Funktione wird nur aufgerufen, wenn flag= 1 ist.
Dieser wird nach dem 1. Aufruf auf o gesetzt.
Momentan wird die Funktion nur 1 mal aufgerufen.

Das ist ganz klar. Hier übergeben wir timer[0].function die Adresse von der Funktion void call_func_1 ( void )
void timers_set ( void )

Code: Alles auswählen

{
	memset ( &timer, 0, sizeof (timer));
	timer[0].t_time = 1000;
	timer[0].t_type = PERIODIC;
	timer[0].flag = 	TRUE;
	timer[0].function = &call_func_1;

void call_func_1 ( void )
{
 call_isr_timer_0++;
}
Hier rufen wir die funktione, in dem wir die Adresse der Function mit Hilfe des Pointers abholen.

Code: Alles auswählen

(*timer[0].function)();//call_func_1();
Das hier ist mir nicht ganz klar.
timer[0].function = &call_func_1;
Die Adresse speichern wir in einem Pointer von Typ void.......

Was erreichen wir damit?
(int argrument)

Code: Alles auswählen

typedef struct Timers 
{
	unsigned int 	t_time;
	unsigned char 	t_type;
	unsigned char 	flag;
   	void (*function) (int argument);
}TIME_TYPE;
extern TIME_TYPE timer[MAX_TIMERS];
von dem Compiler erhalten ich folgende Fehler/Warnungen:
timer_02_set.c(28): warning: #513-D: a value of type "void (*)(void)" cannot be assigned to an entity of type "void (*)(int)"

timer_03_process.c(41): error: #165: too few arguments in function call

Vielen Dank.
Windows XP Prof
Visual Studion 2005
Keil µVision 3

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Funktionaufruf

Beitrag von Kerli » Di Jul 21, 2009 9:54 am

SeriK00 hat geschrieben:Das hier ist mir nicht ganz klar.
timer[0].function = &call_func_1;
function ist definiert als "void (*function) (int argument)", dh es ist ein Funktionszeiger auf eine Funktion mit einem Rückgabetyp void und einem Parameter vom Typ int. Dh. mit dem Adressoperator kannst du die Adresse einer Funktion erhalten und diese dann in dem Funktionszeiger speichern.
SeriK00 hat geschrieben:Was erreichen wir damit?
(int argrument)
Wie bereits oben erwähnt sind das die Funktionsargumente. Hier können auch nur die leeren Klammern bzw. (void) stehen wenn die Funktion keine Argumente erwartet aber auch mehrerer wie zb. (int,float) für eine Funktion die einen Integer und einen Float-Wert erwartet.
SeriK00 hat geschrieben:von dem Compiler erhalten ich folgende Fehler/Warnungen:
timer_02_set.c(28): warning: #513-D: a value of type "void (*)(void)" cannot be assigned to an entity of type "void (*)(int)"
Jetzt sollte die das Problem eigentlich gleich auffallen. Auch bei Funktionszeigern kann man nur gleiche Typen zuweisen. Und die beiden Funktionssignaturen sind doch nicht so ganz gleich ;)
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Antworten