Como trabalhar com timer dos pic na linguagem c ccs

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor carlucio » 05 Jan 2014 15:25

ola,


Estou ainda aprendendo de pouco em pouco a trabalhar com os pic, agora cheguei em uma fase de trabalhar com os timer. Ate aprendi a gerar um segundo com um codigo que esta no livro do fabio, so que agora queria aprender a incrementar variaveis com este um segundo gerado de tempo em tempo e fazer um comparação para executar uma função. O projeto que estou tentando fazer é automatizar um tanquinho utilizando a placa do micro clp pic. O projeto conta com 3 botoes (entradas digitais no pic16f628a) sendo uma para nivel maximo de agua, outra para ativar a função 1 e outra para ativar a função 2. E 4 saidas (a rele) sendo 1 soleinoide para encher o tanquinho , 1 solenoide para esvaziar o tanquinho, 1 para acionar uma sirene e outra para rodar o motor. O roteiro do projeto é o seguinte:

função 1:
enche de agua
opera 5min
para 3min
opera 4 min
para 3 min
descarta agua
enche de agua para enxague
opera 6 min.
descarta agua
sinaliza termino

função 2:
enche de agua
opera 5min
para 2min
opera 3 min
para 2 min
descarta agua
sinaliza termino

Como incrementar uma variavel x dentro destas funçoes para fazer comparações para acionar as saidas quando coincidirem com o valor do x incrementado? Sera escolhido ou uma função ou a outra.

Sera que alguem pode me dar uma dica?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor Rodrigo_P_A » 05 Jan 2014 19:03

Tem um jeito simples sem interrupção:
Código: Selecionar todos
void main()
{
 int x;
 x=0;
 for ( ;; )   // looping infinito
 {
      delay_ms(1000); // delay de 1 segundo
     if ( x==0 )
    { // enche de agua
    }
     if ( x == 300 )
     { // 5 minutos....  faz o que tem que fazer qdo for 5 minutos
     }
     x++; // incrementa
 }
}


essa é a idéia, dá uma pensada nisso.

Para a aplicação que você informou nem precisa usar interrupção, se você num quiser.
---
Avatar do usuário
Rodrigo_P_A
Dword
 
Mensagens: 2237
Registrado em: 12 Out 2006 18:27
Localização: Osasco - S.P - Brasil

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor andre_luis » 05 Jan 2014 19:51

Já fiz um projeto de uma lavadora com diversas funcionalidades baseado no microprocessador 51:

O núcleo do controle foi meio que baseado em máquina de estados, implementado pelo comando switch.
Tomando seu fluxo acima como referencia, seria algo assim:
Código: Selecionar todos
if ( funcao==1 )
{
Switch ( estado )
{
case ENCHE_DE_AGUA : { ... }
case OPERA_5MIN : { ... }
case PARA_3MIN : { ... }
case OPERA_4MIN : { ... }
case PARA_3MIN : { ... }
case DESCARTA_AGUA_1A_VEZ: { ... }
case ENCHE_PARA_ENXAGUAR : { ... }
case OPERA_6MIN: { ... }
case DESCARTA_AGUA_2A_VEZ: { ... }
case SINALIZA_TERMINO : { ... }
}
}
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor carlucio » 06 Jan 2014 09:50

Caro Rodrigo_P_A:

Entendi o seu entendimento, so que vejo que esta dentro da função main, como colocar os valores de comparação em duas funçoes diferentes?

EX:
funçao 1:
void passo_1(void){
if (x==300) {...}//roda motor
if(x==180){...} //para motor
....
....
....
esvazia;
enche de novo
....
....
.....
break;
}


funçao 2:

void passo_2(void){

if (x==300) {...}//roda motor
if(x==120){...} //para motor
....
....
....
break;
}

No caso sera selecionado ou uma ou outra antes ate de se ligar o processo.

Duvida: Funçoes nao sao sempre declaradas antes do main?


