Secuenciador programable de 8 canales 2.0

De Ucontrol
Saltar a: navegación, buscar

<keywords content="TTL 74Ls164N, electronica, circuito, pic, NE555, PIC BASIC, PIC SIMULATOR IDE, esquema, circuito impreso, proyecto, gratis, download, programa, CMOS, pin, e/s, i/o, ucontrol, PIC, 16F628a, 16f84a" /> <center>


Inicio Foro Revista uControl Circuiteca Microcontroladores Electrónica Básica Herramientas y Software Tutoriales Colaboradores Enlaces
¿Ya descargaste los ejemplares GRATUITOS de la Revista uControl? ¡No te los pierdas!.
<linkedimage>

wikipage=Dado electrónico con PIC tooltip=Dado electrónico con PIC img_src=Image:dado100.jpg img_width=150px img_alt=Dado electrónico con PIC </linkedimage>

Dado electrónico
<linkedimage>

wikipage=Como trucar un servo tooltip=Como trucar un servo img_src=Image:trucaservo150.jpg img_width=150px img_alt=Como trucar un servo </linkedimage>

¿Como trucar un servo?
<linkedimage>

wikipage=Comunicación inalámbrica entre PICs tooltip=Comunicación inalámbrica entre PICs img_src=Image:TXRX150.jpg img_width=150px img_alt=Comunicación inalámbrica entre PICs </linkedimage>

Comunicación inalámbrica
<linkedimage>

wikipage=CCS - Libreria de gráficos para GLCD K0108 tooltip=CCS - Libreria de gráficos para GLCD K0108 img_src=Image:GLCD-100.gif img_width=150px img_alt=CCS - Libreria de gráficos para GLCD K0108 </linkedimage>

Gráficos con CCS
<linkedimage>

wikipage=Funcionamiento de una matriz de LEDs tooltip=Funcionamiento de una matriz de LEDs img_src=Image:GNUxx.jpg img_width=150px img_alt=Funcionamiento de una matriz de LEDs </linkedimage>

Carteles de LEDs
Foroizq.jpg
Todos los articulos y proyectos de uControl tienen su lugar en el foro. Si tienes dudas o comentarios, busca o crea el hilo correspondiente, y tendrás una rapida respuesta.
Foroder.jpg
Secuenciador programable de 8 canales 2.0.

Introducción

Secuenciador programable de 8 canales 2.0

En uControl ya teniamos un Secuenciador programable de 8 canales, pero nos parecío interesante la posibilidad de construir la version 2.0 del mismo, de forma que pudiese utilizarse junto con las placas Módulo Reles x 4 y Módulo Reles x 8 del PIC TRAINER. Además, aprovecharemos este montaje para analizar paso a paso un programa completo en CCS.

Contenido


El circuito

El circuito de nuestro Secuenciador de 8 canales es bastante simple. Consta de una etapa de alimentación, construída alrededor de un regulador de voltaje LM7805. En la bornera de entrada deberemos proporcionar una tensión de corriente continua de 12V. Un diodo 1N4007 protege al circuito de una eventual conexión con la polaridad invertida. Un diodo LED indica si el circuito esta o no alimentado.


SECUEN8X4-002.GIF
Este es el esquema eléctrico del montaje.


El microcontrolador se conecta a un para de interruptores del tipo "Dip Switch" mediate los bits 2 y 3 del puerto A. Esto permite cuatro conbinaciones de "abierto/cerrado" diferentes, cada una de ellas selecciona uno de los cuatro programas posibles tal como puede verse en la tabla siguiente:


SECUEN8X4-006.GIF
Selección del programa.


Más abajo, en la sección correspondiente al software, veremos que caracterísicas tiene cada uno de los programas posibles.

El puerto B del microcontrolador es el encargado de manejar las 8 salidas. Cada uno de sus pines controla una de las entradas del driver ULN2803, que a su vez se encarga de encender los LEDs y las placas externas a travez de un par de conectores IDC de 10 vías, con un pinout compatible con el PIC TRAINER.


PICTRAINERconector1.JPG
Pinout de los conectores
IDC1.jpg
La muesca de las fichas deben
ir hacia afuera del PCB.


