Mostrando entradas con la etiqueta PIC. Mostrar todas las entradas
Mostrando entradas con la etiqueta PIC. Mostrar todas las entradas

Probador de PIC16F876

¿Cuantas veces se han visto con la necesidad de probar un firmware que han programado pero no tienen el circuito hecho para probar? Bueno lo que aquí propongo es una placa con todos los componentes para hacer trabajar al PIC, pero con la particularidad de que los puertos están disponibles para el uso que queramos darle.

El diagrama es el siguiente:

Circuito del probador de PIC16F876 (haga click para agrandar)

A simple vista se ven 5 conectores que 3 corresponden a los puertos del PIC (A,B y C) 1 para la alimentación, y el 5to par el ICSP (In Circuit Serial Programming). Para los que no sepan lo que es esto, les comento que es, como lo indica su nombre en inglés, la programación serial en circuito, o sea que se puede programar (grabar el firmware) directamente en la placa sin necesidad de extraer el integrado en ningún momento.

Aunque también se podría extraer el PIC en cualquier momento gracias a la implementación de un zócalo de 28 pines, dicho sea de paso aconsejo que cada vez que se fabrique un circuito, y sobretodo si está pensado para pruebas, que cualquier integrado que vayamos a utilizar no se suelde directamente a la placa sino que se utilicen zócalos; por económico que sea un integrado no significa que lo tengamos siempre a mano, ni sea fácil de conseguir.

Volviendo a lo que es el circuito en cuestión, es muy sencillo y lo unico que tiene de particular es que facilita la puesta en marcha del PIC, sólo con colocarle los 5volts de alimentación el PIC estaría funcionando, ya que cuenta con un cristal, también se podría utilizar varias velocidades de cristales, por medio de jumpers o zócalos.

Cuenta con protección anti inversión de polaridad, muy útil para cuando estamos haciendo pruebas, como también aislamiento de tensiones para cuando está alimentado y conjuntamente se conecta el ICSP, en tal caso una tensión no interfiere con la otra. Y está incluido el circuito de reset.
Está pensado para utilizarlo en protoboards para lo cual los pines de conexión de alimentación y puertos tendrían que ser de tira de pines acodados a 90º. Por el mismo motivo no se incluyen en el diseño resistencias de pull-up ni pull-down, se supone que el prototipo que se diseñe contendrá las resistencias necesarias.

Puede ser adaptado a cualquier modelo de PIC muy facilmente, solo basta con agragar o quitar pines a los puertos amoldandolos a las necesidades y al modelo del microcontrolador, cada uno puede pensar sus circuitos dependiendo de la necesidad que tenga...

Control de un módulo LCD con PIC y CCS C

Partiendo de saber la Conexión y funciones de un módulo LCD ahora veremos como se utiliza en la práctica. Para empezar aquí les dejo el diagrama de la conexión mas básica para poder comenzar a utilizar el display.

Conexión LCD a PIC16F84A

En el diagrama utilizamos el Pin 0 del puerto A para la señal Enable del display y el Pin 1 del mismo puerto para la señal RS.

R/W lo conectamos directamente a GND ya que en este proyecto no leeremos el estado del display en ningún momento.
El puerto B lo dedicaremos enteramente al bus de datos del LCD.

Todos los puertos que no utilizaremos, asi como el RESET del PIC, los conectamos a 5V por medio de un resistor.

Alimentamos todo a 5V por medio de una fuente que puede llegar a ser la Fuente de alimentación y cargador de baterías explicada en este blog y listo.

Pero falta algo, el programa o firmware que hace que el display haga algo... Para eso debemos crear el código, compilarlo y grabarlo en el PIC para que este lo ejecute, nosotros usaremos CCS C .

La rutina que hace esto sería esta:

#include <16f84a.h>
#use delay (clock=4000000)

#define E Pin_A0
#define RS Pin_A1

/*  Declaro las funciones antes de utilizarlas en main()
    para que sean reconocidas  */

void print(int c);
void Enviar(int8 Dato, int1 Comando);
void Iniciar_LCD(void);

//Comienzo del programa

void main(void){
   Iniciar_LCD();                // Inicio el Modulo
   print ("PICROBOT");           // Escribo PICROBOT en la pantalla
}
                                       
//Funciones

void print(int8 c){
   enviar (c,1);                 // Envio caracter c con RS a 1 (dato)
                                 // CCS C se encarga de enviar uno a uno
}                                // los caracteres contenidos en c
                                     