Tentei utilzar a interrupção de timer antes para gerar o 1 segundo e tentei colocar para incrementar a variavel" x " tanto dentro de uma função como na outra em uma ate faz mais ou menos na outra não. Coloquei ate outra variavel "y" na outra função e nada. A minha duvida esta ai, vista que as funçoes ficam sempre acima do main(?) por isso não entendi muito de como fazer.




Caro: Rodrigo_P_A andre_teprom

No caso de switch tambem ate pensei, so não fiz porque não sei a maneira correta para declarar, em outras oportunidades de outros programas ate tentei mas meu entendimento ainda é pouco e tenho dificuldades por exemplo, no pedaço do codigo que voce mandou o que se refere a palavara [estado, e como declararia ela acima?
Outra duvida é dentro de cada case tem o codigo referente ao que se deve fazer, ai tambem te pergunto acima não deveria ter um interrupçao de timer para gera o 1 segundo para fazer comparação dentro das variaveis?
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor cfreund » 06 Jan 2014 12:41

Como referência:

Código: Selecionar todos
enum {
   FIM,
   ESPERA_2MIN = 2,
   ESPERA_3MIN,
   ESPERA_4MIN,
   ESPERA_5MIN,
   ESPERA_6MIN,
   LIGAR_MOTOR,
   DESLIGAR_MOTOR,
   COMPLETAR_AGUA,
   DESCARTAR_AGUA,
} STEPS;

const unsigned char funcao1[] = {

   COMPLETAR_AGUA,

   LIGAR_MOTOR,
   ESPERA_5MIN,

   DESLIGAR_MOTOR,
   ESPERA_3MIN,
   
   LIGAR_MOTOR,
   ESPERA_4MIN,

   DESLIGAR_MOTOR,
   ESPERA_3MIN,
      
   DESCARTAR_AGUA,

   COMPLETAR_AGUA,

   LIGAR_MOTOR,
   ESPERA_6MIN,

   DESCARTAR_AGUA,
   
   FIM
};

const unsigned char funcao2[] = {

   COMPLETAR_AGUA,
   
   LIGAR_MOTOR,
   ESPERA_5MIN,

   DESLIGAR_MOTOR,
   ESPERA_2MIN,
      
   LIGAR_MOTOR,
   ESPERA_3MIN,

   DESLIGAR_MOTOR,
   ESPERA_2MIN,
      
   DESCARTAR_AGUA,

   FIM
};

void executar(const unsigned char *passos);

int main(){
   while(1){
      if(BOTA01){
         executar(funcao1);
      } else if(BOTA02){
         executar(funcao2);
      }
   }
}

void executar(const unsigned char *passos){
   unsigned int  i;
   
   for(; *passos; passos++){
      switch(*passos){
      case ESPERA_2MIN:
      case ESPERA_3MIN:
      case ESPERA_4MIN:
      case ESPERA_5MIN:
      case ESPERA_6MIN:
         i = 60 * (*passos);
         while(i--) delay_ms(1000);
         break;
      case LIGAR_MOTOR:
         // ...
         break;
      case DESLIGAR_MOTOR:
         // ...
         break;
      case COMPLETAR_AGUA:
         // Ativar solenóide e aguardar o nível ser completado
         break;
      case DESCARTAR_AGUA:
         // Ativar solenóide e aguardar esvaziamento
         break;
      default: // FIM
         // Acionar sirene
         return;
      }
   }
}
Editado pela última vez por cfreund em 06 Mai 2014 10:43, em um total de 1 vez.
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor carlucio » 05 Mai 2014 21:05

Estou com dificuldades para saber fazer o programa esperar / parar a contagem, e aguardar atingir o nivel (na função processo de enxague).
Quando o mesmo descarta a agua e voltar a enxer o mesmo deve chegar a um sensor de nivel e ativar no programa a contagem para operação novamente. So que conforme o programa em anexo quando chega nesta parte do programa não faz mas nada.
Sera que alguem tem ideia do que esta errado ou faltando?

Outra duvida e que quando se aciona uma função e quando a mesma chega ao final, se eu quiser utilizar a outra função o mesmo não aceita e tem de resetar o mesmo.
O que esta faltando ou errado?

Vejam:

Código: Selecionar todos
#define nivel_agua pin_a2
#define programa_1 pin_a3
#define programa_2 pin_a0
#define encher_tanquinho pin_b3
#define esvaziar_tanquinho pin_b0
#define alarme pin_b5
#define rodar_motor pin_b4

int1 a=0, b=0, c=0;
int16 func1=0, func2=0, func3=0;

int contagem_t0=0;
int processo_normal, processo_enxague;
static boolean led;


#int_RTCC
void RTCC_isr(void) {

set_timer0 (131-get_timer0());
contagem_t0++;
if(contagem_t0==125)
{
contagem_t0=0;
led=!led;
output_bit(pin_a6,led);
if(func1==2000)
{
func1=0;
}
else{
func1++;
}

if(func2==3000)
{
func2=0;
}
else{
func2++;
}
if(func3==1000)
{
func3=0;
}
else{
func3++;
}

}
}


void processo_normal(void){
while(!input(programa_1))
for(;;){
a=1;
//func1=0;
//programa_1==1;


if(a==1 && func1>=0 && func1<=30)
{
output_high(rodar_motor);
}
if(a==1 && func1>=31 && func1<=60 )
{
output_low(rodar_motor);
}

if(a==1 && func1>=61 && func1<=100 )
{
output_high(rodar_motor);
}

if(a==1 && func1>=101 && func1<=120 )
{
output_low(rodar_motor);
}

if(a==1 && func1>=121 && func1<=160 )
{
output_high(rodar_motor);
}

if(a==1 && func1>=161 && func1<=180 )
{
output_low(rodar_motor);
}
if(a==1 && func1>=181 && func1<=220 )
{
output_high(rodar_motor);
}
if(a==1 && func1>=221 && func1<=250 )
{
output_low(rodar_motor);
}
if(a==1 && func1>=251 && func1<=270 )
{
output_high(rodar_motor);
}
if(a==1 && func1>=271 && func1<=280 )
{
output_low(rodar_motor);
}
if(a==1 && func1>=281 && func1<=460 )
{
output_high(esvaziar_tanquinho);
}
if(a==1 && func1>=461 && func1<=465 )
{
output_low(esvaziar_tanquinho);
}

if(a==1 && func1>=466 && func1<=467 )
{
output_high(alarme);
delay_ms(250);
output_low(alarme);
delay_ms(250);
output_high(alarme);
delay_ms(250);
output_high(alarme);
delay_ms(250);
output_low(alarme);
delay_ms(250);
output_high(alarme);
delay_ms(250);
}
if(a==1 && func1>=468 && func1<=469 )
{
output_low(alarme);
}
if(a==1 && func1>=470 && func1<=471 )
{
output_high(alarme);
}
if(a==1 && func1>=472 && func1<=473 )
{
output_low(alarme);
}
if(a==1 && func1>=474 && func1<=475 )
{
output_high(alarme);
}
if(a==1 && func1>=476 && func1<=477 )
{
output_low(alarme);
}
}



break;
}

//}



void processo_enxague(void){
while(!input(programa_2))
for(;;){
b=1;
//func2=0;
//programa_2==1;


if(b==1 && func2>=0 && func2<=10)//roda 10 segundos
{
output_high(rodar_motor);
}
if(b==1 && func2>=11 && func2<=20 )//para 10 segundos
{
output_low(rodar_motor);
}

if(b==1 && func2>=21 && func2<=40 )//roda 20 segundos
{
output_high(rodar_motor);
}

if(b==1 && func2>=41 && func2<=60 )//para 20 segundos
{
output_low(rodar_motor);
}

if(b==1 && func2>=61 && func2<=80 )// roda 20 segundos
{
output_high(rodar_motor);
}

if(b==1 && func2>=81 && func2<=100 )// para 20 segundos
{
output_low(rodar_motor);
}
if(b==1 && func2>=101 && func2<=120 )// roda 20 segundos
{
output_high(rodar_motor);
}
if(b==1 && func2>=121 && func2<=140 )// para 20 segundos
{
output_low(rodar_motor);
}
if(b==1 && func2>=141 && func2<=160 ) // roda 20 segundos
{
output_high(rodar_motor);
}
if(b==1 && func2>=161 && func2<=170 )// para 10 segundos
{
output_low(rodar_motor);
}
if(b==1 && func2>=171 && func2<=350 )
{
output_high(esvaziar_tanquinho);
}
if(b==1 && func2>=351 && func2<=355 )
{
output_low(esvaziar_tanquinho);
output_high(encher_tanquinho);
}
if(!input(nivel_agua)==0){
output_low(encher_tanquinho);
c=1;
func3=0;
set_timer0(0);
}

if(c==1 && func3>=0 && func3<=10)
{
output_high(rodar_motor);
}
if(c==1 && func3>=11 && func3<=20)
{
output_low(rodar_motor);
}
if(c==1 && func3>=21 && func3<=30)
{
output_high(rodar_motor);
}
if(c==1 && func3>=0 && func3<=10)
{
output_low(rodar_motor);
}


break;
}
}












void main()
{



setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
set_timer0(131);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);

//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

// TODO: USER CODE!!


while(true){

output_low(rodar_motor);


if(input(programa_1)==0){
set_timer0(0);
func1=0;
processo_normal();
}

if(input(programa_2)==0){
set_timer0(0);
func2=0;

processo_enxague();
}
}
}
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor andre_luis » 05 Mai 2014 23:21

