Professional Documents
Culture Documents
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).
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).
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)
void main(void)
{
while (true)
{
// m =1ms/180
void main()
{
while(true){
output_b(0x00);
delay_ms(1000);
}
else if ((input(PIN_A0) == 0)) // esta apagado
{
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
//***************PROGRAMA
PRINCIPAL*********************************************************************************
******************
void main()
{
//*********************Variables auxiliares*****************************
int aux=1;
int aux1=0;
int aux2=1;
int aux3=1;
//**********************************************************************
}
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;
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 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
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/