void Enviar(int8 Dato, int1 Comando){
   output_low(E);                // E en bajo
   output_b(Dato);               // Cargo el puerto B con Dato
   output_bit(RS,comando);       // Pongo RS en 0 o 1 dependiendo si es
                                 // un comando o dato lo que estoy
                                 // enviando
   output_high(E);               // E en alto
   delay_us(1);                  // Espero a estabilizar tensión
   output_low(E);                // E en bajo
   delay_us(40);                 // Espero 40 uS a que el LCD trabaje
                                 //
   if (Dato < 4) delay_us(1600); // Si envio un Home o un Clear display
                                 // espero otros 1600 uSegundos que
                                 // sumado a los 40 uS anteriores hacen
}                                // 1.64 mS que es lo que tardan estas
                                 // operaciones

void Iniciar_LCD(void){          //
   delay_ms(15);                 // Espero a que se estabilice
                                 // la tensión.
   
   enviar(0b00000001,0);         // Envio un CLEAR DISPLAY
                                 // (Borra la pantalla)
   
   delay_ms(5);                  // Espero 5 mS
   
   enviar(0b00111000,0);         // Envio un FUNCTION SET para bus de 8
                                 // bits, 2 lineas y caracteres de 5x7
                                 // pixeles.
   
   enviar(0b00001100,0);         // Envio un DISPLAY ON/OFF CONTROL
                                 // con pantalla encendida, Cursor
                                 //  apagado y si parpadear.
   
   enviar(0b00000110,0);         // Envio un ENTRY MODE SET con 
                                 // Incrementa cursor y desplaza cursor
}

Este programa introducido en el PIC conectado al circuito anterior hace que nuestro módulo muestre en pantalla la frase:

PICROBOT

En realidad lo único que hace es inicializar el LCD y mostrar el mensaje, se puede adaptar y hacer que muestre cualquier frase cambiando simplemente la palabra PICROBOT por lo que deseen en la línea:

print ("PICROBOT");

Hay que aclarar que para que funcione hay que respetar las comillas.

Pero si arman el circuito y graban el PIC con la rutina, verán que pueden modificar la frase, pero siempre aparecerá en la primer línea. Si volvemos a Conexión y funciones de un módulo LCD y consultamos dichas funciones, veremos que hay una que se llama SET DD RAM ADDRESS; La memoria DD RAM es la que contiene los caracteres que están en pantalla. De modo que esa función se llama Establecer la dirección de la DD RAM, o sea, que lo que hace es cambiar la posición donde se almacenará el próximo caracter, por lo tanto, lugar donde aparecerá en pantalla.

Para hacer que escriba donde queramos, antes de escribir, deberemos ejecutar un SET DD RAM ADDRESS. Continuando con nuestra rutina lo podemos hacer del siguiente modo:

void locate(x,y){
   int d=128;                // Cargo d con 128 (10000000) b7 a 1
   d+=y*64;                  // si y (linea) es 1 sumo 64 a d (11000000) b6 a 1
   d+=x;                     // a todo esto le sumo la posicion de x
   enviar (d,0);             // envio todo al display con RS a 0 (comando)
}

Entonces si, por ejemplo, queremos escribir Hola en la primer línea y Mundo en la segunda, el main() de nuestra rutina se vería así:

void main(void){
   Iniciar_LCD();             // Inicio el Módulo
   locate(6,0);               // Ubico el cursor en la columna 6
                              // de la primer línea
   print ("HOLA");            // Escribo HOLA
   locate(5,1);               // Ubico el cursor en la columna 5
                              // de la segunda línea
   print ("MUNDO");           // y escribo MUNDO
}

En un display de 16 caracteres x 2 líneas se verá centrada la frase HOLA MUNDO. Cabe destacar que antes de poder utilizar la función locate() se debe declarar mediante la sentencia:

void locate(x,y);

Luego podemos simplificar el borrado de la pantalla (CLEAR DISPLAY) con la función:

void cls(void){
   enviar (1,0);              // envio 00000001 (Clear display) 
}                             // con RS a 0 (comando)

Recuerden que CLEAR DISPLAY era 00000001 que es igual a 1 en decimal. De esta forma y previamente declarado cada vez que querramos borrar la pantalla introduciremos en el código la línea cls(); Por último en la entrada Librería para el manejo de un módulo LCD en CCS C encontrarás todas las funciones y la opción para descargarla.

