75347569-hi-tech

109

Upload: gabriela-o

Post on 13-Aug-2015

268 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 75347569-Hi-Tech
Page 2: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

2 Para Microcontroladores PIC16 100 % C!!!

Tabla de contenido

Introducción ........................................................................................................................................... 3

1. Programas a usar en este curso.................................................................................................. 4

1.1 Hoja de proyectos ................................................................................................................. 5

1.2 Entorno de un Programa ...................................................................................................... 8

1.2.1 Tipos de Variables ......................................................................................................... 8

1.2.2 Formato Radix ................................................................................................................ 9

1.2.3 Expresiones .................................................................................................................... 9

1.2.4 Instrucciones ................................................................................................................ 10

1.3 Inicializando nuestro Programa .......................................................................................... 13

Programas Sencillos ............................................................................................................................... 14

1.4 Parpadeo .............................................................................................................................. 14

1.5 Display de 7 segmentos ..................................................................................................... 17

1.6 Usando el USART ............................................................................................................... 21

1.7 Interrupciones por Timers ................................................................................................... 27

1.7.1 Uso del Timer0 y USART ............................................................................................ 30

1.8 Uso del PWM (Pulse Width Module) ................................................................................. 33

1.9 Valores ADC (Convertidor de Análogo-Digital)................................................................. 36

2.0 Uso del LCD ........................................................................................................................ 43

2.1 Lector de Voltaje ................................................................................................................. 48

2.2 Selector de canal análogo con Teclado 4x4 ..................................................................... 51

2.3 PWM a salida análogo ........................................................................................................ 57

2.4 Medidor de voltaje por software ......................................................................................... 61

2.5 Reloj con Displays ............................................................................................................... 65

2.6 Control de Servo ................................................................................................................. 75

2.6.1 Software para control de servo ................................................................................... 83

2.7 Control de velocidad ............................................................................................................ 88

2.7.1 Software para labview ................................................................................................. 91

2.8 Matriz de Led 8x24 (Contador de 000 a 999) ................................................................... 98

Gracias! .......................................................................................................................................... 109

Page 3: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

3 Para Microcontroladores PIC16 100 % C!!!

Introducción

Este curso ofrece a los alumnos o maestros que estén involucrándose en la

programación de microcontroladores PIC, y algunas veces no se sabe que

compiladores en C se pueden usar ya que por internet se puede encontrar una gran

variedad de compiladores en C, y es muy importante elegir cuál de estos es más

flexible a la hora de programar. El compilador Hi tech es un buen compilador para no

empezar a programar ya que es un programa para los profesionales en la

programación, ya que no ofrece librerías, ni drivers para nuestros proyectos, en este

compilador se necesita crear las librerías de casi todos los módulos que contiene el

micro, mientras MikroC es un buen compilador para empezar, ya que se basa más la

programación a nivel educacional, ya que ofrece más librerías de LCD, GLCD, MMC

CARD, PWM entre varios y la programación se hace más sencilla, pero la desventaja

es que es un compilador ya estructurado y no se puede hacer mucho en las librerías ya

que si se quiere modificar alguna de ellas es muy difícil. Ahora el compilador más

famoso por internet ya que ofrece un sinfín de proyectos programados con el

compilador PIC C COMPILER por la compañía CCS, este programa es uno de los

mejores ya que ofrece librerías muy útiles y versátiles, gracias al internet se puede

encontrar varios ejemplos, es gran compilador recomendado por un servidor.

Page 4: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

4 Para Microcontroladores PIC16 100 % C!!!

1. Programas a usar en este curso

El primer programa que usaremos en este curso es el más conocido entre los

programadores de microcontroladores PIC.

1.-MPLAB v8.53

Se puede descargar gratuitamente en la página de www.microchip.com

2.-Hi tech Compiler for PIC10/12/16

Se puede descargar el lite mode que ofrece gratis solo la única desventaja que la

optimización es desactivada, www.htsoft.com

3.-Proteus 7.x

Se puede bajar versión demo en la página www.labcenter.co.uk

Page 5: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

5 Para Microcontroladores PIC16 100 % C!!!

1.1 Hoja de proyectos

Para la creación de nuestro primer programa se debe de crear un espacio de trabajo, abrimos

nuestro programa MPLAB, y después dirigimos nuestro ratón donde dice <proyect> y después

< proyect Wizard>

Aparcera una ventana, en esta venta solo es un saludo, presionamos <next>, después

elegimos que microcontroladores usaremos en este caso usaremos el microcontrolador

PIC16F886 y presionamos <next>.

Page 6: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

6 Para Microcontroladores PIC16 100 % C!!!

Ahora nos pedirá el compilador que usaremos para programar el micro, en este caso usaremos

el compilador Hi tech y presionamos <next>.

Después usaremos guardaremos el proyecto en la localidad que nosotros conocemos, y

después presionamos <next>, <next> y <finish>

Ahora que hemos creado el lugar de trabajo, presionamos en la hoja en blanco en la parte

superior izquierda, y guardamos esa hoja en la misma localidad y agregamos la opción de <add

file to proyect> y listo, has creado el lugar de trabajo, cada vez que vallamos hacer un proyecto

se tiene que hacer los pasos anteriores.

Page 7: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

7 Para Microcontroladores PIC16 100 % C!!!

Page 8: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

8 Para Microcontroladores PIC16 100 % C!!!

1.2 Entorno de un Programa

Antes de empezar a programar y simular hay que tener en cuenta los siguientes conocimientos.

*Conocimiento de algún lenguaje de programación

*Conocimiento en electrónica análogo y digital

Para entender la programación en C para microcontroladores se dará una pequeña

actualización para aquellos que aun no saben la programación de alto nivel.

1.2.1 Tipos de Variables

El compilador HI-TECH Compiler soporta tipos de información básica con 1, 2,3 y 4 tamaño de

byte. Todos los tipos de milti-byte siguen por lo menos el formato del primer byte más

significante. El tamaño de valores WORD tienen el byte más significante en la dirección más

baja y DOUBLE WORD tiene el byte y WORD en el primer formato más significante en la

dirección más baja.

En la tabla siguiente se explica:

Page 9: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

9 Para Microcontroladores PIC16 100 % C!!!

1.2.2 Formato Radix

Cualquier constate integral tendrá un tipo con la cual es el tipo más pequeño que puede

mantener el valor sin desbordar. El sufijo l o L puede ser usado con la contante para indicar que

debe ser asignado también un tipo SIGNED LONG o UNSIGNED LONG tiene un sufijo u o U

podría usarse con la contante para indicar que debe ser asignado un tipo sin signo. Y ambos I o

L y u o U poden ser usados para indicar un tipo UNSIGNED LONG INT.

Para los valores de tipo carácter se pueden encerrar con apostrofes ‘ por ejemplo:

‘A’

Una variable de tipo carácter de varios elementos no pueden usar este tipo de apostrofes ya

que son caracteres de tipo string, que es una cadena de caracteres, para usar este tipo de

variable string se debe de hacer como el ejemplo:

char cadena[ ]=”HOLA MUNDO”;

1.2.3 Expresiones

Las operaciones y directivas son comprimidas de expresiones. Expresiones pueden ser hechas

de número, identificadores, cadenas de caracteres y operadores. Los operadores pueden ser

unitarios (un operador ej. not) o binario (2 operadores ej. +). Los operadores permitidos están

en la tabla siguiente.

Page 10: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

10 Para Microcontroladores PIC16 100 % C!!!

1.2.4 Instrucciones

