CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Conditional call for functions not working!

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
younder



Joined: 24 Jan 2013
Posts: 53
Location: Brazil

View user's profile Send private message

Conditional call for functions not working!
PostPosted: Thu Jan 24, 2013 6:47 am     Reply with quote

Does anyone know why the function below is not working?
Code:

if (TON[0].PV<TON[0].SP)
  {
   Timer(0,50);
  }

On the other hand, the one below works!
Code:

if (TON[0].PV<TON[0].SP) goto TON0;
     
    TON0: Timer(0,50);

Any help on that would be appreciated!

Thanks!
Hugo
_________________
Hugo Silva
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 24, 2013 1:23 pm     Reply with quote

Post a test program.
Example of a short, compilable test program for structure problems:
http://www.ccsinfo.com/forum/viewtopic.php?t=43677&start=5

Also post your CCS compiler version. It's given at the top of the .LST file.
Example of version numbers:
http://www.ccsinfo.com/devices.php?page=versioninfo
Ttelmah



Joined: 11 Mar 2010
Posts: 19401

View user's profile Send private message

PostPosted: Thu Jan 24, 2013 3:42 pm     Reply with quote

Note the syntax is not CCS, unless he has written his own Timer function....

Best Wishes
younder



Joined: 24 Jan 2013
Posts: 53
Location: Brazil

View user's profile Send private message

PostPosted: Fri Jan 25, 2013 4:25 am     Reply with quote

Ttelmah wrote:
Note the syntax is not CCS, unless he has written his own Timer function....

Best Wishes


You are right, I'm trying to make my own timer function... The CCS Version is 4.114.

The idea is conditionally call the timer always when a IF logic is true.
In the code that I had mentioned I was trying to test the timer function by creating a Clock of 1s using two timers (TON[0] & TON[1]), than I stopped at that point because I know something is wrong but I just can't see it.. Help!!!

Below is the full code:
Code:

#include <16f877.h>           // identifica microcontrolador alvo
#device ADC=10                // define AD para 10 bits, variando de 0 a 1023
#use delay (clock=20000000)   // <- define cristal para 20Mhz. Para outros valores, mude e recompile.
#include <cuscostdio.h>       // inclui biblioteca de funções do projeto CUSCOPiC
#fuses HS, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, PUT // configura fuses

// =============================================================
// "Interrupcao Timer1", executada a cada 100ms
// =============================================================
//int16 conta=0;          // variável global
int1 Pulso_100ms=0;     // variável global com pulso de clock de 100ms
int1 Pulso_200ms=0;     // variável global com pulso de clock de 200ms
int1 Pulso_500ms=0;     // variável global com pulso de clock de 500ms
int1 Pulso_1000ms=0;    // variável global com pulso de clock de 1000ms
int1 Pulso_2000ms=0;    // variável global com pulso de clock de 2000ms
int1 Pulso_5000ms=0;    // variável global com pulso de clock de 5000ms
#int_timer1             // linha que define que a próxima função será associada à interrupção de tempo do TIMER0
void timer1()           // esta função não precisará ser chamada. Será executada automaticamente.
  {
static int8 conta200=0; // variável local
static int8 conta500=0; // variável local
static int8 conta1000=0;// variável local
static int8 conta2000=0;// variável local
static int8 conta5000=0;// variável local
      set_timer1(3036 + get_timer1()); //Pulso de clock de 100ms @ 20 MHz
//      conta++;
 
//Gerador de Pulso de 100ms
         Pulso_100ms = ~Pulso_100ms;      //Inverte Bit cada vez que executa Interrupção do Timer1
//Gerador de Pulso de 200ms
               conta200++;
            if (conta200==2) Pulso_200ms=1;
            if (conta200==4) Pulso_200ms=0, conta200=0;
//Gerador de Pulso de 500ms
                conta500++;
            if (conta500==5) Pulso_500ms=1;
            if (conta500==10) Pulso_500ms=0, conta500=0;
//Gerador de Pulso de 1000ms
               conta1000++;
            if (conta1000==10) Pulso_1000ms=1;
            if (conta1000==20) Pulso_1000ms=0, conta1000=0;
//Gerador de Pulso de 2000ms
               conta2000++;
            if (conta2000==20) Pulso_2000ms=1;
            if (conta2000==40) Pulso_2000ms=0, conta2000=0;
//Gerador de Pulso de 5000ms
               conta5000++;
            if (conta5000==50) Pulso_5000ms=1;
            if (conta5000==100) Pulso_5000ms=0, conta5000=0;
 }
