You are on page 1of 32

INSTITUTO TECNOLOGICO DE LEÓN

TECNOLÓGICO NACIONAL DE MÉXICO

Materia: Microcontroladores
Documentación segundo examen parcial

Alumnos:
Jesús Mejía Manzo
Roberto Suárez Moreno

Profesor:
ING. MENDEZ ZAMORA GUILLERMO
EDUARDO

Fecha de entrega:
05/04/2018
Marco teórico:
Conexiones básicas de una pantalla lcd 16×2
El HD44780 permite conectarse a través de un bus de 4 u 8 bits. El modo de 4 bits permite
usar solo 4 pines para el bus de datos, dándonos un total de 6 o 7 pines requeridos para la
interfaz con el LCD, mientras que el modo de 8 bits requiere 10 u 11 pines. El pin RW es el
único que puede omitirse si se usa la pantalla en modo de solo escritura y deberá
conectarse a tierra si no se usa. En este caso el microcontrolador no puede leer desde el
chip controlador de pantalla, pero en la mayoría de las situaciones esto no es necesario y
nuestra librería no implementa aun esta funcionalidad.
Notese que todas estas configuraciones son ilustrarivas, la pantalla se puede conectar a
cualquier combinación de pines posible, ya que nuestra librería soporta usar cualquier pin
como parte del bus de datos y señales de control.
Diagrama para modo de 4 bits
Las conexiones para el módo de 4 bits en un PIC16F88 se muestran a continuación. Se
utilizan los primeros 4 bits del puerto A (RA0-RA3) como bus de datos. RB0 como señal de
habilitación (E) y RB1 como señal de selección de registro (RS).

Diagrama para modo de 8 bits


Las conexiones para el módo de 8 bits son algo más complicadas, ya que requerimos las 8
lineas de datos activas. En este caso utilizaremos los 8 bits del puerto B, aunque se puede
usar cualquier combinación de pines con nuestra librería. RA0 ahora funciona como señal de
selección de registro (RS) y RA1 como señal de habilitación (E).

Comandos del controlador HD44780


Para conocer un poco mejor los comandos soportados por la librería para la pantalla lcd
16×2, es necesario estudiar el juego de instrucciones soportadas por el chip controlador de
pantalla, el cual se resume en la siguiente tabla que hemos traducido de la hoja de datos. La
mayoría de los comandos listados pueden ser ejecutados llamando a una función en C de
nuestra librería.

Código de Operación Tiemp


Instrucci o de
Descripción
ón R R/ B B B B B B B B Ejecuc
S W 7 6 5 4 3 2 1 0 ión

Borra el
contenido de la
Clear pantalla y retorna 1.52
0 0 0 0 0 0 0 0 0 1
display el cursor a la ms
posición “home”
(dirección 0).

Retorna el cursor
Cursor a la posición 1.52
0 0 0 0 0 0 0 0 1 *
home “Home”. Retorna ms
también el área
de visión a la
posición inicial. El
contenido de la
DDRAM
permanece
intacto.

Incrementar/Decr
ementar dirección
(I/D); Habilitar
corrimiento de
Entry I/
0 0 0 0 0 0 0 1 S pantalla (S). 37 μs
mode set D
Estas
operaciones se
realizan al leer o
escribir datos

Enciende o
apaga el display
Display (D), Cursor
on/off 0 0 0 0 0 0 1 D C B encendido / 37 μs
control apagado (C),
destello del
cursor (blink) (B).

Selecciona entre
desplazamiento
de pantalla o de
cursor (S/C),
selecciona la
Cursor/di S/ R/ dirección de
0 0 0 0 0 1 * * 37 μs
splay shift C L desplazamiento
(R/L). El
contenido de la
DDRAM
permanece
intacto.

Configurar en
ancho de bus (4
u 8 bits)
Function D
0 0 0 0 1 N F * * (DL),Numero de 37 μs
set L
lineas de display
(N), y tipo de
fuente (F).

Escribe la
Set
dirección de
CGRAM 0 0 0 1 CGRAM address 37 μs
CGRAM. Los
address
datos a
almacenar en
CGRAM pueden
ser enviados
después de esta
instrucción

