Вы находитесь на странице: 1из 122

CERTIFICADOS

Calidad en nuestros productos. Tecnologa a su


Servicio

ISO 9001:2008

PROGRAMA DE CAPACITACIN SENA BOGOTA

SEMANA 22 AL 25 DE ABRIL
TEMA: PROGRAMACIN MICROCONTROLADORES MICROCHIP

1 MATERIALES NECESARIOS

Programadores ICSP PICKIT3

Kit Explorer 16. Referencia DM240001

Kit m_touch. Referencia 183026-2

Starter kit PIC32. Referencia DM320001

Kit TRACME 2013 (GPS y GSM). Referencia

2 TEMAS

Abril 22
-

Nueva plataforma de trabajo MPLABX de MICROCHIP

Nuevos compiladores XC8, XC16 y XC32 de MICROCHIP para el trabajo con


lenguaje C

Programas bsicos en lenguaje ensamblador y en lenguaje C con el PIC 16F1937


utilizando el kit m_touch

Abril 23
-

Programas en el PIC de 16 bits 24FXXXX utilizando la tarjeta EXPLORER 16 y los


programadores PICKIT3

Abril 24
-

Programas en el dsPIC de 16 bits 33Fxxxx utilizando la tarjeta EXPLORER 16 y


los programadores PICKIT3

Abril 25
-

Trabajo con el Starter kit PIC32

Demostracin con el kit TRACME 2013 (GPS Y GSM)

Preparado por:
Luis Guillermo Montoya Diaz
Asesor Profesional
SUCONEL S.A

Descripcin detallada de las clases:


Introduccin a las nuevas herramientas de Microchip, tanto en Hardware como en
Software
Instalacin de los siguientes programas:
-

MPLABX Ver. 1.60


Compilador XC8 de Microchip para la programacin en lenguaje C de los
microcontroladores de la familia de 8 bits

Lo primero que vamos a realizar, luego de instalar el software necesario, ser aprender a
manejar la nueva plataforma de MICROCHIP llamada MPLABX, para eso, debemos
seguir el paso a paso que se presenta a partir de la siguiente pgina.
Adicional a esto se iniciar el curso con 2 programas bsicos en el manejo de entradas y
salidas, tanto en lenguaje ensamblador como en lenguaje C, para as poder continuar con
propiedad el resto del curso.

Paso a paso para el manejo del MPLABX


Este paso a paso se realiza con un primer ejemplo, el cual ensea el manejo de
entradas y salidas en el PIC 16F887. Se utilizar la versin 1.60 que es la ltima
en la web de Microchip en este momento.
Se utilizar el compilador XC8 para el trabajo en lenguaje C y el mpasm 5.48 para
el trabajo en lenguaje ensamblador.

Luego de abrir el MPLABX utilizando el icono que se crea automticamente en el


escritorio, es bueno verificar si los compiladores a utilizar estn instalados. Para
eso se ingresa por la pestaa Tools y luego en el tem options, se llega al
siguiente cuadro de dilogo.

En ste, en la opcin Embedded, verificamos que efectivamente, tanto el


compilador para ensamblador mpasm 5.48 como el compilador para lenguaje C
XC8, estn instalados. En caso de no hallarse, se debe hacer click en la pestaa
Scan for Build Tools y automticamente, buscar los compiladores en el PC,
siempre y cuando se hallan instalado previamente.
Tanto el MPLABX como el compilador XC8 se bajan gratuitamente de la pgina
www.microchip.com/MPLABX
Si todo est listo se comienza el ejemplo en lenguaje ensamblador creando un
nuevo proyecto como lo indica la figura siguiente:

File y luego New Project

Sale el primer paso que es elegir el tipo de proyecto a realizar se elige Microchip
Embedded y Standalone Project click en Next.

En el paso dos se elige el dispositivo, en este caso en la familia de medio rango de


8 bits de Microchip se selecciona la referencia PIC16F877. Click en Next.

El paso tres es opcional y solo aparece para aquellos microcontroladores que


poseen alguna herramienta de simulacin. El paso cuatro entonces es la seleccin
de la herramienta para la programacin y/o simulacin del proyecto. En este caso
se elige el PICKIT3, si ya est conectado a un puerto USB del PC, aparece con el

respectivo nmero de serie como se aprecia en el cuadro de dilogo. Click en


Next.

El paso seis permite seleccionar el compilador, inicialmente, elegimos mpasm 5.48


porque trabajaremos en ensamblador. Click en Next.

Como paso sptimo y ltimo, damos nombre al proyecto y elegimos la carpeta


donde almacenaremos nuestros archivos. Click en Finish.

Ya est terminado el proyecto donde se almacenarn los archivos fuente y


ejecutable de la aplicacin. Seleccionamos en el nombre del proyecto la opcin
Source File, luego New y por ltimo la opcin Other.

Ac se encuentran las diferentes extensiones a usar en ensamblador, en este


caso se elige Assembly.asm y click en Next.

Para facilitar las cosas, le damos el mismo nombre al archivo fuente y se


almacenar automticamente en la carpeta donde est ubicado el Proyecto. Click
en Finish.

Aparece entonces el editor para comenzar con el cdigo de nuestra aplicacin. Lo


primero ser elegir los bits de configuracin entrando por la pestaa Window luego
la opcin Pic Memory Views y finalmente, Configuration Bits.

Por el momento solo se necesita el oscilador XT para trabajar a 4MHZ,


deshabilitar el perro guardin WDT y la programacin a bajo voltaje, es decir, el bit
LVP en OFF. Luego de realizar la seleccin se crea la palabra de configuracin en
la pestaa Generate Source Code to Output

Se selecciona la palabra de configuracin, se copia y se pega en la parte inicial del


editor.

Inicio el cdigo y al finalizar lo compilo del icono Clean and Build (Escoba y
martillo). Si no hay errores debe aparecer la frase Loading Completed.
Ahora se procede con la programacin. Si el programador est conectado, como
en este caso que tenemos seleccionado y conectado a nuestra aplicacin el
PICKIT3, se debe habilitar la alimentacin a travs del puerto USB donde est
conectado el PICKIT3, esto se hace si la aplicacin no tiene alimentacin
independiente. Si alimentamos a travs del PICKIT3, se debe verificar que el
consumo de corriente de la aplicacin no supere los 500 mA para no poner en
riesgo el puerto USB del PC.

La programacin se hace desde el icono Make and Programming Device (Flecha


verde hacia abajo). El aviso en rojo aparece cuando la aplicacin no posee
alimentacin y debemos habilitarla a travs del puerto USB del PICKIT3 as:

Vamos a propiedades del projecto con File y luego Project Properties

Selecciono PICKIT3 y luego en Option Categories elijo Power y coloco el chulo en


Power Target circuit from PICKIT3. Luego Apply y OK.

Volvemos entonces a programar y aparece el aviso de precaucin preguntando si


el dispositivo trabaja a 5VDC, click en OK.

Al finalizar la programacin
Programming/Verify complete

en

forma

correcta,

aparece

el

aviso

Se verifica entonces en el hardware.


Ahora veamos los pocos cambios que se deben realizar para la aplicacin en
lenguaje C.

Iniciamos el proyecto nuevo

Se elige el tipo de proyecto. Click en Next.

Se elige la herramienta de simulacin y/o programacin. En este caso PICKIT3.


Como est conectado aparece el nmero de serie. Click en Next.

En este caso se elige el compilador para lenguaje C llamado XC8. La versin 1.12
es la ltima al momento de realizar este ejercicio. Click en Next.

Le doy el nombre al proyecto y selecciono la carpeta para almacenarlo. Click en


Finish.

Con el proyecto listo a la izquierda de tu PC, se selecciona Source File luego New
y finalmente
C source file si est presente, sino es as, se selecciona Other y se busca C
Source File.

Se da el nombre al archivo fuente, la extensin no es necesaria, ya est implcita.


Click en Finish.

Aparece el editor y lo primero ser la configuracin de bits tal como se hizo en


ensamblador para obtener la palabra de configuracin. Window luego la opcin Pic
Memory Views y finalmente, Configuration Bits.

Por el momento solo se necesita el oscilador XT para trabajar a 4MHZ,


deshabilitar el perro guardin WDT y la programacin a bajo voltaje, es decir, el bit
LVP en OFF. Luego de realizar la seleccin se crea la palabra de configuracin en
la pestaa Generate Source Code to Output.

Se copia y se pega al inicio del editor.

Se define la velocidad del oscilador a 4000000 HZ y se da inicio al cdigo en C


con la funcin principal void main()

Al terminar el cdigo, se compila y se debe obtener, si no hay errores, el mensaje


Loading Completed.
Puede verse el funcionamiento en el simulador Proteus o directamente en el
Hardware. Para programar se da click al icono Make and Programming (Flecha
verde hacia abajo)

Si no hay problemas, debe aparecer el aviso Programming/Verify complete.

ENTRADAS Y SALIDAS EN EL MICROCONTROLADOR 16F887

Lo primero ser entonces conocer el PIC 16F887 en sus funciones bsicas de


configuracin y funcionamiento.
Para ello, se trabajarn algunos de los pines de sus puertos como simples lneas
de entrada o salida.
Se debe tener en cuenta inicialmente, que este dispositivo posee 5 puertos
llamados A, B, C, D y E como lo muestra la siguiente figura y que cada uno de
ellos tiene un nmero de pines determinado, para ser utilizados como entrada
digital, salida digital con una de sus funciones alternas, por ejemplo entrada para
conversin anloga a digital, salida de PWM, transmisin o recepcin de datos por
comunicacin serial, etc.

Figura 1. Diagrama de pines del PIC 16F887


Las lneas fsicas con las que el microcontrolador se comunica con el mundo
exterior se llaman puertos, en este caso se tienen: PORTA, PORTB, PORTC,
PORTD Y PORTE y su correspondiente registro de configuracin, es decir, quien