// *************************************************************
// =============================================================
// "One Shot Rise, OSR", Gera pulso na borda de subida do clock de 100ms
// =============================================================
int1 OSR_100ms;  //Variável global pulso 100ms (Borda de subida)
void F_OSR_100ms() //Declaração da função
{
static int1 aux100;     //Variável local usada para intertravamento
   if (Pulso_100ms) //Se Pulso está Ligado
      { 
         if (~aux100) OSR_100ms=1; //e aux100 em Zero, Pulso de Subida vai pra 1
         if (aux100) OSR_100ms=0; //Passa no primeiro scan, continua varredura
         aux100=1; //Coloca variavel auxiliar em 1 que vai zerar borda de subida no próximo scan
      }
      else aux100=0;
}
// *************************************************************
// =============================================================
// "One Shot Rise, OSR", Gera pulso na borda de subida do clock de 500ms
// =============================================================
int1 OSR_500ms;  //Variável global pulso 500ms (Borda de subida)
void F_OSR_500ms() //Declaração da função
{
static int1 aux500;     //Variável local usada para intertravamento
   if (Pulso_500ms) //Se Pulso está Ligado
      { 
         if (~aux500) OSR_500ms=1; //e aux500 em Zero, Pulso de Subida vai pra 1
         if (aux500) OSR_500ms=0; //Passa no primeiro scan, continua varredura
         aux500=1; //Coloca variavel auxiliar em 1 que vai zerar borda de subida no próximo scan
      }
      else aux500=0;
}
// *************************************************************
// =============================================================
// "Timer ON Delay", Temporizador com retardo para ativar (em milisegundos)
// TON.SP = Setpoint
// TON.PV = Tempo atual
// TON.Q  = Sáida do Temporizador 1= Setpoint atingido
// TON.R  = Reset, Zera temporizador
// =============================================================

Typedef Struct {
   int8 SP;   
   int8 PV;       
   int8 Q;
   int8 R;
   }  TON_Struct;

 TON_Struct TON[2]={{0,0,0,0},{0,0,0,0}};
   
void Timer(int8 IN_TON_Nr,int8 IN_SP)
  {   
    TON[IN_TON_Nr].SP=IN_SP;
   
      if (TON[IN_TON_Nr].PV>=TON[IN_TON_Nr].SP) TON[IN_TON_Nr].Q=1;
      if ((OSR_100ms)&&(TON[IN_TON_Nr].PV<TON[IN_TON_Nr].SP)) TON[IN_TON_Nr].PV=(TON[IN_TON_Nr].PV+2);
      if (TON[IN_TON_Nr].R) TON[IN_TON_Nr].PV=0, TON[IN_TON_Nr].Q=0;
  }
// *************************************************************

void main()
 {
   enable_interrupts(global); //Habilito as interrupções globais
   enable_interrupts (int_timer1); // Habilito as interrupções do timer1
   setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); //Configura o timer1 para clock interno e prescaler dividindo por 8
   lcd_init(); // inicializa display
   INT TESTE=0;//TON[0].PV=0,TON[1].PV=0 ;//int8 counter=0;
     
 while(1)
   {
      F_OSR_100ms(); //Chamada da função geradora de pulsos de borda de 100ms
      F_OSR_500ms(); //Chamada da função geradora de pulsos de borda de 500ms
     
      if (Pulso_100ms) output_high(PIN_C0); else output_low(PIN_C0);
      if (Pulso_200ms) output_high(PIN_C1); else output_low(PIN_C1);
      if (Pulso_500ms) output_high(PIN_C2); else output_low(PIN_C2);
      if (Pulso_1000ms) output_high(PIN_C3); else output_low(PIN_C3);
      if (Pulso_2000ms) output_high(PIN_C4); else output_low(PIN_C4);
      if (Pulso_5000ms) output_high(PIN_C5); else output_low(PIN_C5);

      if (OSR_100ms) printf(LCD_PUTC,"\f%U %U %u %u\n%U %U %u %u",TON[0].SP,TON[0].PV,TON[0].R,TON[0].Q,TON[1].SP,TON[1].PV,TON[1].R,TESTE);

if (TON[0].PV<TON[0].SP)
  {
   Timer(0,50);
  }

//if (TON[0].PV<TON[0].SP) goto TON0;     
//    TON0: Timer(0,50);
   
       //lamps
      if (TON[0].PV<TON[0].SP) output_high(PIN_D0); ELSE output_LOW(PIN_D0);
      if (TON[1].PV<TON[1].SP) output_high(PIN_D3); ELSE output_LOW(PIN_D3);
     
   }
 }

_________________
Hugo Silva
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Jan 25, 2013 5:04 am     Reply with quote

Looks primarly like a confuse application design.

The .SP and .PV fields are used before being initialized (in the Timer() function).

Code:
if (TON[0].PV<TON[0].SP) goto TON0;
    TON0: Timer(0,50);

Misses the point, because Timer() is executed unconditionally.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Jan 25, 2013 8:53 am     Reply with quote