Conexión y funciones de un módulo LCD

Una pantalla de cristal líquido o LCD (Liquid Cristal Display) es un dispositivo para la presentación de imagenes o caracteres. En este caso usaremos uno basado en el µControlador Hitachi 44780 o compatible, que muestra 16 o 20 caracteres en 1, 2 o 4 líneas. Las funciones de control son iguales para todos los modelos.

Conexionado:
PINNombreDirecciónFunción
01VssPGND
02VddPAlimentación a 5V
03VeePControl de contraste
04RSISelección de Registro / Dato
05RWISelección de Escritura / Lestura
06EIEnable / Disable
07 - 14D0 - D7I/OBus de datos
15 - 16A - KPCorresponden al ánodo y cátodo del backlight  (si el modelo lo tiene)

Bueno, la operacion del display es bastante sencilla ya que el µControlador interno, hace casi todo el trabajo, para comandarlo debemos saber como funcionan sus pines.

Para enviar un comando o un dato deberemos primero indicar que es lo que estamos enviando para eso se usa el pin RS, cuando este pin esta en 0 el LCD interpretará la información que esta prensente en sus pines D0 a D7 como un comando, si está en 1 significa que estamos enviandole un caracter, en cuyo caso se imprimira donde esté actualmente el cursor.

Asimismo en lugar de enviar información puede llegar el momento en que queramos leer algo de su memoria, para eso se utiliza el pin R/W, en 0 el LCD estará en modo escritura y en 1 en modo lectura.

El pin E es el que le indica al display que ejecute la operación que estamos enviandole, cuando este pin esta en 0 cualquier modificación que hagamos en sus otros pines será ignorada. Entonces la forma de proceder será asi:


- Se colocan los pines RS en 1 o 0 dependiendo si vamos a enviar un caracter o una dirección.

- R/W a 0 si queremos enviar un caracter o un comando y en 1 si queremos leer algun dato del display.

- Ponemos D0 a D7 Con el valor del caracter que queremos imprimir, o con el comando que deseamos ejecutar en el display ( si R/W es 1 estos pines se convertiran en salidas y solo podremos leer el estado)

- Por ultimo se pone en alto el pin E y el display ejecutará la función.

Ahora bien, como ya comenté por ahi, el R/W no lo usaremos, ya que como nosotros escribiremos en el display no necesitaremos obtener ninguna información de el, para hacer esto basta con conectar el pin 5 (R/W) directamente a GND y el LCD estará siempre en modo escritura.

El funcionamiente se resumiría asi: RS nos servirá para indicarle al LCD si lo que le estamos mandando es un comando o un caracter; D0 a D7 para enviarle el dato o el comando y E para que lo ejecute.

Para enviar un caracter simplemente ponemos RS en 1 y el valor binario del caracter en los pines D0 a D7E y aparecerá nuestro caracter en pantalla. luego pasamos a 1 el pin.

Impresión de caracteres.

Pero esto solo nos permite escribir un caracter al lado de otro, para seleccionar donde escribir, borrar pantalla etc debemos hacer el mismo procedimiento pero con el pin RS en 0 y los pines D0 a D7 con el valor del comando correspondiente a la operación que queramos hacer:

CLEAR DISPLAY Borra el contenido de la pantalla.

HOMEColoca el cursor en el primer espacio de la primera línea sin modificar el contenido de la pantalla.

ENTRY MODE SETEspecifica el modo en que se imprimiran los caracteres. 

I/D = 0 Incrementa el cursor 
I/D=1 Decrementa el cursor  
S=0 Desplaza el cursor
S=1 Desplaza el display

DISPLAY ON/OFF CONTROL Control de encendido y apagado de la pantalla.

D=0 Pantalla apagado
D=1 Pantalla encendida
C=0 Oculta el cursor
C=1 Muestra el cursor
B=0 Cursor estático
B=1 Cursor parpadeante

CURSOR OR DISPLAY SHIFT Mueve el display o el cursor.

S/C=0 Mueve el cursor
S/C=1 Mueve el display
R/L=0 Mueve a la derecha
R/L=1 Mueve a la izquierda

FUNCTION SET Establece el bus de datos, cantidad de líneas y modo de caracteres.