while(1){ //accion}

Esta es una instrucción de “Mientras sea verdad” se puede hacer ciclos perpetuos o con un fin

por ejemplo:

While(var<10){

Var++;

}

do{ //acción }while(1);

Esta es una instrucción parecida a la de arriba la diferencia es que al menos una vez entrara al

ciclo y al último se hará la comparación por ejemplo

Page 11: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

11 Para Microcontroladores PIC16 100 % C!!!

do{

Var++;

}while(var<3);

If(//comparación) {//acción}

[else if()]{//accion}

[else {//accion}]

Esta sentencia compara si es cierta entra al ciclo, ejemplo:

Var=2;

If(var==1){

//acción

}else if(var==2){

//Aquí entra ya que es verdad la comparación

}else{

//acción

}

De otra forma se puede desarrollar estas comparaciones, es muy común usar la instrucción

Switch (variable){

Page 12: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

12 Para Microcontroladores PIC16 100 % C!!!

Case 0: //acción

Break;

Case 1; //acción

Break;

Case…

Default: //acción

Break;

}

Como vemos si la variable tiene un valor fuera de rango de los “case” entonces lo que se

ejecutara será lo que contenga en “default”, pero si es lo contrario si la variable contiene un

valor de 0 entonces entrara hacer la acción en el “case 0”.

Para desarrollar un ciclo contable y fácil de hacer se usa:

For(variable=0;variable<100;variable++){

//acción

}

Se usa un ciclo for, como vemos en el ejemplo la variable en inicializada cuando entra por

primera vez al ciclo, después comparara en este caso la variable es menor de 100, si es así

entonces realiza la acción y después suma uno a la variable.

Page 13: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

13 Para Microcontroladores PIC16 100 % C!!!

1.3 Inicializando nuestro Programa

Para empezar hacer nuestro programa siempre hay que tener en cuenta algunos puntos

importantes.

En nuestra hoja de trabajo siempre se incluirá la librería del Microcontrolador en este caso es

estándar ya que solo debemos de colocar la línea:

#include<htc.h> //Incluimos librería del micro a usar

Después se debe de configurar las __CONFIG, que son la configuración del procesador. Se

debe de tomar en cuenta que siempre se debe de configurar lo más importante.

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

Después si usamos un cristal interno o externo se debe de especificar a qué velocidad

va a trabajar el microcontrolador.

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

Estas tres líneas anteriores es lo básico para tener configurado correctamente nuestro

programa y microcontrolador.

Page 14: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

14 Para Microcontroladores PIC16 100 % C!!!

Programas Sencillos

1.4 Parpadeo

Al inicio de nuestro programa inicializamos el puerto B como salida, con la instrucción

TRISB, después se debe de desactivar las interrupciones, después para hacer el ciclo

perpetuo se debe de usar el while.

El esquema a manejar es el siguiente:

Material a usar:

1 MCU PIC16F886

1 LED

1 Resistencia de 10Kohm

1 Resistencia de 330ohm

Page 15: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

15 Para Microcontroladores PIC16 100 % C!!!

Programa del Micro:

#include<htc.h> //Incluimos libreria del micro a usar

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

void main(void){

//Puerto B como salida

TRISB=0x00;

//Comparadores desactivados

// CMCON=0x07;

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

__delay_ms(10);

RB0=0;

__delay_ms(10);

RB0=1;

}

}

Page 16: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

16 Para Microcontroladores PIC16 100 % C!!!

Al simular se observa que tiene una frecuencia de parpadeo 50Hz

Page 17: 75347569-Hi-Tech

1.5 Display de 7 segmentos

Este ejemplo demuestra como usar el display de 7 segmentos, para empezar debemos de

sacar los valores necesarios para mostrar cada número por ejemplo, para mostrar el valor de

cero, se debe de prender simultáneamente los led,

A,B,C,D,E,F

Para poner a uno cada uno de ellos se tiene que usar la siguiente forma, ponemos las letras

que empiecen al revés F,E,D,C,B,A y cada uno será un UNO pero solo tenemos 6 valores y

necesitamos 2 más para que sea un byte completo, entonces los que falten simplemente

estarán en cero. Hay que tomar en cuenta si nuestro display es catodo o anodo ya que puede

afectar que valores deben de ser cero o unos.

00111111 = 0 en el display catodo pero como usamos un anodo común cambian lo valores

11000000

Y Asi para todos los números, hasta el 9.

A

B

C

D

E

F

Page 18: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

18 Para Microcontroladores PIC16 100 % C!!!

Después simplemente todos esos valores lo ponemos a una arreglo de un solo byte

Unsigned char arrey[]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,

0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};

Ahora simplemente agregamos una variable mas para el uso del For.

for(x=0;x<10;x++){ //Ciclo for

PORTC=mostrar[x]; //Saca el valor que correponde al puerto C

DELAY1S(); //LLama a la funcion de retardo de 1seg

}

ESTE SERIA UN ALGORITMO MUY SIMPLE.

La función “DELAY1S” es un retardo de un segundo esta función se tuvo que hacer, ya que el compilador no ofrece tanto retardo para una frecuencia de 4Mhz.

Entonces se desarrolla funciones que requieran mas temporización.

//Funcion de retardo de 1 seg

//1/10mS = 100 repeticiones para obtener un 1seg

void DELAY1S(void){

//Varibale local entonces solo se usa en esta funcion

unsigned char time;

for(time=0;time<100;time++){

__delay_ms(10);

}

}

Page 19: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

19 Para Microcontroladores PIC16 100 % C!!!

Programa que contiene el Microcontrolador.

#include<htc.h> //Incluimos libreria del micro a usar

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

//Arreglo de 1 byte que contiene la numeracion

//para que se muestre en un Display de 7 SEG

unsigned char mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,

0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};

//Variable para el ciclo FOR

unsigned char x;

//Funcion de retardo de 1 seg

//1/10mS = 100 repeticiones para obtener un 1seg

void DELAY1S(void){

//Varibale local entonces solo se usa en esta funcion

unsigned char time;

for(time=0;time<100;time++){

__delay_ms(10);

}

}

void main(void){

//Puerto B como salida

TRISC=0x00;

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

for(x=0;x<10;x++){ //Ciclo for

PORTC=mostrar[x]; //Saca el valor que correponde al puerto C

DELAY1S(); //LLama a la funcion de retardo de 1seg

Page 20: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

20 Para Microcontroladores PIC16 100 % C!!!

}

}

}

Simulación

Page 21: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

21 Para Microcontroladores PIC16 100 % C!!!

1.6 Usando el USART

Ya que el compilador Hi-tech no ofrece librerías listas para usar los módulos de comunicación,

adc, pwm, etc. Se ha creado la librería para el uso del USART integrado

que contiene el microcontrolador. Para el uso de la librería simplemente

copiamos la carpeta “libUSART” y la pegamos donde hemos creado

nuestro proyecto. Y después agregamos en nuestro espacio de trabajo

los archivos siguientes.

Y listo para usar el USART del microcontrolador.

Nota.- Esta Liberia solo funciona para micros que tienen integrado el USART (hardware) y no

que sean simulados (por software)

Nuestro primer proyecto con el USART será mandar un mensaje de “HOLA MUNDO” utilizando

la librería antes mencionado.

Tenga en cuenta que para la realización de este circuito se debe de contar con un integrado

especial para transformar los niveles RS232 a TTL, el CI que vamos a usar será MAX232.

Las conexiones de este circuito será el siguiente:

Page 22: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

22 Para Microcontroladores PIC16 100 % C!!!

Si se cuenta con una laptop, recuerde adquirir un cable de USB<->SERIAL para poder hacer la

simulación.

Un diagrama sencillo para entender la conexión de PC a PIC seria;

Para programar el microcontrolador para el uso de este modulo, en sencillo, simplemente

incluimos nuestra librería, en este caso el archivo “.H” después de haber incluido el archivo que

especifica nuestro Microcontrolador. Después como un pin del Puerto C es el transmisor y el

otro receptor, entonces debemos de definir los pines de entrada y salida.

Buscamos la velocidad de comunicación (baudios) con la formula:

����� � � ����� ∗ 16� � 1

La variable “value” es el valor que necesitamos escribir en la función de openUSART();

PC MAX232 PIC

Page 23: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

23 Para Microcontroladores PIC16 100 % C!!!

Explicación de funciones de la función openUSART (unsigned char, interrupciones RX, TX);

UNSIGNED CHAR es un valor entero de 0 a 255 donde especifica que valor necesitamos con

respecto a la frecuencia de trabajo. Para saber el valor se usa la formula antes vista.

RX, TX especifica si queremos interrupciones de Recepción o Transmisor.

Por ejemplo queremos una velocidad de 9600 bits x segundo =9600baud y usamos una

frecuencia de 4Mhz, despejamos la formula anterior;

����� � � 4�ℎ�9600 ∗ 16� − 1

Value=25

Este valor se debe de cargar a la función openUSART (25,OFF,OFF);

Programa que contiene nuestro micro;

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

#include"libUSART/usartdr.h" //Libreria creada para uso del usart

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 8MHZ

Unsigned char letra[]={“HOLA MUNDO”};

/////////////////////////////////////////////////

Page 24: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

24 Para Microcontroladores PIC16 100 % C!!!

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISA=0x07;

TRISC=0x80; //RC7=RX,RC6=TX

//Configuracion del USART

OpenUSART(25,OFF,OFF); //value=(FOSC/(baud*16))-1

//SIN INTERRUPCIONES

//a 9600 baudios

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

For(x=0;x<10;x++){

Putch(letra[x];

}

while(1);

}

Recuerde usar el CI max232 para la conexión PC<-<MAX>->PIC

Page 25: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

25 Para Microcontroladores PIC16 100 % C!!!

Ahora bien si deseamos no usar el ciclo for ni una variable que contenga el texto, podemos

usar la instrucción “prinft(string)” simplemente incluimos en nuestro proyecto el siguiente

archivo, <stdio.h>.

Entonces modificamos nuestro programita.

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

#include"libUSART/usartdr.h" //Libreria creada para uso del usart

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 8MHZ

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISA=0x07;

TRISC=0x80; //RC7=RX,RC6=TX

//Configuracion del USART

OpenUSART(25,OFF,OFF); //value=(FOSC/(baud*16))-1

//SIN INTERRUPCIONES

//a 9600 baudios

Page 26: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

26 Para Microcontroladores PIC16 100 % C!!!

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

printf("hola mundo");

while(1);

}

Este método es muy simple, pero conlleva a usar mas memoria de la forma anterior, se

recomienda hacer una función simple, para realizar la misma función pero el uso de

memoria que sea menor.

Page 27: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

27 Para Microcontroladores PIC16 100 % C!!!

1.7 Interrupciones por Timers

Ahora viene un tema muy interesante, interrupciones por timer0, este tema se debe de aclarar

muy concretamente ya que es un modulo muy complejo para entender, pero primero que nada

vallamos a definir ¿Que es una interrupción?.

Es un evento que cambia el proceso a otro lugar y cuando este proceso termine regresa al

estado actual.

Ej.

Cuando estamos hablando con un amigo, y de repente suena el teléfono, ¿Qué hacemos?

Interrumpimos la plática y después contestamos el teléfono, ahí estamos haciendo otra

actividad, pero al terminar de hablar por teléfono, regresamos con nuestro amigo y hablamos

donde nos quedamos antes de que el teléfono sonara.

Las interrupción en los microcontroladores es prácticamente igual, ya que cuando el micro este

haciendo un proceso y de repente surge una interrupción este guarda en una memoria el lugar

donde se había quedado y atiende la interrupción y después regresa a donde se había

quedado.

Para entender mejor este aspecto ya en la práctica, el PIC16F886 tiene timers que pueden ser

usados como contadores de eventos externos o internos, en este caso usaremos internos.

Además los timers pueden variar a su tamaño ya que pueden ser de 8,16 bits,

Cuando un timer es configurado para que overflow (desbordado) tenemos una interrupción.

En el microcontrolador tenemos el timer 0,1,2, el timer0 es de 8 bit en los PIC16 mientras en los

PIC18 pueden ser de 8 o 16 bit, este timer puede actuar como contador interno o externo, en el

Page 28: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

28 Para Microcontroladores PIC16 100 % C!!!

interno tenemos que hay que contar los pulsos de oscilador/4. Se puede configurar este timer0

para que ocurra una interrupción. En este caso que sea interno, por ejemplo.

Queremos que haga una interrupción cada 3mS.

Entonces usaremos una fórmula para configurar y saber qué valor del timer0 debemos de

cargar cada vez que ocurra una interrupción.

����� = � 4��� ∗ � ����� ∗ (256 − ��$0)

Prescalar es un valor que puede ser cargado de 2, 4, 8, 16, 32, 64, 128, 256 el TMR0 es el

valor que debemos de encontrar entonces simplemente despejamos.

��$0 = 256 − { '����( 4��) ∗ � ����� }

TMR0=244 //VALOR QUE SE DEBE DE CARGAR AL TIMER0 CADA VEZ QUE SE

OVERFLOW

Se nota que la interrupción es cada 3mS entonces sumando el voltaje positivo y cero es igual a

6mS, entonces estamos generando una frecuencia de 162Hz aprox.

Page 29: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

29 Para Microcontroladores PIC16 100 % C!!!

Vemos el Diagrama a usar

El programa que ahora haremos es el siguiente para comprobar cómo funciona la interrupción

por timer0.

#include<htc.h> //Incluimos libreria del micro a usar

#include"libTIMER0/OpenTimer0.h"//Incluimos libreria de timer0

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

void main(void){

TRISB=0x00;

ANSELH=0x00;//Desactivamos PORTB como entrada analoga

OpenTIMER0(prescalar_256,ON);

//Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer0)

// 500uS=tiempo maximo

// timer0=+256-{tiempo/[(1/(FOSC/4))*preescalar]}

TMR0=244;

GIE=1; //INTERRUPCIONES GLOBALES ACTIVADAS

PEIE=1; //ACTIVA INTERURPCIONES POR PERIFERICOS

Page 30: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

30 Para Microcontroladores PIC16 100 % C!!!

while(1);

}

////////////////////////////////////

///Interrupcion Por timer0

////////////////////////////////////

static void interrupt

isr(void){

if(T0IF){

RB0=~RB0;//Cmabia de estado cada vez ejecuta esta accion //amado TOGGLE

T0IF=0; //Camabia flag de interrupcion

}

TMR0=244;//Carga otra vez el timer 0

}

1.7.1 Uso del Timer0 y USART

Este ejemplo es muy sencillo, utilizaremos la interrupción por TIMER0, para que se desborde

cada ~65mS que es el tiempo máximo que puede desbordar el TIMER0, después al tener 15

interrupciones cumplidas pasara aproximadamente 1 segundo, después sumara +1 a la

variable que se mostrara por el USART.

Programa principal del PIC16f628A:

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

#include"timer0/OpenTimer0.h"//Incluimos libreria de timer0

#include"lib/usartdr.h" //Incluimos libreria del serial

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

////////////////////////////////////////////

//Variables a usar

Page 31: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

31 Para Microcontroladores PIC16 100 % C!!!

////////////////////////////////////////////

unsigned char cont=0,seg=0;

unsigned int numero;

void main(void){

TRISB=0;

OpenTIMER0(prescalar_256,ON);

//Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer1)

// 65mS=tiempo maximo

// timer0=+256-{tiempo/[(1/(FOSC/4))*preescalar]}

TMR0=2;

//Configuracion del USART

OpenUSART(25,OFF,OFF); //value=(FOSC/(baud*16))-1

//SIN INTERRUPCIONES

//a 9600 baudios

GIE=1; //INTERRUPCIONES GLOBALES ACTIVADAS

PEIE=1; //ACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

if(seg){ //Ha lledo a 1 seg

printf("Contando = %u\r\n",numero++); //Imprime y suma +1

seg=0; //Reset flag de segundo

}

}

}

////////////////////////////////////

///Interrupcion Por timer0

////////////////////////////////////

static void interrupt

isr(void){

if(T0IF){ //Ha surguido una interrupcion?

cont++; //Cuenta mas +1

if(cont==15){ //Ha llegado a 1 seg?

seg=1; //Pone flag de segundo

cont=0; //Vuelve a contar

}

T0IF=0; //Rest falg de interrupcion por timer0

TMR0=2; //Carga timer0 para dar 65mS*15=1seg

}

}

El esquema manejar es el siguiente:

Page 32: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

32 Para Microcontroladores PIC16 100 % C!!!

Nota: Use siempre el circuito MAX232 para adaptar los niveles rs232 a TTL cada vez que use

una comunicación serial.

Page 33: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

33 Para Microcontroladores PIC16 100 % C!!!

1.8 Uso del PWM (Pulse Width Module)

El PIC16F628A contiene un canal llamado CCP, que puede funcionar como:

Comparador

Captura

PWM

Para configurar el PWM, se ha creado una librería para manejar tal canal en modo PWM, la

función siguiente contiene solo un parámetro para calcular, que es el periodo, el periodo

simplemente es el tiempo que deseamos.

void OpenPwm(const unsigned char periodo);

El periodo se puede calcular con una simple formula.

+,� �� � = (�� � + 1) ∗ � 4��� ∗ (��$2 � ����� )

PWM period = Tiempo propuesto por nosotros

Periodo= El valor necesario para cargar en nuestra formula.

Tosc = 1/(FOSC/4)=4/TOSC

TMR2 preescalar = Es el valor que se ha propuesto para el timer2.

Ahora que hablamos del timer2 es necesario agregar la librería para trabajar con el timer2, este

timer2 es un contador de 8-bit parecido al timer0 pero simplemente contiene 3 preescalares.

#define PRESCALE_1

#define PRESCALE_4

#define PRESCALE_16

Page 34: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

34 Para Microcontroladores PIC16 100 % C!!!

La función del timer2 se debe de agregar antes de poner la línea de PWM.

Un ejemplo sencillo es hacer uso del PWM y que tenga una frecuencia de 1Khz teniendo como

prescalar en el timer2 un valor de 16 y un cristal interno corriendo a 4Mhz, si despejamos la

fórmula para obtener el número “periodo” tenemos que:

�� � = / 1� ∗ ( 4��) ∗ � ����� 0 − 1

�� � = / 111ℎ� ∗ ( 44�ℎ�) ∗ 160 − 1

Tenemos que debemos de cargar el valor de 61 a la función de PWM.

OpenTimer2(PRESCALE_16);

OpenPwm(61);

Ahora tenemos una función de cambiar el ancho de pulso que es:

void PwmDuty(unsigned char duty);

duty= Es un valor unsigned char de 0 a 255, que corresponde de 0 a 100% de ancho de pulso.

Ahora bien si queremos un ancho de pulso de 50 % a 1kHz es simplemente cargar el valor

255/2=127.

PwmDuty(127);

Esto corresponde a usar un valor de 8 bit, mas adelante se usara 10-bit para mejor precisión de ancho de pulso.

Programa sencillo para uso del PWM.

Page 35: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

35 Para Microcontroladores PIC16 100 % C!!!

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

#include"timer2/timer2.h"//LLama la libreria de usar Timer2

#include"pwmdr/pwm.h"//LLama libreria para usar PWM

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISB=0;

//Configuramos TIMER 2 para PWM

OpenTimer2(PRESCALE_16);

//Usamos libreria PWM

OpenPwm(61);

//PWM period = [(period ) + 1] x 4 x Tosc x TMR2 prescaler

//PWM period = [(255)+1]x(4/4Mhz)x16

// [.001s/((4/4Mhz)*16)]-1=period

// [1/(f*(4/Tosc)*preescalar)]-1=period

PwmDuty(127); //255=100% 127=50% de duty

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1);

}

Page 36: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