Lista de componentes

La lista de componentes es más bien pequeña:


<linkedimage>

wikipage=Publicidad tooltip=Publicidad img_src=Image:banner1.jpg img_width=801px

</linkedimage>

PCB

El circuito impreso necesario es de doble cara. El tamaño de los pads y de las pistas es bastante grande, por lo que no es dificil de construir en casa. Si no sabes como hacerlo, puedes aprender con con este tutorial.


SECUEN8X4-003.GIF
Este es el aspecto del PCB.


SECUEN8X4-004.GIF
Este es el lado cobre del PCB.


SECUEN8X4-005.GIF
Y este el lado de los componentes.


Montaje

El montaje no requiere de ninguna técnica en especial. Una vez que tengamos el PCB listo y agujereado, procedemos a soldar los componentes. Podemos comenzar por los resistores y los LEDs. Al hacerlo, hay que tener en cuenta que los LEDs deben tener la muesca que indica el cátodo hacia el lado correcto. Si no lo hacemos asi, el proyecto no funcionará.

Más tarde soldaremos los zócalos, los interruptores, los condensadores , el diodo 1N4007 (cuidando su orientación) y el LM7805. Por ultimo, soldaremos el cristal.

Programación en CCS

Aprovecharemos este montaje para aprender más sobre el compilador CCS. El siguiente es el listado completo del programa, que más abajo analizamos parte por parte.


//------Directivas para el compilador--------
#include <16f628a.h>                      //PIC utilizado
#fuses INTRC,NOWDT,PROTECT,NOLVP, NOMCLR  //Configuramos los fuses
#use delay (clock=4000000)                //Oscilador a 4Mhz
#use fast_io(a)                           //Optimizamos E/S del PORTA
#use fast_io(b)                           //Optimizamos E/S del PORTB
#byte porta = 0x5                         //Direccion del PORTA
#byte portb = 0x6                         //Direccion del PORTB
//
//------Prototipos de funciones-----
int8 leo_prog(void);         //Funcion que lee los dip/switches
void salidas_off( void);     //Funcion que apaga todas las salidas del PORTB
void pausax(int demora);     //Funcion que hace una demora de x decimas de seg.
//------------------------------------------------------------------------------
//------Programa principal----------
//------------------------------------------------------------------------------
void main(void)
{
   //
   //--------------------------------------------------------------------------
   #rom 0x2100 = {0x01} // Demora (1/10s) entre cada paso del Prog.0
   // 64 valores del programa 0
   #rom 0x2101 = {0x11, 0x22, 0x11, 0x22, 0x11, 0x22, 0x11, 0x22 }
   #rom 0x2109 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2111 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x2119 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2121 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x2129 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2131 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x2139 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   //
   #rom 0x2141 = {0x02} // Demora (1/10s) entre cada paso del Prog.1
   #rom 0x2142 = {0x44, 0x55, 0x44, 0x55, 0x44, 0x55, 0x44, 0x55 }
   #rom 0x214A = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2152 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x215A = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }  
   //
   #rom 0x2162 = {0x03} // Demora (1/10s) entre cada paso del Prog.2
   #rom 0x2163 = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF }
   #rom 0x216B = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }  
   //
   #rom 0x2173 = {0x04} // Demora (1/10s) entre cada paso del Prog.3
   #rom 0x2174 = {0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F }   
   //--------------------------------------------------------------------------
   //Variables
   int  programa = 0, instruccion_actual = 65;
   long demora = 0; 
   long tabla[4]={0x2100,0x2141,0x2162,0x2173};  //Pos. de inicio de cada prog.
   int pasos[4]={64,32,16,8};                    //Longitud de cada prog.
   //--------------------------------------------------------------------------      
   //configuro los pines de los puertos
   set_tris_a(0xFE);            //Todo el puerto como entrada.
   set_tris_b(0x00);            //Todo el puerto como salida.
   disable_interrupts(GLOBAL);  //todas las interrupciones desactivadas
   //
   //Comienzo el bucle infinito.
   do{ 
      if (instruccion_actual >= pasos[programa]) {
         instruccion_actual = 0;
         programa = leo_prog();    //Leo el numero de prog. selecc.
         demora = tabla [programa]; //Guardo la posicion de la demora prog.
      }
      //Leo el valor de la EEPROM corresp. a este programa y posicion
      portb = READ_EEPROM((long) demora + instruccion_actual+1);
      instruccion_actual++;
      pausax(READ_EEPROM(demora));           
   }while(TRUE);      //Repito el bucle
}
//------------------------------------------------------------------------------
//Funcion leo_prog. Lee el estado de los switchs 
// 1 y 2 (PIN_A2 y PIN_A3)
int8 leo_prog(void) {
   int8 programa_aux=0;   
   if (input(PIN_A3)) programa_aux++;
   if (input(PIN_A2)) programa_aux = programa_aux+2;      
   return programa_aux;
}
//Funcion salidas_off. 
void salidas_off(void) {
   portb = 0x00;
}
//Funcion pausax. Hace una pausa de "demora" decimas de segundos. 
void pausax(int demora) {
   int i;
   for (i=0; i<demora; i++) {
       delay_ms(100); }
}  