FvM wrote:
Looks primarly like a confuse application design.
I agree. For it's small size it takes too much time for me to figure out what it is doing and how. I stopped trying.

Quote:
The .SP and .PV fields are used before being initialized (in the Timer() function).
I don't think so. The struct is initialized to all zeroes.
Code:
TON_Struct TON[2]={{0,0,0,0},{0,0,0,0}};


Code:
if (~aux100) OSR_100ms=1; //e aux100 em Zero, Pulso de Subida vai pra 1
if (aux100) OSR_100ms=0; //Passa no primeiro scan, continua varredura
This is a difficult way to write:
Code:
if (aux100 == 0) OSR_100ms=1; //e aux100 em Zero, Pulso de Subida vai pra 1
else OSR_100ms=0;             //Passa no primeiro scan, continua varredura


When posting code, please use the 'code' buttons. It makes your code easier to read. Easy to read code will give you more and better responses. Even when you forgot to do this you can edit your post later.

As it stands, your program is too large for me to study, but my guess is your problem is in your Timer function. I've no clue as to what that function is doing. A little bit of comments there would help a lot.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Fri Jan 25, 2013 11:24 am     Reply with quote

Quote:
I don't think so. The struct is initialized to all zeroes.

I meant initialized to reasonable values. All zero is the condition to get Timer() never called, as observed.
younder



Joined: 24 Jan 2013
Posts: 53
Location: Brazil

View user's profile Send private message

PostPosted: Fri Jan 25, 2013 9:59 pm     Reply with quote

ckielstra wrote:
FvM wrote:
Looks primarly like a confuse application design.
I agree. For it's small size it takes too much time for me to figure out what it is doing and how. I stopped trying.

Quote:
The .SP and .PV fields are used before being initialized (in the Timer() function).
I don't think so. The struct is initialized to all zeroes.
Code:
TON_Struct TON[2]={{0,0,0,0},{0,0,0,0}};


Code:
if (~aux100) OSR_100ms=1; //e aux100 em Zero, Pulso de Subida vai pra 1
if (aux100) OSR_100ms=0; //Passa no primeiro scan, continua varredura
This is a difficult way to write:
Code:
if (aux100 == 0) OSR_100ms=1; //e aux100 em Zero, Pulso de Subida vai pra 1
else OSR_100ms=0;             //Passa no primeiro scan, continua varredura


When posting code, please use the 'code' buttons. It makes your code easier to read. Easy to read code will give you more and better responses. Even when you forgot to do this you can edit your post later.

As it stands, your program is too large for me to study, but my guess is your problem is in your Timer function. I've no clue as to what that function is doing. A little bit of comments there would help a lot.


I could make it work! Thanks for the tips... I just want to know if anyone has any idea in how to optimize the code considering that I will use these timers later in the application that I'm planning to develop...I'm just trying to avoid the use of delay_ms() as much as I can including for LCD print call, would that be the best way to have a While(True) loop with the cycle time optimized? Any reply/comment/idea would be appreciated!



Code:
#include <16f877.h>           // identifica microcontrolador alvo
#device ADC=10                // define AD para 10 bits, variando de 0 a 1023
#use delay (clock=20000000)   // <- define cristal para 4Mhz. Para outros valores, mude e recompile.
#include <cuscostdio.h>       // inclui biblioteca de funções do projeto CUSCOPiC
#fuses HS, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, PUT // configura fuses

// =============================================================
// "Interrupcao Timer1", executada a cada 100ms
// =============================================================
int1 Pulso_100ms=0;     // Global variable - variável global com pulso de clock de 100ms
#int_timer1             // Definition that next line will be associated to Timer1 - linha que define que a próxima função será associada à interrupção de tempo do TIMER0
void timer1()           // Function called automaticaly every 100ms - esta função não precisará ser chamada. Será executada automaticamente.
  {
      set_timer1(3036 + get_timer1()); //Pulso de clock de 100ms @ 20 MHz
         Pulso_100ms = ~Pulso_100ms;   //100ms Clock Pulse - Gerador de Pulso de 100ms - Inverte Bit cada vez que executa Interrupção do Timer1
 }
// *************************************************************
// =============================================================
// "One Shot Rising, OSR", Generates rising edge pulse every 100ms - Gera pulso na borda de subida do clock de 100ms
// =============================================================
int1 OSR_100ms;  //Global variable - Variável global pulso 100ms (Borda de subida)
void F_OSR_100ms() //Function declaration - Declaração da função
{
static int1 aux100;     //Auxiliar Variable - Variável local usada para intertravamento
   if (Pulso_100ms) //If pulse is true - Se Pulso está Ligado
      { 
         if (aux100==0) OSR_100ms=1; else OSR_100ms=0; //and aux100 is false then OSR_100ms=TRUE for only one scan - e aux100 em Zero, Pulso de Subida vai pra 1
         aux100=1; //Next scan OSR_100ms will be false - Coloca variavel auxiliar em 1 que vai zerar borda de subida no próximo scan
      }
      else aux100=0; //Clear aux100 till next rising edge detection - Espera por novo pulso
}
// *************************************************************
// =============================================================
// "Timer ON Delay", Temporizador com retardo para ativar (em milisegundos)
// TON.SP = Setpoint
// TON.PV = Timer counter value - Tempo atual
// TON.Q  = Timer output - Sáida do Temporizador 1= Setpoint atingido
// TON.R  = Reset - Zera temporizador
// =============================================================
 const int8 TimerArray=3;