carlucio escreveu:quando se aciona uma função e quando a mesma chega ao final, se eu quiser utilizar a outra função o mesmo não aceita e tem de resetar o mesmo. O que esta faltando ou errado?


Meu palpite é o for(;;) que deve estar segurando a rotina.

Bom, dei uma olhada no seu programa, e vi algumas implementações que podem vir a dar problema.

O primeiro ponto é o fato de você realizar o uso de bastantes if aninhados.
Fica um pouco difícil de debugar, prefira o switch-case que é mais flexível.

O segundo ponto foi o fato de você ter estruturado o programa praticamente inline com poucas camadas hierarquicas de funções.

Dá uma olhada nesse artigo aqui, e vê se ajuda um pouco: Projeto experimental de lavadora de roupas
Tem o código fonte do projeto, que foi feito em C para o 8051, mas é facilmente portável para o PIC.



+++
"Por maior que seja o buraco em que você se encontra, relaxe, porque ainda não há terra em cima."
Avatar do usuário
andre_luis
Dword
 
Mensagens: 5447
Registrado em: 11 Out 2006 18:27
Localização: Brasil - RJ

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor cfreund » 06 Mai 2014 08:40

Não conseguiu entender a estrutura que propus?
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor carlucio » 06 Mai 2014 10:22