36 Para Microcontroladores PIC16 100 % C!!!

La simulación tenemos:

1.9 Valores ADC (Convertidor de Análogo-Digital)

El convertidor Análogo-Digital convierte un valor de voltaje a un numero entero de 8 o 10-bits, si

es un valor de 8 bit corresponde a un valor de 0 a 255, y si es de 10 bit entonces es de 0 a

1024.

La exactitud lo darán los bits, mas bits que tenga un ADC entonces tendremos un valor más

cercano al valor que hemos medido.

Por ejemplo el ADC del PIC16F886 puede ser configurado de 8 o 10 bit, usaremos uno de 8 bit,

que mida un voltaje de 2.456 volts, el ADC hace lo siguiente:

Si tenemos como referencia el valor de la alimentación en este caso con +5 y masa, entonces

tenemos un rango de 0 a 5 Volts,

� � = ��� �� � ∗ 2555 = 2.456 ∗ 2555

� � = 125.256 ≅ 125

Page 37: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

37 Para Microcontroladores PIC16 100 % C!!!

Como vemos se ha redondeado ya que lo que entrega el ADC es un valor entero de tipo

unsigned char , pero ahora usaremos uno de 10 bit;

� � = ��� �� � ∗ 2555 = 2.456 ∗ 10245

� � = 502.9888 ≅ 503

Para comparar se hace las operaciones inversamente:

�� � 8 ��': ��' = � � ∗ 5255 = 125 ∗ 5255

��' = 2.450

�� � 10 ��': ��' = � � ∗ 51024 = 503 ∗ 51024

��' = 2.456

Como vemos al usar un convertidor de 8 bit sea a perdido 6 mVolts, mientras el convertidor de

10 bit no se perdió nada ya que el valor se encuentra en rango.

Las operaciones anteriores lo hace automáticamente el convertidor y nosotros simplemente

pedimos el valor obtenido.

La función que vamos a usar para la configuración del ADC es la siguiente:

void OpenADC(const unsigned char FOSC,const unsigned char an0,const unsigned char an1);

Donde:

FOSC = tiempo de conversion, se puede tomar un valor de los siguientes:

FOSC_2

FOSC_8

Page 38: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

38 Para Microcontroladores PIC16 100 % C!!!

FOSC_32

FOSC_FRC *Por lo general se usa un tiempo preestablecido a 2u a 6uS

an0 = Que canales vamos a usar como ADC del puerto A

//an0

#define AN0 0X01

#define AN0_AN1 0X03

#define AN0_AN2 0X07

#define AN0_AN3 0X0F

#define AN0_AN4 0X1F

#define AN0_AN6 0X7F

#define AN0_AN7 0XFF

an1= Los canales de puerto B

//an1

#define AN8 0X01

#define AN8_AN9 0X02

#define AN8_AN10 0X07

#define AN8_AN11 0X0F

#define AN8_AN12 0X1F

#define AN8_AN13 0X3F El canal ADC contiene un multiplexor que hace la función de establecer el canal por el

cual pedimos el ADC. En la figura siguiente se muestra como está constituido el

convertidor análogo-digital:

Sacado del Datasheet del Microcontrolador PIC16F886

Selección del Canal

Cuando se cambia a un canal es necesario hacer un

retardo especifico, esto puede ser uS, o mS.

Por ejemplo:

Delay_mS(1); //Retardo de 1 milisegundo

Page 39: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

39 Para Microcontroladores PIC16 100 % C!!!

Seleccionar canal (CANAL);

Para hacer esta acción se ha creado una función que pueda cambiar el canal muy fácilmente.

void channelADC(unsigned char ch);

ch = este valor puede entrar de 0 a 15, que corresponde al máximo de canales que puede tener

en este caso el Microcontrolador PIC16F886.

Ten en cuenta que si usted establece solo dos canales, se refiere que simplemente usara un

rango de 0 a 1, y así sucesivamente.

Después de seleccionar el canal se debe de empezar la conversión, en este caso se ha creado

una función de “startADC”

void startADC(void);

Después de empezar el ADC funcionar se debe de esperar hasta que este termine, usando una

instrucción adicional que el usuario debe de usar.

while(GODONE!=0);

Esto hace un ciclo hasta que termine la conversión, al terminar la conversión usted ya puede

leer el dato, por default tiene un valor de 10 bit, entonces necesitamos una variable 16 bit para

guardar el valor (unsigned int).

Se ha creado una función de leer dato análogo.

unsigned int readADC()

Este función es llamada y devuelve un valor de 10 bit de un valor análogo obtenido. Ej.

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

Page 40: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

40 Para Microcontroladores PIC16 100 % C!!!

#include"libUSART/usartdr.h" //Libreria creada para uso del usart

#include"libADC/adcdr.h"//Inluimos libreria de trabajo con ADC

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

unsigned int adc[3];

unsigned char y;

///////////////////////////////

//Funcion de 1 segundo

////////////////////////////////

void Delay1S(void){

unsigned char x;

for(x=0;x<100;x++){

__delay_ms(10);

}

}

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISA=0x07;

TRISC=0x80; //RB1=RX,RB2=TX

//Configuracion del USART

OpenUSART(51,OFF,OFF); //value=(FOSC/(baud*16))-1

//SIN INTERRUPCIONES

Page 41: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

41 Para Microcontroladores PIC16 100 % C!!!

//a 9600 baudios

//Configuracion del ADC

OpenADC(FOSC_FRC,AN0_AN2,OFF);

//Oscilador interno

//AN0 a AN2 como entrada analogo

//PORTB sin analoga

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

Delay1S(); //Retardo de 1 SEG

for(y=0;y<3;y++){ //CICLO para leer las 3 entradas analogas

channelADC(y);

__delay_ms(1);

startADC();

while(GODONE!=0);

adc[y]=readADC();

}//imprime el valor de cada entrada

printf("AN0= %u | AN1= %u | AN2= %u\r\n",adc[0],adc[1],adc[2]);

}

}

El ejemplo anterior funciona de la siguiente manera, configuramos nuestro ADC que

trabaje con un oscilador interno, con entradas análogas que empieza de AN0, AN1,

AN2, también configuramos el USART que trabaje a una velocidad de 9600 baud, al

empezar el programa principal, este selecciona el canal que vamos a usar con un ciclo

for, después hay un retardo de 1mS después empieza la conversión y esperamos a

que termine y después con un arreglo de datos de tipo int guarda el dato análogo.

Al salir del ciclo for el arreglo contiene las 3 lecturas de los 3 canales análogos, al tener

los datos estos son visualizados con printf();

Page 42: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

42 Para Microcontroladores PIC16 100 % C!!!

Mostramos la simulación:

Page 43: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

43 Para Microcontroladores PIC16 100 % C!!!

2.0 Uso del LCD

Los LCDs pueden adherir una gran variedad de aplicaciones en términos de promover

una interfaz para el usuario que este manejando un aparato, como puede ser debuger

de una aplicación, simplemente dar una buena vista a nuestro proyecto. El LCD más

común es el Hitachi 44780, el cual da una simple interfaz entre el procesador y un LCD.

Usando este interfaz tampoco es tan simple para nuevos diseñadores o programadores

porque es difícil encontrar una buena documentación sobre el este interfaz, inicializar

el interfaz puede ser un problema.

Para el uso sencillo del LCD se ha creado funciones para manejar estos tipos de

display, basándose en la información y tabla siguiente.

Establece Display/Cursor: D—Prende lcd(1)/apaga LCD(0) C—Cursor activado (1)/Desactivado (0) B—Parpadeo del Cursor activado (1)/Desactivado (0) Mover Cursor/Recorrer cursor: SC—Corrimiento del display activado (1)/Desactivado (0) RL—Corrimiento hacia derecha (1)/Izquierda (0)

Page 44: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

44 Para Microcontroladores PIC16 100 % C!!!

Establecer tamaño del interfaz DL—Dato de 8 bit(1)/4 bit(0) N—Numero de líneas del Display 1(0)/2(1) F—Tamaño de letra 5 x 10(1)/5 x 7(0) Estado del bit de BUSY: BF—Bit en UNO cuando este en proceso de algo

Mover cursor a la posición de la RAM:

A—Direccion Leer/Escribir en el LCD: H—DATOS

Antes de enviar cualquier comando o datos hacia el LCD, el modulo debe ser inicializado, en este

caso se trabajara con un modo de 8 bit, Esto es hecho usando las siguientes instrucciones.

1 Esperar 15mS después de conectar la alimentación 2 Escribir 0x30 hacia el LCD y esperar 5mS antes de otra instrucción 3 Escribir 0x30 hacia el LCD y esperar 160uS antes de otra instrucción 4 Establecer LCD

Escribe el modo a usar 8 o 4 bit Escribe 0x01 para apagar display Escribe 0x01 para limpiar display Escribe la dirección del cursor Escribe prender display/cusor

Todo lo anterior se resume a usar la función:

Lcd_init(unsigned char config); //Inicializamos LCD.

Config = Puede ser dos opciones

CURSOR_ON Prende el cursor y parpadea

CURSOR_OFF Apaga Cursor

Hay otras funciones públicas, a esto se refiere a que el usuario puede llamarlas

sabiendo que son especialmente para lo que es, las funciones públicas son las

siguientes:

//writeCLCD(unsigned char c);

Page 45: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

45 Para Microcontroladores PIC16 100 % C!!!

// Funcion que escribe un caracter en el LCD

//writeSLCD(unsigned char *dir);

// funcion para escribir una cadena de caracteres

// guardadas en la RAM

//writeRSLCD(const unsigned char *string);

// funcion para escribir una cadena de caracteres

// guardadas en la ROM

//gotoXYLCD(unsigned char x,unsigned char y);

// Posiciona el cursor en el lugar elegido

Para dar un pequeño ejemplo del uso del Modulo LCD, se desarrolla lo siguiente, Al

iniciar la simulación, se escribirá en el LCD la letra ‘A’ demostrando la función

writeCLCD(); después borrara la pantalla con la instrucción que no es publica pero es

usada para poder limpiar la pantalla LCD, send_byte(CLEAR); envía un comando de

limpiar pantalla, y después escribimos un string guardado en la ROM y comprobamos

la función, writeRSLCD(); después con un ciclo for hara contar 0 a 100 y será mostrado

en el lcd los valores de 0 a 100, poniendo en prueba una nueva función:

sprintf(arreglo,"datos en string %si hay valores a transformar ",valor a transformer a

string);

Esta instrucción para usarla se debe de agregar la librería stdio.h al principio del

programa.

Después será proyectado al LCD con el uso de la instrucción writeSLCD();.

Page 46: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

46 Para Microcontroladores PIC16 100 % C!!!

Programa de ejemplo:

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

#include"liblcd/lcddr.h"

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

//////////////////////////////////////////////////

//VARIBALES GLOBALES

//////////////////////////////////////////////////

unsigned char value;

unsigned char word[25];

//////////////////////////////////////////////////

//Funcion de segundo

//////////////////////////////////////////////////

void DELAY1S(void){

unsigned char seg;

for(seg=0;seg<100;seg++){

__delay_ms(10);

}

}

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

/////////////////////////////////////////////////

//Funcion Principal

/////////////////////////////////////////////////

void main(void){

PORTA=0x00;

TRISA=0x20;

Page 47: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

47 Para Microcontroladores PIC16 100 % C!!!

lcd_init(CURSOR_OFF);

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

writeCLCD('A'); //Escribe un simple caracter

DELAY1S(); //Funcion de retardo 1 segundo

gotoXYLCD(1,2);//FILA 2

writeRSLCD("HOLA MUNDO");//Escribe un string guardado en la ROM

gotoXYLCD(1,1); //FILA 1

writeRSLCD("I CAN WRITE");//Escribe un string guardado en la ROM

DELAY1S();

DELAY1S();

send_byte(CLEAR); //CLEAR DISPLAY

for(value=0;value<100;value++){

gotoXYLCD(1,2);

sprintf(word,"VALUE=%u ",value);

writeSLCD(word); //Escribe un string guardado en la RAM

DELAY1S();

}

while(1);

}

Simulación correspondiente:

Page 48: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

48 Para Microcontroladores PIC16 100 % C!!!

2.1 Lector de Voltaje

Ahora empecemos hacer una práctica sencilla para poner a prueba el funcionamiento

del LCD y el convertidor análogo-digital, se trata de leer un dato análogo y después

transformar ese dato a un valor de voltaje, como el rango máximo es de 0 a 5 v,

entonces es una tarea muy sencilla, solo usaremos un canal análogo, en mi caso el

AN0.

Use un potenciómetro de cualquier valor, preferentemente de 1kohm a 500 kohm,

conecte la terminal del potenciómetro hacia la entrada análoga del microcontrolador

(AN0), después conecte el LCD, en el puerto C.

Para cambiar el puerto de trabajo del LCD, se puede modificar la librería lcddr.h Solo

cambie los parámetros indicados en el archivo .H y listo.

#define PUERTOX TRISC

#define PUERTOY PORTC

#define E RB4

#define RS RB5

#define RW RB6

Presentamos el Programa:

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

#include<math.h> //para uso del float

#include"liblcd/lcddr.h" //Libreria creada para uso del lcd

#include"libADC/adcdr.h"//Inluimos libreria de trabajo con ADC

Page 49: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

49 Para Microcontroladores PIC16 100 % C!!!

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 8MHZ

////////////////////////////////////////////////

//Variables Globales

////////////////////////////////////////////////

//unsigned int adc;

float adc;

unsigned char y;

unsigned int word[25];

int lengh;

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISA=0x01;

TRISB=0x00;//Puerto para PINES DE E,RS,RW del LCD