decide si los pines del puerto sern entrada o salida, se llaman TRIS as: TRISA,
TRISB, TRISC, TRISD y TRISE.
Recuerde que a diferencia de otros microcontroladores como los ATMEL AVR y
los FREESCALE, en los PIC de MICROCHIP las entradas se configuran con unos
y las salidas con ceros, por ejemplo si se configura el registro TRISA como
01001011, el microcontrolador tendr los pines RA0, RA1, RA3 Y RA6 con la
impedancia respectiva para el trabajo como entradas y los dems pines podrn
trabajarse como salidas.
Como se ve en el diagrama de pines, las lneas que se utilizan para convertir
seales anlogas a digitales son 14 y estn ubicadas en los puertos A, B y E,
denotados como AN0, AN1AN13, los registros encargados de configurar los
canales anlogos se llaman ANSEL y ANSELH, stos vienen preparados de
fbrica para recibir seales anlogas, por lo tanto, se deben limpiar (Cargar con
cero) si no se va a realizar ninguna conversin A/D, as se podrn trabajar todos
los pines como entrada o salida digital. En el captulo dedicado a la conversin
anlogo a digital se tratar ms a fondo el trabajo de estos registros.
Con estos conceptos bsicos se da comienzo al primer ejemplo que simplemente,
permite contar de 0 a 9 los pulsos generados desde el pin RD4 del puerto D,
visualizando en el puerto A, a travs de leds y en el puerto C, mediante un display
de siete segmentos de ctodo comn conectado a un decodificador BCD a 7
segmentos. Ver plano electrnico.
La cuenta solo se incrementar con flanco de subida, as aseguramos que se
incremente solo en uno cada que se presiona el pulsador.

R2
220

R3
220

R4
220

R5
220

D1

U1
1

LED-RED

D2
LED-RED
D3

LED-RED

D4

LED-RED

2
3
4
5
6
7
14
13
33
34
35
36
37
38
39
40

RE3/MCLR/VPP

RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7
PIC16F887

U2
15
16
17
18
23
24
25
26

7
1
2
6
4
5
3

A
B
C
D
BI/RBO
RBI
LT

QA
QB
QC
QD
QE
QF
QG

13
12
11
10
9
15
14

7448
19
20
21
22
27
28
29
30

R6

Q1
2N2222

2.7K

8
9
10

R1
10k

Figura 2. Plano electrnico para el ejemplo de manejo de entradas y salidas


;*********************************************************************************************
Programa en lenguaje ensamblador
;*********************************************************************************************
; Se incluye archivo .inc que contiene los registros y bis especiales del PIC
;*********************************************************************************************
#include "p16F887.inc"
;*********************************************************************************************
; Palabras de Configuracin de bits generadas automticamente por el software
;*********************************************************************************************
; CONFIG1
;__config 0xEFF1
__CONFIG _CONFIG1, _FOSC_XT & _WDTE_OFF & _PWRTE_OFF &
_MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _IESO_ON &
_FCMEN_ON & _LVP_OFF
; CONFIG2
; __config 0xFFFF

__CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF


;*******************************************************************************************
; Bloque para registros de propsito general
;*********************************************************************************************
CBLOCK 0X20

; Inicio del bloque de registros generales

REG1, REG2, CONT

; Estos se ubican luego de la posicin 0x20 de la RAM

ENDC

; Fin del bloque de registros

;*********************************************************************************************
ORG 00
; Primera posicin de la memoria de programa
GOTO
ORG

INICIO
05

; Voy a la etiqueta de inicio


; Salvo el vector de interrupcin

;*********************************************************************************************
; Subrutina de retardo para milisegundos
;*********************************************************************************************
RETARDO ; el literal que viene en W es el nmero de milisegundos del retard o
MOVWF REG1
DOS

MOVLW .110
MOVWF REG2

UNO

NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ REG2
GOTO

UNO

DECFSZ REG1
GOTO

DOS

RETURN
;*********************************************************************************************
; Programa principal
;*********************************************************************************************
INICIO

LIMPIAR

PREG

BANKSEL TRISA

; Voy al banco 1 para configurar puertos

CLRF

TRISA

; Puerto A como salidas

CLRF

TRISC

; Puerto C como salidas

MOVLW B'00010000'

; RD4 entrada y los dems

MOVWF TRISD

; pines del puerto D son salidas

BANKSEL ANSEL

; Voy al banco 3 para configurar ANSEL

CLRF

ANSEL

; Todos los pines digitales

CLRF

ANSELH

; Todos los pines digitales

BANKSEL PORTD

; Regreso al banco 0

BSF

; Habilito transistor para ctodo del display

PORTD,0

CLRF

CONT

; Limpio contador

MOVF

CONT,W

; Paso contador a W

MOVWF PORTC

; Paso W al puerto C (0 en 7 segmentos)

MOVWF PORTA

; Paso W al puerto A (Leds apagados)

BTFSC PORTD,4

; Pregunto si RD4 est en 0, pulsador


; presionado?

GOTO

$-1

MOVLW .200

; Si no, vuelvo a preguntar


; Si RD4 est en 0, retardo de 200 ms

CALL

RETARDO

; para evitar rebote de contacto

BTFSS PORTD,4

; Pregunto si vuelve a 0 para iniciar conteo

GOTO

; por flanco de bajada, sino, continuo

$-1

; preguntando
INCF

CONT

; Si est en 0, incremento contador

MOVLW 0X0A

; Cargo W con 10 para comparacin

XORWF CONT,0

; Xor de W con Contador y resultado en W

BTFSC STATUS,2

; Pregunto por la bandera Z

GOTO

; Si es uno, es porque el contador est en

LIMPIAR

; 10 y debo ir a limpiar contador


MOVF

CONT,W

; Si no, Paso contador a W

MOVWF PORTC

; Paso W al puerto C (7 segmentos)

MOVWF PORTA

; Paso W al puerto A (Leds)

GOTO

; Pregunto nuevamente por el pulsador.

PREG

END
//*********************************************************************************************

Programa en lenguaje C
//*********************************************************************************************
#include <xc.h>

//Se incluye la libreria xc.h necesaria por contener los


// registros y bits especiales del micro.

//*********************************************************************************************
// Palabras de configuracin de bits generadas automticamente por el compilador
// ********************************************************************************************
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = OFF

// Oscillator Selection bits XT oscillator


// Watchdog Timer Enable (WDT disabled)
// Power-up Timer Enable bit (PWRT disabled)
// RE3/MCLR pin function is MCLR
// Code Protection bit (protection is disabled)
// Data Code Protection bit (protection is disabled)
// Brown Out Reset Selection bits
// Internal External Switchover Enable
// Fail-Safe Clock Monitor Enabled bit
// HV on MCLR must be used for programming

// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Reset set to 4.0V
#pragma config WRT = OFF

// Flash Program Memory Self Write Enable bits

//*********************************************************************************************
// Definicin de la velocidad del oscilador
// ********************************************************************************************
#define _XTAL_FREQ 4000000
// ********************************************************************************************

// Declaracin de variables
// ********************************************************************************************
char cont = 0; // Declaro variable cont como un char y la inicio en 0
// ********************************************************************************************
void main()
{
TRISA=0;

//Puerto A como salidas

TRISC=0;

//Puerto C como salidas

TRISD=0X10;

// RD4 entrada los dems salida

ANSEL=0;

// Todos los pines digitales

ANSELH=0;

// Todos los pines digitales

PORTA=0;

// Limpio puerto A

PORTC=0;

// Limpio puerto C

RD0=1;

// Habilito salida del transistor para ctodo del display

while(1)

// Inicio ciclo infinito

{
if(cont<10)

// Pregunto si contador es menor que 10

{
if (!RD4)

// Pregunto si RD4=0

{
__delay_ms(200); // Retardo para evitar rebote de contacto
while(!RD4)

// Mientras RD4 sea cero no haga nada

continue;

// Si pasa a uno continua

cont=cont+1;

// Incremento contador por flanco de subida

PORTC=cont;

// Muestro el conteo en display de 7 segmentos

PORTA=cont;

// Muestro el conteo en los leds

}
}
else
{
cont=0;

// Si el contador no es menor que 10, lo limpio

}
}
}

Algunas variaciones para optimizar el cdigo en lenguaje C pueden ser:

1 Definir las entradas y salidas con nombres diferentes a los pines y los puertos
as:
#define suiche RD4

// Nombro el pin RD4 como suiche

#define display PORTC

// Nombro el puerto C como display

#define leds

PORTA

// Nombro el puerto A como leds

#define Q1

RD0

// Nombro el pin RD0 como Q1

De esta manera se puede realizar el cdigo ms fcilmente y a la hora de cambiar


un pin o un puerto por otro, simplemente se realiza en la definicin y no en todo el
programa.
2 Se pueden crear funciones, stas son importantes porque si se utilizan varias
veces, solo se tiene que realizar el llamado. Por ejemplo, La parte de cdigo que
incrementa y muestra el contador en los puertos en el ejemplo anterior, se puede
sacar en la siguiente funcin:
void incremente (void)
{

cont=cont+1;
display=cont;
leds=cont;
}

Y se hace el llamado con la instruccin


Incremente(); // El nombre de la funcin puede ser cualquiera
La variable cont la declaramos como char, ya que esta va solo hasta 9 y el char es
de 8 bits, pero se debe tener en cuenta que si declaramos solo char esta ir desde
-127 hasta 128 porque es variable signada, si necesitamos variables mayores a
128 y menores a 255 se debe declarar como:
unsigned char cont; // Variable son signo, es decir, con rango desde 0 hasta 255
Para nmeros mayores a 255, las variables se deben declarar como enteros as:
Int cont;

// Esta variable ir desde -32767 hasta 32768

Unsigned int

// Esta variable ira desde 0 hasta 65535

El cdigo completo con los cambios es el siguiente:


// PIC16F887 Configuration Bit Settings
//*********************************************************************************************
// Inclusin de la libreria xc.h y configuracin de bits
//*********************************************************************************************
#include <xc.h>
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF

// Oscillator Selection bits XT oscillator


// Watchdog Timer Enable (WDT disabled)
// Power-up Timer Enable bit (PWRT disabled)

#pragma config MCLRE = ON


#pragma config CP = OFF

// RE3/MCLR pin function is MCLR


// Code Protection bit (protection is disabled)

#pragma config CPD = OFF


#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = OFF

// Data Code Protection bit (protection is disabled)


// Brown Out Reset Selection bits
// Internal External Switchover Enable
// Fail-Safe Clock Monitor Enabled bit
// HV on MCLR must be used for programming

// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Reset set to 4.0V
#pragma config WRT = OFF

// Flash Program Memory Self Write Enable bits

//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
Definicin de nombres para las variables
//*********************************************************************************************
#define suiche RD4

// Nombro el pin RD4 como suiche

#define display PORTC

// Nombro el puerto C como display

#define leds

PORTA

// Nombro el puerto A como leds

#define Q1

RD0

// Nombro el pin RD0 como Q1

//*********************************************************************************************
// Declaracin de variables
//*********************************************************************************************
char cont=0; // Declaro variable cont como char y la inicio en 0