Escribe la
dirección de
DDRAM. Los
Set datos a
DDRAM 0 0 1 DDRAM address almacenar en 37 μs
address DDRAM pueden
ser enviados
después de esta
instrucción

Leer bandera
“Ocupado”
(Bussy Flag)
indicando si el
controlador está
realizando alguna
Read operación interna
busy flag B o esta listo para
0 1 CGRAM/DDRAM address 0 μs
&address F aceptar
counter datos/comandos.
Lee la dirección
CGRAM o
DDRAM
(dependiendo de
la instrucción
previa).

Write Escribe datos a


CGRAM las memorias
1 0 Write Data 37 μs
orDDRA CGRAM o
M DDRAM.

Read Lee datos desde


from las memorias
1 1 Read Data 37 μs
CG/DDR CGRAM o
AM DDRAM.

Nombres y significado de de bits en instrucciones


I/D – 0 = disminuir el contador de dirección, 1 = incrementar el contador de dirección;
S – 0 = Sin corrimiento de display, 1 = Con corrimiento de display;
D – 0 = Display Apagado, 1 = Display Encendido;
C – 0 = Cursor Apagado, 1 = Cursor Encendido;
B – 0 = Parpadeo cursor Apagado, 1 = Parpadeo Cursor Encendido;
S/C – 0 = Mover Cursor, 1 = Corrimiento de pantalla;
R/L – 0 = Mover/Correr a la izquierda, 1 = Mover/Correr a la derecha;
DL – 0 = Interfaz de 4 bits, 1 = Interfaz de 8 bits;
N – 0 = 1 linea, 1 = 2 lineas;
F – 0 = 5×8 puntos, 1 = 5×10 puntos;
BF – 0 = puede aceptar instrucción, 1 = operación interna en progreso.

Teclado Matricial con PIC

¿Como funciona un teclado matricial?


El principio de funcionamiento es sencillo y es similar a lo que haríamos para multiplexar leds
o dipslays de 7 segmentos. El programa configura el puerto B del PIC de la siguiente
forma: RB4 a RB7 funcionan como salidas y la otra mitad (RB0-RB3) como entradas. Las
filas (horizontal) del teclado matricial se conectan a los bits más significativos que funcionan
como salidas, mientras que las columnas (vertical) se conectan a los bits menos significativos
del puerto que funcionan como entradas con resistencias pull-down. Cualquier tecla que se
oprima en una columna causará que uno de los bits menos significativos del puerto
(RB0 – RB3) cambie de un estado lógico bajo a un estado alto.
La siguiente imágen muestra las conexiones del teclado al puerto B del microcontrolador. La
imagen muestra el teclado en reposo (sin teclas oprimidas).
¿Que pasa cuando se oprime una tecla en un teclado matricial?… la corriente puede fluir
a través del switch y el voltaje de los pines conectados a las filas del teclado (5 V o nivel alto)
aparece ahora también en alguno de los pines RB0 a RB3 según la columna en la que se
encuentra la tecla oprimida. La siguiente imagen ilustra lo que sucede al oprimir una tecla: al
oprimir el botón 6 provocamos un cambio en el PIN RB2 que ahora recibe un 1 o estado alto.
Sabemos entonces que se ha pulsado un botón en la segunda columna y se muestra como un
nivel lógico alto aparece en los bits menos significativos del puerto B, especificamente en RB2.
De esta manera el microcontrolador sabe que se ha oprimido una tecla al detectar un
cambio de nivel en los bits menos significativos. Hasta el momento, se sabe que se ha
oprimido una tecla en alguna columna (dependiendo del bit activo RB3 a RB0), sin embargo,
no sabemos en cual fila. Para resolver en que fila se oprimió una tecla, hay que realizar
un proceso de escaneo del teclado. En este proceso, colocaremos en secuencia un 1 lógico
(estado alto) en los 4 bits más significativos del puerto y leeremos el estado de los 4 bits
menos significativos. Sigamos con el ejemplo en el que se ha oprimido la tecla 6 pero ahora
viéndolo gráficamente en una animación:
El microcontrolador escanea en forma sucesiva los pines de salida, mientras lee las entradas
en la parte baja del puerto, de manera que puede detectar que teclas están oprimidas en cada
fila. Ahora solo falta escribir nuestro codigo en C que implemente los procedimientos
mencionados anteriormente y nos devuelva un valor de la tecla oprimida, por ejemplo,
mediante un número binario.
Programa en C para teclado matricial
El programa es bastante sencillo e implementa todos los procesos que describimos en la
teoría vista anteriormente. El código se ha mantenido simple intencionalmente para que se
pueda apreciar el funcionamiento de la manera más obvia posible. La
función keypad_read() es la encargada de realizar la mayor parte de las tareas para
determinar que tecla ha sido pulsada. El valor que retorna es una palabra de 16 bits en la cual,
cada uno de los bits representa una tecla, en donde un bit en estado alto representa una tecla
oprimida. Como la función no retorna como tal la tecla pulsada, sino una cadena de bits que
representan las teclas, es posible detectar cuando se presiona más de una tecla de forma
simultanea. El código de esta función es el siguiente:

1 /**
2 * Procesa las entradas del teclado matricial y determina la tecla que esta
3 * siendo oprimida. Retorna una palabra binaria de 16 bits en la cual los bits
4 * que se encuentran en estado alto representan teclas oprimidas.
5 *
6 * Esta función esta diseñada para poder detectar cuando se oprimen varias
7 * teclas sin embargo, debido a limitantes de la forma de conexión del teclado
8 * matricial, no se deben esperar resultados correctos al oprimir varias teclas
9 *
10 * @return Retorna una palabra de 16 bits, cada bit representa una tecla.
11 */
12 uint16_t keypad_read()
13 {
14 unsigned char count = 0;
15 unsigned char bitmask = 0x10;
16
17 // Valor de retorno de la funcion keypad_read() entero de 16 bits
18 uint16_t keys =0;
19
20 // Revisamos si alguna de las lineas en la parte baja esta en estado alto
21 // debido a que se ha cerrado un switch en el teclado.
22 if( PORTB & 0x0F )
23 {
24 // Escaneamos las filas una por una para determinar la tecla oprimida
25 do
26 {
27 // Apagamos todas las filas (parte alta)
28 PORTB &= 0x0F;
29 // Seleccionamos solo una como salida (bit del registro tris = 0)
30 TRISB &= ~bitmask;
31 // Y colocamos el pin en estado alto
32 PORTB |= bitmask;
33 // Esperamos unos cuantos milisegundos y leemos las columnas
34 delay_ms(100);
35 // Guardamos las columnas en una variable de 16 bits
36 keys |= (PORTB & 0x0F);
37 // Si ya hemos leido 4 columnas, las siguientes instrucciones no son
38 // necesarias, por lo que salimos del ciclo
39 if( count == 3 )
40 break;
41 // Recorremos la lectura a la izquierda para hacer espacio
42 keys = keys<<4;
43 // Recorremos el bitmask de la fila a leer
44 bitmask = bitmask<<1;
45 // Incrementar el contador de filas
46 count ++;
47 } while(1);
48
49 // Mantenemos parte alta = salidas y parte baja = entradas
50 TRISB = 0x0F;
51 // Mantenemos los bits mas significativos del puerto en estado alto
52 PORTB = 0xF0;
53 return keys;
54 }
55 return 0;
56 }

CONTROL DE SERVOMOTOR
#include <16F887.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18)
used for I/O
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWRT //Program memory not write protected
#FUSES BORV40
#define SERVO PIN_C1
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7,bits=8)

/*—————— Main Program ——————–*/


int16 pulso;
int16 bajo; // tiemp0 que esta en cero
int16 periodo; // periodo de la senal PWM
int i; // generar cliclo for para generar un tren de pulsa