//Configuracion del ADC

OpenADC(FOSC_FRC,AN0,OFF);

//Oscilador interno

//AN0 como entrada analogo

//PORTB sin analoga

//Inicializamos LDC

lcd_init(CURSOR_OFF); //Inicializa Cursor APAGADO

Page 50: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

50 Para Microcontroladores PIC16 100 % C!!!

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

writeRSLCD("Lectura de ADC");

while(1){

__delay_ms(100);

channelADC(0); //Canal 0

startADC(); //Empieza Conversion

while(GODONE!=0); //Ha terminado

adc=readADC(); //lee dato de 10 bit

adc=(adc*5)/1024; //

sprintf(word,"AN0=%.2f volts",adc);//Cambia todo a un string completo

gotoXYLCD(1,2); //Segunda Linea

writeSLCD(word); //Escribe la conversion del LCD

}

}

Simulación Correspondiente:

Page 51: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

51 Para Microcontroladores PIC16 100 % C!!!

2.2 Selector de canal análogo con Teclado 4x4

Después de ver el uso de los canales análogos, y el modulo LCD, ahora debemos de

conocer el uso del teclado 4x4, el funcionamiento es sencillo.

Un teclado que funciona a base de matriz, conexiones de fila y columna, es una

manera eficiente para utilizar menos pines y hacer la programación de este más

sencilla, para los que apenas inician en la programación a lo mejor es muy complejo

realizar este tipo de librerías, por eso se ha realizado una librería para trabajar al

menos usar teclados 4x4.

Para que usted tengo noción de cómo funcionan, se da un pequeños pasos de cómo se

debe de realizar una librería de cualquier tamaño de teclado.

Realizar librería de 4X4 por pasos:

1.- Selecciona el puerto a usar (si el puerto contiene resistencias pull-ups mucho mejor)

2.- Hacer en nibble mas alto como entrada, y el nibble de menos peso como salida

Page 52: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

52 Para Microcontroladores PIC16 100 % C!!!

3.- SI tiene resistencias pull-ups el puerto seleccionado actívelas, sino se debe de

colocar externamente las resistencias en el nibble de entrada hacia +5.

4.-Inicialize la salida como encendidos, y después apaga el pin 1110eeee y haga un

corrimiento de mayor a menor:

11011111

10111111

01111111

En cada transición de corrimiento debe de haber un retardo de 5mS, y guarde el dato

de corrimiento, y lea el puerto completo, para saber si hubo algún cambio.

5.- Hay dos opciones para tomar una letra cuando se presiona y cuando no se

presiona:

5.1 Si no presiona ninguna letra procure regresar un valor que usted conozca y

que no esté en rango de las letras que se vaya a usar.

5.2 Si se presiona una tecla guarde el valor obtenido, y decodifique ese valor

con una letra establecida por nosotros y regrese y salga del ciclo y use la letra o

valor obtenido a su antojo.

Estos pasos pueden funcionar para teclados de otro valor por ejemplo 4x10, 10x12 etc.

Se ha creado dos funciones necesarias para el uso del teclado 4x4, son las siguientes:

void key_init(void); Llamamos antes de otra funcion

unsigned char getkey(unsigned char kbd); Lee el dato del teclado

kbd = debe de ser un valor 0 para inicializar la función de leer teclado

Esta función devuelve un valor de tipo unsigned char (0 – 255)

Page 53: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

53 Para Microcontroladores PIC16 100 % C!!!

Para saber cómo funciona, vamos a desarrollar un proyecto sencillo, es tener 4

opciones en la pantalla LCD, que nos indique que canal análogo queremos ver, para la

selección del canal se usara por supuesto el teclado 4x4.

El programa a manejar es el siguiente:

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

#include"liblcd/lcddr.h"//Libreria para trabajar con Lcd

#include"libkey/keydr.h"//Libreria para trabajar con teclado 4x4

#include"libADC/adcdr.h"//Libreria para trabajar con ADC

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

//////////////////////////////////////////////////

//VARIBALES GLOBALES

//////////////////////////////////////////////////

unsigned char value,x;

unsigned int ADC,analogo;

unsigned char word[25];

//////////////////////////////////////////////////

//Funcion de segundo

//////////////////////////////////////////////////

void DELAY1S(void){

unsigned char seg;

for(seg=0;seg<100;seg++){

__delay_ms(10);

}

}

///////////////////////////////////////////////////

//FUNCION DE TENER CANAL ANALOGO

Page 54: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

54 Para Microcontroladores PIC16 100 % C!!!

///////////////////////////////////////////////////

unsigned int LEEADC(unsigned char y){

channelADC(y);

__delay_ms(1);

startADC();

while(GODONE!=0);

ADC=readADC();

return ADC;

}

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

/////////////////////////////////////////////////

//Funcion Principal

/////////////////////////////////////////////////

void main(void){

//Configuramos El puerto A como nibble alto como Salida y nibble Bajo como entrada

TRISA=0x0F;

//Inicializamos teclado 4x4

key_init();

//Inicializamos LCD 16X2 con cursor apagado

lcd_init(CURSOR_OFF);

//Inicializamos Convertidor Analogo AN0->AN4 puerto B no analogo

OpenADC(FOSC_FRC,AN0_AN3,OFF);

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

//Parte del Programa que menciona que canal queremos ver;

send_byte(CLEAR);

gotoXYLCD(1,1);

writeRSLCD("CANAL ANALOGO");

gotoXYLCD(1,2);

writeRSLCD("A0, A1, A2, A3");

value=0;

while(value==0)value=getkey(0);

//Funcion que te deja ver el canal analogo que hallamos elegido

switch(value){

case '0':

send_byte(CLEAR);

Page 55: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

55 Para Microcontroladores PIC16 100 % C!!!

gotoXYLCD(1,1);

writeRSLCD("CANAL CERO");

//Ver canal Canal analogo 0

while(1){

analogo=LEEADC(0);

gotoXYLCD(1,2);

sprintf(word,"%i Salir(A) ",analogo);

writeSLCD(word);

value=getkey(0);

if(value=='A') break;

}

break;

case '1':

send_byte(CLEAR);

gotoXYLCD(1,1);

writeRSLCD("CANAL UNO");

//Ver canal Canal analogo 1

while(1){

analogo=LEEADC(1);

gotoXYLCD(1,2);

sprintf(word,"%i Salir(A) ",analogo);

writeSLCD(word);

value=getkey(0);

if(value=='A') break;

}

break;

case '2':

send_byte(CLEAR);

gotoXYLCD(1,1);

writeRSLCD("CANAL DOS");

//Ver canal Canal analogo 2

while(1){

analogo=LEEADC(2);

gotoXYLCD(1,2);

sprintf(word,"%i Salir(A) ",analogo);

writeSLCD(word);

value=getkey(0);

if(value=='A') break;

}

break;

case '3':

send_byte(CLEAR);

gotoXYLCD(1,1);

writeRSLCD("CANAL TRES");

//Ver canal Canal analogo 3

while(1){

Page 56: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

56 Para Microcontroladores PIC16 100 % C!!!

analogo=LEEADC(3);//Llama a la funcion de llamar

analogo

gotoXYLCD(1,2); //Posiciona Cursor en coordenadas

seleccionadas

//Convierte a la variable a un string

sprintf(word,"%i Salir(A) ",analogo);

//Escribe en el LCD

writeSLCD(word);

//lee teclado

value=getkey(0);

//Si presionamos 'A' salimos

if(value=='A') break;

}

break;

default:

//Sino se presiono una de las letras que deben

send_byte(CLEAR);

writeRSLCD("Intente Otra vez");

DELAY1S();

break;

}

}

}

Simulación:

Page 57: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

57 Para Microcontroladores PIC16 100 % C!!!

2.3 PWM a salida análogo

Esta práctica es muy interesante ya que usaremos el PWM que contiene el

microcontrolador, y el USART integrado, con

el uso de un filtro RC, podemos obtener por

medio del PWM unas salida análoga de 10-bit,

para cambiar el valor de salida, usaremos un

software que fue creado en Microsoft Visual

C# 2010 express Edition , que puede ser

bajado solo registrándose en la página de Microsoft.

El funcionamiento del Software es muy sencillo, solo tiene la opción de cambiar el

puerto (COM) y los baudios, y por supuesto contiene un barra deslizadora que hace la

función de cambiar el voltaje, como vemos en la imagen el software.

Para hacer la simulación correspondiente se tiene otro software sirve para hacer

Puertos virtuales, donde podemos hacer enlaces entre dos programas como puede ser

PROTEUS y nuestro software Convertidor de Digital a análogo.

El programa a que a continuación se da, se basa en la interrupción por recepción, cada

vez que el programa envía un dato, el proceso que esté haciendo en ese momento el

microcontroladores es interrumpido para recibir el dato, y después vuelve al proceso

donde se había quedado.

Como ahora se tiene pensado usar 10-bit en la configuración del duty del PWM,

entonces simplemente en las librerías que hemos usado para el PWM, la función

Page 58: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

58 Para Microcontroladores PIC16 100 % C!!!

PwmDuty.c cambie simplemente de char a int, y también cambie en pwm.h la función

PwmDuty.c por lo que se había cambiado anteriormente.

Al tener lo anterior, se creado dos líneas que harán que pueda convertir un valor

unsigned char a unsigned int, esto hace que pueda usarse dos byte individualmente y

unirse para crear un Word.

Mostramos el programa del PIC.

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

///////////////////////////////////////////////////

//Librerias de trabajo

////////////////////////////////////////////////////

#include"libUSART/usartdr.h" //Libreria creada para uso del usart

#include"timer2/timer2.h"//Incluimos timer2

#include"pwmdr/pwm.h" //Incluimos libreria para trabajar con PWM

////////////////////////////////////////////////

///Variables globales ////////

////////////////////////////////////////////////

unsigned int DUTY;

unsigned char uPWM[2];

bit flag=0;

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

Page 59: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

59 Para Microcontroladores PIC16 100 % C!!!

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){

//Ha resivido un dato?

if(RCIF){

//Tomo 2 bytes del serial

uPWM[0]=getch();

uPWM[1]=getch();

//Ya termine de resivir

RCIF=0;

//Habilito cambio de PWM DUTY

flag=1;

}

}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISC=0x80; //RB1=RX,RB2=TX

//Configuracion del USART

OpenUSART(207,OFF,ON); //value=(FOSC/(baud*16))-1

//INTERRUPCIONES POR RECEPCION

//a 2400 baudios

//Configuramos el timer2

OpenTimer2(PRESCALE_16);

//Configuramos el PWM

OpenPwm(124); //para f=1Khz

//PWM period = [(period ) + 1] x 4 x Tosc x TMR2 prescaler

//PWM period = [(255)+1]x(4/4Mhz)x16

// [.001s/((4/8Mhz)*16)]-1=period

// [1/(f*(4/Tosc)*preescalar)]-1=period

PwmDuty(0);

GIE=1; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=1; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

//Espera a habilitar

if(flag){

//////////////////////////////////////

//DUTY=0xPWM[1]PWM[0]=16bit

DUTY=(unsigned int)uPWM[1]<<8;

DUTY|=((unsigned int)uPWM[0]&0x00FF);

//////////////////////////////////////

//Cambiamos el duty del PWM

PwmDuty(DUTY);

//

Page 60: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

60 Para Microcontroladores PIC16 100 % C!!!

flag=0;

}

}

}

Antes de Inicialar debemos de tener abierto el Software Virtual Serial port, Creamos 2

puertos Virtuales en el botón “ADD PAIR” al tener dos parece cada uno será conectado

a un programa, por ejemplo para el COM1 será conectado a proteus por medio del

compim, mientras que el COM2 será conectado a nuestro software convertidor Digital a

Análogo.

Al tener conectado satisfactoriamente nuestra conexión virtual, ya podemos a poner

mover la barra que hará cambiar el voltaje en la salida del PWM conectado al arreglo

RC.Vemos que al medir el voltaje ser acerca mucho al voltaje del software, se observa

también el PWM, tiene una frecuencia de 1Khz como hemos precisado.

Page 61: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

61 Para Microcontroladores PIC16 100 % C!!!

NOTA: Recuerde que si desea realizar la practica Físicamente, se debe de usar el

MAX232 para hacer el interfaz de comunicación entre el PIC y PC.

2.4 Medidor de voltaje por software

Esta práctica es muy sencilla, es hacer un enlace con un programa creado en Visual

C# para luego ser conectado vía serial a nuestro microcontrolador, que este toma un

valor análogo en el canal 0 (AN0) y

después es procesado para enviarlo

por el serial.

Use el MAX232 para hacer la

conexión entre PIC y PC, coloque un

potenciómetro de cualquier valor que

usted desee a la entrada RA0 que es

la entrada análogo que vamos a usar, abra el software para conectarlo en el COM

disponible en nuestra computadora, o si usted desea crear un enlace virtual entren

proteus y nuestro programa, utilizando el software Virtual Serial Port.

Abrimos el programa ADC.exe y dirigimos nuestro mouse al botón serial y elegimos el

COM2 a 2400 baud y decimos ok y conectamos.

Page 62: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

62 Para Microcontroladores PIC16 100 % C!!!

Ahora habrá haga o abra la simulación en proteus, use el COMPIM para simular

puertos, y seleccione COM1 a 2400 baud, y presione play.

Se observa que cambia el voltaje cada vez que movemos el potenciómetro.

El programa que contiene el Microcontrolador es el siguiente:

Page 63: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

63 Para Microcontroladores PIC16 100 % C!!!

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

///////////////////////////////////////////////////

//Librerias de trabajo