Typedef Struct {
   int8 SP;   
   int8 PV;       
   int8 Q;
   int8 R;
   int8 EN;
}  TON_Struct;

 TON_Struct TON[TimerArray]={{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}; //Timer array declaration - define a quantidade de temporizadores que poderão ser usadas no programa {0,0,0,0,0},{0,0,0,0,0}
   
void Timer(int8 IN_TON_Nr,int8 IN_SP) //Timer Function  - Declaração da função
  {     
  static int8 temp[TimerArray];       
  static int8 Edge_EN[TimerArray];     
//------------------------------------ //TON[X].EN=1 ->Generates Edge Rising pulse for Reset Timer 
   if (TON[IN_TON_Nr].EN)
      { 
         if (temp[IN_TON_Nr]==0) Edge_EN[IN_TON_Nr]=1; else Edge_EN[IN_TON_Nr]=0; 
         temp[IN_TON_Nr]=1;
      }
      else temp[IN_TON_Nr]=0;
//-----------------------------------

         TON[IN_TON_Nr].SP=IN_SP; // Initializes .SP according called Timer - Copia Setpoint do TON chamadado
   
            if (TON[IN_TON_Nr].PV>=TON[IN_TON_Nr].SP) TON[IN_TON_Nr].Q=1, TON[IN_TON_Nr].EN=0; // If .PV reaches .SP, Output .Q is True - Se Contador >= Setpoint seta saída "Q"
            if ((OSR_100ms)&&(TON[IN_TON_Nr].EN)&&(TON[IN_TON_Nr].PV<TON[IN_TON_Nr].SP)) TON[IN_TON_Nr].PV=(TON[IN_TON_Nr].PV+2); // Increment counter every 200ms - Inicia contagem de tempo, incrementa a cada período de 200ms
            if ((TON[IN_TON_Nr].R)||(Edge_EN[IN_TON_Nr])) TON[IN_TON_Nr].PV=0, TON[IN_TON_Nr].Q=0, TON[IN_TON_Nr].R=0; //If .R is True, Clear Timer - Reseta e Zera variáveis do contador quando TON[x].R=1
  }
// *************************************************************

void main()
 {
   enable_interrupts(global); //Enable Global Interrupts - Habilito as interrupções globais
   enable_interrupts (int_timer1); //Enable Timer1 interrupts - Habilito as interrupções do timer1
   setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); //Configures timer1 - Configura o timer1 para clock interno e prescaler dividindo por 8
   lcd_init(); // Initialize 16x2 LCD - inicializa display
   TON[0].EN=1; //Initialize Timer 0 .EN=1
 while(1)
   {
      F_OSR_100ms(); // Call One Shot rise Function to generates 100ms clock pulse - Chamada da função geradora de pulsos de borda de 100ms

// Example of an Output shift by using "Own Home made timer"
//------------------------------------------------------
      Timer(0,20); // Timer(#,Setpoint x 100ms) -> Timer 0 Declaration with 2s of setpoint
         If (TON[0].Q) TON[1].EN=1,output_low(PIN_D0); ELSE output_high(PIN_D0); //TON[1].EN=1 ->Enable, Reset and Start Timer
      Timer(1,10); // Timer(#,Setpoint x 100ms) -> Timer 1 Declaration with 1s of setpoint
         If (TON[1].Q) TON[2].EN=1,output_low(PIN_D1); ELSE output_high(PIN_D1); //TON[0].EN=1 ->Enable, Reset and Start Timer
      Timer(2,15); // Timer(#,Setpoint x 100ms) -> Timer 2 Declaration with 1,5s of setpoint
         If (TON[2].Q) TON[0].EN=1,output_low(PIN_D2); ELSE output_high(PIN_D2); //TON[0].EN=1 ->Enable, Reset and Start Timer
//------------------------------------------------------

      if (OSR_100ms) printf(LCD_PUTC,"\f%U %U %u %u\n%U %U %u %u",TON[0].SP,TON[0].PV,TON[0].R,TON[0].Q,TON[1].SP,TON[1].PV,TON[1].R,TON[1].Q); //Print TON[0] & TON[1] variables
   
   }
 }

_________________
Hugo Silva
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group