DL=0 Bus de datos de 4 bits (D4 a D7)
DL=1 Bus de datos de 8 bits (D0 a D7)  
N=0 LCD de 1 línea  
N=1 LCD de 2 líneas
F=0 Caracteres de 5 x 7 pixeles
F=1 caracteres de 5 x 10 pixeles

SET CG RAM ADDRESS

Ingresando de este modo la dirección de la CG RAM, indica que cuando usemos el comando para escribir en el display, lo que enviaremos serán caracteres personalizados, se necesitan 7 instrucciones por caracter.

SET DD RAM ADDRESS

Cuando escribimos en el display lo que en realidad estamos diciendole al módulo que haga es almacenar X caracter en Y posición de memoria, con este comando indicamos en que lugar de la DD RAM se guardará el próximo caracter que enviemos. 80-8F corresponde a la memoria para la primera linea y C0-CF a la segunda.

Lo siguiente que nos queda es mostrar las rutinas para hacer todo esto, y eso lo pueden ver en este apartado: Control de un módulo LCD con PIC y CCS C

SiLMuP (mi robot Sigue Líneas MultiPropósito)

Les presento a mi primer robot: SiLMuP ( Sigue Líneas MultiPropósito )

Aún en construcción y sin los sensores instalados.

Construcción:

- El cuerpo del robot está construido con ángulos de aluminio, escuadras metálicas y muchos tornillos.

- Los motores y reductoras son del sistema de detección de monedas de máquinas tragaperras, adaptadas.

- Las ruedas son rodillos para papel de impresora HP DeskJet 670C con unos engranajes recortados y pegados ( en la primer imagen). En la siguiente son del primer fascículo del Citroen C4 de la editorial Salvat escala 1:10.

- La tercera rueda es una rueda de mueble (rueda loca)

Con ruedas de radiomodelismo, el sensor de líneas y un servo para regular la distancia al suelo.

Electrónica:

La fuente es la misma que figura en el apartado "Fuente de alimentación y cargador de baterías" esta compuesta por un regulador de voltaje para la lógica (5v) y otro para alimentación de los IRLED (7v); Tiene un LM317 para cargar las 8 baterías de Ni-MH de 1.2v 2500mAh c/u. La energía para mover los motores de tracción la proporciona directamente las baterías.

El microcontrolador es un PIC16F876 de la casa Microchip programado en CCS C.

Integrados:

2 - 74HC165 para la lectura de sensores.
1 - 74HC595 para el manejo del display LCD y teclas de función.
3 - 74HC14 para estabilizar señales procedentes de los sensores.
1 - MAX232 para la comunicación mediante RS232 a PC.
1 - NE555 para generar la señal para los LED's infrarrojos de todos los sensores.

La etapa de potencia esta formada por dos puentes H hechos con transistores BD677 y BD678 principalmente.

Pronto habrá mas noticias...

SHIFT REGISTER ¿que son y cómo se usan?

Un registro de desplazamiento (shift register en inglés), es un integrado capaz de almacenar bits y presentarlos en sus pines.

Hay varios tipos pero los que aquí nos interesan son los del tipo Serial-Paralelo y Paralelo-Serial, esto significa que en el primer caso los bits "entran" en forma serial (uno a uno) y "salen" de forma paralela, en el segundo caso entrar en paralelo (todos juntos) y salen en serie.

Unos de los integrados que hacen esto, entre muchos otros, son el 74HC595 y el 74HC165, que son Serial/Paralelo y Paralelo/Serial respectivamente.

El pinout del 74HC595 es el siguiente:

Los pines marcados como Q0-Q7 son salidas y reflejan el estado interno de cada bit cuando es activado poniendo a nivel alto el pin 12 (STCP), los datos ingresan de forma serial por el pin 14(DS) cada vez que el pin SHCP pasa de estado bajo a alto ( de 0v a 5v).

También se pueden enlazar varios integrados iguales de modo que ampliamos la cantidad de bits. para ello agregamos un segundo integrado y conectamos la patilla DS a la patilla Q7' del primero.

La secuencia seria la siguiente:
1.Se pone el pin DS en el estado del bit que se quiera ingresar
2.Pin SHCP en bajo
3.Pin SHCP en alto
4.Se repite el proceso hasta enviar los 8 bits
5.Se coloca el pin STCP en bajo
6.Se coloca el pin STCP en alto

y de esa forma aparece el byte en las salidas.

Pinout del 74HC165:

De manera similar funciona el 74HC165 solo que a los bit los "lee" todos juntos.

Aquí las entradas son D0 a D7 y la salida es Q7, PL es el Load y cuando pasa a estado bajo carga los valores de las patas D0-D7 en "memoria" y dandole pulsos altos y bajos a CP los datos van saliendo bit a bit.

Para encadenar varios basta con conectar Q7 de un integrado con DS del siguiente y leer la pata Q7 del último.

Este es el diagrama de conexión para leer 16 bits (2bytes) con dos integrados enlazados:

La forma de proceder sería asi:
Se pone en bajo el Load para tomar el estado de todas las entradas (b0 a b15) luego se envia la señal de reloj poniendo en bajo y luego en alto Clk y se lee el estado de DI (Data-In). Recordar que en DI aparecerá primero el bit mas significativo (MSB).

Esta técnica es válida para controlar un display LCD, o multiplexar cualquier dato.

Aquí esta el código en CSS C:
#include <16f84a.h> 

#define  Clk    Pin_A0 
#define  Load   Pin_A1 
#define  DI     Pin_A2 

#use     fast_io(a) 
#use     fast_io(b) 
 
int Leer_Shift (void); 
 
void main(void){

   set_tris_A(0b10100);
   set_tris_B(0b00000000);

   do{
      if (input(pin_a4)==true) output_b(leer_shift());
   }while(true);

}
int Leer_Shift (void){
   int t;
   int Lectura=0;
   output_low (Load);      // Pongo a low Load para "cargar" el estado de las
   output_high(Load);      // entradas y paso a high para poder leerlas.     

   for(t=0;t<=7;++t){      // Hago un ciclo de 8 pasos (0 - 7) 

      Lectura<<=1;         // Roto los bits de la variable temporal
      Lectura+=input(Di);  // y le sumo el valor del ultimo bit leido      

      output_low(Clk);     // La transicion low-to-high hace que la      
      output_high(Clk);    // memoria interna del integrado rote.
   }
   return Lectura;
}

En el ejemplo, Clock se conectaría al pin 0, Load al pin 1 y DI al pin 2 del Puerto A. Pero este programa solo leerá de b8 a b15, para leer b0 a b15 se deberá usar Int de 16 bits para guardar los datos o dos de 8 bits y guardarlos en variables diferentes. Aparte de todo esto se deberá hacer un bucle de 16 ciclos en lugar de los 8 para leer 1 byte.

Con este circuito el único pin exclusivo para el funcionamiento del registro es el pin A2 (Data in) ya que los otros se pueden conectar a otros circuitos sin que afecten a este.

SiLMuP (todavía en construcción) utiliza un 74HC595 para controlar el display LCD y por el mismo bus controlar las teclas de función y un 74HC165 para leer el estado de los sensores de líneas.

De esta forma controla un display LCD, 4 teclas de función, 8 sensores siguelineas, y proximamente mas sensores y bumpers para obstaculos con 6 pines del pic y solo 3 son exclusivos.

Probador de PIC 16X84

Este circuito (de diseño propio, aunque esto no tenga demasiado mérito) te va a permitir probar tus programas, despues de grabarlos en el PIC, sin necesidad de hacer uno específico para cada configuración.
Circuito probador de PIC
El funcionamiento es bastante sencillo y se entiende a simple vista sin tener demasiados conocimientos de electrónica. De todas formas aca va la explicación: Se trata de 13 "puertos" conectados a los 5 RA y los 8 RB del PIC . Cada puerto se puede configurar como entrada o salida, por medio de un jumper o puente, según corresponda. Por ejemplo, si un puente está colocado sobre los pines 1 y 2 del JP1 significa que RA4 es una entrada y será activada por el pulsador S1, en cambio, si el puente se encuentra en los pines 2 y 3 del mismo jumper, RA4 será una salida que encenderá el LED1 cuando se encuentre con un "1 lógico".
Esta es una foto del probador que hice. Está montado sobre una placa perforada de 10x10cm. (esta escrita y tiene manchas de desoldadura porque es una placa reciclada) La diferencia de esta placa con el circuito, es que a la derecha se observan componentes que no figuran en el diagrama. Son los componente que conforman el regulador de voltaje que sirve para poder usar una fuente de entre 5V y 13V (el PIC funciona con 5V) y eliminar ruidos. (Pronto suibiré el circuito)

Tal vez le interese: