Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

16/10/2015 #41

Avatar de rockoztar

Imagine que meter esos delays me generarian problemas , pero era lo unico que conocia para realizar esa funcion. Entre las publicaciones que he checado encontre este tuyo, me recomiendas utilizar contadores para controlar el tiempo que ocuparé el encendido de cada LED? Espero que con algo asi ahora si pueda cambiar de caso. Estoy en toda la disposicion de seguir leyendo y buscar mas ejemplos aqui en el foro. Tengo como 2 semanas apenas con esto.
Gracias por responder.



Saludos!
16/10/2015 #42

Avatar de TRILO-BYTE

me conmueve tu honestidad y tu lucha por conocimiento

te explicare:

el sistema Multitarea consiste en hacer una base de tiempo, esta base de tiempo parte de una unidad fija de reloj.

digamos 50us

obteniendo esta base de reloj podemos sacar muchos multiplos de este reloj, puede ser mas pequeño

todo depende de los ticks del CPU

ejemplo

1 tick= 1/(fosc/4)

digamos que tenemos un cristal de 20Mhz

1 tick estaria dado en 20/4= 5Mhz ahora 1/5Mhz
nos daria 0.2us como un tick

que significa que cada instruccion se ejecutaria a 0.2us asi que esa seria nuestra frecuencia limite para hacer un timer o base de tiempo.

pero por comodidad haremos un ejemplo con un timer de 1ms

en el CCS tenemos la estructura del timer de la siguiente manera:

Código:
#INT_TIMER0
void TIMER0_isr(void)
{
   //codigo
}
esta estructura nos permite hacer un desbordamiento de timer con la cual podemos hacer nuestra base de tiempo

hay calculadoras para hacer un calculo rapido para el desbordamiento de timer en lo particular me gusta el Pic Timer Calculator 0.9.0

hay que hacer unos calculillos para obtener la frecuencia de desbordamiento del timer.

en este caso busque el resultado del timer con un cristal de 20Mhz para timer 0

y me dio los siguientes resultados:

timer 0
preescaler 1:32
modo 8 bit
y el modo de interrupcion es 100

ahora el codigo quedaria del siguiente modo


Código:
#INT_TIMER0
void TIMER0_isr(void)
{
   //codigo
   set_TIMER0(100);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}
y en el main quedaria asi:

Código:
void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32|RTCC_8_bit); //preescaler a 32 y 8 bits
   enable_interrupts(global);
while(1)
{
//codigo
}

}


ahora ya que tenemos toda la base de la estructura del programa nos falta hacer nuestra base de tiempo que es la que nos importa como dije

esta interrupcion se dara cada 1ms

podemos generar tiempos de 1,2,3 segundos o 50ms, 500ms ,etc.
siempre y cuando no sean menores a 1ms

ahora lo que falta es hacer uso de variables globales para hacer las cuentas tanto en la interrupcion como usarlas en el main


eso se hace asi:

Código:
#include<blabla.h>
#include <etc.c>
y asi ...


int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3; //seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   contador++;
   if(contador>=1000)
   {
      contador=0; //reiniciamos la cuenta
       segundo1++;
       segundo2++;
       segundo3++;
   }

   set_TIMER0(100);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32|RTCC_8_bit); //preescaler a 32 y 8 bits
   enable_interrupts(global);
   while(1)
   {
     if(segundo1>=3) //si son 3 segundos prende led
     {
        segundo1=0;
        //prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              //apagamos o hacemos otra cosa  
           }

      if(segundo2>=1) //si son 1 segundos prende led
     {
        segundo2=0;
        //prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              //apagamos o hacemos otra cosa  
           }


     if(segundo3>=60) //si son 60 segundos prende led
     {
        segundo3=0;
        //prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              //apagamos o hacemos otra cosa  
           }


   }//fin de while

}// fin del main


y asi bajita la mano hisimos un proseso multitarea en el prendido de 3 leds con 3 tiempos diferentes

los 3 son totalmente independientes , estudia el codigo, piensalo, juega con el