Vamos a ver que hace cada parte del programa. El siguiente bloque

//------Directivas para el compilador--------
#include <16f628a.h>                      //PIC utilizado
#fuses INTRC,NOWDT,PROTECT,NOLVP, NOMCLR  //Configuramos los fuses
#use delay (clock=4000000)                //Oscilador a 4Mhz
#use fast_io(a)                           //Optimizamos E/S del PORTA
#use fast_io(b)                           //Optimizamos E/S del PORTB
#byte porta = 0x5                         //Direccion del PORTA
#byte portb = 0x6                         //Direccion del PORTB

constituyen las directivas para que el compilador CCS sepa que microcontrolador estamos usando, que frecuencia de reloj, y en que direcciones están los puertos del PIC16F628A.

A continuación, declaramos los prototipos de las funciones que utilizaremos en el programa. Son solo 3:

//------Prototipos de funciones-----
int8 leo_prog(void);         //Funcion que lee los dip/switches
void salidas_off( void);     //Funcion que apaga todas las salidas del PORTB
void pausax(int demora);     //Funcion que hace una demora de x decimas de seg.

La función main() comienza cargando en la ROM del PIC el contenido del los cuatro programas:

   //--------------------------------------------------------------------------
   #rom 0x2100 = {0x01} // Demora (1/10s) entre cada paso del Prog.0
   // 64 valores del programa 0
   #rom 0x2101 = {0x11, 0x22, 0x11, 0x22, 0x11, 0x22, 0x11, 0x22 }
   #rom 0x2109 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2111 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x2119 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2121 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x2129 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2131 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x2139 = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   //
   #rom 0x2141 = {0x02} // Demora (1/10s) entre cada paso del Prog.1
   #rom 0x2142 = {0x44, 0x55, 0x44, 0x55, 0x44, 0x55, 0x44, 0x55 }
   #rom 0x214A = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }
   #rom 0x2152 = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }
   #rom 0x215A = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }  
   //
   #rom 0x2162 = {0x03} // Demora (1/10s) entre cada paso del Prog.2
   #rom 0x2163 = {0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF }
   #rom 0x216B = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }  
   //
   #rom 0x2173 = {0x04} // Demora (1/10s) entre cada paso del Prog.3
   #rom 0x2174 = {0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F }   

El programa 0 tiene una longitud de 65 bytes; el número 1 mide 33 bytes; el número 2, 17; y el número 3 sólo 9 bytes. En cada uno de los programas el primer byte de la serie indica la demora entre cada uno de los pasos que lo componen. El valor posible va de 0 a 225 (0x00 a 0xFF). Cuando se esta reproduciendo un programa, el microcontrolador hace una demora de un tiempo igual al indicado por este valor multiplicado por 0.1 segundos. Esto significa que cada paso de programa puede demorar de 0.1 a 25.5 segundos. En el listado hemos elegido valores de 0.1, 0.2, 0.3 y 0.4 segundos para cada programa, pero por supuesto, el lector podrá utilizar los valores que crea convenientes.