cfrend, realmente não consegui entender ainda como funciona o switch case, esta forma que usei pois não conheço outra que poderia fazer funcionar. Acho tambem que se usa-se o switch case ficaria preso no mesmo problema do sensor de nivel.
Estou aberto para tentar entender como funciona o switch case porque mesmo com alguns livros que tenho aqui não consigo entender a logistica do funcionamento do mesmo.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor cfreund » 06 Mai 2014 10:28

Semelhante:

Código: Selecionar todos
for (; *passos; passos++) {
    if ( (*passos == ESPERA_2MIN) || (*passos == ESPERA_3MIN) || (*passos == ESPERA_4MIN) || (*passos == ESPERA_5MIN) || (*passos == ESPERA_6MIN) ) {
        i = 60 * (*passos);
        while(i--) delay_ms(1000);
    } else if (*passos == LIGAR_MOTOR) {
         // ...
    } else if (*passos == DESLIGAR_MOTOR) {
         // ...
    } else if (*passos == COMPLETAR_AGUA) {
         // Ativar solenóide e aguardar o nível ser completado
    } else if (*passos == DESCARTAR_AGUA) {
         // Ativar solenóide e aguardar esvaziamento
    } else { // FIM
         // Acionar sirene
         return;
    }
}


Quando usar switch, não esqueça de empregar o 'break'.
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor carlucio » 06 Mai 2014 10:33

andre teprom,

O referido artigo que voce linkou so tem partes do codigo, no local que refere-se ao link para baixar o codigo em c o mesmo esta dizendo que o arquivo foi removido.
Caso tenho o codigo e puder dispor o meu email é : carluciorodrigues@ibest.com.br
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor cfreund » 06 Mai 2014 10:44

cpp code
void executar(const unsigned char *passos){
unsigned int i;

for(; *passos; passos++){ // Incrementa se 'passos' for diferente de 'FINAL'. (FINAL = 0)
switch(*passos){
case ESPERA_2MIN: // Se 'passos' for igual a ESPERA_2MIN, executará desde aqui, até o 'break'
case ESPERA_3MIN: // ESPERA_2MIN = 2 ~ ESPERA_6MIN = 6
case ESPERA_4MIN:
case ESPERA_5MIN:
case ESPERA_6MIN:
i = 60 * (*passos); // Se 'passos' for igual a ESPERA_4MIN, i = 240.
while(i--) delay_ms(1000); // Enquanto 'i' for maior que 0, espera 1 segundo. Após, decrementa 'i'.
break;
case LIGAR_MOTOR:
// ...
break;
case DESLIGAR_MOTOR:
// ...
break;
case COMPLETAR_AGUA:
// Ativar solenóide e aguardar o nível ser completado
break;
case DESCARTAR_AGUA:
// Ativar solenóide e aguardar esvaziamento
break;
default: // FIM
// Acionar sirene
return;
}
}
}
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor carlucio » 06 Mai 2014 16:03

cfreund

como é feito a temporização com switch case?
Também não entendi no seu codigo com é incrementado os cases.
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor cfreund » 06 Mai 2014 16:15

O switch testa a variável e pula para o case correspondente. Se não encontrar, vai para o default. Após executar o código do case correspondente, termine com break. Caso contrário, irá processas as linhas seguintes.

A variável passos controla o que será feito:

cpp code
passos = 1;
switch (passos) { // <- Vai pular para a linha "case 1"
case 0:
case 1: // <- Continua executando a partir daqui
break;
case 2:
case 3:
}

passos = 'A';
switch (passos) { // <- Vai pular para a linha "case 'A'"
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 'A': // <- Continua executando a partir daqui
}
Cláudio F
Avatar do usuário
cfreund
Word
 
Mensagens: 672
Registrado em: 14 Out 2006 14:02
Localização: São Paulo

Re: Como trabalhar com timer dos pic na linguagem c ccs

Mensagempor carlucio » 06 Mai 2014 16:23

cfreund,

A temporização pode ser feita dentro das cases?
Como vi no seu exemplo voce determinou passo = 1 e passo=a. O que que determina esse 1 ou a?

No caso desse programa que estou fazendo chega uma hora que o programa fica dependendo de alcançar o nivel para prosseguir. Tambem pode ser feito dentro de um case?
O programa ainda não esta completo pois estou trabalhando de parte em parte mas no inicio de cada função e no final da função enxague o programa vai ficar parado dependendo de se alcançar o nivel. como fazer isso? (com case se faz? com interrupção?)
carlucio
Byte
 
Mensagens: 118
Registrado em: 05 Jan 2014 15:07

Próximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron

x