////////////////////////////////////////////////////

#include"libUSART/usartdr.h" //Libreria creada para uso del usart

#include"libADC/adcdr.h" //Libreria creada para uso del ADC

////////////////////////////////////////////////

///Variables globales ////////

////////////////////////////////////////////////

unsigned int ADC;

unsigned char send[2];

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISA=0x01; //RA0=entrada

TRISC=0x80; //RC8=RX,RC7=TX

//Configuracion del USART

OpenUSART(207,OFF,OFF); //value=(FOSC/(baud*16))-1

//No interrupciones

//a 2400 baudios

Page 64: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

64 Para Microcontroladores PIC16 100 % C!!!

//Configuramos ADC

OpenADC(FOSC_FRC,AN0,OFF);//Canal AN0 como analogo

GIE=0; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=0; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

__delay_ms(1); //Tiempo antes de pedir otro dato

startADC(); //Empieza conversion

while(GODONE!=0); //ha terminad?

ADC=readADC(); //SI, lee dato

send[0]=ADC&0xFF; //toma el low byte

send[1]=(ADC>>8)&0x03;//Toma el high byte

putch(send[0]); //envia low byte primero

putch(send[1]); //envia high byte segundo

}

}

Se observa que se descompone la variable ADC ya que es una variable de 16-bit,

entonces lo que pasa es separar en 2 byte la variable, uno nombrado como bajo byte

(low byte) y alto byte(high byte). Después es enviar el low byte y en seguida el high

byte, y el software se encargara de unir los dos byte para transformarlo en el valor que

había leído.

Nota: la instrucción ADC>>8 mueve 8-bit a la derecha y después pasa por una

comparación AND para que solo acepte 3 bit del byte que se forma al moverlo.

Ejemplo:

ADC=0Xff00;

ADC>>8=0x00FF

0x00FF&0x03=0x03

Page 65: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

65 Para Microcontroladores PIC16 100 % C!!!

2.5 Reloj con Displays

Ahora haremos una práctica muy interesantes vamos a usar dos interrupciones por

timer0,1, cada uno manejara un tiempo establecido, para que estén en sincronía.

El timer 0 manejara el corrimiento entre los Display a esto se le llama multiplexado, ya

que solo un display será activado por un cierto tiempo y después apagara para prender

el siguiente Display. Ejemplo:

Para mostrar el numero en el primer display se debe de activar el pin “1” y los demas

se deben de dejar a cero, para que

solo muestre un solo numero en el

display correspondiente, como se

muestra en la imagen, debemos de

tener un controlador que pueda

cambiar el numero al correr los

pines del selector, para que estén

en sincronía.

Es muy importante realizar esta acciones a una gran velocidad, normalmente para 6

displays que serán multiplexados, se debe de tener mas de 60Hz en cada uno de los

displays ya para evitar flashazos.

El corrimiento se hará con el timer0 que estará configurado a que haga un

desbordamiento cada 1mS, teniendo que cambiar al siguiente display, la fórmula para

Page 66: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

66 Para Microcontroladores PIC16 100 % C!!!

calcular el valor para se pueda cargarse al “TMR0” se debe de calcular con la fórmula

del timer0.

��$0 = 256 − { '����( 4��) ∗ � ����� }

Si va a operar nuestro microcontrolador con un cristal interno de 8Mhz, con un

prescalar de 16 para tener una frecuencia de 1Khz (1mS), se despeja y obtenemos:

��$0 = 131

Este valor se debe de cargar cada vez que surja la interrupción del timer0, si nuestro

reloj tiene 6 displays y cada uno se va a cambiar cada 1mS entonces tenemos que la

frecuencia de cada uno será de:

� = 117�6 ≅ 1667�

Que será más que suficiente para eliminar los tales flashazos.

Como mencione anteriormente se debe de tener dos interrupciones funcionando a la

vez, la primera interrupción ya la hemos visto y como opera, ahora la siguiente

interrupción es la más primordial, ya que es la que se encargara de contar el tiempo y

no se debe de interrumpir en absoluto.

Para el uso de esta interrupción se usara el timer1 ya que s muy parecido al timer0

pero contiene contador de 16 bit, y tiene más temporización que el timer0 la formula es

igual que el del timer0 pero ahora solos sustituiremos:

Page 67: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

67 Para Microcontroladores PIC16 100 % C!!!

��$1 = 65536 − { '����( 4��) ∗ � ����� }

El prescalar solo tiene 4 (1,2,4,8), despejamos y tenemos

��$1 = 15550

Este valor es para tener una interrupción cada 200mS para tener un segundo se debe

de dividir este valor por el reciproco y tenemos que:

8 = � 1200�9� = 5

Deben surgir 5 interrupciones para tener 1 Segundo, entonces aumentara una variable

que guardara. Cada segundo que pase y así al llegar a 60 segundos y aumenta otra

variable que guardara los minutos y cuando los minutos alcancen 60 minutos este

aumenta la variable horas, y así.

Ahora para mostrar los números en los display se debe de contar en cuenta los valores

de corrimiento como se hablo anteriormente, estos valores de corrimiento será hecho

en el puerto B, como son 6 display entonces se usaran 6 pines del puerto B para

multiplexarlos, al Iniciar el corrimiento este tiene un valor de 1, al correrlo, tomara un

valor de 2, y de nuevamente al correrlo este tomara un valor de 4, por deducción se

incrementa en múltiplos de 2, entonces solo basta de usar instrucciones de if cada vez

que llegue al valor deseado por ejemplo:

Page 68: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

68 Para Microcontroladores PIC16 100 % C!!!

If((PORTB&0x3F)==1) {

Mostrar el valor que corresponde al Display 1

}

……

Ahora bien como deseamos cambiar manualmente los valores de HORAS y MINUTOS,

se usaran simplemente 3 push botons para hacer estos cambios, uno será el que

establece la hora y minutos, si este botón no está presionado no afecta presionar los

botones de hora y minutos, pero sí lo contrario está presionado se podrá cambiar

satisfactoriamente los valores hora y minutos.

Aquí Mostramos el resultado de la programación:

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

__CONFIG(DEBUGDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

Page 69: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

69 Para Microcontroladores PIC16 100 % C!!!

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

//DEBUGDIS = Desactiva Debug

//BOR = Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

/////////////////////////////////////////////////

//Librerias

/////////////////////////////////////////////////

#include"timer0/OpenTimer0.h"//Incluimos libreria de timer0

#include"libADC/adcdr.h" //Libreria creada para uso del ADC

#include"timer1/timer1dr.h" //Libreria para uso del timer1

/////////////////////////////////////////////////

//Definiciones de trabajo

/////////////////////////////////////////////////

#define SET_TIEMPO !(PORTA&0x01)

#define HORA !(PORTA&0x02)

#define MIN !(PORTA&0X04)

////////////////////////////////////////////////

//Variables Globales

////////////////////////////////////////////////

const unsigned char mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,

0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};

unsigned char H2,H1,M2,M1,S2,S1;

unsigned char overflow1;

unsigned char TIEMPO=1,FECHA=0;

////////////////////////////////////

///Interrupcion Por timer0 y timer1

////////////////////////////////////

static void interrupt

isr(void){

////////////////////////////////////////////

//CADA 1mS se efectuara esta accion

//Esta Funcion se encarga de correr los display

//Para cuando es necesario mostrar el numero

//En el Display siguiente

////////////////////////////////////////////

if(T0IF && !TMR1IF){

if((PORTB&0x3F)<32){

PORTB=(PORTB<<1)|0x40;

}else{

PORTB=0x41;

}

T0IF=0;

Page 70: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

70 Para Microcontroladores PIC16 100 % C!!!

TMR0=131;//Carga otra vez el timer 0

}

///////////////////////////////////////////

//Cada 200mS se efectuara esta accion

//Esta funcion se enecarga de incrementar

//las variables que se mostraran en los

//Displays

///////////////////////////////////////////

if(TMR1IF && TMR1IE){

T0IF=0; //Desactiva Timer0

overflow1++;

if(overflow1==5){

overflow1=0;

S1++;

if(S1==10){

S1=0;

S2++;

if(S2==6){

S2=0;

M1++;

if(M1==10){

M1=0;

M2++;

if(M2==6){

M2=0;

H1++;

if(H1==10 && H2<2){

H1=0;

H2++;

}else if(H1==4 && H2==2){

H2=H1=0;

}

}

}

}

}

}

T0IF=1; //Activa TIMER0

TMR1IF=0;//FLAG CERO

TMR1LOAD(15550);//Carga el timer

}

}

void main(void){

///////////////////////////////////////////////////

//Puerto B como salida ///

//Desactiva entradas analogas ///

//Puerto B sera usado para activar los Display ///

Page 71: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

71 Para Microcontroladores PIC16 100 % C!!!

///////////////////////////////////////////////////

TRISB=0X00;

PORTB=0X41;

///////////////////////////////////////////////////

//Puerto C como salida ///

//Puerto C sera usado para sacar el numero ///

///////////////////////////////////////////////////

TRISC=0;

PORTC=0;

///////////////////////////////////////////////////

//PORTA <PIN A1 a A7> como salida ///

//PORTA <PIN A0> como entrada analoga ///

///////////////////////////////////////////////////

TRISA=0X07;

PORTA=0x00;

CM1CON0=0x00;//Desactiva comparadores

CM2CON0=0x00;

//Configuramos ADC

OpenADC(FOSC_FRC,OFF,OFF);//No usaremos Canal Analgos

//Configuramos TIMER0

//Para obtener 1 mS

OpenTIMER0(prescalar_16,ON);

//Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer1)

// 1mS=tiempo maximo

// timer0=+256-{tiempo/[(1/(FOSC/4))*preescalar]}

TMR0=131;

OpenTIMER1(pr_8,ON);

//Interrupcion timpo=(1/(FOSC/4))*preescalar*(256-timer1)

// 200mS=tiempo maximo

// timer1=+65536-{tiempo/[(1/(FOSC/4))*preescalar]}

TMR1LOAD(15550);

GIE=1; //INTERRUPCIONES GLOBALES ACTIVADAS

PEIE=1; //ACTIVA INTERURPCIONES POR PERIFERICOS

/////////////////////////////////////////////////////

//Inicia el Ciclo Perpetuo

/////////////////////////////////////////////////////

while(1){

if(TIEMPO && !FECHA){

/////////////////////////////////////////////////////

//Cuando sea 1 en el puerto B este muestra el valor

//Que contiene la variable

//Asi es para todas las comparaciones

/////////////////////////////////////////////////////

if((PORTB&0x3F)==1){

PORTC=mostrar[S1];

Page 72: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

72 Para Microcontroladores PIC16 100 % C!!!

}else if((PORTB&0x3F)==2){

PORTC=mostrar[S2];

}else if((PORTB&0x3F)==4){

/////////////////////////////////////////////////////

//Si presionamos el boton de SET_TIEMPO

//Este da permiso para que pueda incrementar

//la vriable de MINUTOS

/////////////////////////////////////////////////////

if(!SET_TIEMPO){

if(!MIN){

M1++;

while(!MIN);

if(M1==10){

M1=0;

M2++;

if(M2==6){

M2=0;

}

}

}

}

PORTC=mostrar[M1];

}else if((PORTB&0x3F)==8){

PORTC=mostrar[M2];

}else if((PORTB&0x3F)==16){

/////////////////////////////////////////////////////

//Si presionamos el boton de SET_TIEMPO

//Este da permiso para que pueda incrementar

//la variable de HORAS

/////////////////////////////////////////////////////

if(!SET_TIEMPO){

if(!HORA){

H1++;

while(!HORA);

if(H1==10 && H2<2){

H1=0;

H2++;

}else if(H1==4 && H2==2){

H2=H1=0;

}

}

}

PORTC=mostrar[H1];

}else if((PORTB&0x3F)==32){

PORTC=mostrar[H2];

}

}

Page 73: 75347569-Hi-Tech

Curso de Hi

73 Para Microcontroladores PIC16 100 % C!!!

}

}

Recuerde usar en cada Display una conexión de transistor como se muestra abajo:

Curso de Hi-tech Compiler (lite Mode)

Para Microcontroladores PIC16 100 % C!!!

Recuerde usar en cada Display una conexión de transistor como se muestra abajo:

tech Compiler (lite Mode) 2010

Recuerde usar en cada Display una conexión de transistor como se muestra abajo:

Page 74: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

74 Para Microcontroladores PIC16 100 % C!!!

Cada Display tendrá su propio transistor, para que no

caiga toda la corriente en el Microcontrolador, y

también pueda iluminar mucho más.

Ahora se propone que usted haga las siguientes

modificaciones:

1.- Que pueda mostrar la fecha : Dia/Mes/Año

Utilizando 4 interruptores.

2.- Después de realizar lo anterior coloque un sensor de temperatura (LM35) para que

pueda mostrar cada 30 Segundos la temperatura:

El sensor calíbrelo a que muestre una temperatura de 0 a 100 grados.

Page 75: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

75 Para Microcontroladores PIC16 100 % C!!!

2.6 Control de Servo

Entender este tema es muy complicado ya que requiere muchas operación si se desea

realizar un control de varios servos, por esta razón se simplificara a un solo servo a

controlar, haciendo más sencilla la explicación y las operaciones.

Primero que nada hay que saber que es un servo, servo es un pequeño pero potente

dispositivo que dispone en su interior de un pequeño motor con un

reductor de velocidad y multiplicador de fuerza, también dispone de

un pequeño circuito que gobierna el sistema. El recorrido del eje de

salida es de 180º en la mayoría de ellos, pero puede ser fácilmente

modificado para tener un recorrido libre de 360º y actuar así como un

motor.

El control de posición lo efectúa el servo internamente mediante un potenciómetro que

va conectado mecánicamente al eje de salida y controla un pwm (modulador de

anchura de pulsos) interno para así compararlo con la entrada pwm externa del servo,

mediante un sistema diferencial, y así modificar la posición del eje de salida hasta que

los valores se igualen y el servo pare en la posición indicada, en esta posición el motor

del servo deja de consumir corriente y tan solo circula una pequeña corriente hasta el

circuito interno, si forzamos el servo (moviendo el eje de salida con la mano) en este

momento el control diferencial interno lo detecta y envía la corriente necesaria al motor

para corregir la posición.

Page 76: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

76 Para Microcontroladores PIC16 100 % C!!!

Para controlar un servo tendremos que aplicar un pulso de duración y frecuencia

específicos. todos los servos disponen de tres cables dos para alimentación Vcc y Gnd

y otro cable para aplicar el tren de pulsos de control que harán que el circuito de control

diferencial interno ponga el servo en la posición indicada por la anchura del pulso.

En la siguiente tabla están indicados los valores de control y disposición de cables de

varias marcas que comercializan servos.

Nosotros nos basaremos en las características que contiene la marca de servos hi tech

como se aprecia en la tabla anterior las características de ancho de pulso es de 0.9 ms

como mínimo y 2.1 ms como máximo entonces tenemos un rango de operación del

servo es de:

�8: = 2.1�9 − 0.9�9 = 1.2�9

Lógica de SERVO

Para operar un servo via rs232, con un microcontrolador en general, se debe de tomar

2 interrupciones, una por timer y otra por USART, en este caso el tiempo es muy

importante entonces es mas primordial que se atienda la interrupción por timer que por

Page 77: 75347569-Hi-Tech

Curso de Hi

77 Para Microcontroladores PIC16 100 % C!!!

recepción del USART. Ya que necesitamos una estabilidad en la frecuencia que debe

de tener el servo.

porción en tiempo alto y el resto quedara en bajo

tiempo alto.

El uso del timer1 es muy importante su configuración, en este caso se debe de

configurar de la siguiente manera:

1.-Prescalar de 2 para tener un tick cada 0.4uS

2.- Activar la interrupción por TIMER1

Si tenemos un pulso máximo de 2.1ms este valor lo divi

Este valor son los tick necesarios para llevar

bien para sacar los tick mínimos para llevar el pulso a 0.9ms se divide entre 0.4us

como la vez anterior.

Curso de Hi-tech Compiler (lite Mode)

Para Microcontroladores PIC16 100 % C!!!

recepción del USART. Ya que necesitamos una estabilidad en la frecuencia que debe

Para tener la frecuencia estable aunque se

modifique el ancho de pulso, y que este en

rango de operación del servomotor, se debe

de llevar a cabo las siguientes formulas.

Como sabemos que 50Hz equivale a tiempo

a 20 ms, y que solo va a variar una pequeña

porción en tiempo alto y el resto quedara en bajo, las operaciones se harán para el

El uso del timer1 es muy importante su configuración, en este caso se debe de

configurar de la siguiente manera:

Prescalar de 2 para tener un tick cada 0.4uS

Activar la interrupción por TIMER1

Si tenemos un pulso máximo de 2.1ms este valor lo dividimos por 0.4us:

'��1��; = 2.1�0.4� � 5250

Este valor son los tick necesarios para llevar a cabo un pulso positivo de 2.1ms, ahora

bien para sacar los tick mínimos para llevar el pulso a 0.9ms se divide entre 0.4us

tech Compiler (lite Mode) 2010

recepción del USART. Ya que necesitamos una estabilidad en la frecuencia que debe

Para tener la frecuencia estable aunque se

modifique el ancho de pulso, y que este en

operación del servomotor, se debe

de llevar a cabo las siguientes formulas.

Como sabemos que 50Hz equivale a tiempo

a 20 ms, y que solo va a variar una pequeña

, las operaciones se harán para el

El uso del timer1 es muy importante su configuración, en este caso se debe de

dimos por 0.4us:

un pulso positivo de 2.1ms, ahora

bien para sacar los tick mínimos para llevar el pulso a 0.9ms se divide entre 0.4us

Page 78: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

78 Para Microcontroladores PIC16 100 % C!!!

'��1��8�� �0.9�0.4� = 2250

Para saber el rango con los que vamos a controlar solamente restamos:

�8: = '��1��; − '��1��8�� = 5250 − 2250 = 3000

Si observa que el rango es el mismo de 1.2ms (valor obtenido al restar 2.1ms-0.9ms)

3000 ∗ 0.4� = 1.2�

Ahora debemos de sacar el valor que es necesario para cada grado, es simplemente

dividir:

��� ;: � = �8:180 = 3000180 = 16.6666 ≅ 17

Entonces se nota que para que gire un grado se debe de tener 17.

Por ejemplo:

Si deseamos que nuestro motor gire a 50 grados entonces:

50 ∗ 17 = 850

Pero como sabemos que los tick mínimos son 2250 entonces se lo sumamos:

2250 + 850 = 3100

Para cargárselo al timer1 se debe de restar 65536 que es el valor de 16 bit

65536 − 3100 = 62436

Page 79: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

79 Para Microcontroladores PIC16 100 % C!!!

Antes de cargárselo al timer1 se debe de activar el pin y después cargar el valor

obtenido al timer1, entonces va a durar el ancho de pulso el tiempo que corresponde

para que pueda girar el servo a 50 grados, y después se generara una interrupción

donde se debe de cargar el timer1 con el valor del pulso abajo.

Para sacar el valor del tiempo bajo simplemente se debe de sacar cuantos tick son

para 20ms:

'��120� = 20�0.4� = 50000

Al tener este valor se debe de restar 3100 (valor obtenido anteriormente para sacar

tiempo alto)

50000 − 3100 = 46900

Y por ultimo este valor se resta a 65536 para después cargárselo al timer1:

65536 − 46900 = 18636

Recuerde que antes de cargarlo se debe de poner el pin en bajo y después cargar el

valor obtenido al timer1.

En resumen, primero saque el valor para el tiempo alto y bajo, cuando surja la

interrupción ponga el pin en alto y cargue con el tiempo alto, después que surja otra

vez la interrupción ponga el pin a bajo y cargue el tiempo bajo.

Page 80: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

80 Para Microcontroladores PIC16 100 % C!!!

Por lo general el dato que se va a recibir en el puerto será el valor de la posición (0 a

180 grados), el USART debe estar configurado mínimo a 57,600 baud o máximo

115,200 baud.

El diagrama a manejar es el siguiente:

El programa es el siguiente;

#include<htc.h> //Incluimos libreria del micro a usar

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & HS & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 20000000 //Oscilador Externo de 20MHZ

/////////////////////////////////////////////////////////////

//Librerias a usar

/////////////////////////////////////////////////////////////

Page 81: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

81 Para Microcontroladores PIC16 100 % C!!!

#include"libUSART/usartdr.h" //Libreria creada para uso del usart

#include"timer1/timer1dr.h" //Incluimos libreria para uso del Timer1

/////////////////////////////////////////////////////////////

//Variables Globales del Programa

/////////////////////////////////////////////////////////////

unsigned int tick; //Aqui guardara los valores para cargar al timer1

unsigned char flag=1;//Sirve para ver cambio en el POSICION

unsigned char LAHL=1;//SWITCHEA DE ALTO A BAJO EL PULSO PARA SERVO

unsigned int POSICION=90;//Inicializa a 90 grados

unsigned int AUX,AUXH,AUXL;//Auxiliares para operaciones

unsigned int SERVOH,SERVOL;//Guarda datos de alto y bajo

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){

/////////////////////////////////////////////////////////////

//Crea una prioridad si ocurre al mismo tiempo la interrupcion

//entonces no entra al ciclo de recepcion

//esta funcion es baja prioidad.

/////////////////////////////////////////////////////////////

if(RCIF && !TMR1IF && RCIE){

POSICION=getch();

flag=1;

RCIF=0;

}

//////////////////////////////////////////////////////////////

//Funcion para switchear el pulso positivo

//y toma los tick necesarios para cargar al timer1

//y que dure el tiempo seleccionado

//esta funcion en alta prioridad

///////////////////////////////////////////////////////////////

if(TMR1IF){

if(LAHL==1){

RA0=1;

tick=SERVOH;

LAHL=0;

}else{

RA0=0;

tick=SERVOL;

LAHL=1;

}

TMR1IF=0;

Page 82: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

82 Para Microcontroladores PIC16 100 % C!!!

TMR1LOAD(tick);

}

}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

CMCON=0x07; //APAGA COMPRADORES INTERNOS

TRISA=0x00;

TRISB=0x02; //RB1=RX,RB2=TX

//Configuracion del USART

OpenUSART(20,OFF,ON); //value=(FOSC/(baud*16))-1

//interrupcion de recepcion activado

//a 57600 baudios

//Configuramos Timer1

OpenTIMER1(pr_2,ON); //Prescalar de 2

//Activamos la interrupcion por timer

TMR1LOAD(tick);

GIE=1; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=1; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

if(flag==1){

RCIE=0; //Desactiva interrupcion por recepcion del USART

AUX=(POSICION*17)+2200; //AQUI OBTIENES LOS TICK'S~2250

AUXH=65536-AUX; //AQUI OBTIENES EL TIEMPO EN ALTO

SERVOH=AUXH; //ACTUALIZA EL SERVO SELECCIONADO

AUX=50000-AUX; //20ms - (TIEMPO TRANSCURRIDO EN ALTO)

AUXL=65536-AUX; //AQUI OBTIENES EL TIEMPO BAJO

SERVOL=AUXL; //ACTUALIZAS SERVO SELECCIONADO

flag=0;

RCIE=1;

}

}

}