El resto del los bytes que conforman cada programa simplemente representan el valor que adoptará el puerto B en cada paso. 0xFFsignifica que todas las salidas estarán activadas, y 0x00 indica que todas deben apagarse. Cualquier convinacion entre 0x00 y 0xFFes válida. Nuevamente, hemos puesto algunos valores como ejemplo, que el lector podrá modificar a gusto.


Luego procedemos a declarar las variables que utiliza el programa. La primer linea dclara como int a las variables programa e instruccion_actual.

   int  programa = 0, instruccion_actual = 65;

Programa contiene el numero del programa que se ha seleccionado desde los interruptores, y sirve como indice para las tablas que contienen la longitud y posicion de comienzo de cada uno de ellos. instruccion_actual guarda el valor de la instruccion en curso, y se inicializa en 65 para que al ejecutarse el bucle principal por primera vez, se lea el programa mediante la funcion correspondiente.

demora es la cantidad de centesimas de segundo que hay que esperar entre uno y otro paso del programa.

   long demora = 0; 

Las dos tablas siguientes contienen la posición de inicio de cada porgrama, y el número de pasos que contiene cada uno.

   long tabla[4]={0x2100,0x2141,0x2162,0x2173};  //Pos. de inicio de cada prog.
   int pasos[4]={64,32,16,8};                    //Longitud de cada prog.

Luego procedemos a configurar cada pin de I/O y desabilitar las interrupciones:

  //configuro los pines de los puertos
  set_tris_a(0xFE);            //Todo el puerto como entrada.
  set_tris_b(0x00);            //Todo el puerto como salida.
  disable_interrupts(GLOBAL);  //todas las interrupciones desactivadas

Por fin, el bucle principal del programa. Este bucle se repite continuamente mientras que la placa este alimentada:

   do{ 
      if (instruccion_actual >= pasos[programa]) {
         instruccion_actual = 0;
         programa = leo_prog();    //Leo el numero de prog. selecc.
         demora = tabla [programa]; //Guardo la posicion de la demora prog.
      }
      //Leo el valor de la EEPROM corresp. a este programa y posicion
      portb = READ_EEPROM((long) demora + instruccion_actual+1);
      instruccion_actual++;
      pausax(READ_EEPROM(demora));           
   }while(TRUE);      //Repito el bucle

En cada "pasada" se verifica que el contador instruccion_actual no sobrepase el limite impuesto por la longitud del programa en curso. Si es asi, se pone nuevamente en cero, se lee el programa por si el usuario ha modificado la posición de los switches (esto permite cambiar de programa en cualquier momento) y se actualiza el valor de la variable demora para el programa en curso.

Luego, se leer el valor de la posición de la EEPROM correspondiente a instruccion_actual y se incrementa la variable puntero en 1, se llama a la función de demora y se vuelve a comenzar.

Funciones

Ahora, veamos las tres funciones empleadas: La primera de ellas se encarga de leer el estado de los switches, y devuelve un entero con el valor del programa seleccionado:

//Funcion leo_prog. Lee el estado de los switchs 
// 1 y 2 (PIN_A2 y PIN_A3)
int8 leo_prog(void) {
   int8 programa_aux=0;   
   if (input(PIN_A3)) programa_aux++;
   if (input(PIN_A2)) programa_aux = programa_aux+2;      
   return programa_aux;
}

La segunda simplemente pone en cero todas las salidas:

//Funcion salidas_off. 
void salidas_off(void) {
   portb = 0x00;
}

Y la ultima, simplemente repite un bucle las veces indicadas por la variable demora, haciendo una pausa de 100 milisegundos en cada pasada:

//Funcion pausax. Hace una pausa de "demora" decimas de segundos. 
void pausax(int demora) {
   int i;
   for (i=0; i<demora; i++) {
       delay_ms(100); }
}

Autor

Ariel.jpg Datos del Autor
Nombre: Ariel Palazzesi
email: arielpalazzesi@gmail.com
Ver los artículos de este autor. Página con el perfil del autor.

</center>
Cclicence.png

Este contenido se rige por la licencia de Creative Commons "Licencia Creative Commons Atribución-No Comercial-Sin Obras Derivadas 3.0". Para más información, véase la licencia en su forma reducida y completa.

Herramientas personales