//*********************************************************************************************
// Declaracin de funciones
//*********************************************************************************************
void incremente (void) // Declaro y realizo la funcin incremente
{
cont=cont+1;

// Incremento el contador

display=cont;

// Muestro el contador por display de 7 segmentos (PORTC)

leds=cont;

// Muestro contador por leds (PORTA)

}
//*********************************************************************************************
void main()
{
TRISA=0;

//Puerto A como salidas

TRISC=0;

//Puerto C como salidas

TRISD=0X10;

// RD4 entrada los dems salida

ANSEL=0;

// Todos los pines digitales

ANSELH=0;

// Todos los pines digitales

leds=0;

// Limpio puerto A

display=0;

// Limpio puerto C

Q1=1;

// Habilito salida del transistor

while(1)

// Inicio ciclo infinito

{
if(cont<10)
{
if (!suiche) // Pregunto si suiche est presionado, en este caso = 0

{
__delay_ms(200);// Retardo para evitar rebote de contacto
while(!suiche) // Mientras suiche est en cero no haga nada
continue; // Si pasa a uno incrementa contador por flanco de subida
incremente(); // Llamo la funcin incrementar
}
}
else
{
cont=0; // Si cont no es menor que 0, entonces lo limpio.
}
}
}
Puede comparar ambos programas e ir notando las diferencias entre un
compilador y otro. Aunque soy gran amigo del lenguaje ensamblador, el hecho de
no tener que direccionar bancos de memoria de datos, ni tener en cuenta en qu
posicin de memoria comienzan los registros de propsito general, porque en C
simplemente se declaran las variables, adems de la facilidad del procesamiento
matemtico, hace que generalmente me decida por el lenguaje C para realizar mis
aplicaciones.

Realizacin de algunos programas con microcontroladores de 8 bits

Demostracin con el PIC 16F1937

Materiales necesarios
-

Programador ICSP PICKIT3


Kit mTouch Referencia DM183026-2
Extensiones
Televisor o Video Beam

LOS MICROCONTROLADORES PIC DE 6 PINES

Existe en MICROCHIP la referencia de microcontroladores PIC de 6 pines llamada


10F20X, la cual incluye cuatro modelos: 10F200, 10F202, 10F204 y 10F206, estos
difieren entre s, bsicamente, por el tamao de sus memorias de datos y
programa.

Tabla comparativa para la referencia de microcontroladores 10F20X


Obviamente, con tan pocos pines, no existe la posibilidad de conectar un oscilador
externo, ste siempre deber programarse internamente, as las cosas, quedan
los dos pines de alimentacin y 4 lneas, una de ellas para la conexin del reset
MCLR, que tambin puede ser configurada como entrada y las otras tres pueden
ser configuradas como entrada o salida.
El usuario debe tener en cuenta que estos micros en encapsulado DIP poseen 8
pines, pero dos de ellos no se conectan, en montaje superficial, estas referencias
si tienen los seis pines exactos como puede verse en la figura siguiente que nos
ensea los diagramas de pines.

Diagrama de pines de los PIC 10F20X (Encapsulado DIP y SOIC)


Creo que hay muchos aficionados a los PIC que poseen aplicaciones con
dispositivos de 8 pines, donde solo utilizan 2 3 lneas de entrada y salida,
encareciendo as su producto para el usuario final y quizs disminuyendo las
posibilidades de competir en el mercado, simplemente, porque desconocen la
existencia de los 10F20X.
El primer programa ser en lenguaje C. Simplemente, detectar un nivel lgico
alto en el pin GP3 (Solo puede ser MCLR o pin de entrada) para activar las otras
tres salidas, es decir, GP0,1,2 y 3.

D1

R1
220

U1

D2

GP0
GP1
GP2/T0CKI/FOSC4
GP3/MCLR

R2
220

D3

PIC10F200

R3
220

R4
10k

Plano Electrnico

Programa en lenguaje C

// Se incluye la librera principal con los bits y registros especiales del micro
//********************************************************************************************
#include <xc.h>

// Se incluye librera principal con los SFR y sus bits

//********************************************************************************************
// Palabra de configuracin creada automticamente
//*********************************************************************************************

#include <xc.h>

// CONFIG
#pragma config WDTE = OFF
#pragma config CP = OFF

// Watchdog Timer (WDT disabled)


// Code Protect (Code protection off)

#pragma config MCLRE = OFF


// GP3/MCLR pin fuction is digital
//********************************************************************************************
// Se define la velocidad del oscilador
//********************************************************************************************
#define _XTAL_FREQ 4000000
//********************************************************************************************
// Programa principal
//********************************************************************************************
void main()
{
TRIS=0x08;

// Configuro GP3 como entrada. GP2, 1 y 0 como salida

GPIO=0;

// Limpio el Puerto nico en este micro

OPTION=0B00000000; // Necesario para el trabajo del pin GP2


//********************************************************************************************
while(1)

// Inicio del ciclo infinito

{
if (GP3==1) // Pregunto por el estado del pin GP3
{
GPIO=7;
}

// Si est en uno activo GP2, 1 y 0

else
{
GPIO=0;

// si no est en uno apago las salidas GP2, 1 y 0

}
}
}

El anterior es el cdigo en lenguaje C, utilizando el compilador XC8, que es el


ltimo aprobado y revisado para todas las familias de 8 bits de MICROCHIP (10F,
12F, 16F Y 18F). Este puede descargarse en forma gratuita, bajo su versin libre,
al
igual
que
la
nueva
plataforma
MPLABX
de
la
pgina
www.microchip.com/mplabx
A continuacin el cdigo en lenguaje ensamblador
; Se incluye la librera de cabecera con los registros y bits especiales del micro
;*********************************************************************************************
#INCLUDE <P10F200.INC>
;*********************************************************************************************
; Palabra de configuracin de bits
;*********************************************************************************************
__CONFIG _WDTE_OFF & _CP_OFF & _MCLRE_OFF
;*********************************************************************************************
; Bloque para registros de propsito general si los hay
;*********************************************************************************************
CBLOCK 0X10
ENDC
;*********************************************************************************************
ORG

00

GOTO

MAIN

; Voy a programa principal

ORG

05

; Salvo el vector de interrupciones

MOVLW

B'1000'

; Configuro GP3 como entrada y GP2,1 y 0

TRIS

GPIO

; como salidas

MOVLW

B'0000'

; Limpio el option pafra el buen trabajo del

MAIN

OPTION
PREG

OFF

; pin GP2

BTFSS

GPIO,3

; Pregunto por el estado del pin GP3

GOTO

OFF

; Si est en cero voy a apagar salidas

MOVLW

B'111'

; Si est en uno activo las salidas GP2,1, 0

MOVWF

GPIO

GOTO

PREG

; y retorno a preguntar por GP3

CLRF

GPIO

; Apago las salidas

GOTO

PREG

; y retorno a preguntar por GP3

END

VISUALIZACIN DE MENSAJES FIJOS Y VARIABLES EN LCD

LCD1

D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14

RS
RW
E
4
5
6

1
2
3

VSS
VDD
VEE

LM016L

El LCD y sus pines de conexin


Cuando se trabaja con diseo de circuitos electrnicos, muchas veces se tiene la
necesidad de visualizar cosas como: Instrucciones de manejo de una mquina, la
hora en un sistema de tiempo real, el monitoreo de una determinada variable, etc.
Una opcin muy interesante es el display de cristal lquido alfanumrico, estos
estn formados por una matriz de caracteres de 5x7 o 5x10 puntos cada uno,
organizados en 1, 2, 3 4 filas que pueden ir desde 16 hasta 40 caracteres. El
proceso de visualizacin est controlado por un microcontrolador instalado en su
parte posterior.
Todos poseen 16 pines. La luz de fondo est instalada en los pines 15 y 16. Los
dems tienen funciones especficas que se describen en el cuadro siguiente:

Funciones de cada uno de los pines del LCD


Los bits RS, WR y E son los que permiten el control del LCD, aunque el bit WR,
generalmente se encuentra conectado a GND, debido a que siempre estamos
escribiendo en el LCD y para eso este bit debe estar en 0. La funcin de lectura es
utilizada para consultar la bandera de ocupado o Busy Flag del LCD, pero como el
tiempo mximo que tarda ste en realizar una operacin, ya sea de configuracin
o visualizacin de un carcter es de 1,64 ms, simplemente, damos un retardo de 2
ms cada que se requiera una operacin y se evita as la consulta del Busy Flag.
El RS por el contrario, tiene un trabajo muy importante que es el de decidir si el
dato enviado al LCD es para configuracin del mismo, es decir, si queremos que
trabaje a una o dos lneas, a cuatro u ocho bits, con cursor visible o no, etc. O si el
dato es para visualizar. En el primer caso, este bit debe estar en 0 y en segundo
caso debe estar en 1.
El bit enable (E) es para autorizar cualquiera de las 2 operaciones anteriores en el
LCD. Para permitir la operacin el bit E debe estar en 1 y para terminarla, debe
ponerse en 0.
Para configurar el LCD se utiliza la matriz que se ve en el cuadro siguiente:

Matriz para la configuracin del modo de trabajo del LCD

Significado de cada uno de los bits de la matriz de configuracin


Por ejemplo si deseo seleccionar funciones en el LCD, me debo ubicar en la fila 4
de la matriz donde estn los bits DL, N y F los cuales significan:
DL es el ancho del bus de datos, en 1 es de 8 bits y en 0 es de 4 bits
N es el nmero de lneas, si es 1 es trabajo a 2 lneas, si es 0 es trabajo a 1 lnea.
F es es tamao de los caracteres, si es 1 es 5x7, si es 0 es 5x10
As, si deseo trabajar a 8 bits, 2 lneas y caracteres de 5x7 la palabra a enviar al
LCD debe ser 00111000. Recuerde que el 1 que hay en la matriz es obligatorio, en

este caso el bit 5, porque es quien permite al microcontrolador del LCD ubicarse
en la columna correspondiente. El dato en decimal es 56, este nmero no puede
estar en ninguna de las otras filas de la matriz, por la diagonal de unos obligatoria
que est presente en ella.
Ahora viene el programa en lenguaje C para el primer ejercicio de escribir
mensajes fijos en el LCD.
// Programa para escribir un mensaje fijo en un LCD de 2 lneas x 16 caracteres
//*********************************************************************************************
// Se incluye librera xc.h y palabras de configuracin de bits, todo esto generado
// automticamente por el compilador XC8
//*********************************************************************************************
#include <xc.h>
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Defino la velocidad del oscilador necesaria para el clculo de los delay
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
// Defino nombres propios para pines y puerto del PIC usados para RS, E y el dato
//*********************************************************************************************
#define

