Secuenciador programable de 8 canales 2.0
<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!. | |||||||||
|
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> |
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> |
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> |
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> |
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> |
![]() |
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.
|
![]() |
|
Secuenciador programable de 8 canales 2.0.
| ||||||||||
IntroducciónEn 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.
El circuitoEl 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.
Este es el esquema eléctrico del montaje.
Selección del programa.
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.
Pinout de los conectores ![]() La muesca de las fichas deben ir hacia afuera del PCB.
Lista de componentesLa lista de componentes es más bien pequeña:
wikipage=Publicidad tooltip=Publicidad img_src=Image:banner1.jpg img_width=801px </linkedimage>PCBEl 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.
Este es el aspecto del PCB.
Este es el lado cobre del PCB.
Y este el lado de los componentes.
MontajeEl 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 CCSAprovecharemos 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); }
}
//------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.
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. FuncionesAhora, 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
| ||||||||||
|
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. |