Page 83: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

83 Para Microcontroladores PIC16 100 % C!!!

2.6.1 Software para control de servo

El software que vamos a usar en esta ocasión es Microsoft Visual C# 2010 Express,

este nos servirá para realizar nuestras aplicaciones para entornos de Windows, es muy

fácil realizar prácticas sencillas de comunicación serial.

No me involucrare en sintaxis y como se debe de programar

correctamente en este entorno lo que vamos a desarrollar

es cosas sencillas para que usted tenga una noción de cómo funcionan las cosas.

Lo bueno de este software es que es free, entonces no gastaremos ningún centavo en

tenerlo, solo accedemos a la página de www.microsoft.com y buscamos visual c#

express y lo bajamos, ten en cuenta que se debe de registrar para poder bajar el

software.

Al bajarlo debemos de abrirlo y, crear un nuevo proyecto y

nos abrirá una venta para seleccionar que tipo de proyecto

deseamos desarrollar, entonces debemos de usar

Page 84: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

84 Para Microcontroladores PIC16 100 % C!!!

Window form

application

Si deseamos cambiar

el nombre a control de

servo lo podemos

hacer en la parte

inferior. Y después

damos OK para realizar el proyecto y al instante aparece nuestra ventana de trabajo,

que conforma, en la parte izquierda el toolbox <caja de herramientas> es donde se

localiza todos los componentes para realizar acciones especificas, mientras en el

centro el form, en la parte inferior derecha se encuentra las propiedades de los

elementos, si deseamos cambiar algunas propiedad de elementos, simplemente damos

click en el elemento y rápidamente aparecerá las propiedades.

Lo que vamos a hacer primero es colocar el componente de serialport que se

encargara de crear el COM (puerto), que se encuentra en el toolbox, en componentes.

Page 85: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

85 Para Microcontroladores PIC16 100 % C!!!

Después de agregarlo, seleccionamos el

serialport1 para ver las propiedades y

cambiamos <baudrate> a 57600 que

corresponde al valor del microcontrolador.

Después agregamos un trackbar, y

cambiamos la propiedades, el máximo a 180

y mínimo 0, que corresponde al giro máximo

que debe de tener el servo.

Después podemos agregar unos pushboton, para que se

encarguen de abrir y cerrar el puerto correctamente, podemos

cambiar su nombre si lo deseamos, en sus propiedades.

Todo lo anterior no se refiere a que este programado, aun

falta decirle que tiene que hacer cada cosa, para realizar lo

que queremos. Primero que nada es establecer la

comunicación o abrir el puerto, en este caso es COM1 por default si se desea cambiar

puede acceder a las propiedades del serialport y cambiar el COM.

Para abrir el puerto haga dos click en el botón conectar, y agregamos la siguiente línea

private void button1_Click(object sender, EventArgs e)

{

serialPort1.Open();

}

Ahora sigue cerrar el puerto simplemente se debe de seleccionar el otro pushboton y

hacer dos click y poner la siguiente línea.

private void button2_Click(object sender, EventArgs e)

Page 86: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

86 Para Microcontroladores PIC16 100 % C!!!

{

serialPort1.Close();

}

Y listo ya hemos configurado el abrir y cerrar del puerto, ahora falta enviar datos, solo

damos dos click en el trackbar y agregamos la siguiente código.

private void trackBar1_Scroll(object sender, EventArgs e)

{ byte[] dato = {Convert.ToByte(trackBar1.Value) };

if (serialPort1.IsOpen)

{ serialPort1.Write(dato, 0, 1);

}

}

Damos F5 para correr programa y veremos con la ayuda de Virtual serial port la

conexión.

Ahora solo cambiamos de puerto en el COMPIM de proteus a COM2 y listo ya

podemos cambiar el giro del motor, con un software hecho por nosotros mismos.

Page 87: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

87 Para Microcontroladores PIC16 100 % C!!!

Peligro: Si desea realizar la práctica físicamente no olvide usar el MAX232 para

comunicaciones SERIALES entre PIC Y PC.

Page 88: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

88 Para Microcontroladores PIC16 100 % C!!!

2.7 Control de velocidad

Esta práctica es muy sencilla, es controlar la velocidad de un motor CD por

computadora. Usaremos un software llamado labview no importa la versión que usted

pueda conseguir.

Al tener nuestro software hecho en labview que se va a conectar vía serial al

microcontrolador, controlara el ancho de pulso que generara el PIC haciendo que el

motor gire lentamente o rápidamente.

Los elementos que vamos a usar del microcontrolador es el modulo PWM, cosa que ya

hemos visto su programación y uso, el programa que contiene el microcontrolador es el

mismo de la práctica de “canal análogo”.

Solo colocamos a la salida del PWM, una

resistencia de 1kHz, la base de un

transistor 2N2222A y en el colector

colocamos la conexión del motor, en el

otro extremo a la alimentación, y el

emisor solo lo pondremos a masa.

Si usted desea realizar esta práctica físicamente puede usar el MAX232 para hacer

conexiones entre PIC y PC via Serial, en las simulación no se usa el MAX ya que

puede reducir la velocidad y provocar error entonces se puede conectar directamente

para simular perfectamente nuestros circuitos, pensando que no se puede hacer esto

sin el MAX232.

Page 89: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

89 Para Microcontroladores PIC16 100 % C!!!

El código del Microcontrolador es el siguiente:

#include<htc.h> //Incluimos libreria del micro a usar

#include<stdio.h> //libreria para trabajar con conversiones

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 8000000 //Oscilador Interno de 8MHZ

/////////////////////////////////////////////////

//Librerias de perifericos

/////////////////////////////////////////////////

#include"timer2/timer2.h"//LLama la libreria de usar Timer2

#include"pwmdr/pwm.h"//LLama libreria para usar PWM

#include"libUSART/usartdr.h" //Libreria creada para uso del usart

////////////////////////////////////////////////

///Variables globales ////////

////////////////////////////////////////////////

unsigned int DUTY;

unsigned char uPWM[2];

bit flag=0;

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){

//Ha resivido un dato?

if(RCIF){

//Tomo 2 bytes del serial

uPWM[0]=getch();

uPWM[1]=getch();

//Ya termine de resivir

RCIF=0;

//Habilito cambio de PWM DUTY

flag=1;

}

Page 90: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

90 Para Microcontroladores PIC16 100 % C!!!

}

//////////////////////////////////////////////

//Funcion Principal

//////////////////////////////////////////////

void main(void){

TRISC=0x80;

//Configuracion del USART

OpenUSART(51,OFF,ON); //value=(FOSC/(baud*16))-1

//interrupcion de recepcion activado

//a 9600 baudios

//Configuramos TIMER 2 para PWM

OpenTimer2(PRESCALE_16);

//Usamos libreria PWM

OpenPwm(124);

//PWM period = [(period ) + 1] x 4 x Tosc x TMR2 prescaler

//PWM period = [(255)+1]x(4/4Mhz)x16

// [.001s/((4/8Mhz)*16)]-1=period

// [1/(f*(4/Tosc)*preescalar)]-1=period

PwmDuty(0);

GIE=1; //INTERRUPCIONES GLOBALES DesACTIVADAS

PEIE=1; //DesACTIVA INTERURPCIONES POR PERIFERICOS

while(1){

//Espera a habilitar

if(flag){

//////////////////////////////////////

//DUTY=0xPWM[1]PWM[0]=16bit

DUTY=(unsigned int)uPWM[1]<<8;

DUTY|=((unsigned int)uPWM[0]&0x00FF);

//////////////////////////////////////

//Cambiamos el duty del PWM

PwmDuty(DUTY);

//

flag=0;

}

}

}

Page 91: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

91 Para Microcontroladores PIC16 100 % C!!!

2.7.1 Software para labview

Ahora empecemos a desarrollar el programa necesario para llevar a cabo la práctica,

debemos de tener cualquier versión de labview en nuestras manos, para empezar

programar tome en cuenta que si usted es novato en la programación en labview, no se

preocupe aquí le diremos lo más básico para usted sepa por lo menor hacer interfaces

entre PIC y computadora, lo demás poco a poco usted lo aprenderá.

Abrimos labview y creamos un nuevo proyecto, al crear el

proyecto aparecerán dos ventanas de trabajo, una es para

realizar la programación <block digram> de los elementos

agregados en el <front panel> si usted desea tener las dos

ventanas abiertas en la pantalla puede presionar <ctrl><t> y listo tendrá las dos venta

divididas en su pantalla, vamos a dirigir nuestro mouse a la ventana <block diagram> y

presionamos <click> derecho, aparecer una ciertas herramientas, buscaremos la

herramienta <Instrument I/O> presionamos al icono de <serial> aquí se encuentra todo

lo necesario para realizar las practicas con el serial, más que nada funciones de

configuración de COM, baud, timeout, etc. También tenemos funciones de escritura y

lectura.

Después de acceder a las funciones del serial, lo

primero que vamos a hacer es configurar el

puerto, tomamos el icono de <VISA configure

serial port> y lo arrastramos al <block diagram>

esta manera podemos incluir funciones a nuestro programa, <click><arrastrar> <click>.

Page 92: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

92 Para Microcontroladores PIC16 100 % C!!!

Al tener la función de configuración montamos el mouse en el, para después hacer click

derecho en VISA resource name y seleccionamos <create><control> esto permite que

aparezca un control en el panel frontal donde nosotros podemos cambiar, o configurar

manualmente lo que nos pide, esta parte nos menciona que hemos creado un control

donde especifica que ahí va estar COM disponible del serial, si usted tiene una

computadora casera nota que al presionar el control aparecerá los COM disponibles en

su computadora de escritorio, mientras si tiene una laptop, puede usar un cable de

USB a Serial para hacer esta acción.

Regresamos a hace lo mismo con la opción de configuración de

los baudios, al tener estas dos opciones es necesario, ahora

poner una estructura <while> como usted sabe una función

while sirve para hacer un ciclo “hasta que sea verdad”, para

tener esta estructura nos dirigimos a

<programming><structures><while loop> Y simplemente lo

agregamos, hacemos esto para que solo entre una sola vez a la opción de

configuración cada vez que reiniciamos el programa, el <while loop> se encargara de

estar en un ciclo perpetuo hasta que

presionemos <stop>

Ahora agregaremos una función de

secuencia, esta función nos permitirá

hacer que cada acciones se hagan paso

por paso (por secuencia una tras otra), la función llamada <flat sequence> esta en

Page 93: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

93 Para Microcontroladores PIC16 100 % C!!!

<structures>, al

agregarlo a la hoja

block diagram debe de

estar adentro del

<while loop> .

Al tener todo lo anterior

regresa a la hoja front panel y agregue un control de numérico el que usted desee, solo

que sea aquel que puede cambiar su valor cuando el usuario desee, y cambie el rango

que tenga el control que haya elegido de 0 a 100, que corresponde a porcentaje, es

mucho más fácil trabajar de este modo, que poner el valor

actual enviado.

Después agregue si usted lo desea un indicador de string,

para mostrar un texto donde especifique el porcentaje

actual. Ahora que ya tenemos los controles de muestra en el front panel, ahora falta

programar sus funciones, de envio.

Regresemos a la pagina <block diagram> y nos dirigimos a buscar la función <write>

que se encuentra en las funciones del <serial>, esta función <write> al encontrarla la

agregamos en la segunda secuencia ya que va hacer la última acción que es enviar el

dato. Al agregarlo conecte correctamente la salida de la función de configuración a la

entrada de la función de <write> como se indica en la imagen.

Esto tiene que hacerse ya que permite la opción de configuración enviar el puerto

disponible y si hay algún error también enviarlo, y cuando llegue a la función de

Page 94: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

94 Para Microcontroladores PIC16 100 % C!!!

<write>este identifique el COM disponible y la velocidad a escribir (baud) Ahora bien,

fuera del ciclo <while loop> use una función de cerrar puerto que se encuentra también

las funciones del <serial> <close>. Esto permite que cuando salgamos del ciclo <while

loop>pueda cerrar perfectamente el puerto abierto.

Si usted se ha dado cuenta es los mismos pasos que cuando realizamos la práctica de

software de “control de servo”.

Si sabemos que enviaremos 2 bytes seguidos, y que esos bytes no tendrán el valor del

porcentaje si el valor necesario para hacer el ancho de pulso que corresponda al

porcentaje, por ejemplo:

Enviamos un porcentaje de 50% si sabemos que el valor máximo que debe de tener el

pwmduty es de 512, realizamos una regla de tres simple.

� �� ��8'�=�9������8� ∗ 512100 ;

El valor de “f” tendrá un resultado de dos bytes, de los cuales debemos de sacarlos

individualmente. Agregaremos una formula note, que se

encuentra en <structures> para realizar las operaciones

necesarias.

Si usted observa la imagen, se dará cuenta que se ha

creado 2 variables de 1 byte,

Para contener un byte del resultado de la operación anterior, después se juntaran en un

arreglo para ser convertido a una cadena de caracteres, ya que es lo único que permite

Page 95: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

95 Para Microcontroladores PIC16 100 % C!!!

enviar la función de <write>, al transformar un arreglo de bytes a string no afecta el

envío, ya que si en el arreglo se encuentra primero en byte más bajo, este se enviará

primero y después se enviara el 2do byte.

Al realizar todo lo anterior el programa principal puede quedar de la siguiente manera:

En la parte frontal se puede realizar algunos arreglos, para que pueda estar mejor

presentado:

Page 96: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

96 Para Microcontroladores PIC16 100 % C!!!

Ahora bien se ha realizado el programa pero ahora se desea realizar un ejecutable, que

se quiere decir con esto, que se puede ejecutarse sin abrir

labview.

Para hacer lo propuesto el se tiene que grabar en una

librería de tipo LLB, solo grabamos la practica en <save as>

y presionamos “new LLB”. Y después nos pedirá que

nombre queremos para la librería LLB, usted ponga el que

guste, después abrirá otra venta para grabar el archivo, también usted escriba el

nombre que desee.

Ahora nos dirigimos a LLB manager que está ubicado en “tools” lo abrimos y aparecerá

una venta donde buscaremos la librería LLB que creamos.

Presionamos dos veces el archivo y nos llevara al proyecto, ahora nos dirigimos a

“tools” y presionamos la

opción de “buils aplication

(EXE), nos preguntará si

deseamos grabarlo ahí,

solo decimos que si.

Y nos abrirá la venta de

configuración de nuestro

ejecutable

Page 97: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

97 Para Microcontroladores PIC16 100 % C!!!

Si usted desea cambiar el nombre de la aplicación, puede hacerlo en <target

filename>hay más opciones de configuración, como cambiar icono, o que usted haga

su propio icono.

Al terminar solo falta de presionar el botón “build” y listo, te dirá que el ejecutable se

encontrara en la carpeta donde grabamos la librería LLB, pues simplemente vamos a la

carpeta y ahí estará, solo buscamos la carpeta de “builds” y ejecutamos y listo!!!.

Nota: Recuerde usar el MAX232 para hacer comunicaciones seriales entre PC y PIC.

Page 98: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

98 Para Microcontroladores PIC16 100 % C!!!

2.8 Matriz de Led 8x24 (Contador de 000 a 999)

Este proyecto es una matriz de led 8x24, lo que vamos a desarrollar es un contador de

000 a 999, con el cual se usara una de tantas formas de programar una matriz, usando

diferentes circuitos adicionales, para facilitar el resultado.

Una matriz consta de filas y columnas, cuando

se interceptan una fila y una columna solo los

que prenderán son los led, que cumplan con

un nivel alto en al ánodo, y un nivel bajo en el

cátodo, por ejemplo:

Si tenemos una configuración de una matriz

8x8 de led, donde todas las filas están

conectadas al ánodo mientras que están

conectadas todas las columnas los cátodos.

Columna

Fila

Page 99: 75347569-Hi-Tech

Curso de Hi

99 Para Microcontroladores PIC16 100 % C!!!

Si en las filas enviamos un dato de la siguiente manera;

Para:

F1= 0

F2=0

F3=1

Y para las columnas

C=0

C2=1

C3=1

Esto quiere decir que solo va a prender los led que

interceptan de fila a columna, 1 a 0.

Ahora bien, haremos una técnica de corrimiento de bit,

esto quiere decir por ejemplo:

Al Inciar un corrimiento siempre se inicializa enviando

un dato en este caso un “1” después se enviara dat

de valor “0” si nuestro corrimiento solo consta de 8 bit,

entonces el bit que contiene el “1” debe de correr 8 veces antes de salir.

10000000 ->01000000

00100000

Curso de Hi-tech Compiler (lite Mode)

Para Microcontroladores PIC16 100 % C!!!

Si en las filas enviamos un dato de la siguiente manera;

va a prender los led que

interceptan de fila a columna, 1 a 0.

Ahora bien, haremos una técnica de corrimiento de bit,

esto quiere decir por ejemplo:

Al Inciar un corrimiento siempre se inicializa enviando

un dato en este caso un “1” después se enviara datos

de valor “0” si nuestro corrimiento solo consta de 8 bit,

entonces el bit que contiene el “1” debe de correr 8 veces antes de salir.

tech Compiler (lite Mode) 2010

entonces el bit que contiene el “1” debe de correr 8 veces antes de salir.

Page 100: 75347569-Hi-Tech

00000001

00000000

Para hacer esto se cuenta con un

circuito 74HC164 que es especialmente

para corrimientos, se mues

esquema de este circuito. Ahora bien la

explicación de las

conexiones es muy

simple:

DSA y DSB se

conectan las dos para

tener en los pines el

mismo estado lógico y

son el encargado de

enviar el dato un “1” o

“0”.

CP es el encargado de administrar el

tiempo (clock) el tiempo de corrimiento

depende del microcontrolador ya que

este puede generar la suficiente

frecuencia para tener un corrimiento

Para hacer esto se cuenta con un

circuito 74HC164 que es especialmente

para corrimientos, se muestra el

esquema de este circuito. Ahora bien la

es el encargado de administrar el

tiempo (clock) el tiempo de corrimiento

depende del microcontrolador ya que

este puede generar la suficiente

frecuencia para tener un corrimiento

demasiado rápido, cada ciclo del clock

generara que se mueva un bit.

MR Este pin es un “Master Reset” y su

función es “resetear” el dispositivo, si

esta al positivo este funciona

normalmente mientras si esta en cero (a

tierra) este estará en modo reset y el

circuito no funcionara,

aunque se este

enviado pulsos al CP.

Q0~Q7

deben de conectarse a

la fuente de control,

por ejemplo a las

columnas de una

matriz.

Si usted se pregunta cómo conectar

varios de circuitos en serie para tener

un corrimiento de mas bit, solo haga

una conexión del Q7 al DSA,B, mientras

solo puntee los CP’s y MR al mismo pin

demasiado rápido, cada ciclo del clock

generara que se mueva un bit.

e pin es un “Master Reset” y su

función es “resetear” el dispositivo, si

esta al positivo este funciona

normalmente mientras si esta en cero (a

tierra) este estará en modo reset y el

circuito no funcionara,

aunque se este

enviado pulsos al CP.

Q0~Q7 son los que

deben de conectarse a

la fuente de control,

por ejemplo a las

columnas de una

matriz.

Si usted se pregunta cómo conectar

varios de circuitos en serie para tener

un corrimiento de mas bit, solo haga

una conexión del Q7 al DSA,B, mientras

os CP’s y MR al mismo pin

Page 101: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

101 Para Microcontroladores PIC16 100 % C!!!

del microcontrolador y así tendrá un

corrimiento de 16 bit.

El PIC se encargara de administrar el

clock, y el dato, su usted desea

manipular el encendido del circuito

74HC164 solo use otro pin para

conectar el MR y listo.

Nuestra misión en crear un contador de

000 a 999, cada digito se tendrá que

mostrar en cada matriz de 8x8,

entonces necesitamos 3 matrices, y

para cada matriz es necesario un

circuito 74HC164, para manipular las 24

columnas, las filas estarán todas unidas

entre si, solo 8 pines saldrán de las

matrices que serán conectadas al

microcontrolador, pero como sabemos

que el microcontrolador solo puede

administrar una corriente de 100mA en

cada canal del puerto, se debe de

conectar un transistor en cada pin para

que alimente a las filas.

El programa solo usara 5 ciclos “for”:

1er <for> para contar centenas

2do<for>para contar decenas

3er <for>para Contar unidades

4to <for>para Tener un retardo de 1

segundo.

5to <for> para mostrar en cada columna

el valor de la fila.

Para mostrar cada número en el display

correspondiente se tiene que realizar

una lógica, cuando empiece el

corrimiento se debe hacer continuo, y

memorizar la cuenta del corrimiento, al

iniciar la matriz se debe de mostrar

primero las centenas, entonces tomo el

valor del 1er <for> y lo muestro en los

primeros 8 bit, al pasar al 9no bit se

debe de tomar el valor del 2do <for> y

mostrarlo desde el 9no bit al 16vo bit y

por ultimo mostrar el valor del 3er <for>

ten en cuenta que en 1 segundo se

Page 102: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

102 Para Microcontroladores PIC16 100 % C!!!

debe de repetir aproximadamente 113

veces el procedimiento anterior y así no

podríamos percibir un tipo de parpadeo.

Cada vez que es mostrada la fila debe

de esperar un tiempo y después apagar

la fila y hacer el corrimiento.

Ya tenemos la lógica de programación,

ahora te preguntaras como dibujo el

numero en la matriz, es un poco tedioso

realizar esta tarea ya que se necesita

una paciencia enorme, pero bueno, una

técnica es copiar la matriz (solo la

imagen) de proteus o de otra fuente, y

pegarlo a paint, y dibujar el numero, al

tenerlo dibujado se debe de pasar a

numero hexadecimales o binario, por

ejemplo:

Para pasar el número cero a código de

hexadecimal, cada fila corresponde a un

byte, desde el nibble mas bajo estará en

la parte superior de la matriz y el nibble

mas alto en la parte inferior (de arriba

abajo).

El número cero, se puede sacar los

siguientes valores:

0X00,0X3C,0X7E,0XC3,0XC3,0XC3,

0X7E,0X3C

Tomando de referencia la columna 1 de

izquierda a derecha.

Este procedimiento se debe de realizar

para los 10 digitos. (0~9)

Page 103: 75347569-Hi-Tech

Se muestra todos los números dibujados en la matriz:

Todos los números serán pasados a código hexadecimal y colocarlos en un arreglo de

matriz como se ve en el ejemplo de abajo:

const unsigned char ALFA[10][8]={0X00,0X3C,0X7E,0XC3,0XC3,0XC3,0X7E,0X3C, //0

0X00,0X00,0XC4,0XC6,0XFF,0XFF,0XC0,0XC0, //1

0X00,0X00,0XCE,0XE7,0XF3,0XDB,0XCF,0XE6, //2

0X00,0X00,0X42,0XDB,0XDB,0XDB,0XFF,0X7E,//3

0X00,0X10,0XD8,0XDC,0XD6,0XFF,0XFF,0XD8,//4

0X00,0X00,0XCE,0XDF,0XDB,0XDB,0XF3,0X73, //5

0X00,0X00,0X7E,0XFF,0XD3,0XD3,0XF7,0X66, //6

0X00,0X00,0XC3,0XE3,0X73,0X3B,0X1F,0X0F, //7

0X00,0X00,0X66,0XFF,0XDB,0XDB,0XFF,0X66, //8

0X00,0X00,0X4E,0XDF,0XDB,0XDB,0XFF,0X7E}; //9

Page 104: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

104 Para Microcontroladores PIC16 100 % C!!!

Mostramos el Circuito a manejar:

Recuerde que las conexiones de la fila deben de llevar un transistor (2n2222A)

Page 105: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

105 Para Microcontroladores PIC16 100 % C!!!

El código es el siguiente:

#include<htc.h> //Incluimos libreria del micro a usar

__CONFIG(UNPROTECT & WDTDIS & PWRTEN & INTIO & MCLREN & LVPDIS & BORDIS);

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

//UNPROTECT = Codigo no Potegido

//WDTDIS = Watch Dog Timer Desactivado

//PWRTEN = Power Activado

//INTIO = Osiclador interno

//MCLREN = Activamos Master Clear

//LVPDIS = Low Voltage Porgramming Desactivado

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

#define _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ

#define CLOCK RA0

#define DATO RA1

#define RESET RA2

void config(void);

void SEND_DATA(unsigned char DATA);

void CLEAR(void);

//---------------------------------------------------------

//VARIABLES DONDE SE ENCUENTRA LOS NUMEROS /

//---------------------------------------------------------

const unsigned char ALFA[10][8]={0X00,0X3C,0X7E,0XC3,0XC3,0XC3,0X7E,0X3C, //0

0X00,0X00,0XC4,0XC6,0XFF,0XFF,0XC0,0XC0, //1

0X00,0X00,0XCE,0XE7,0XF3,0XDB,0XCF,0XE6, //2

0X00,0X00,0X42,0XDB,0XDB,0XDB,0XFF,0X7E, //3

0X00,0X10,0XD8,0XDC,0XD6,0XFF,0XFF,0XD8, //4

0X00,0X00,0XCE,0XDF,0XDB,0XDB,0XF3,0X73, //5

0X00,0X00,0X7E,0XFF,0XD3,0XD3,0XF7,0X66, //6

0X00,0X00,0XC3,0XE3,0X73,0X3B,0X1F,0X0F, //7

0X00,0X00,0X66,0XFF,0XDB,0XDB,0XFF,0X66, //8

0X00,0X00,0X4E,0XDF,0XDB,0XDB,0XFF,0X7E}; //9

Page 106: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

106 Para Microcontroladores PIC16 100 % C!!!

//---------------------------------------------------------

//VARIABLES A USAR EN EL PROYECTO /

//---------------------------------------------------------

unsigned char MAX; //Variable que se va usar en la funcion "CLEAR"

unsigned char CONT=0; //variable que se va usar en la funcion "HABILITO"

unsigned char Fila; //Para mostrar FILA

unsigned char columna=0;//Varibale para controlar columnas en la matriz

unsigned int time,overload=0;

//time=para un retardo de visualizacion,

//overload variable para alcanzar 1seg con ayuda de la variable

//time

unsigned char dato3,dato2,dato1;

//dato3 para la vizualizacion de la matriz 0xx

//dato2 para ============================= x0x

//dato1 para ============================= xx0

/////////////////////////////////////////////////

//Funcion de interrupcion

//Si no se usa simplemente no hacemos nada...

//Esto sirve para direccionar lo los datos

//en un lugar muy cercano al Inicio de la memoria

//de datos

////////////////////////////////////////////////

static void interrupt

isr(void){}

//-----------------------------------------------------------

// PROGRAMA PRINCIPAL

/

//-----------------------------------------------------------

void main(void){

config(); //Configuramos puertos

RESET=1;

//Ya que el 74HC164 contiene un pin de reset que puede ir directamente

//al POSITIVO pero se puede poner directo al micro para manipular

//el encendido y apagado de la matriz

CLEAR();

//Al inicializar la matriz apagada

overload=113;

//1mS*8=8mS para un segundo=113

//Con la ayuda de MPLAB SIM se puede apreciar el un retardo de

//993.837uS~1Seg

SEND_DATA(1);

//Al inicializar la matriz se envia el dato para proceder a vizualizar

//cada numero.

//Se puede decir que este incio es muy importante

Page 107: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

107 Para Microcontroladores PIC16 100 % C!!!

while(1){

for(dato3=0;dato3<10;dato3++){

//ciclo de vizializacion de centenas

for(dato2=0;dato2<10;dato2++){

//ciclo de vizualizacion de decenas

for(dato1=0;dato1<10;dato1++){

//ciclo de vizializacion de unidades

for(time=0;time<overload;time++){

//tiempo de retardo de vizualizacion que conlleva al timepo de 1segundo

for(Fila=0;Fila<8;Fila++){

//ciclo para mostrar filas, por mientras se switchean cada matriz para

//mostrar en cada matriz el numero correspondiente.

if(columna<8){

//Mostrar DATO3

//Cuando se encuentre empezando en la columna de la izquierda ya que es la primera en

//encender empezara a vizualizar el dato3 que contiene las centenas.

//Ya que cada matriz es de 8x8, al alcanzar la columna 8 este pasara a la suiguiente matriz

PORTB=ALFA[dato3][Fila];

__delay_ms(1);

PORTB=0;

}else if(columna<16){

//Mostrar DATO2

//Que contedra el valor ddecenas ya que el valor de dos matrices es de 16 la variable

//columna llega a 16 pasara a la suiente matriz

PORTB=ALFA[dato2][Fila];

__delay_ms(1);

PORTB=0;

}else if(columna<24){

//Mostrr DATO1

//Que contendra las unidades, al llegar al maximo de columnas que son 24 ya que

//es la union de 3 matrices de 8x8, que correponden a 24 columnas

//al llegar al maximo este enviara un dato 1 para inicializar toda la matriz...

PORTB=ALFA[dato1][Fila];

__delay_ms(1);

PORTB=0;

}

//Cuando llega la columna maxima ya que es 24 columnas se inicializa varibale

//"Columna" para empezar de nuevo.

if(++columna<24){

//Dato 0 para corrimiento

SEND_DATA(0);

}else{

//Dato 1 para inicializar matriz

SEND_DATA(1);

columna=0;

}

}

Page 108: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

108 Para Microcontroladores PIC16 100 % C!!!

}

}

}

}

}

}

//---------------------------------------------------------

//FUNCION DE TE PERIMITE CONFIGURAR PUERTOS /

//---------------------------------------------------------

void config(void){

TRISB=0x00;

PORTB=0x00;

TRISA=0x20;

PORTA=0x00;

CMCON=0x07;

GIE=0;

}

//---------------------------------------------------------

//FUNCION DE TE PERIMITE ENVIAR UN CERO O UNO /

//---------------------------------------------------------

void SEND_DATA(unsigned char DATA){

DATO=DATA;

CLOCK=0;

CLOCK=1;

}

//----------------------------------------------------------

//FUNCION DE BORRADO

/

//----------------------------------------------------------

void CLEAR(void){

for(MAX=1;MAX<=24;MAX++){ //24 ES EL MAXIMO DE->

SEND_DATA(0); //->COLUMNAS

}

}

Page 109: 75347569-Hi-Tech

Curso de Hi-tech Compiler (lite Mode) 2010

109 Para Microcontroladores PIC16 100 % C!!!

Curso de Hi tech Compiler para PIC16 100% C

GraciasGraciasGraciasGracias!!!!

“He realizado varios proyectos y los he

recompilado para poder explicarlos y

realizar este manual para aquellos que

les gustan realizar proyectos a base de

microcontroladores picmicro.”

Usted puede mandar dudas al correo.

[email protected]

Curso v2.0 Terminado en: 23/07/10

Copyright © 2010