|
|
View previous topic :: View next topic |
Author |
Message |
younder
Joined: 24 Jan 2013 Posts: 53 Location: Brazil
|
Conditional call for functions not working! |
Posted: Thu Jan 24, 2013 6:47 am |
|
|
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
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Thu Jan 24, 2013 3:42 pm |
|
|
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
|
|
Posted: Fri Jan 25, 2013 4:25 am |
|
|
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
|
|
Posted: Fri Jan 25, 2013 5:04 am |
|
|
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
|
|
Posted: Fri Jan 25, 2013 8:53 am |
|
|
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
|
|
Posted: Fri Jan 25, 2013 11:24 am |
|
|
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
|
|
Posted: Fri Jan 25, 2013 9:59 pm |
|
|
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 |
|
|
|
|
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
|