void main(void)
{

while (true)
{

// m =1ms/180

pulso=2000 ; // 1ms -180


periodo=20000; // 20 ms
bajo=periodo-(pulso); // 20ms - pulso =19 ms

for (i = 0; i < 50; i++)


{
output_high(SERVO); // PIN_C1=1
delay_us(pulso); // retardo pulso
output_low (SERVO); // PIN_C1=0
delay_us(bajo); // retardo bajo
}

CONTROL DE MOTOR A PASOS


// control de motor de pasos unipolar con un boton de arranque y otro
de giro
#include <16F887.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES LP //Low power osc < 200 khz
#FUSES NOPUT //No Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOIESO //Internal External Switch Over mode
disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or
B5(PIC18) used for I/O
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOWRT //Program memory not write protected
#FUSES BORV40 //Brownout reset at 4.0V
#use delay(clock=8000000)

void main()
{

set_tris_a(0xFF); // configure porta como entrada


set_tris_b(0x00); // configure portb como salida

while(true){

if ((input(PIN_A0) == 1)) // esta apagado


{

output_b(0x00);

delay_ms(1000);

}
else if ((input(PIN_A0) == 0)) // esta apagado
{

// secuencia para que gire el motor a pasos unipolar

output_b(0b00001000) ;
delay_ms(1000); // pausa de 1 seg

output_b(0b00000100) ;
delay_ms(1000);

output_b(0b00000010) ;
delay_ms(1000);

output_b(0b00000001) ;
delay_ms(1000);

}
Objetivo. Realizar un sistema para el control de posición de un motor, donde
permita a un usuario desde un teclado matricial indicar los grados de posición
deseados y la velocidad para un motor, además de visualizar en una LCD los
puntos de control.
Material y Equipo.
 1 Protoboard.
 1 Microcontrolador PIC18F4550.
 1 Motor a pasos (bipolar o unipolar)
 1 Driver para motor a pasos (bipolar o unipolar)
 1 Servomotor
 1 LCD (16x2)
 1 Computadora para simulación de programas
 1 Fuente de alimentación fija (5V) (en caso de trabajar en protoboard)
 1 Multímetro digital
DESCRIPCION DEL SISTEMA:
A continuación se enlistan los requerimientos del sistema.  Para el motor a
pasos el control debe ser de 0° a 360°, y el servomotor de 0° a 180°.  Realizar un
menú en una LCD para interface con el usuario:
 MAIN -> Selección del motor para ajuste de parámetros Figura 1.
 Selección parámetro -> valores de velocidad y posición de control actuales
Figura2.
 Ventana 2 Ajuste posición -> valor deseado de posición Figura 3.
 Ventana 3 Ajuste velocidad -> valor deseado de velocidad Figura 4. En la LCD
se debe poder visualizar el valor de los grados que desea el usuario para la
posición del motor a pasos o servomotor (menú principal). En la LCD se debe
poder visualizar el valor de velocidad (0 a 100%) que desea el usuario para
cambio de una posición a otra en el motor a pasos o servomotor (menú principal).
 Mediante un teclado matricial el usuario debe poder ingresar el valor de la
posición que desea y el valor de velocidad que requiere para los cambios de
posición en un motor específico (motor a pasos o servomotor).  Al menos debe
haber 4 velocidades diferentes 0%(stop), 25%(baja), 50%(media) y 100%(alta)
Código:
Interfaz.c
//Instituto Tecnológico de León
//4 de Abril del 2018
//Autores: Jesús Mejía Manzo, Roberto Suárez Moreno
//Versión 2
//Examen parcial 2

#include <Interfaz.h> //Inclusión de lo que hay en el .h (fuses, ajuste de pines


como E/S etc.
#include <string.h> //Libería string.h para utilizar algunas funciones
#define LCD_ENABLE_PIN PIN_D6 //Definición de los puertos que se conectan a
la LCD
#define LCD_RS_PIN PIN_D4 //Definición de los puertos que se conectan a la
LCD
#define LCD_RW_PIN PIN_D5 //Definición de los puertos que se conectan a la
LCD
#define LCD_DATA4 PIN_D0 //Definición de los puertos que se conectan a la
LCD
#define LCD_DATA5 PIN_D1 //Definición de los puertos que se conectan a la
LCD
#define LCD_DATA6 PIN_D2 //Definición de los puertos que se conectan a la
LCD
#define LCD_DATA7 PIN_D3 //Definición de los puertos que se conectan a la
LCD
#include <lcd.c> //Librería para usar la LCD
#define use_portb_kbd TRUE //Definición del puerto b para el teclado matricial
#include <KBD4x4.c> //Inclusión del la librería del teclado matricial 4*4
//*****************DECLARACIÓN DE
FUNCIONES********************************************

char keypad_read(); //Función del teclado


int16 getValueKeypad(int col_cursor,int fil_cursor, int digitos); //Función del teclado
para obtener varios digitos (hata 5 dígitos)

//***************PROGRAMA
PRINCIPAL*********************************************************************************
******************
void main()
{

set_tris_d(0x00); // Ajusta el puerto d como salida


output_high(PIN_D7); //Pone en alto el Pin D7, necesario para activar la LCD
lcd_init(); //Esta función inicializa la LCD
set_tris_b(0x0F); // filas(input) parte baja columnas (output) arte alta
port_b_pullups(0x0F);//Activa solo los pullups de los 4 primeros pines
output_b(0x0F); // filas en 1 y columnas con 0
char key=0; //Variable donde se guardarán los caracteres del teclado
int16 valoringre=0; //Variable donde se guardarán los valores de velocidad y
posición.
char gato ="#"; //Variable char que guarda #
char asterisco ="*"; //Variable char que guarda *

//*********************Variables auxiliares*****************************
int aux=1;
int aux1=0;
int aux2=1;
int aux3=1;
//**********************************************************************

while (aux)//Mientras aux sea 1...


{
MENUPRINCIPAL: //Etiqueta de menú principal
lcd_putc("\f"); //Imprime el menú de selección de motor
lcd_putc(" SELEC. MOTOR"); //Imprime la frase entre comillas
lcd_gotoxy(1,2); //Cambia a la segunda fila de la LCD
lcd_putc("MPP-># SERVO->*");//Imprime las opciones
key=keypad_read(); //Llamo a la función del teclado
aux = strcmp (key, gato); //Comparo la tecla presionada con #
if(!aux) //Si se presionó la tecla #, aux=0
{
aux1=1; //aux1 se vuelve 0, entonces será el motor a pasos
}
else
{
aux = strcmp (key, asterisco); //Si no compara lo que se ingresó con *
if(!aux) //Si se presionó *, aux=0 entonces hará lo siguiente
{
aux1=2; //Si se presionó * aux1 se vuelve 2, entonces será el
servo
}
}

switch(aux1) //Switch para cuando se elige algún motor


{
case 1://*********MOTOR A PASOS******************
//El motor a pasos es de únicamenta 4 posiciones, ya que cada paso es de 90°
//Por ende solo hay las siguientes posiciones: 90, 180, 270 y 360°
while(aux2) //aux2 se declaró con valor de 1 al inicio,
{
BACK: //Etiqueta para regresar aquí
lcd_putc("\f"); //Limpia la pantalla LCD
lcd_gotoxy(1,1); //Se ubica en la posición 1,1
lcd_putc("SELEC POSICION");//Imprime el texto ente comillas
lcd_gotoxy(1,2); //Cambia a la siguiente fila
lcd_putc("NEXT-># MAIN->*");//Imprime el texto de las opciones
valoringre=getvalueKeypad(7,2,3); //Mando llamar la segunda función y
la variable adquiere el valor ingresado
key=keypad_read(); //Llamo a la primer función
aux2 = strcmp (key, asterisco);//Comparo lo que se ingresó en el
teclado con *
if (!aux2) //Si se presionó *, aux2=0
{
goto MENUPRINCIPAL; //Si se presiona * se devulve al menu principal
}
else
{
aux2=strcmp (key, gato); //Si no, aux2 se hará 0 si se presiona #,
saliendo del ciclo
}
}
switch(valoringre) //Switch para las posisciones del motor a pasos y las
velocidades en cada posición
{
case 90: //Posición a 90°
while(aux3)
{
lcd_putc("\f"); //Esta parte es para el menú de la velocidad
lcd_gotoxy(1,1);
lcd_putc("SELEC VELOCIDAD");
lcd_gotoxy(1,2);
lcd_putc("BACK-># MAIN->*");
valoringre=getvalueKeypad(7,2,3); //Mando llamar la
segunda función y la variable adquiere el valor ingresado
key=keypad_read(); //Mando a llamar a la primer función
aux2 = strcmp (key, asterisco);//Comparo lo que se ingresó
en el teclado con *
if (!aux)
{
goto MENUPRINCIPAL; //Si se presiona * se devulve al
menu principal
}
else
{
aux2=strcmp (key, gato);
if(!aux2){goto BACK;}
}
}
switch(valoringre)
{
case(0):output_low(X1); //Al ser la velocidad 0, no se
mueve
case(25): output_high(X1); //Al elegir 90° solo se acciona
una bobina del motor
delay_ms(600); //Y a distintas velocidades
output_low(X1);
case(50):output_high(X1);
delay_ms(300);
output_low(X1);
case(100):output_high(X1);
delay_ms(150);
output_low(X1);
default: break;

}
case 180: //Posición a 180°
while(aux3)
{
lcd_putc("\f"); //Esta parte es para el menú de la velocidad
lcd_gotoxy(1,1);
lcd_putc("SELEC VELOCIDAD");
lcd_gotoxy(1,2);
lcd_putc("BACK-># MAIN->*");
valoringre=getvalueKeypad(7,2,3); //Mando llamar la
segunda función y la variable adquiere el valor ingresado
key=keypad_read(); //Mando a llamar a la primer función
aux2 = strcmp (key, asterisco);//Comparo lo que se ingresó
en el teclado con *
if (!aux)
{
goto MENUPRINCIPAL; //Si se presiona * se devulve al
menu principal
}
else
{
aux2=strcmp (key, gato);
if(!aux2){goto BACK;}
}
}
switch(valoringre)
{
case(0): output_low(X1); //En vel=0 no se mueve
case(25): output_high(X1); //En la posición de 180° es
necesario activar dos bobinas
delay_ms(600);
output_low(X1);
output_high(X2);
delay_ms(600);
output_low(X2);
case(50):output_high(X1);
delay_ms(300);
output_low(X1);
output_high(X2);
delay_ms(300);
output_low(X2);
case(100):output_high(X1);
delay_ms(150);
output_low(X1);
output_high(X2);
delay_ms(150);
output_low(X2);
default: break;
}
case 270: //Posición a 270°
while(aux3)
{
lcd_putc("\f"); //Esta parte es para el menú de la velocidad
lcd_gotoxy(1,1);
lcd_putc("SELEC VELOCIDAD");
lcd_gotoxy(1,2);
lcd_putc("BACK-># MAIN->*");
valoringre=getvalueKeypad(7,2,3); //Mando llamar la
segunda función y la variable adquiere el valor ingresado
key=keypad_read(); //Mando a llamar a la primer función
aux2 = strcmp (key, asterisco);//Comparo lo que se ingresó
en el teclado con *
if (!aux)
{
goto MENUPRINCIPAL; //Si se presiona * se devulve al
menu principal
}
else
{
aux2=strcmp (key, gato);
if(!aux2){goto BACK;}
}
}
switch(valoringre)
{
case(0): output_low(X1); //Si vel=0 entonces no se mueve
case(25): output_high(X1); //Para 270° es necesario
activar 3 bobinas
delay_ms(600);
output_low(X1);
output_high(X2);
delay_ms(600);
output_low(X2);
output_high(X3);
delay_ms(600);
output_low(X3);
case(50):output_high(X1);
delay_ms(300);
output_low(X1);
output_high(X2);
delay_ms(300);
output_low(X2);
output_high(X3);
delay_ms(300);
output_low(X3);
case(100):output_high(X1);
delay_ms(150);
output_low(X1);
output_high(X2);
delay_ms(150);
output_low(X2);
output_high(X3);
delay_ms(150);
output_low(X3);
default: break;
}
case 4: //Posición a 360° o una vuelta
while(aux3)
{
lcd_putc("\f"); //Esta parte es para el menú de la velocidad
lcd_gotoxy(1,1);
lcd_putc("SELEC VELOCIDAD");
lcd_gotoxy(1,2);
lcd_putc("BACK-># MAIN->*");
valoringre=getvalueKeypad(7,2,3); //Mando llamar la
segunda función y la variable adquiere el valor ingresado
key=keypad_read(); //Mando a llamar a la primer función
aux2 = strcmp (key, asterisco);//Comparo lo que se ingresó
en el teclado con *
if (!aux)
{
goto MENUPRINCIPAL; //Si se presiona * se devulve al
menu principal
}
else
{
aux2=strcmp (key, gato);
if(!aux2){goto BACK;}
}
}
switch(valoringre)
{
case(1): output_low(X1); //Vel=0 entonces no se mueve
case(2): output_high(X1); //Para una vuelta es necesario
activar las 4 bobinas
delay_ms(600);
output_low(X1);
output_high(X2);
delay_ms(600);
output_low(X2);
output_high(X3);
delay_ms(600);
output_low(X3);
output_high(X4);
delay_ms(600);
output_low(X4);
case(3):output_high(X1);
delay_ms(300);
output_low(X1);
output_high(X2);
delay_ms(300);
output_low(X2);
output_high(X3);
delay_ms(300);
output_low(X3);
output_high(X4);
delay_ms(300);
output_low(X4);
case(4):output_high(X1);
delay_ms(150);
output_low(X1);
output_high(X2);
delay_ms(150);
output_low(X2);
output_high(X3);
delay_ms(150);
output_low(X3);
output_high(X4);
delay_ms(150);
output_low(X4);
default: break;
}
default: break;

case(2)://********SERVOMOTOR***********************
//El servomotor solo tiene la opción de posición
while(aux2) //aux2 se declaró con valor de 1 al inicio,
{
lcd_putc("\f"); //Limpia la pantalla LCD
lcd_gotoxy(1,1); //Se ubica en la posición 1,1
lcd_putc("SELEC POSICION");//Imprime el texto ente comillas
lcd_gotoxy(1,2); //Cambia a la siguiente fila
lcd_putc("NEXT-># MAIN->*");//Imprime el texto de las opciones
valoringre=getvalueKeypad(7,2,3); //Mando llamar la segunda función y
la variable adquiere el valor ingresado
key=keypad_read(); //Llamo a la primer función
aux2 = strcmp (key, asterisco);//Comparo lo que se ingresó en el
teclado con *
if (!aux2) //Si se presionó *, aux2=0
{
goto MENUPRINCIPAL; //Si se presiona * se devulve al menu principal
}
else
{
aux2=strcmp (key, gato); //Si no, aux2 se hará 0 si se presiona #,
saliendo del ciclo
}
}

int16 Taquito=90;
int16 x=Taquito*1700;
int16 Tortita=x/180;
int16 Quesadilla=Tortita+850;
int16 y=Taquito*1700;
int16 Quesitorta=y/180;
int16 Pastel=19150-Quesitorta;
for(int16 i=1;i<340;i++) // For para 340 repeticiones
{
output_high(pin_c0); // Salida en alto en el pin b0
delay_us(Quesadilla);
output_low(pin_c0);
delay_us(Pastel);
//x=x+5; // El inetardo con el valor en ycremento del tiempo en el valor
en alto
//y=y-5; // decremento del tiempo del valor en bajo

}
}
//case 2://*************SERVO***********************

//******************FUNCION DEL
TECLADO**********************************************
char keypad_read()
{
char const keypad[4][4]={{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'},{'*','0','#','D'}};
int columna = 0;
int fila=-1;
char key=0xFF;
byte bitmask = 0xEF;

// Revisamos si alguna de las lineas en la parte alta esta en estado bajo


// debido a que se ha cerrado un switch en el teclado.
if((!input(PIN_B0)) || (!input(PIN_B1)) ||(!input(PIN_B2)) ||(!input(PIN_B3)))
{
delay_ms(50);
// Escaneamos las columnas una por una para determinar la tecla oprimida
do
{
// al inicio colocamos el pin en estado bajo de la primer columna 1110 1111
output_b(bitmask);
// Guardamos la fila en una variable
switch(input_b() | 0xF0)
{
case 0xFE: fila=0; // 1110 1111
break;
case 0xFD: fila=1; // 1101 1111
break;
case 0xFB: fila=2; // 1011 1111
break;
case 0xF7: fila=3; // 0111 1111
break;
default:
break;
}
if(fila != -1) break; //si ya se encontro la fila se sale del ciclo (do while)
bitmask = (bitmask<<1)|0X01;
// Incrementar el contador de columnas
columna ++;
}
while(columna < 4);
key = keypad[fila][columna];
output_b(0x0F); // todas las columnas con cero
while((!input(PIN_B0)) || (!input(PIN_B1)) ||(!input(PIN_B2))
||(!input(PIN_B3))); //retiene hasta que se libera el boton
return key;
}
return key;
}

//**************Función para obtener varios números del teclado


matricial******************+

int16 getValueKeypad(int col_cursor,int fil_cursor, int digitos){ // los digitos


maximos a utilizar son 5 (32767)

char ch='\0';
char esc = '#'; // tecla de confirmacion/finalizacion
de número
int16 value=0;
int d=col_cursor;
do{
lcd_gotoxy(d,fil_cursor);
lcd_cursor_on(TRUE);
ch = kbd_getc();
if(ch !='\0'&& ch!=esc){ // es diferente del valor default y de la tecla
de finalizacion?
if(ch >= '0' && ch <= '9'){ // es un digito ascii entre 0 and 9?
value = (value * 10) + (ch - '0'); // Se acumula el valor
lcd_gotoxy(col_cursor,fil_cursor); //
printf(lcd_putc,"%Ld",value);
d++;
if(d == (col_cursor + digitos)) {
lcd_cursor_on(FALSE);
delay_ms(1000);
}
}
}
}while(ch!=esc && (d < (col_cursor + digitos))); // el numero 10 indica que el
numero Maximo tiene 3 digitos
lcd_cursor_on(FALSE);
return value;

}
Interfaz.h
#include <18F4550.h>
#device ADC=16

#FUSES XT
#FUSES MCLR
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18)
used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing
mode disabled (Legacy mode)

#use fast_io(B)
#use fast_io(D)
#use fast_io(C)

#use FIXED_IO (A_outputs=PIN_A0,PIN_A1,PIN_A2,PIN_A3)


#define X1 PIN_A0
#define X2 PIN_A1
#define X3 PIN_A2
#define X4 PIN_A3

/*#define LCD_ENABLE_PIN PIN_D6 //Definición de los puertos que se conectan


a la LCD
#define LCD_RS_PIN PIN_D4
#define LCD_RW_PIN PIN_D5
#define LCD_DATA4 PIN_D0
#define LCD_DATA5 PIN_D1
#define LCD_DATA6 PIN_D2
#define LCD_DATA7 PIN_D3*/

#use delay(crystal=4000000)
Conclusión:
Actualmente hay varias familias de microcontroladores, de diferentes
fabricantes, que permiten hacer más o menos cosas con más o menos
facilidades. Los microcontroladores se conectan al mundo real con
componentes electrónicos que miden temperatura, o la cantidad de luz que
llega a un cuarto, entre miles de funciones que actualmente se pueden realizar
en la electrónica moderna. Estos microcontroladores son programados para que
estén contínuamente ejecutando alguna tarea y tomen acciones al ver los
valores que le entregan los componentes electrónicos que usan. Los lenguajes
de programación que usan estos chips son variados, pero predomina el C, como
lenguaje principal, aunque hay Pascal, Sketch, Processing y BASIC, entre muchos
otros.

Bibliografía.
Christian Agustín Vázquez Villanueva. (4th May 2014). Control de motor a pasos
unipolar con un microcontrolador pic. 5 de abril del 2018, de Blogspot Sitio web:
http://roboticaycontrol.blogspot.mx/2014/05/control-de-motor-pasos-unipolar-con-
un.html

willynovi. (01 de Febrero de 2013). Código C control de servomotor (GRADOS). 5


de abril del 2018, de TODOPIC Sitio web:
http://www.todopic.com.ar/foros/index.php?topic=40055.0

Rubén. (Jul 26, 2013). Teclado Matricial con PIC. 5 de abril del 2018, de
GeekFactory Sitio web: https://www.geekfactory.mx/tutoriales/tutoriales-
pic/teclado-matricial-con-pic/

Jesus Ruben Santa Anna Zamudio. (Ago 2, 2014). Pantalla LCD 16×2 con PIC. 5
de abril del 2018, de GeekFactory Sitio web:
https://www.geekfactory.mx/tutoriales/tutoriales-pic/pantalla-lcd-16x2-con-
pic-libreria/

You might also like