y seguimos con el proseso de

LECTURA DE BOTONES

sin rebotes con multitarea
16/10/2015 #43

Avatar de rockoztar

Ya quedo! Deja le doy una buena leida porque son varias cosas, lo estudio y escribo mis dudas. Neta muchas gracias por responder a mi post.

Saludos!
19/10/2015 #44

Avatar de rockoztar

¿Qué tal, TRILO-BYTE? Ya estuve leyendo tu programa.
Este fin de semana no pude trabajar en el, hasta ahorita, pero creo que estoy haciendo algo mal, no sé si en los fuses o si tengo que agregar alguna librería.
Si puedo compilar el código, pero no hace nada el micro.

Este es el código que puse. (NOTA: puse 4000000 porque es el cristal que tengo.)
Te anexo la imagen del Timer Calculator, el dato de 131 fue el que agregué en el código.

Saludos!

Código PHP:
#include <16f628a.h>
            //libreria donde esta la funcion rand(); 

#fuses   INTRC_IO,NOWDT,NOPROTECT
#use delay(clock=4000000)




  
int16 contador//lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3//seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   
contador++;
   if(
contador>=1000)
   {
      
contador=0//reiniciamos la cuenta
       
segundo1++;
       
segundo2++;
       
segundo3++;
   }

   
set_TIMER0(131);   //desborda cada 1ms
   
clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   
setup_timer_0(RTCC_INTERNAL RTCC_DIV_32|RTCC_8_bit); //preescaler a 32 y 8 bits
   
enable_interrupts(global);
   while(
1)
   {
     if(
segundo1>=3//si son 3 segundos prende led
     
{
        
segundo1=0;
        
output_high(PIN_B0);//prendemos led eso depende del pin que uses o hacer otra cosa
     
}
     else{ 
             
output_low(PIN_B0); //apagamos o hacemos otra cosa  
           
}

      if(
segundo2>=1//si son 1 segundos prende led
     
{
        
segundo2=0;
        
output_high(PIN_B1);//prendemos led eso depende del pin que uses o hacer otra cosa
     
}
     else{ 
              
output_low(PIN_B1);//apagamos o hacemos otra cosa  
           
}


     if(
segundo3>=60//si son 60 segundos prende led
     
{
        
segundo3=0;
        
output_high(PIN_B2);//prendemos led eso depende del pin que uses o hacer otra cosa
     
}
     else{ 
              
output_low(PIN_B2);//apagamos o hacemos otra cosa  
           
}


   }
//fin de while

}// fin del main 
---------- Actualizado después de 3 minutos ----------

Aquí está la imagen, no se había subido.
Imágenes Adjuntas
Tipo de Archivo: jpg Timer Calculator.jpg (130,3 KB (Kilobytes), 11 visitas)
19/10/2015 #45

Avatar de TRILO-BYTE

no se aver prueba asi:
Código:
#include <16f628a.h>
            //libreria donde esta la funcion rand(); 

#fuses   XT,NOWDT,NOPROTECT //con cristal 
#use delay(clock=4M) // 4 Mhz




  int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3; //seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   contador++;
   if(contador>=1000)
   {
      contador=0; //reiniciamos la cuenta
       segundo1++;
       segundo2++;
       segundo3++;
   }

   set_TIMER0(6);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4|RTCC_8_bit); //preescaler a 4 y 8 bits
   enable_interrupts(global);
   while(1)
   {
     if(segundo1>=3) //si son 3 segundos prende led
     {
        segundo1=0;
        output_high(PIN_B0);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
             output_low(PIN_B0); //apagamos o hacemos otra cosa  
           }

      if(segundo2>=1) //si son 1 segundos prende led
     {
        segundo2=0;
        output_high(PIN_B1);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              output_low(PIN_B1);//apagamos o hacemos otra cosa  
           }


     if(segundo3>=60) //si son 60 segundos prende led
     {
        segundo3=0;
        output_high(PIN_B2);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              output_low(PIN_B2);//apagamos o hacemos otra cosa  
           }


   }//fin de while

}// fin del main
20/10/2015 #46

Avatar de rockoztar

Anexo fotos de como lo tengo conectado... sigue sin funcionar... Espero que solo sea algo sencillo. Solo tengo esos jumpers :S asi que por eso se ve todo feo.
Imágenes Adjuntas
Tipo de Archivo: jpg IMG_20151020_093431252.jpg (109,6 KB (Kilobytes), 10 visitas)
Tipo de Archivo: jpg IMG_20151020_093522894.jpg (76,4 KB (Kilobytes), 10 visitas)
Tipo de Archivo: jpg IMG_20151020_093540668.jpg (98,5 KB (Kilobytes), 10 visitas)
22/10/2015 #47

Avatar de rockoztar

Encuentras algo raro en la conexión? Lo volvi a programar en otro micro y nada :/
22/10/2015 #48

Avatar de TRILO-BYTE

¿El pin de MCRL tiene una resistencia de 10 KΩ a VCC?

---------- Actualizado después de 4 minutos ----------

A ver, creo que planteé mal el programa, porque sólo un instante de tiempo se mantiene encendido y lo demás está apagado.

---------- Actualizado después de 29 minutos ----------

Prueba lo siguiente:

El programa lo ando planteando mal desde hace años, pero ya está corregido.

Código PHP:
#include <16f628a.h>
            //libreria donde esta la funcion rand(); 

#fuses   XT,NOWDT,NOPROTECT //con cristal 
#use delay(clock=4M) // 4 Mhz




  
int16 contador//lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3//seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   
contador++;
   if(
contador>=1000)
   {
      
contador=0//reiniciamos la cuenta
       
segundo1++;
       
segundo2++;
       
segundo3++;
   }

   
set_TIMER0(6);   //desborda cada 1ms
   
clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   
setup_timer_0(RTCC_INTERNAL RTCC_DIV_4|RTCC_8_bit); //preescaler a 4 y 8 bits
   
enable_interrupts(INT_TIMER0);  //ME FALTO ESTA INSTRUCCION MUY IMPORTANTE!!!
   
enable_interrupts(global);
   while(
1)
   {


//corregido andaba planteando mal el programa, lo planteaba para hacer PWM y no para 
//una señal cuadrada, para que una señal sea cuadrada deben durar los 2 periodos
//el mismo tiempo por eso la segunda sentencia va al doble de la primera


     
if(segundo1>=3//si son 3 segundos prende led
     
{
      
output_high(PIN_B0);//prendemos led eso depende del pin que uses o hacer otra cosa
     
}
     if(
segundo1>=6)
     {
      
segundo1=0;
      
output_low(PIN_B0);
     }

      
      
     if(
segundo2>=1//si son 1 segundos prende led
     

      
output_high(PIN_B1);//prendemos led eso depende del pin que uses o hacer otra cosa 
     
}
     if(
segundo2>=2)
     {
      
segundo2=0;
      
output_low(PIN_B1);
     }
     


     if(
segundo3>=5//si son 5 segundos prende led
     
{
      
output_high(PIN_B2);//prendemos led eso depende del pin que uses o hacer otra cosa
     
}     
     if(
segundo3>=10)
     {
      
segundo3=0;
      
output_low(PIN_B2);
     }



   }
//fin de while

}// fin 
22/10/2015 #49

Avatar de rockoztar

Dame unos segundos mientras cargo el nuevo codigo... ahorita te digo que paso. Gracias TRILO

---------- Actualizado después de 14 minutos ----------

Listo, los contadores estan funcionando!
Imágenes Adjuntas
Tipo de Archivo: jpg IMG_20151022_151732121.jpg (79,4 KB (Kilobytes), 5 visitas)
Tipo de Archivo: jpg IMG_20151022_151721571.jpg (88,3 KB (Kilobytes), 5 visitas)
22/10/2015 #50

Avatar de TRILO-BYTE

Ahora debes empezar a plantear por ti mismo la escritura de una LCD.

Digamos, encender un led cada 0.5 segundos, generar un tren de pulsos a unos cuantos Kilohertz y escribir en la LCD una palabra cada 2 segundos y al mismo tiempo leer un ADC y mostrarlo en la LCD.

Todo eso es posible, gracias al TIMER.
22/10/2015 #51

Avatar de rockoztar

Voy a escribir un programa con eso que pides.
Creo que tengo un LCD por aquí, pero también voy a ir metiendo el Timer 0 en mi programa con el que estaba teniendo problemas. (El del semáforo)
Aunque aún falta ver lo de los botones con multitarea.

De verdad muchas gracias por la paciencia y por enseñarme como funciona el Timer.
Seguiré publicando los avances.
11/11/2015 #52

Avatar de rockoztar

Que tal, estoy de regreso para seguir con el aprendizaje... estuve fuera de esto por motivos de trabajo :/ pero les dejo un semáforo con tiempo fijo realizado con timer0, lo que realmente necesito hacer es un semaforo con 4 funciones... Tiempo fijo, Luces aleatorias(random), Avanzar luz por luz (Manual) y Avanzar luz por luz (Random). Necesito utilizar 2 push.

TRILO-BYTE, seguia lectura de botones sin rebotes con timer0 de verdad gracias... dejo el programa aqui.


Código:
#include <16f628a.h> 
         

#fuses   XT,NOWDT,NOPROTECT //con cristal  
#use delay(clock=4M) // 4 Mhz 




  int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo 
char segundo1,segundo2,segundo3; //seran nuestros segundos 


#INT_TIMER0 
void TIMER0_isr(void) 
{ 
   contador++; 
   if(contador>=1000) 
   { 
      contador=0; //reiniciamos la cuenta 
       segundo1++; 
       segundo2++; 
       segundo3++;
   } 

   set_TIMER0(6);   //desborda cada 1ms 
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto 
} 




void main() 
{ 

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4|RTCC_8_bit); //preescaler a 4 y 8 bits 
   enable_interrupts(INT_TIMER0);  //IMPORTANTE 
   enable_interrupts(global); 
   while(1) 
   { 


//corregido andaba planteando mal el programa, lo planteaba para hacer PWM y no para  
//una señal cuadrada, para que una señal sea cuadrada deben durar los 2 periodos 
//el mismo tiempo por eso la segunda sentencia va al doble de la primera 


       
//ENCENDIDO DE VERDE Y DESTELLO DE VERDE//
//ESTOY USANDO TRANSISTORES 3906 POR ESO EL ENCENDIDO LO TENGO EN LOW//     
     
       
       if(segundo1<=3)
       {
           output_low(PIN_B0); //PRENDE VERDE
       }
       
                              //DESTELLO DE VERDE//
       
                             if(segundo1>=4)
                             {
                                        if(contador<=500)
                                           {
                                            output_high(PIN_B0);
                                           }
                                        if(contador>=500)
                                           {
                                            output_low(PIN_B0);
                                           }
                              }
      
          
                                
                     if(segundo1>=6)
                        {
                         output_high(PIN_B0);    
                        }
     
       
                    if(segundo1>=10)   //REGRESO A 0 EL CONTADOR SEGUNDOS1
                    {
                     segundo1=0;
                    }
     
       
       
         //ENCENDIDO DE AMBAR//
       
       
             if(segundo2<=5)
             {
              output_high(PIN_B1);
              }
       
                      if(segundo2>=6)
                       {
                       output_low(PIN_B1);
                       }
       
                           if(segundo2>=7)
                             {
                             output_high(PIN_B1);
                              }
       
                                  if(segundo2>=10)
                                  {
                                   segundo2=0;
                                   }
       
       
       
          //ENCENDIDO DE ROJO//
       
                   if(segundo3<=6)
                    {
                     output_high(PIN_B2);
                     }
       
                             if(segundo3>=7)
                                {
                                 output_low(PIN_B2);
                                   }
       
                                        if(segundo3>=10)
                                        {
                                          output_high(PIN_B2);
                                          segundo3=0;
                                         }
       
       
       
       
    }   //CIERRO WHILE
} //CIERRO MAIN
11/11/2015 #53

Avatar de TRILO-BYTE

muy bien muy bien

felicidades hay compañeros que por mas que se les explica siguen usando delay

ya quitaste delay de tu sistema es muy buen avance.

por ahi creo que dario puso una libreria para usar botones
no la he revisado pero supongo que su codigo es mas eficiente que el mio.
creo que esta dentro de este mismo tema
11/11/2015 #54

Avatar de rockoztar

Dario es D@arkbytes? Porque si es el mismo, yo utilice la libreria que el subio (botton) y viene en mi programa anterior.

Entonces lo que puedo hacer es juntar la libreria del Push y el timer0?
Crees que con eso pueda hacer lo que dije en el mensaje anterior?


Saludos
Y gracias por responder a mis mensajes y explicarme lo del timer0 (Y)
11/11/2015 #55
Moderador

Avatar de D@rkbytes

rockoztar dijo: Ver Mensaje
¿Dario es D@rkbytes? Porque si es el mismo, yo utilicé la librería que él subió (button) y viene en mi programa anterior.
Dario, antes D@rio, y yo, D@rkbytes, somos personas diferentes.
Tal vez te cause confusión porque Dario antes tenía el @ en su nick, pero pidió un cambio de nick y ahora es Dario.
11/11/2015 #56

Avatar de Dr. Zoidberg

Doble personalidad virtual...
Interesante tema para una tesis de psicología.
12/11/2015 #57

Avatar de TRILO-BYTE

hay muchos darios asi como davits digo trilo-bytes es la misma gata pero revolcada

lo que digo SI puedes usar la libreria

¿hay conflictos con timer?

no se no he revisado la libreria pero pues el pic deberia traer otro TIMER si hay algun conflicto
digamos ya estoy usando timer 1 en XY cosa especifica usamos otro
12/11/2015 #58

Avatar de rockoztar

Gracias por la aclaración y por la ayuda. Ya busqué quien es Dario, buscaré la librería que publicó y comento como me fue con eso.

Como no cumplo las Políticas del Foro, me editaron el mensaje.


Normas del Foro 2.9 Los usuarios no pueden publicar, solicitar ni difundir información que promueva el plagio, la piratería, la divulgación de números de serie, crack o similares, o copias no autorizadas de material protegido por derechos de autor.
12/11/2015 #59
Moderador

Avatar de D@rkbytes

rockoztar dijo: Ver Mensaje
Gracias por la aclaración y por la ayuda.
Ya busqué quien es Dario, buscaré la librería que publicó y comento cómo me fue con eso.
Si te refieres a la librería "Button.c", yo la publiqué aquí en el Foro, comentando que no es de mi autoría.
D@rkbytes dijo: Ver Mensaje
Hace algún tiempo, buscando una buena solución para el problema de los rebotes en los pulsadores, encontré una librería escrita en C para PIC C Compiler.
Esta librería surge de una instrucción de PICBasic "BUTTON Pin,Down,Delay,Rate,BVar,Action,Label" que sirve muy bien para este propósito y lo que hace esta librería es muy similar, pues fue realizada para imitar a la instrucción de PICBasic, pero sin el salto a otra subrutina "Label".
El autor, del cual ya no recuerdo su nombre ni el sitio, describe detalladamente las funciones que usó para crear la rutina button, y también los parámetros a usar.

Adjunto esta librería que es de libre distribución y un ejemplo sencillo de su uso.

Suerte.
Descarga: Librería Button.c
12/11/2015 #60

Avatar de rockoztar

Yo ya use esa libreria y da 0 rebotes... lo unico que no se es si esa es la libreria a la que se refiere TRILO.

Esa ya la tengo descargada. Gracias D@rkbytes.... lo que hare es probar esa libreria con mi codigo de TIMER0.
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.