LCD_RS

RD6

#define

LCD_EN

RD7

#define

LCD_DATA PORTB

//*********************************************************************************************
// Declaro funciones para el LCD

//*********************************************************************************************
void lcd_init (void);

// Inicializacin del LCD

void set_lcd (void);

// Configuracin del LCD

void lcd_puts(const char * s);

// Cadenas de caracteres al LCD

void lcd_goto(unsigned char pos);

// Direcciones en el LCD

void lcd_write(unsigned char c); // Escritura en el LCD

void main()
{
TRISD=0;

// Puerto D como salidas para bits RS (RD6) y E (RD7)

TRISB=0;

// Puerto B como salidas para enviar el dato al LCD

PORTB=0;

// Limpio Puerto B

PORTD=0; // Limpio Puerto D


ANSEL=0;

// Todos los pines digitales

ANSELH=0; // Todos los pines digitales

lcd_init();

// Llamo funcn de inicializacin

while(1)
{
lcd_goto(0); // selecciono primera lnea
lcd_puts(" BIENVENIDOS
lcd_goto(0x40);
lcd_puts("

"); // Mensaje para la primera lnea

// Selecciono segunda lnea

LIBRO PIC

"); // Mensaje para la segunda lnea

while(1) // Ciclo while para no hacer nada. Ya mostr el mensaje.

continue;
}
}
void lcd_init (void) // funcin de inicializacin del LCD
{
LCD_DATA=2;

// Mando el dato 2 al Puerto para iniciar el LCD

set_lcd();

// Llamo la funcin de configuracin

LCD_DATA=56;

// Mando el dato 56 al Puerto para 8 bits, 2 lneas y 5x7

set_lcd();

// Llamo funcin de configuracin

LCD_DATA=15;

// Mando el dato 15 para prender LCD con cursor

set_lcd();
LCD_DATA=6;
set_lcd();
LCD_DATA=1;
set_lcd();
}

void set_lcd (void) // Funcin de configuracin


{
LCD_RS=0;

// RS en 0 para indicar al LCD que es configuracin

LCD_EN=1;

// Habilito la operacin

__delay_ms(2); // Retardo necesario para la operacin


LCD_EN=0;
}

// Termina la operacin

void lcd_goto(unsigned char pos)

// Funcin de direcciones

{
LCD_RS = 0;

// RS en 0 para configuracin

lcd_write(0x80+pos);

// Sumo 80H a pos que viene con un dato

}
void lcd_write(unsigned char c)

// Funcin de escritura en el LCD

{
LCD_EN=1;

// Habilito la operacin

LCD_DATA = ( c );

// Mando al puerto el dato que hay en c.

__delay_ms(2);

// Retardo necesario para operacin

LCD_EN=0;

// Termina la operacin

}
/* Escribo una cadena de caracteres en el LCD */
void lcd_puts(const char * s)
{
LCD_RS = 1;

// Habilito la operacin

while(*s)

// Mientras haya caracteres en la cadena enviada

lcd_write(*s++);

// Pase al siguiente

}
Todas las funciones utilizadas pueden formar un archivo de cabecera .h para
anexar al proyecto y dejar el programa principal ms corto.

LCD1
LM016L

D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14

RS
RW
E
4
5
6

1
2
3

VSS
VDD
VEE

U1
1
2
3
4
5
6
7
14
13
33
34
35
36
37
38
39
40

RE3/MCLR/VPP

RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7

15
16
17
18
23
24
25
26
19
20
21
22
27
28
29
30
8
9
10

PIC16F887

Simulacin mensaje fijo

MENSAJE VARIABLE EN EL LCD


Es muy sencillo mostrar mensajes fijos en el LCD, pero la versatilidad de estos
dispositivos es visualizar datos variables. En el ejemplo siguiente anexaremos un
conteo desde 0 a 999 al programa anterior y luego se monitorear la variable
voltaje cambiando desde 0 hasta 5 voltios.
// Programa para mostrar un mensaje variable en un display LCD de 2 x 16
//*********************************************************************************************
#include <xc.h>
//*********************************************************************************************
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
#define _XTAL_FREQ 4000000

//*********************************************************************************************
#define

LCD_RS RD6

#define LCD_EN RD7


#define LCD_DATA PORTB
//*********************************************************************************************
char centenas, decenas, unidades; // Defino variables char. Solo van de 0 a 9
int cont=0, aux=0; // Defino variables int. Van desde 0 hasta 999
void bin_bcd (void) // Funcin binario a BCD
{
aux=cont;

// paso cont a aux para no daar el proceso

centenas=0; // Inicializo variables en 0;


decenas=0;
unidades=0;
while(aux>=100) // Inicio restas sucesivas para Binario BCD
{
aux=aux-100;
centenas=centenas+1;
}
while(aux>=10)
{
aux=aux-10;
decenas=decenas+1;
}
unidades=aux;
}

void lcd_init (void);


void set_lcd (void);
void lcd_puts(const char * s);
void lcd_putch(char c);
void lcd_goto(unsigned char pos);
void lcd_write(unsigned char c);
void main()
{
TRISD=0;
TRISB=0;
PORTB=0;
PORTD=0;
PORTC=0;
ANSEL=0;
ANSELH=0;

lcd_init();
while(1)
{
lcd_goto(0); // selecciono primera lnea
lcd_puts("

CONTADOR

lcd_goto(0x40);

");

// Selecciono segunda lnea

lcd_puts(" IGUAL A:
while(cont<999)

");

{
cont++;
bin_bcd();
lcd_goto(0x4C);

// Ubico centenas en posicin 4C del LCD

lcd_putch(centenas+48); // Sumo 48 para pasar a ASCII


lcd_goto(0x4D);

// Ubico decenas en posicin 4D del LCD

lcd_putch(decenas+48);

// Sumo 48 para pasar a ASCII

lcd_goto(0x4E);

// Ubico unidades en posicin 4D del LCD

lcd_putch(unidades+48); // Sumo 48 para pasar a ASCII


__delay_ms(500);
}
}
}

void lcd_init(void)
{
LCD_DATA=2;
set_lcd();
LCD_DATA=56;
set_lcd();
LCD_DATA=15;
set_lcd();
LCD_DATA=6;
set_lcd();
LCD_DATA=1;

// Incremento cuenta cada 500 ms

set_lcd();
}

void set_lcd (void)


{
LCD_RS=0;
LCD_EN=1;
__delay_ms(2);
LCD_EN=0;
}

/*
* Voy a una posicin especfica
*/
void lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write(0x80+pos);
}

void lcd_write(unsigned char c)


{

LCD_EN=1;
LCD_DATA = ( c );

__delay_ms(2);
LCD_EN=0;
}

/* Escribo una cadena de caracteres en el LCD */

void lcd_puts(const char * s)


{
LCD_RS = 1;
while(*s)
lcd_write(*s++);
}

/* Escribo un caracter en el LCD */

void lcd_putch(char c)
{
LCD_RS = 1;
lcd_write( c );
}

// write characters

LCD1
LM016L

D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14

RS
RW
E
4
5
6

1
2
3

VSS
VDD
VEE

U1
1
2
3
4
5
6
7
14
13
33
34
35
36
37
38
39
40

RE3/MCLR/VPP

RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7
PIC16F887

Simulacin de mensaje variable

15
16
17
18
23
24
25
26
19
20
21
22
27
28
29
30
8
9
10

CONVERSIN ANLOGO A DIGITAL EN EL PIC 16F887

Bloque ADC del PIC16F887


El mdulo del conversor en la mayora de los microcontroladores de 8 bits de
MICROCHIP es de 10 bits, por lo tanto, su resolucin ser:
Resolucin = Vreferencia / # de cuantificaciones (1023)
El microcontrolador 16F887 posee 14 canales anlogos llamados AN0,
AN1AN13 distribuidos en los puertos A, B y E, los registros que permiten la
seleccin individual de cada canal son ANSEL y ANSELH que vienen configurados
de fbrica para recibir seales anlogas, es por eso que en los programas
anteriores siempre se ponan a 0 cuando en ellos iba a intervenir algn pin de los
puertos A, B E.

Registros ANSEL Y ANSELH


Si observan el diagrama de pines del 16F887, pueden notar que los canales AN0
a AN7 estn ubicados en los puertos A y E, por lo tanto, el ANSEL tiene que ver
con la conversin en cualquiera de esos canales. Los canales 8 al 13 estn
ubicados en el puerto B y por eso es el ANSELH quien se encargar de ellos.
Por ejemplo, si deseo configurar el canal 3 para la conversin A/D de una seal
anloga a digital, debo poner en uno el bit 3 del registro ANSEL y obviamente
configurar como entrada el bit 3 del registro TRISA para que quede como entrada
el bit 3 del puerto A.
ANSEL= 0B00001000; // En hexadecimal 0x08;
TRISA = 0B00001000;
Adicionalmente, existen otros registros relacionados con la conversin anlogo a
digital como son: ADCON0, ADCON1, ADRESH y ADRESL, los dos ltimos son
los que almacenan el resultado digital de la conversin, ya que el mdulo de
conversin es a 10 bits, esos 10 bits del resultado se pueden alinear a izquierda o
a derecha con la configuracin del bit ADFM del registro ADCON1.

Alineacin del resultado digital de la conversin A/D


Los registros ADCON0 y ADCON1 son los de control de la conversin A/D, en
ellos se configura la velocidad del conversor, el canal elegido, la alineacin del

resultado, el voltaje de referencia, el bit de inicio de la conversin que igualmente


sirve como bandera de indicacin de la finalizacin del proceso.
Se plantear entonces un ejercicio bsico para entender la conversin A/D y luego
se trabajar con una seal de voltaje visualizada en en LCD y una seal de
temperatura enviada serialmente al PC.
Para todos los ejemplos se utiliza la alimentacin como voltaje de referencia, as
las cosas la resolucin ser:
Resolucin = 5V / 1023 = 0,00488 V/cuantificacin
Seal anloga = Seal digital * resolucin
Se utiliza un potencimetro conectado en el pin E0 del microcontrolador, que
pertenece al canal anlogo AN5. Lo primero es configurar los registros ANSEL y
TRISE as:
ANSEL = 0B00100000; // Canal AN5 anlogo
TRISE = 0B00000001;
Ahora el registro ADCON0

// Bit 0 del puerto E como entrada

Registro ADCON0
Para el ejercicio, si queremos velocidad Fosc/8, canal 5 y habilitar el mdulo de
conversin, el ADCON0 queda as:
ADCON0 = 0B01010101;
Por ltimo el ADCON1

Registro ADCON1
Si el voltaje de referencia es el de alimentacin y se quiere alinear el resultado a la
derecha, el registro ADCON1 queda as:
ADCON1 = 0B10000000;
Programa de conversin anlogo a digital
//*********************************************************************************************
// Se incluye archivo de cabecera xc.h y las palabras de configuracin
//*********************************************************************************************
#include <xc.h>
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Se define al velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000

//*********************************************************************************************
void main()
{
TRISE=0X01;

// Bit 0 del puerto E como entrada

TRISB=0;

// Puerto B como salida para resultado digital LSB en leds

TRISC=0;

// Puerto C como salida para resultado digital MSB en leds

ADCON0=0X55; // Fosc/8, canal 5 y habilitacin del mdulo de conversin


ADCON1=0X80; // Vref 5V y alineacin del resultado a derecha
ANSEL=0X20;

// Canal AN5 anlogo

ANSELH=0;

// Todos los demas pines digitales

PORTB=0;

// Limpio Puerto B

PORTC=0;

// Limpio Puerto B

while(1)
{
GO=1;

// Inicio el proceso de conversin

while(GO==1) // Mientras este bit este en uno est an en el proceso


continue;

}
}

// Si cambia a 0 termin la conversin

PORTB=ADRESL;

// Paso parte baja del resultado al puerto B

PORTC=ADRESH;

// Paso parte alta del resultado al puerto C

__delay_ms(200);

// Conversin cada 200 ms

D1
LED-RED
D2

R1

LED-RED
D4

U1
1

220

R2

2
3
4
5
6
7
14
13

220

R3
220

LED-RED
D5

R4
220

R5
LED-RED
D6

LED-RED
D7

33
34
35
36
37
38
39
40

220

R6
220

R7
220

LED-RED
D8

R8

LED-RED

D10

R9

RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RA0/AN0/ULPWU/C12IN0RC2/P1A/CCP1
RA1/AN1/C12IN1RC3/SCK/SCL
RA2/AN2/VREF-/CVREF/C2IN+ RC4/SDI/SDA
RA3/AN3/VREF+/C1IN+
RC5/SDO
RA4/T0CKI/C1OUT
RC6/TX/CK
RA5/AN4/SS/C2OUT
RC7/RX/DT
RA6/OSC2/CLKOUT
RA7/OSC1/CLKIN
RD0
RD1
RB0/AN12/INT
RD2
RB1/AN10/C12IN3RD3
RB2/AN8
RD4
RB3/AN9/PGM/C12IN2RD5/P1B
RB4/AN11
RD6/P1C
RB5/AN13/T1G
RD7/P1D
RB6/ICSPCLK
RB7/ICSPDAT
RE0/AN5
RE1/AN6
RE2/AN7

15
16
17
18
23
24
25
26

C0
C1

19
20
21
22
27
28
29
30
U1(RE0/AN5)
V=4.45

8
9
10

PIC16F887

220
LED-RED
D9

RE3/MCLR/VPP

C0

220

R10

RV1
C1

220

LED-RED

89%

LED-RED
D3

1k

Figura 6. Plano Electrnico


Como se puede ver en la simulacin el resultado digital en los leds es de 909, as
confirmamos el valor de voltaje a la entrada multiplicando por la resolucin
Seal anloga = 909 * 0.00488 = 4.44V que es lo que nos muestra el medidor a la
entrada.

MONITOREO DE VOLTAJE CON VISUALIZACIN EN EL LCD


En esta oportunidad combinaremos la visualizacin en el LCD con la conversin
A/D para realizar as, algunas aplicaciones particulares.
A continuacin el lenguaje en lenguaje C con su respectiva documentacin
// Se incluye el archivo de cabecera y las palabras de configuracin generadas
automticamente
//*******************************************************************************
#include <xc.h>
//*******************************************************************************
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*******************************************************************************
// Definicin de la velocidad del oscilador
//*******************************************************************************
#define _XTAL_FREQ 4000000
//*******************************************************************************
// Nombres a pines y puerto del PIC para el trabajo en el LCD
//*******************************************************************************
#define

LCD_RS

RD6 // Llamo LCD_RS al pin RD6

#define

LCD_EN

RD7 // Llamo LCD_E al pin RD7

#define

LCD_DATA PORTB // Llamo LCD_DATA al puerto B

//*******************************************************************************
// Declaracin de variables
//*******************************************************************************
Unsigned int voltaje, digital,temp; // Declaro variables enteras sin signo

char diezmil, miles, centenas, decenas, unidades; // Declaro variables char


//*******************************************************************************

// Declaracin de funciones
//*******************************************************************************

void binbcd (void); // Funcin para conversin de binario a BCD


void lcd_init (void); // 6 funciones necesarias para trabajar el LCD
void set_lcd (void);
void lcd_puts(const char * s);
void lcd_putch(char c);
void lcd_goto(unsigned char pos);
void lcd_write(unsigned char c);

void main()
{
TRISD=0;

// Puerto D como salidas para pines RS (RD6) y E (RD7)

TRISB=0;

// Puerto B como salidas para envo del dato al LCD

PORTB=0;

// Limpio Puerto B

PORTD=0;

// Limpio Puerto D

TRISE=0X01;

// Bit 0 del Puerto E como entrada. Canal anlogo AN5

ADCON0=0X55;

// Velocidad Fosc/8, Canal 5, Mdulo conversor en ON

ADCON1=0X80;

// Vref = 5V, Alineacin del resultado a derecha

ANSEL=0X20;

// Seleccin unicamente canal 5 como anlogo

ANSELH=0;

// los dems pines digitales

lcd_init();

// Llamo funcin de inicializacin del LCD

while(1)

// Inicio ciclo infinito

{
lcd_goto(0);

// selecciono primera lnea

lcd_puts (" EL VOLTAJE DEL "); // Mensaje para la primera lnea


lcd_goto (0x40);

// Selecciono segunda lnea

lcd_puts ("PROCESO ES: . "); // Mensaje para la segunda lnea


GO=1;

// Inicio el proceso de conversin

while(GO==1)

// Mientras GO=1, est en proceso

continue;

// Si pasa a 0 continuo

digital=(ADRESH*256)+ADRESL; // Algoritmo clculo dato digital


voltaje=digital*49;

// Multiplico por resolucin

binbcd();

// Voy a conversin BIN a BCD

lcd_goto(0x4C);

// Ubico entero en CC del LCD

lcd_putch(diezmil+48);

// Sumo 48 para convertir a ASCII

lcd_goto(0x4E);

// Ubico decimal en CE del LCD

lcd_putch(miles+48);

// Sumo 48 para convertir a ASCII

lcd_goto(0x4F);

// Ubico otro decimal en CF del LCD

lcd_putch(centenas+48);

// Sumo 48 para convertir a ASCII

__delay_ms(500);

// Repito proceso cada 500 ms

}
}
void lcd_init(void)

// Funcin de inicializacin del LCD

{
LCD_DATA=2;

// Ver captulo de manejo del LCD

set_lcd();
LCD_DATA=56;
set_lcd();
LCD_DATA=15;
set_lcd();
LCD_DATA=6;
set_lcd();
LCD_DATA=1;
set_lcd();
}
void set_lcd (void)
{
LCD_RS=0;
LCD_EN=1;
__delay_ms(2);
LCD_EN=0;
}

void lcd_goto(unsigned char pos)


{
LCD_RS = 0;
lcd_write(0x80+pos);
}
void lcd_write(unsigned char c)
{

LCD_EN=1;
LCD_DATA = ( c );
__delay_ms(2);
LCD_EN=0;
}
/* Escribo una cadena de caracteres en el LCD */
void lcd_puts(const char * s)
{
LCD_RS = 1;
while(*s)
lcd_write(*s++);
}
/* Escribo un caracter en el LCD */
void lcd_putch(char c)
{
LCD_RS = 1;

// write characters

lcd_write( c );
}
void binbcd (void)
{
temp=voltaje;

// Paso voltaje a temperatura para no daar el resultado

diezmil=0;

// Inicializo variables en 0

miles=0;
centenas=0;
decenas=0;

unidades=0;
while(temp>10000)
{
temp=temp-10000;
diezmil=diezmil+1;
}
while(temp>1000)
{
temp=temp-1000;
miles=miles+1;
}
while(temp>100)
{
temp=temp-100;
centenas=centenas+1;
}
while(temp>10)
{
temp=temp-10;
decenas=decenas+1;
}
unidades=temp;
}

// Inicio restas sucesivas para obtener datos en BCD

Simulacin

COMUNICACIN SERIAL A TRAVS DEL MDULO USART


A pesar de los tantos protocolos de comunicacin existentes en la actualidad, el
protocolo de comunicacin serial bajo la norma RS232 sigue estando vigente para
muchas de las aplicaciones que requieren de un envo o recepcin de datos. Los
dispositivos programables nos facilitan el trabajo porque ahora incluyen en su
mayora, un mdulo llamado USART o a veces solo UART, debido a que la opcin
sncrona ha dejado de usarse por ser solo Hall Duplex y cada vez es ms
necesario estar enviando y recibiendo datos al tiempo, esto se consigue con la
opcin asincrna que permite el trabajo bidireccional tambin conocido como Full
Duplex.
El mdulo UART particularmente en los PIC, solo requiere que el dato sea puesto
en un registro de transmisin y listo. Las tramas ya estn calculadas por los
registros de desplazamiento TSR para la transmisin y RSR para la recepcin y la
velocidad est garantizada con la configuracin acertada del registro generador de
baudios.
Los registros asociados al proceso de transmisin y recepcin con el mdulo
UART del PIC 16F887 son:
TXREG: Registro donde se almacena el dato a enviar
RCREG: Registro donde se almacena el dato recibido
TXSTA: Registro de control de la transmisin
RCSTA: Registro de control de la recepcin
SPBRG: Generador de baudios
Hablemos de TXSTA, RCSTA y SPBRG para entender bien el proceso.

Registro de control de la transmisin TXSTA


Registro TXSTA
Para realizar una transmisin a 8 bits debemos tener en cuenta en este registro, el
bit 5 TXEN = 1 para habilitar la transmisin, el bit 2 BRGH para calcular la palabra
de configuracin del registro generador de baudios SPBRG as:
Si BRGH = 0 se tiene una constante K = 64 para desarrollar la frmula, pero si el
bit BRGH = 1, se tiene una constante K = 16.
SPBRG = [Fosc (Hz) / ( K * Velocidad en baudios)] 1

Por ejemplo si queremos realizar una comunicacin a 9600 bps y tenemos un


oscilador de 20 Mhz y configuramos el bit BRGH en 0. La palabra a enviar al
registro SPBRG ser:
SPBRG = [20000000 / (64*9600)] 1 = 31.552 = 32
Generalmente, hay un error en la comunicacin, debido a que el dato a cargar en
el SPBRG es un entero aproximado, entonces la velocidad ser un poco ms o
menos de lo deseado. Calculemos el error para el ejemplo anterior as:
Error = [(Vel. Calculada Vel. Deseada) / Vel. Deseada] * 100
La velocidad deseada es 9600, pero la real calculada es:
Vel (bps) = [Fosc (Hz) / (K*(SPBRG+1))] = [20000000 Hz / (64 * 32+1)] = 9469.7
Error = [(9469.7 9600) / 9600] * 100 = - 1.357%
Estos datos se pueden confirmar en las tablas que hay en las figuras 3 y 4 de este
captulo.
Por ltimo se debe tener en cuenta la bandera de finalizacin de la transmisin
TRMT, la cual se pone en uno cuando el registro de desplazamiento de la
transmisin TSR est vaci indicando que se puede enviar otro dato.
Para el primer ejercicio se trabajar con frecuencia de oscilacin de 4 Mhz y con
una velocidad de 9600 baudios, con el bit BRGH del registro TXSTA en 1. Por lo
tanto la palabra para cargar el SPBRG debe ser:
SPBRG = [4000000 / (16 * 9600)] 1 = 25
Tenemos entonces 2 registros listos
TXSTA = 0X24;

// Hablito transmisin y BRGH en 1

SPBRG = 25 ;

// Velocidad 9600 bps

Registro de control de la recepcin RCSTA


Aunque solo vamos a transmitir, el bit de habilitacin del puerto serial se encuentra
en el registro RCSTA (bit 7 llamado SPEN). Por lo tanto, se debe poner ese bit a 1
SPEN = 1;

Tabla para configurar SPBRG con bit BRGH en 0

Tabla para configurar SPBRG con bit BRGH en 1


Hagamos uso de los registros configurados para el primer ejemplo que ser
simplemente enviar un carcter al PC.
// Programa de comunicacin serial bsico
//*********************************************************************************************
// Se incluye librera xc.h y palabras de configuracin de bits
//*********************************************************************************************
#include <xc.h>
//*********************************************************************************************
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Defincin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
void main()
{

TRISC=0;

// Puerto C como salidas para el pin de transmisin

TXSTA=0X24;

// Habilito la transmission y bit BRGH en 1

SPBRG=25;

// Velocidad a 9600 bps

SPEN=1;

// Habilito el Puerto serial del PIC

while(1)
{
TXREG=65;

// Envo la letra a en ASCII

while(TRMT==0)

// Pregunto si TSR est vaco para enviar nuevamente

continue;
__delay_ms(500);

// Envo cada 500 ms

}
}

Simulacin
Cuando deseamos enviar cadenas de caracteres existe la instruccin printf que
hace parte de la librera stdio.h.

Veamos un ejemplo donde se enva una cadena de caracteres y una variable.


//*********************************************************************************************
// Programa serial para envi mediante la instruccin printf al PC.
//*********************************************************************************************
// Se incluyen las libreras necesarias
//*********************************************************************************************
#include <xc.h>
#include <stdio.h>
//*********************************************************************************************
// Palabras de configuracin de bits generadas automticamente por el software
//*********************************************************************************************
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
// Definicin de variables y funciones
//*********************************************************************************************
char cont;
void putch (unsigned char byte);
//*********************************************************************************************
void main()

{
TRISC=0;

// Puerto C como salidas para pin de transmisin

SPEN=1;

// Habilitacin del Puerto serial del PIC

SPBRG=25;

// Velocidad 2400 bps

TXSTA=0X20;

// Habilito la transmisin y bit BRGH en 0

while(1)
{
for(cont=0;cont<10;cont++) // for para el conteo de uno a 10
{
printf("\r Contador = %d\n",cont); // Envo del mensaje y la variable cont
__delay_ms(1000);

// Envo cada segundo

}
}
}
void putch (unsigned char byte) // Funcin para envo con printf
{
while(!TRMT)

// Pregunto si TRMT cambio a 1

continue;
TXREG=byte;
}

// Envo el siguiente byte

Simulacin
Por ltimo, vamos a utilizar la comunicacin para monitorear una variable anloga
y enviarla al PC
// Programa de monitoreo de temperatura en el PC
//*********************************************************************************************
// Se incluyen las libreras necesarias y las palabras de configuracin de bits
//*********************************************************************************************
#include <xc.h>
#include <stdio.h>
__CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF
& CPD_OFF & BOREN_ON & IESO_ON & FCMEN_ON & LVP_OFF);
__CONFIG(BOR4V_BOR40V & WRT_OFF);
//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************

#define _XTAL_FREQ 4000000


//*********************************************************************************************
// Declaracin de variables y funciones
//*********************************************************************************************
int digital;
float temperatura;
void putch (unsigned char byte);
//*********************************************************************************************
void main()
{
TRISE=0X02;

// Bit 1 del Puerto E como entrada. Canal anlogo AN6

TRISC=0;

// Puerto C como salida para pin de transmisin

ADCON0=0X59; // Velocidad de conversion Fosc/8, canal 6, mdulo A/D ON


ADCON1=0X80; // Vref = 5V y alineacin del resultado digital a derecha
ANSEL=0X40;

// Canal 6 anlogo

ANSELH=0;

// los dems pines digitales

TXSTA=0X26;

// Habilito transmisin y bit BRGH en 1

SPBRG=25;

// Velocidad 9600 bps

RCSTA=0X80;

// Habilitacin del puerto serial del PIC

while(1)
{
GO=1;

// Inicio la conversion A/D

while(GO==1) // Mientras est en uno continua la conversin


continue;
digital=(ADRESH*256)+ADRESL; // Unifico el valor digital del resultado

temperatura=((digital*0.488)-50); // Algoritmo para clculo de la temperatura


printf("\r La temperatura es:%2.2f\n",temperatura); // Envo de la cadena de
// caracteres y la variable.
__delay_ms(200);

// Cada 200 ms

}
}
void putch (unsigned char byte)

// Funcin para el trabajo con printf

{
while(!TRMT)
continue;
TXREG=byte;
}

Simulacin

// Envo de cada byte de la cadena de


// caracteres

RECEPCIN DE DATOS POR INTERRUPCIN


Generalmente hablamos de transmitir datos, pero nunca nos ocupamos de la
recepcin. En este ejemplo se ver una forma muy prctica de recibir datos
utilizando la interrupcin por recepcin.
Se enviar un dato desde un microcontrolador a otro, donde se comparar y se
anunciar en dos leds si es mayor o menor que el dato elegido en el receptor.
Si la lectura del puerto A que tiene 3 entradas, es decir, que puede estar entre 0 y
7, es mayor a 4 que fue el nmero elegido para comparar en el receptor, se
activar RA0, pero si es menor a 4, se activar RA1. El nmero recibido
serialmente por medio de una interrupcin por recepcin siempre se muestra en el
display de siete segmentos.

En la simulacin superior se puede ver que la lectura del puerto A es 3, ya que los
pulsadores ubicados en RA0 y RA1 no estn presionados y la polarizacin de
estos es a 5V, por lo tanto se leen unos, el pulsador RA2 est presionado, es decir
que entra un 0. La lectura es 3, es menor a 4 y por eso se activa RA1.
En la simulacin inferior se puede ver que la lectura del puerto A es 7, ya que los 3
pulsadores no estn presionados y la polarizacin de estos es a 5V, por lo tanto se
leen unos. La lectura es 7, es mayor a 4 y por eso se activa RA0.
Mientras no haya interrupcin por recepcin del dato, el PIC permanece activando
y desactivando la salida RA2.
Programa de transmisin

//*********************************************************************************************
// Se incluye la librera xc.h con bits y registros especiales del micro
//*********************************************************************************************
#include <xc.h>
//*********************************************************************************************
// Palabras de configuracin de bits
//*********************************************************************************************

// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = OFF

// XT oscillator
// Watchdog Timer Disable
// Power-up Timer Enable bit (PWRT disabled)
// pin function is MCLR
// Program memory code protection is disabled
// Data memory code protection is disabled
// BOR enabled
// Internal External Switchover
// Fail-Safe Clock Monitor Enabled bit
// HV on MCLR must be used for programming

// CONFIG2
#pragma config BOR4V = BOR21V // Brown-out Reset set to 2.1V
#pragma config WRT = OFF

// Flash Program Memory Disable

//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
// Declaracin de variables
//*********************************************************************************************
char aux=0;
//*********************************************************************************************
void main()

{
TRISC=0X00;

// Puerto C como salidas para pin TX

TRISA=0XFF;

// Puerto A como entradas para lectura de pulsadors+es

TXSTA=0X26;

// Habilito transmisin y bit BRGH en 1

SPBRG=25;

// Velocidad a 9600 bps

SPEN=1;

// Habilito Puerto serial del PIC

ANSEL=0;

// Todos los pines digitales

ANSELH=0;

// Todos los pines digitales

while(1)
{
aux=PORTA; // Leo el puerto A y lo llevo al registro aux
TXREG=aux; // Llevo el dato al registro de transmisin
while(TRMT==0)
continue;
__delay_ms(5000);

// Espero a que termine el envo del dato


// Para continuar
// Retardo de 5 segundos

}
}

Programa de recepcin
//*********************************************************************************************
// Se incluye librera con bits y registros especiales
//*********************************************************************************************
#include <xc.h>
//*********************************************************************************************

// Palabras de configuracin de bits


//*********************************************************************************************
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = OFF

// XT oscillator
// Watchdog Timer Disable
// Power-up Timer Enable bit (PWRT disabled)
// pin function is MCLR
// Program memory code protection is disabled
// Data memory code protection is disabled
// BOR enabled
// Internal External Switchover
// Fail-Safe Clock Monitor Enabled bit
// HV on MCLR must be used for programming

// CONFIG2
#pragma config BOR4V = BOR21V // Brown-out Reset set to 2.1V
#pragma config WRT = OFF

// Flash Program Memory Disable

//*********************************************************************************************
// Definicin de la velocidad del oscilador
//*********************************************************************************************
#define _XTAL_FREQ 4000000
//*********************************************************************************************
// Declaracin de variables
//*********************************************************************************************
char temp=4;
char aux;

//*********************************************************************************************
void main()
{
TRISC=0X80;

// Puerto C como salidas para display solo C7 entrada para RX

TRISA=0;

// Puerto A como salidas para los leds indicadores

TRISD=0;

// Puerto D como salidas para habilitar transistor de display

TXSTA=0X26;

// Habilito transmisin y bit BRGH en 1

SPBRG=25;

// Velocidad 9600 bps

RCSTA=0X90;

// Habilito puerto serial y recepcin de datos

INTCON=0XC0; // Habilito interrupciones perifricas


RCIE=1;

// Habilito interrupcin por recepcin

ANSEL=0;

// Todos los pines digitales

ANSELH=0;

// Todos los pines digitales

PORTA=0;

// Limpio Puerto A

PORTD=0;

// Limpio Puerto D

PORTC=0;

// Limpio puerto C

RD0=1;

// Habilito transistor para el display

while(1)
{
RA2=~RA2;

// Mientras no hay interrupcin, hay intermitencia en

__delay_ms(200);

// salida RA2 cada 200 ms

}
}
void interrupt isr()
{

// Funcin de interrupcin

PORTC=RCREG;

// Paso dato recibido al Puerto C para mostrar

aux=RCREG;

// Paso dato recibido al registro aux para comparacin

if(aux>temp)

// Comparo dato recibido con la constante temp

{
RA0=1;

// Si dato recibido es mayor activo RA0 por un segundo

__delay_ms(1000);
RA0=0;
}
else

// Si es menor, active RA1 por un segundo

{
RA1=1;
__delay_ms(1000);
RA1=0;
}
RCIF=0;

// Limpio bandera de interrupcin

__delay_ms(100);
}

MODULACIN DE ANCHO DE PULSO - PWM


La modulacin de ancho de pulso es una tcnica que suministra potencia a una
carga cambiando rpidamente entre los estados ON y OFF, es decir carga
completa y cero carga. La seal PWM se asemeja a una onda cuadrada donde la
porcin alta de la seal es considerada el estado ON y la porcin baja el estado
OFF. La porcin alta tambin conocida como ancho de pulso puede variar en
tiempo y es definida por pasos. Un alto nmero de pasos extiende el ancho de
pulso y aplica mayor potencia a la carga, disminuir el nmero de pasos implica
acortar el ancho de pulso y por lo tanto disminuir la potencia a la carga. El perodo
PWM es definido como la duracin de un ciclo completo o la cantidad total de
tiempo combinada en alto y bajo.
La resolucin PWM, define el mximo nmero de pasos que pueden estar
presentes en un perodo PWM. Una resolucin alta permite un control ms preciso
del tiempo del ancho de pulso y por ende de la potencia aplicada a la carga.
El trmino Duty Cycle determina la proporcin del tiempo en ON y OFF y es
expresado en porcentaje, donde 0% es estado OFF y 100% es estado ON, por
ejemplo, si tenemos el 40% de Duty Cycle, significa que el ancho de pulso (Estado
ON) es del 40% de la onda y el 60% es el estado OFF bajo de la onda. En otras
palabras un Duty Cycle bajo determina menos potencia aplicada a la carga y un
Duty Cycle alto significa ms potencia aplicada a la carga.
La tcnica PWM es muy utilizada para el control de motores, control de
iluminacin entre otros.
MODULACIN DE ANCHO DE PULSO EN LOS MICROCONTROLADORES PIC
Aprovechemos la presencia en el mercado de los nuevos microcontroladores PIC
de MICROCHIP y elijamos una de estas referencias nuevas, llenas de grandes
caractersticas para practicar con este tema.
Para este caso vamos a trabajar con un PIC de 18 pines referencia 16F1827 que
posee entre otras cosas 4 mdulos CCP, quiere decir que con cada mdulo yo
puedo trabajar Comparacin, Captura o PWM, en este caso nos dedicaremos al
tema de modulacin de ancho de pulso en el primer mdulo, es decir el CCP1, el
cual se puede trabajar a 10 bits.

Podemos ver en el diagrama de pines que el mdulo CCP1 tiene salida por los
pines RB0 por el pin RB3. Se selecciona en el registro APFCON.

El perodo, el Duty Cycle y la resolucin son controladas por los siguientes


registros:
PRx: Registro de 8 bits en el que se almacena el perodo que deseo para la
modulacin
TxCON: Control para los timer 2, 4 y 6

CCPRxL: Registro donde se almacenan los 8 bits ms significativos para el ancho


de pulso que se desea.
CCPxCON: Registro que define el trabajo del mdulo CCP, si es PWM, los 4 bits
menos significativos son los que tienen que ver con l. Los bits 4 y 5 son los 2 bits
menos significativos para completar los 10 bits del proceso.

Obviamente, el correspondiente registro TRISB deber ser limpiado en RB0


RB3, segn la salida que vayamos a utilizar para la modulacin.
Veamos un ejemplo para explicar de una mejor manera la tcnica PWM

#include <xc.h>
// CONFIG1
#pragma config FOSC = HS

// Oscillator Selection HS Oscillator, High-speed

#pragma config WDTE = OFF

// Watchdog Timer Enable (WDT disabled)

#pragma config PWRTE = OFF

// Power-up Timer Enable (PWRT disabled)

#pragma config MCLRE = ON


#pragma config CP = OFF

// MCLR Pin Extern


// Flash Program Memory Code Protection disable

#pragma config CPD = OFF

// Data Memory Code Protection disabled

#pragma config BOREN = ON

// Brown-out Reset Enable

#pragma config CLKOUTEN = OFF // Clock Out Disable


#pragma config IESO = ON

// Internal/External Switchover

#pragma config FCMEN = ON

// Fail-Safe Clock Monitor Enable

// CONFIG2
#pragma config WRT = OFF

// Flash Memory Self-Write Protection

#pragma config PLLEN = OFF

// PLL Enable (4x PLL disabled)

#pragma config STVREN = ON

// Stack Overflow/Underflow Reset Enable

#pragma config BORV = LO

// Brown-out Reset Voltage Selection

#pragma config LVP = OFF

// Low-Voltage Programming Disable

#define _XTAL_FREQ 20000000


unsigned int i;
void main ()
{
TRISB=255; //Deshabilito la salida del mdulo CCP1, mientras se
//realiza la configuracin de los registros
APFCON0=0;

//Elijo RB3 para salida CCP1, en 1 es RB0

PR2=255;

// Perodo para la seal PWM + 2 bits del oscilador int

CCPTMRS=0;

// Bits 0 y 1 para elegir el timer para CCP1. TMR2=0;

CCPR1L= 128;

// Ancho de pulso 8 MSB

CCP1CON=0X0C; // Bits 4 y 5 LSB para ancho de pulso y bits 0,1,2,3


// 11xx = para modo PWM
TMR2IF=0; // Limpio bandera de desbordamiento del TMR2
T2CON=0B00000010; // Preescala y activacin del timer2
TRISB=0;

// Habilito el mdulo CCP1

while(1)
{
TMR2=0;
for (i=0;i<250;i++)
{
TMR2ON=1; // bit 2 del T2CON se activa TMR2
while (TMR2IF==0)
continue;
TMR2IF=0;
}
}
}
Las frmulas para hallar los diferentes parmetros son las siguientes:
1 Perodo PWM = (PRx + 1) * 4 * Tosc * Preescala del TIMER
2 Ancho de pulso = CCPRxL:CCPxCON(4:5) * Tosc * Preescala del TIMER
3 Duty Cycle = {CCPRxL:CCPxCON(4:5) } / { 4(PRx + 1)}
4 Resolucin = log {4 (PRx + 1)} / log (2)

5 Frecuencia PWM = 1 / Perodo PWM


Ejemplo: Supongamos que tenemos el PIC 1827 trabajando a una Fosc de 20
MHZ, un periodo PWM mximo configurado en el registro PR2 = 255 y un ancho
de pulso configurado como 10000000 00 en el registro CCPR1L y en los bits 4 y 5
del registro CCP1CON, es decir un ancho de pulso de 512, adems de una
preescala para el TIMER2 de 16 configurada en el registro T2CON. As las cosas,
entremos a calcular cada uno de los parmetros:
1 Perodo PWM = (255 + 1) * 4 * 1/Fosc * 16 = 256 * 4 * 0,05us * 16 = 819us
2 Ancho de pulso = 512 * 0,05us * 16 = 410us
3 Duty cycle = ( 512 / 1024 ) * 100 = 50% ON y 50% OFF
4 Resolucin = log (1024) / log(2) = 10 bits
5 Frecuencia PWM = 1 / 819us = 0,00122 MHZ = 1,22 KHZ
La base de tiempo para la modulacin por CCP1 ser el Timer2, es decir, el TMR2
se inicia y empieza a compararse con el valor de ancho de pulso configurado, el
nivel de salida en el pin CCP1 inicia en alto, cuando son igulaes el TMR2 y el
ancho de pulso configurado, la salida del CCP1 pasa a nivel bajo, el TMR2 sigue
incrementndose, pero esta vez se compara con el perodo configurado, cuando
son iguales, el TMR2 se hace 0 y la salida del CCP1 vuelve a nivel alto para iniciar
un nuevo ciclo.
Los valores se pueden confirmar en la simulacin en proteus mostrada en la figura
siguiente:

Si se quiere ir incrementando el ancho de pulso poco a poco, simplemente se


inicia el registro que tiene que ver con el ancho de pulso, es decir el CCPR1L en 0
y se va incrementando en uno en el programa principal. El cdigo para ese
programa quedara as:
void main ()
{
TRISB=255; //Deshabilito la salida del mdulo CCP1, mientras se
//realiza la configuracin de los registros
APFCON0=0;
PR2=255;

//Elijo RB3 para salida CCP1, en 1 es RB0

// Perodo para la seal PWM + 2 bits del oscilador int

CCPTMRS=0;

// Bits 0 y 1 para elegir el timer para CCP1. TMR2=0;

CCPR1L= 0; // Ancho de pulso 8 MSB se inicia en 0.


CCP1CON=0X0C; // Bits 4 y 5 LSB para ancho de pulso y bits 0,1,2,3

// 11xx = para modo PWM


TMR2IF=0; // Limpio bandera de desbordamiento del TMR2
T2CON=0B00000010; // Preescala y activacin del timer2
TRISB=0;

// Habilito el mdulo CCP1

while(1)
{
TMR2=0;
for (i=0;i<250;i++)
{
TMR2ON=1; // bit 2 del T2CON se activa TMR2
while (TMR2IF==0)
continue;
TMR2IF=0;
}
CCPR1L = CCPR1L +1; Se incrementa ancho de pulso en uno
}
}

Introduccin a la familia de dispositivos de 16 bits de Microchip

Los microcontroladores de 16 bits referencia 24FXXXXX


Programacin en lenguaje C de una aplicacin I/O sobre la tarjeta de
entrenamiento Explorer 16
Conversin A/D en los PIC de 16 bits
Comunicacin serial en los PIC de 16 bits
Demostracin de estas caractersticas en la tarjeta de entrenamiento Explorer 16

Materiales necesarios

Kit de entrenamiento Explorer 16


Programador ICSP PICKIT3
Extensiones para 120VAC
Televisor Video Beam

Veamos inicialmente, algunas de las caractersticas principales de los microcontroladores


de 16 bits, serie 24F y en particular el PIC 24FJ256GA10

Programacin en la tarjeta EXPLORER 16 de programas bsicos de entradas y salidas y


la conversin A/D

Trabajo con los dsPIC de Microchip, particularmente, con el DSP 33FJ256GP710

Introduccin al procesamiento digital de seales con los DSP de MICROCHIP


Demostracin con el DSP 33FXXXX

CONVERSIN A/D EN 10 BITS EN EL DSP 33FJ256GA710


La demostracin bsica del proceso de conversin A/D se har en un
DSP33F256GA710, aprovechando la tarjeta de entrenamiento EXPLORER 16.
La tarjeta posee una resistencia variable conectada en el pin RB0, que es el canal
anlogo AN0, permitiendo variar voltaje entre 0 y 5V.
Veamos algunos detalles importantes del tema antes de hablar de la configuracin
de los registros.

El TAD es la mnima unidad para definir los tiempos de conversin.


La velocidad del mdulo de conversin A/D de 10 bits en el DSP 33FJ256GA710,
puede ser de hasta 1 milln de muestras por segundo (1Msps), pero esas
velocidades altas requieren, para su correcto funcionamiento, el voltaje de
referencia conectado en los pines VREF+ y VREF- del DSP. En nuestro caso, el
voltaje de referencia ser de 5V y estar conectado a los pines AVDD y AVSS,
podremos elegir una velocidad de 500 Ksps (500 mil muestras por segundo) con
un tiempo mmino de conversin de 2 us y un TAD de 154 ns como lo indica la
figura en la pgina anterior.
Con el valor del TAD y la frecuencia de oscilacin a la que estar conectado el
DSP, se puede calcular el valor que representa los tiempos de conversin y que
debe ir en los 6 bits ADCS del registro de control ADCON3. Ver figura siguiente:

El clculo anterior es para una velocidad de conversin de 500Ksps, es decir, con


un tiempo mnimo de conversin de 2us por muestra. Como bien lo dice la teora,
el tiempo mnimo de conversin, en sus etapas de cuantificacin y codificacin es
tambin equivalente a 12 TAD y el tiempo mnimo en la etapa de adquisicin es
1TAD. En conclusin el tiempo mnimo total de conversin es de 13 TAD.

As las cosas:
12TAD x 154 ns = 1,848us (Cuantificacin y codificacin)
1TAD x 154 ns = 15nss = 0,154us (Adquisicin)
Total = 1,848 + 0,154 = 2,002us (Cumple perfectamente con el requerimiento de
velocidad del conversor A/D, o sea, 500 Ksps)

Ejemplo: Una seal de audio cuya frecuencia de muestreo es de 44100 HZ se debe tratar
en un DSP 30F4012 a una velocidad de 500Ksps. La frecuencia de oscilacin en el DSP
es de 80MHZ.
Hallar los tiempos de adquisicin y muestreo y el parmetro para los bits ADCS del
registro de control ADCON3.

Solucin:
Tiempo de muestreo es 1/44,1KHZ = 0,0226 ms, = 22,6 us
TAD = 154 ns
TCY = 50 ns
ADCS = 2 (TAD / TCY) 1 = 2 (154/50) - 1= 5,16 se aproxima hacia arriba ADCS = 6
TAD real de trabajo = [(ADCS + 1) * TCY] / 2 = (7 * 50 ns) / 2 = 175 ns
Tiempo de conversin (Cuantificacin y Codificacin) = 12 x 175 = 2,1 us
Tiempo de adquisicin = 22,6 us 2,1 us = 20,5 us

Los registros que tienen que ver con el mdulo de conversin A/D de los DSP 33F
son:
ADCON1
ADCON2
ADCON3
ADPCFG
ADCSSL
ADCHS
ADCBUF0 A ADCBUFF (16 registros que almacenan el resultado de la conversin
A/D, se pueden almacenar hasta 16 resultados de 16 muestras)
ADPCFG es quien dice cuales son entradas anlogas (ceros) y cuales son
entradas o salidas digitales (unos). En nuestro ejemplo necesitamos solamente
RB0 como anloga, por lo tanto, el registro ADPCFG quedar en el programa as:
ADPCFG = 0xFFFE;
As mismo el TRISB debe configurarse para que el pin RB0 del puerto B sea
entrada
TRISB = 0x0001;
ADCHS simplemente, se configura con el nmero del canal anlogo a utilizar, en
este caso cero.

ADCHS = 0;
ADCSSL se utiliza para configurar los canales A/D a escanear, si se van a utilizar
varios, si es solo uno, se configura con cero.
ADCSSL = 0;
Ahora veamos los registros de control:
1 ADCON1

El registro quedar configurado en cero para nuestro ejemplo, es decir:


ADCON1 = 0;
Por las siguientes razones:
An no vamos a habilitar el mdulo de conversin A/D, lo haremos en el programa
principal, por lo tanto ADON = 0. No entraremos al estado pasivo (IDLE), por lo
tanto, no hay problema con el ADSIDL = 0. El formato numrico a utilizar ser
entero, entonces los bits FORM = 00. Los 3 bits SSRC estarn en cero, porque
limpiando el bit SAMP, finalizaremos el muestreo e iniciar la conversin. ASAM =
0, ya que el muestreo comenzar cuando se ponga el bit SAMP en uno. SAMP
inicialmente lo dejaremos en cero e iniciaremos el muestreo en el programa
principal y DONE es la bandera que me indica, ponindose en uno, si la
conversin A/D termin, la iniciaremos entonces en cero.

2 - ADCON2

ADCON2 = 0
Por las siguientes razones:

Voltaje de referencia para el conversor A/D ser el de alimentacin, como es solo


una entrada a CH0, no habr escaneo de varios canales, el buffer de
almacenamiento de las muestras estar configurado para recibir datos de 16 bits y
no utilizaremos interrupciones por un determinado nmero de muestras,
simplemente, cada que una muestra es convertida a digital la enviar al ADCBUF0
y de ah la enviaremos al puerto B. Su trabajo ser enviarla serialmente a alguna
terminal serial en el PC.
3 ADCON3

Como no vamos a tratar una seal con una frecuencia muy exigente, entonces el
parmetro que me permite configurar los tiempos de adquisicin y conversin
puede estar al mximo, es decir los 6 bits ADCS = 3F, como el mtodo de
conversin es manual, o sea poniendo a 1 el bit SAMP iniciar el muestreo y luego
de un retardo, poniendo este mismo bit a cero, finalizar el muestreo e iniciar la
conversin, los bits de tiempo para el mtodo automtico no los voy a utilizar,
entonces SAMC = 0, el reloj base para la conversin ser derivado de la
frecuencia de oscilacin principal, por lo tanto ADRC = 0,

En conclusin ADCON3 = 0x003F;


El programa completo de conversin A/D de una seal de 0 a 5V es el que sigue:
#include

"p30f4012.h"

void delay(void); /*Declaro la funcion delay*/


int main

(void)

{
TRISB=0X0001;
PORTB=0;
ADPCFG=0XFFFE;
ADCON1=0X2000;
ADCON2=0;
ADCON3=0X003F;
ADCHS=0X0000;
ADCSSL=0;
while(1)
{
ADCON1bits.ADON=1;
ADCON1bits.SAMP=1;
delay();
ADCON1bits.SAMP=0;
while(ADCON1bits.DONE==0)
continue;
PORTB=ADCBUF0;
ADCON1bits.DONE==0;
}

}
void delay(void)
{
unsigned long i;
for(i=50;i>0;i--);
}

Introduccin a la familia de dispositivos de 32 bits de Microchip

Los microcontroladores de 32 bits referencia 32FXXXXX


Programacin en lenguaje C de una aplicacin I/O sobre la tarjeta de
entrenamiento PIC STARTER 32

Materiales necesarios
-

Kit Starter Kit 32


Programador ICSP PICKIT3
Extensiones para 120VAC
Televisor Video Beam

Ejemplos bsicos
1. Manejo de entradas y salidas
void main()
{
// 0. initialization
DDPCONbits.JTAGEN = 0; // disable JTAGport, libre PORTA
TRISA = 0x0000;

// todo PORTA como saida

TRISB = 0xffff;
T1CON = 0x8030;

// TMR1 on, prescale 1:256

PR1 = 0xFFFF;
AD1PCFG =0XFFFF;

// 1. Loop principal
while( 1)
{
if (PORTBbits.RB2==0)
{
//1.1 todos los LED ON
PORTA = 0xff;
}
else
{
// 1.2 todos los LED OFF
PORTA = 0;
}}}

2. Manejo de los Timers


/*
** Loops.c
*/

#include <p32xxxx.h>

//#define DELAY 3600


#define DELAY 5

// 256ms delay
// reduced delay for simulation

main()
{
// 0. initialization
DDPCONbits.JTAGEN = 0; // disable JTAGport, free up PORTA
TRISA = 0xff00;

// all PORTA as output

T1CON = 0x8030;
PR1 = 0xFFFF;

// TMR1 on, prescale 1:256 PB=36MHz


// set period register to max

// 1. main loop
while( 1)
{
//1.1 turn all LED ON
PORTA = 0xff;
TMR1 = 0;
while ( TMR1 < DELAY)

{
// just wait here
}

// 1.2 turn all LED OFF


PORTA = 0;
TMR1 = 0;
while ( TMR1 < DELAY)
{
}
} // main loop
} // main

Вам также может понравиться