Programación de Microcontroladores
Programación de Microcontroladores
Programación de microcontroladores
P1C en lenguaje C
Programación de microcontroladores
PIC en lenguaje C
Cándido Bariáin
Jesús María Corres
Carlos Ruiz
Marcombo
Programación de microcontroladores PIC en lenguaje C
© 2017 Cándido Bariáin Aisa, Jesús María Corres Sanz y Carlos Ruiz Zamarreño
ISBN: 978-84-267-2427-4
DL: B-25226-2016
ÍNDICE
In tr o d u cció n ........................................................ ...9
B ib lio g r a fía ........................................................... 10
1. Introducción a la programación en C ........... 11
1.1 Introducción............................................... .11
1.1.1 Estructura de un programa en C ...... .12
1.1.2 Directivas del preprocesador........... .13
1.1.3. Función Printf.................................... .14
1.1.4. Variables y tipos de datos................. .15
1.1.5 Definiciones de constantes................ .17
1.1.6 Macros y compilación condicional .... 18
1.2. Uso de las variables................................. .18
1.2.1 Declaraciones..................................... .18
1.2.2 Conversiones de tipo s....................... .20
1.2.3 Clases de almacenamiento................ .21
1.3. Funciones.................................................. .22
1.3.1. Paso de argumentos a las funciones 22
Página | 1
1.8.1. Estructuras..............................................................................................................................33
1.8.2. Uniones................................................................................................................................... 34
2. Puertos de entrada y salida digitales............................................................................................... 37
2.1 LED y Pulsadores............................................................................................................................38
2.1.1 Secuencias de encendido de LED........................................................................................... 38
2.1.2 Generación de la señal de auxilio internacional y su visualización mediante un LED........40
2.1.3 Visualización de una cadena de caracteres en código morse mediante un LED ................ 42
2.1.4 Generación de la señal acústica SOS mediante un Zumbador Piezoeléctrico.....................45
2.2 Visualizadores numéricos de 7 segmentos.................................................................................. 47
2.2.1 Control de 1 display............................................................................................................... 48
2.2.2 Control de un visualizador con 4 displays.............................................................................49
2.3. Exploración de teclado matricial.............................................................................................. 52
2.4 Control de Pantallas LCD.......................................................................................................... 54
2.4.1 Envío de cadenas de caracteres al LCD................................................................................ 56
2.4.2 Creación de nuevos caracteres.............................................................................................. 57
2.4.3 Cronómetro segundero en la pantalla LCD.......................................................................... 58
3. Temporizadores................................................................................................................................... 61
3.1. Temporizador 0 ........................................................................................................................... 62
3.1.1 Utilización del Temporizador 0 sin interrupción................................................................... 63
3.1.2 Utilización del Temporizador 0 con interrupción..................................................................64
3.1.3 Utilización del Temporizador 0 como contador de pulsos....................................................66
3.2. Temporizador 1 ........................................................................................................................... 68
3.2.1 Utilización del Temporizador 1 sin interrupción................................................................... 69
3.2.2 Utilización del Temporizador 1 con interrupción..................................................................71
3.2.3 Utilización del Temporizador 1 como contador de pulsos....................................................74
3.2.4 Utilización del Temporizador 1 con un oscilador externo.....................................................79
3.3. Temporizador 2 ........................................................................................................................... 78
3.3.1 Utilización del Temporizador 2 sin interrupción................................................................... 79
3.3.2 Utilización del Temporizador 2 con interrupción..................................................................81
3.4. WATCHDOG................................................................................................................................. 84
3.4.1 Uso de TIMER 0, TIM E R ly WATCHDOG.......................................................................... 85
4. Módulos de Captura, Comparación y Modulación de A nchura de Pulsos (PW M )............................ 89
4.1. Módulo Captura..........................................................................................................................
4.1.1. Cálculo del periodo de una señal......................................................................................... 99
4.1.2. Medidor de distancias...........................................................................................................9¿*
4.1.3. Medidor de anchura de pulsos..............................................................................................97
4.1.4. Calculo de la velocidad de un motor................................................................................. 163
4.2. Módulo Comparación................................................................................................................ 166
4.2.1. Temporizador automático de 16 bits.............................................................................107
Página | 2
4.2.2. Contador de cajas en cinta transportadora
4.3. Módulo PWM............................................ ...................................... ....109
4 . 3 . 1. Generación de tonos............................ ......................................... ....112
4.3.2. Señal periódica con ciclo de trabajo variable ........................................... ....113
4.3.3. Control motor D C ................................... ......................................... ...115
4.3.4. Creación de melodías.............................. ......................................... ...118
5. Módulos analógicos.............................................. .................................. ...122
Página | 3
A1.6. usart.h / usart.c................................................
..176
A1.7. ¡2c.h/¡2c.c.......................................................
..177
Al.S. Icd.h/lcd.c.......................................................
..178
A2. Registros de Funciones Especiales (SFR s) .....................
..181
A2.1. STATUS............................................................
..181
A2.2. Registro OPTION_REG.......................................
..182
A2.3.T1CON.............................................................
..182
A2.4.T2CON.............................................................
,.183
A2.5. Registro INTCON...............................................
..183
A2.6. Registro PIE1....................................................
.184
A2.7. Registro PIR1....................................................
.184
A2.8. Registro PIE2 y PIR2..........................................
,.185
A2.9. CCPxCON..........................................................
.185
A2.10. ADCONO.........................................................
.186
[Link]. ADCON1.........................................................
.186
A2.12. CVRCON.........................................................
.187
A2.13. CMCON..........................................................
.187
[Link]............................................................
.188
A2.15. RCSTA............................................................ .188
A2.16. PCON............................................................. .188
A2.17. SSPSTAT......................................................... .189
A2.18. SSPCON......................................................... .190
A2.19. SSPCON2....................................................... .191
A2.20. PALABRA DE CONFIGURACIÓN........................ .191
A3. Introducción a MPLAB-IDE/MPLAB-SIM con Hi-T ech . .193
A3.0. Instalación....................................................... .193
A3.1. Configuración................................................... .194
A3.2. Creación del proyecto...................................... .194
A3.3. Creación del fichero fuente.............................. .198
A3.4. Compilación del proyecto................................. .200
A3.5. Simulación del proyecto................................... .203
A3.6. Observando el funcionamiento......................... .207
A3.7. Generador de Estímulos................................... .210
A3.7. Interfaz de control........................................... .213
A4. T abla de códigos ASCII................................................ ,215
Página | 4
INDICE DE FIGURAS
Figura 1.1: Simulación Ejemplo 1.1.1....................................................................................... .13
Figura 1.2: Simulación Ejemplo 1.1.4a..................................................................................... .15
Figura 1.3: Simulación Ejemplo 1.1.4b..................................................................................... .16
Figura 1.4: Simulación Ejemplo 1.1.4b, valor de las variables.................................................... .16
Figura 1.5: Simulación Ejemplo 1.1.4c....................................................................................... -16
Figura 1.6: Simulación Ejemplo 1.1.4c, valor de las variables..................................................... .17
Figura 1.7: Simulación Ejemplo 1.1.4b....................................................................................... .17
Figura 1.8: Simulación Ejemplo 1.1.4b, valor de las variables..................................................... .17
Figura 1.9: Simulación Ejemplo 1.1.5......................................................................................... 18
Figura 1.10: Simulación Ejemplo 1.2.1....................................................................................... 19
Figura l . l i : Simulación Ejemplo 1.2.I B ..................................................................................... .20
Figura 1.12: Simulación Ejemplo 1.2.2....................................................................................... .21
Figura 1.13: Simulación Ejemplo 1.3.1....................................................................................... 22
Figura 1.13: Simulación Ejemplo 1.3.I B .....................................................................................
Figura 1.14: Simulación Ejemplo 1.3.3....................................................................................... .25
Figura 1.15: Simulación Ejemplo 1.5.2........................................................................................ .28
Figura 1.16: Simulación Ejemplo 1.5.3........................................................................................ ,28
Figura 1.17: Simulación Ejemplo 1.5.4........................................................................................ 29
Figura 1.18: Simulación Ejemplo 1.5.6........................................................................................ .29
Figura 1.19: Simulación Ejemplo 1.6.2........................................................................................ .30
Figura 1.20: Simulación Ejemplo 1.6.3........................................................................................ .31
Figura 1.21: Simulación Ejemplo 1.7a.........................................................................................
Figura 1.22: Simulación Ejemplo 1.7b.........................................................................................
Figura 2.1: Los puertos de E/S del microcontrolador PIC16F877A................................................ .37
Figura 2.2: Conexiones con el PIC16F877A .................................................................................. .3S
Figura 2.3: Diagrama de funcionamiento de la secuencia de encendido/apagado de los LED...... .39
Figura 2.4: Simulación del ejercicio 2.1.1..................................................................................... .40
Figura 2.5: Conexiones con el PIC16F877A .................................................................................. .40
Figura 2.6: Simulación del ejercicio 2.1.2...................................................................................... .42
Figura 2.7: Simulación del ejercicio 2.1.3...................................................................................... .45
Figura 2.8: Conexiones con el PIC16F877A.................................................................................. .45
Figura 2.9: Simulación del ejercido 2.1.4..................................................................................... .47
Figura 2.10: Diagrama interno de un display 7 segmentos........................................................... .48
Figura 2.11: Conexión de un display de 7 segmentos con el PIC16F877A. Codigo 7 segmentos y
complementado de las cifras hexadecimales (0-F)........................................................................ .48
Página | 5
Figura 5.9: Esquema de conexiones con el microcontrolador para utilizar el sensor
de temperatura analógico TC1047 propuesto en el ejercicio 5.3.4............................... 142
Figura 6.1: Esquema de bloques del módulo transmisor USART................................... .146
Figura 6.2: Esquema de bloques del módulo receptor USART..................................... .147
Figura 6.3: Simulación de la configuración el módulo USART (Watch)......................... .149
Figura 6.4: Esquema de conexiones con el microcontrolador para utilizar el módulo
de comunicaciones USART propuesto en el ejercicio 6.1.2.......................................... .149
Figura 6.5: Configuración de MPLAB SIM para utilizar el módulo USART y simulación
del ejercicio 6.1.2...................................................................................................... ,.151
Figura 6.6: Simulación del ejercicio 6.1.2 utilizando el progrma HERCULES................ ..152
Figura 6.7: Simulación el ejericio 6.1.3 utilizando el programa HERCULES................. ..154
Figura 6.8: Simulación del ejercicio 6.1.4 utilizando el programa HERCULES.............. ..156
Figura 6.9: Esquema de bloques del módulo MSSP................................................... ..157
Figura 6.10: Esquema de conexiones con el microcontrolador para utilizar el sensor
de temperatura digital TC74 propuesto en el ejercicio 6.2.2.........................................................160
Figura 6.11: Esquema para la lectura de datos utilizando el sensor de temperatura digital TC74. .160
Figura 6.12: Esquema de conexiones con el microcontrolador para utilizar la memoria EEPROM
24LC256 propuesto en el ejercicio 6.2.3.......................................................................................162
Figura 6.13: Esquema para la lectura y escritura de datos en la memoria EEPROM 24LC256........ 163
Figura 7.1: Simulación de la escritura en la memoria EEPROM interna propuesto
en el ejercicio 7.1.1...................................................................................................................... 167
Figura 7.2: Esquema de bloques del circuito de reset...................................................................162
Figura 7.3: Simulación del sistema para la detección del origen de RESET propuesto
en el ejercicio 7.2.1 (Watch)......................................................................................................... 169
Figura 7.4: Configuración de MPLAB SIM para la simulación del ejercicio 7.2.1............................ 1®®
Figura 7.5: Simulación del programa de detección de origen de RESET propuesto
en el ejercicio 7.2.1......................................................................................................................120
Página | 8
Introducción
Este es un libro que guía en el aprendizaje de la programación en C de sistemas embebidos.
C es un lenguaje de nivel medio, muy bien estructurado, que soporta el uso de fundones y
módulos, pero que permite el uso de todas las características de bajo nivel, propias del
ensamblador. Como el lenguaje C es eficiente y está muy probado en la programación de
sistemas embebidos, es el más usado, por delante del ensamblador y de lenguajes de alto
nivel orientados a objetos como C++ o Java. Los campos de aplicación son muchos: audio,
automoción, comunicaciones, periféricos de ordenadores, equipos de consumo,
instrumentación industrial, procesamiento de imagen, control de motores, robótica, etc. En
este libro se usa el compilador de C de microchip y el microprocesador PIC16F877A, pero los
conceptos y ejercicios son válidos para otras plataformas y compiladores mediante ligeras
modificaciones.
El libro se ha estructurado para que el aprendizaje sea gradual: primero se introducen los
esquemas de programación en C y después se aplican a los proyectos de diseño con ei
microcontrolador PIC. A lo largo de los distintos temas se han creado funciones que
permiten un uso sencillo de los periféricos de los que dispone el microcontrolador. De esta
manera la programación del microcontrolador para lograr que realice las tareas deseadas es
más directa y el código, más fácil de interpretar.
El uso del simulador permite desarrollar programas sin necesidad de disponer de
equipamiento hardware. Muchos de los ejercicios se pueden simular para comprobar su
funcionamiento, lo que ahorra mucho tiempo en el proceso de diseño.
Página | 9
Bibliografía
• Hoja de Especificaciones del PIC16F877A. PIC16F87xA DataSheet. Microchip
DS39582b ([Link]).
• Guía de usuario HI-TECH C® for PIC10/12/16. DS51865A ([Link]).
• Guía de usuario de los microcontroladores PIC de gama media. PICmicro Mid-Range
MCU Family Reference Manual. DS33023a ([Link]).
• Compiled Tips 'N Tricks Guide. DS01146B ([Link]).
• Sensor de luminosidad TSL251RD. ([Link]).
• Sensor de temperatura digital TC74. DS21462D. ([Link]).
• Memoria EEPROM 24LC256. DS21203M. ([Link]).
• Sensor de temperatura TC1047A. DS21498D ([Link]).
• Hoja de especificaciones del MAX232. ([Link]).
• Hoja de especificaciones de la pantalla LCD Hitachi HD44780
[Link]
• The C Programming Language, second edition, de Brian W. Kernighan y Dennis M.
Ritchie. Ed. Prentice Hall.
• Ejercicios de programación con microcontroladores PIC de Jesús M. Corres, Carlos
Ruiz y, Cándido Bariáin. Ed. Marcombo.
Página | 10
1. ¡nixoducción a la programación en C
1.1. Introducción
1.1.1. Estructura de un programa en C
1.1.2. Directivas del preprocesador
1.1.3. Función Printf
1.1.4. Variables y tipos de datos
1.1.5. Definiciones de constantes
1.1.6. Macros y compilación condicional
1.2. Uso de las variables
1.2.1. Declaraciones
1.2.2. Conversiones de tipos
1.2.3. Clases de almacenamiento
1.3. Funciones
1.3.1. Paso de argumentos a las funciones
1.3.2. Retorno de resultados
1.3.3. interrupciones
1.4. Operadores
1.5. Estructuras de control
1.5.1. Condicionales
1.5.2. Bucles de tipo FOR
1.5.3. Bucles de tipo WHILE
1.5.4. Bucles de tipo DO-WHILE 1.5.5 Break
1.5.6. Continué
1.5.7. Condicionales switch - case
1.6. Vectores
1.6.1. Vectores unidimensionales
1.6.2. Cadenas de caracteres
1.6.3. Vectores multidimensionales
1.7. Punteros
1.8. Estructuras y Uniones
1.8.1. Estructuras
1.8.2. Uniones
1.1 Introducción
La programación en C de microcontroladores tiene importantes ventajas respecto al
lenguaje ensamblador. C es un lenguaje de programación de propósito general, mientras
que el lenguaje ensamblador está ligado a un microprocesador especifico. Una vez se
aprende a programar en C con un microcontrolador es muy sencillo cambiar a otra familia y,
además, los códigos son mucho más fáciles de entender y modificar.
Página | 11
Programación de microcontroladores PIC en lenguaje C
En este libro se emplean ejemplos cuya dificultad aumenta de forma progresiva para
facilitar la comprensión de las estructuras de datos y de programación. Para profundizar
más en el conocimiento de la programación en C es recomendable consultar libros de
referencia como The C Programming Language, second edition, de Kernighan y Ritchie.
Código fuente
/ / D ir e c t iv a s d e l p r e p r o c e s a d o r
# in c lu d e < h tc .h >
# in c lu d e < s t d io .h >
# in c lu d e <m ath.h>
__ CONFIG(FOSC HS & WDTE_OFF & LVP_OFF & PWRTE_ON) ; / / B it s de c o n f i g u r a c i ó n p a r a
/ / e l P IC
# d e fin e _XTAL_FREQ 20000000 / / F r e c u e n c ia de t r a b a j o a 20MHz
/ / D e c la r a c ió n y d e f i n i c i ó n de v a r i a b l e s g l o b a l e s
v o l a t i l e s ig n e d c h a r v e c t o r [ 9 0 ] ;
/ / D e c la ra c ió n de v a r i a b l e s l o c a l e s
f l o a t x?
in t x l= - 1 0 ;
u n s ign ed i n t x2=123;
s ig n e d ch a r x 3 = -1 0 ;
ch a r x4=200;
f l o a t y = 1 .2 5 ;
ch ar z [ 2 0 ] = " Cadena de c a r a c t e r e s " ;
Página | 12
1. Introducción a la programación en C
ch ar i ;
w h ile (1 );
}
v o i d p u t c h (u n s ig n e d c h a r b y t e ) { / / F u n c ió n p u t c h ( ) , qu e s e e j e c u t a al
/ / e m p le a r p r i n t f
TXSTA=0x26;
RCSTA|= 0 x 8 0 ;
TXR EG =byte;
w h i l e ( ! T X I F )c o n t in u é ;
T X IF = 0 ;
}
Resultado:
Al realizar un programa en C es necesario tener en cuenta que existe una serie de palabras
reservadas que no se pueden utilizar para definir variables o nombres de funciones. A
continuación, se muestra la lista de palabras reservadas de ANSI C:
a u to d o u b le in t s tru c t
b rea k e ls e lo n g s w itc h
case enum r e g is t e r typ e d ef
char e x te rn re tu rn u n ió n
const f lo a t sh ort u n s ig n e d
c o n t in u é fo r s ig n e d v o id
d e fa u lt g o to s iz e o f v o la tile
do if s ta tic w h ile
Página | 13
Programación de microcontroladores PIC en lenguaje C
En la siguiente tabla se muestran las directivas de tipo "pragma", las cuales modifican el
comportamiento del compilador.
D ir e c t iv c M e a n in g E x a m p le
no j i s D is a b le J IS c h a ra c te r h a n d lin g (d e - # p ra gm a n o jis
fa u lt)
pack S p e c i f y stru ctu re p a c k in g # p ra gm a pack 1
p r in tf_ c h e c k E n a b le p r in if- s t y le fo r m a l s irin g # p ra gm a
c h e c k in g p r in tf_ c h e c k (p r in tf)
con st
regsu sed S p e c i f y r eg is te rs u sed b y fu n c lio n # p ra gm a regsu sed
w r e g ,fs r
s w itc h S p e c if y c o d e g e n e ra tio n f o r s w itc h ü p ragm a s w itc h d ir e c t
s ta tem en ls
w a r n in g C o n tro l m e s s a g in g p a ra m eters tfp ra g m a w a r n in g d is a b le
2 9 9 ,4 0 7
La entrada de la función printf consta de una cadena de control y una lista de argumentos:
p r in tf ( " c a d e n a _ d e _ c o n t r o l" , a rg u m e n to s );
Dentro de la cadena de control se pueden incluir caracteres constantes y códigos especiales. Los códigos
especiales van precedidos por % y están vinculados a la siguiente lista de argumentos:
%c C a r á c te r
%d e n t e r o d ec im a l con s ig n o
%f coma f l o t a n t e n o t a c ió n d e c im a l
%e coma f l o t a n t e n o t a c ió n e x p o n e n c ia l
%u e n t e r o d ec im a l s in s ig n o
%x e n t e r o s in s ig n o h e x a d e cim a l m in ú scu la s
%X e n t e r o s in s ig n o h e x a d e cim a l m ayúscu las
1 p r e f i j o usado ju n t o a %d, %u, %x p a ra e s p e c i f i c a r e n t e r o l a r g o
Página | 14
1. Introducción a la programación en C
%0 [w id th ] Se im prim en lo o c e r o s a l a i z q u i e r d a , [w id t h ] i n d i c a e l número t o t a l de
d íg ito s .
%[w id t h ] . [ p r e c i s i ó n ] La p r e c i s i ó n i n d i c a e l núm ero d e d e c i m a l e s .
Códigos de escape:
\n n u e va l í n e a
\ t t a b u la d o r h o r i z o n t a l
\ r r e to r n o de c a rr o
\ f fo r m fe e d
V C o m illa s im p le
\ " C o m illa d o b le
\\ C o n tr a b a r r a
%% S ím b o lo de p o r c e n t a j e
\? I n t e r r o g a n t e
\b b a c k s p a c e
\0 C a r á c t e r n u lo
\ v T a b u la d o r v e r t i c a l
\xhhh C ó d ig o h e x a d e c im a l hhh
Bit
Un bit tiene dos posibles estados: "0" o "1". Cada uno de los LED o interruptores conectados
a un puerto se pueden controlar mediante este tipo de dato.
Ejemplo 1.1.4A:
s t a t ic b it b l;
b l =0 ;
p r i n t f ( " % d - %d \ n " , b l , ~ b l);
Resultado:
O u tp u t
Página | 15
Programación de microcontroladores PIC en lenguaje C
127. Para indicarlo existen en C los modificadores signed y unsigned. Por ejemplo, para
declarar las variables x e y como char con signo y sin signo respectivamente:
s ig n e d ch a r x ;
u n s ig n e d ch a r y ;
Int
Los datos enteros (integer) son tipos de datos de 16 bits. También pueden ser con signo o
sin signo.
Ejemplo 1.1.4B:
in t x l = -10000;
u n s ig n ed i n t x2=12300;
p r i n t f ( ux l= % d \ n ", x l ) ;
p r i n t f ( nx 2 =% d\n ",x 2 ) ;
Resultado:
Íj Watch i a c o É s
AddSFR ADCONO v Add Symbol -
üpdate j Addreaa j Symbol Ñame Valué | Decimal Binary
Q2E mam gxl OxDSFO -10000 11011000 11120000
030 main@x2 0x300C 12300 00110000 0000110Q
1 ; -
Watch 1 Watch 2 V/atch 3 Watch 4
Long
Son datos enteros de 32 bits.
Ejemplo: 1.1.4C
lo n g u n sign ed i n t x2=123045;
p r i n t f ( " x 2 = % ld \ n ",x 2 ) ;
Resultado:
Página | 16
1. Introducción a la programación en C
•j Watch
AddSFR ADCONO v AddSymbol .
U p d a te j A d d re a a | S y m b o l lla m e j V a lu é j D e c im a l | 3 l= .ry
03D m a ln @ x2
Float, Double
Son números reales de 24 bits por defecto en formato IEEE754. Se pueden cambiar a 32
bits (Project/Build options/Project/Global).
Ejemplo 1.1.4D:
f l o a t y = 1 .2 5 , x = 0 .0 0 3 4 ;
p r i n t f ( " x = % f\ n " ,x );
Resultado:
H Watch a 3* 3
AddSFR ADCONO v Add Symbol main@y V
^ d e f i n e < l a b e l > v a lu é
Página | 17
C
Programación de microcontroladores PIC en lenguaje
Por ejemplo:
« d e f i n e p i 3.14159265359
ch ar co n s t i d [ 5 ] = {" 1 2 3 4 " };
p r i n t f ( "%s\n“ , i d ) ;
Resultado:
AddSR 6DCOIIO
" p í a t e ! A d ir e s a ¡ S y c io l ¡
p 3009 5 c a l = 3l á
00110001
P 0039 10] 00110010
P 00SA I» !
P 0003 - 12] 00110011
00110100
P 300C
_________ P 000D -
13]
[«]
00000000
Watchl v/aich 2 W¿ch3 W¿ch4
« d e f i n e MAX(A,B) (A > B )? A :B
z = M A X (x ,y ); // z c o n t ie n e e l v a l o r m ayor de x e y
Ejemplo:
# d e f in e o u t p u t _ h ig h (A ) A=1
# d e f in e HW_VERSION 5
# i f HW_VERSION>3
o u tp u t_h igh (R B O ) ;
# e ls e
o u t p u t _ h ig h (R B 1 );
# e n d if
Las variables locales definidas en distintas funciones pueden compartir el mismo nombre y solo
existirán durante la ejecución de la función y se liberarán posteriormente para su reutilización
por otras funciones excepto en el caso de ser de tipo static (véase apartado 1.2.3).
Página | 18
1. Introducción a la programación en C
v o id f 2 (v o id ){
i n t c o u n t;
f o r (c o u n t = 0 ; c o u n t < 10 ; c o u n t+ + )
p r in t f(" % d "/ c o u n t);
}
fio {
i n t c o u n t;
f o r (c o u n t = 0 ; c o u n t c lO ; c o u n t + + ) {
f 2 () ;
p r i n t f ( " - %d \ n " , c o u n t ) ;
}
}
v o id m a in (v o id ){
fl() ;
w h ile ( 1) ;
}
Resultado:
Output
Bu'ld ’ Versión Control [Link] m Res MPL¿£ SIM SIM Uartl
0123456 7 89 -0
01 23456 7 89 -1
0 1 2 3456 789 -2
01 23456 789 -3
01 23456 789 -4
0 1 2 3 456 789 -5
01 23 456 789 -6
0 1 2 3456 789 -7
0 123456 789 -8
0123456789-9
Las variables globales se pueden usar en distintas funciones, y deben declararse antes de
usarse por primera vez.
i n t max;
fl(){
in t i ;
f o r ( i = 0 ; i< m a x ;i+ + )
p r i n t f ( "%d " , i ) ;
}
v o id m a in (v o id ){
max= 1 0 ;
fio ;
w h ile ( 1) ;
}
t y p e d e f s ig n e d c h a r i n t 8 ;
in t 8 i= 1 2 ;
Página | 19
Programación de microcontroladores PIC en lenguaje C
NombreN
};
Ejemplo 1.2.1B:
Resultado:
¡ _____ ° utPui______ c s in n r e a
Bu-d Versión Control : Fnd m File: . MPLAB SIM SIM Uatll
jJuevesj — “
También se puede forzar la conversión de tipos usando el siguiente formato: (tipo) valor
En el siguiente ejemplo se convierte el float en int:
flo a t f;
f = 100.2 ;
p r in tf("% d \ n " , ( i n t ) f ) ;
p r in tf("% d \ n " , f ) ;
Obsérvese que el resultado del segundo printf no es correcto, mientras que el primero si.
Resultado:
O u tp u t — - —
100
-1 4 2 3 4
auto: Las variables definidas dentro de una función son auto por defecto. El compilador
asigna un bloque de RAM a esas variables y las posiciones de memoria que ocupan se
pueden reutilizar cuando se sale de la función.
static: Las variables definidas como static son globalmente activas y solo se inicializan una
vez, aunque se definan dentro de una función.
En el siguiente ejemplo:
v o id te s t(){
ch ar x , y , z ;
s t a t i c i n t c o u n t = 4;
p r i n t f ( " c o u n t = % d \ n " ,+ + c o u n t );
>
No es una variable global, porque no se puede acceder a ella desde otras funciones.
Página | 21
Programación de microcontroladores PIC en lenguaje C
1.3. Funciones
Las fundones son los bloques con los que se construyen los programas en C. Encapsulan
partes del código, ayudando a que se puedan reutilizar en otros programas.
Ejemplo:
v o i d s u m a (in t a , i n t b ) ; / / D e c la r a c ió n d e l p r o t o t i p o de l a fu n c ió n
v o id r e s t a ( i n t a , in t b) ; / / D e c la r a c ió n d e l p r o t o t i p o de l a fu n c ió n
v o id m a in (v o id ){
i n t a = 1 0 / b = l;
suma (a , b ) ;
r e s t a (a ,b );
p r i n t f ( "O p e r a n d o s : % d,% d\n" , a , b ) ;
}
v o i d s u m a (in t a , i n t b ) {
a =a +b;
p r i n t f ( "Suma: % d\n"/a ) ;
}
v o id r e s t a ( i n t a, in t b ) {
b = a -b ;
p r i n t f ( " R e s t a : % d\n"/b ) ;
}
En el ejemplo anterior se han pasado los argumentos por valor. Cualquier cambio realizado
en la variable no modifica el valor original pasado como argumento como se muestra a
continuación.
Resultado:
También se puede pasar el argumento utilizando el "paso por referencia". En este caso, se
pasa la dirección de la variable, con lo que es posible modificar el valor de la variable
original dentro de la función.
Página | 22
1. Introducción a la programación en C
v o id m a in (v o id ){
in t in p u tl= 1 0 ;
n e g (fc in p u tl);
p r i n t f ( " V a r i a b l e : % d\n ", i n p u t l ) ;
w h ile (1 );
v o i d n e g ( i n t * in p u t ) {
* in p u t= - * in p u t;
}
Resultado:
in t fu ñ e ( ) ; / / D e c la r a c ió n d e l p r o t o t i p o de la fu n c ió n
i n t s u m (in t a , in t b) ; / / D e c la r a c ió n d e l p r o t o t i p o de l a fu n c ió n
v o id m a in (v o id ){
i n t num;
num = fu ñ e ( ) ;
p r i n t f ( "% d \ n ", n u m );
num = s u m (5 ,1 2 7 );
p r i n t f ( "% d\nM, n u m );
w h ile ( 1) ;
}
in t fu ñ e ( ) {
re tu r n 6;
i n t s u m (in t a , i n t b ) {
in t r e s u lt;
r e s u lt = a + b;
re tu r n r e s u lt ;
}
En cuanto una función llega a la línea en que está el comando return. termina su ejecución.
Todas las sentencias que se encuentren después no se ejecutarán.
Página | 23
Programación de microcontroladores PIC en lenguaje C
1.3.3 Interrupciones
Son funciones especiales que se activan por un evento hardware. Se declaran mediante el
modificador interrupt.
En el siguiente ejemplo la interrupción ISR se ejecuta cada vez que el temporizador TMRO se
desborda (el funcionamiento de los temporizadores se describirá en el Capítulo 3),
incrementando el contador xl.
S in e lu d e < h tc .h >
S in e lu d e < s t d io .h >
S in e lu d e “ i n t e r r u p t s . h M
S in e lu d e nt i m e r s , h n
__ CONFIG(FOSC_HS & WDTE_OFF & L V P O F F & PW R TE O N );
« d e f i n e _XTAL_FREQ 20000000
v o id in te r r u p t I S R (v o id ); / / D e c la r a c ió n d e l p r o t o t i p o d e l a fu n c ió n
in t x l= 0 ; / / D e c la r a c ió n de v a r i a b l e g l o b a l
v o id m a in (v o id ){
e i () ; / / H a b ilita in te r r u p c io n e s g lo b a le s
e n a b le _ in te r r u p t s (IN T T 0) ; / / H a b i l i t a i n t e r r u p c i ó n d e l T im e r 0
setu p_tim erO (R TC C _IN TE R N A L|R TC C _D IV 2); / / C o n fig u ra e l T im e r 0
w h ile (1 ) ;
}
v o id in te r r u p t I S R (v o id ){
if([Link] == 1 && [Link] == 1){
s e t _ t im e r O (0 x 0 0 ); / / A ju s ta e l c o n t a d o r d e l TIMER
IN TCO N [Link] R O IF = 0;
p r i n t f ( " % d \ n ",x l);
x l+ + ;
}
}
v o i d p u tc h (u n s ig n e d c h a r b y t e ) {
TXSTA=0x26;
RCSTA|=0x80;
TXREG=byte;
w h i l e ( ! T X I F )c o n t in u é ;
T X IF = 0 ;
}
Resultado:
Página | 24
1. Introducción a la programación en C
1.4. Operadores
En la siguiente tabla se muestran los operadores C en orden de precedencia, de m ayor a
menor. Su asociatividad indica cómo se aplican en una expresión los operadores de la
misma precedencia.
f, . ,
O
Página | 25
Programación de microcontroladores PIC en lenguaje C
Notas:
¿agina | 26
1. Introducción a la programación en C
Ejemplos:
sum = a+b+ + -> sum = a+b b = b +1
sum = a+b- - -> sum = a+b b = b -1
sum = a+ ++b -> b = b +1 sum = a+b
sum = a+ - -b -> b = b - 1 sum = a+b
if ( e x p r e s ió n ) s e n te n c ia ; e ls e s e n t e n c ia _ a lte r n a tiv a ;
Cuando los bloques condicionales constan de varias sentencias, estas se agrupan entre
llaves:
if ( e x p r e s ió n ) (s e n t e n c ia !.; s e n te n c ia 2 ; ...} e ls e (s e n t e n c ia _ a lt e r n a t iv a l;
Ejemplo:
i f (c o u n t <0) p r i n t f ( " N e g a t i v o \ n " ) ;
e l s e i f (c o u n t ==0) p r i n t f ( " C e r o \ n " ) ;
e ls e p r i n t f ( "P o s itiv o \ n ") ;
Ejemplo:
i ? j=o : j= l;
fo r (s e n t e n c ia _ in ic ia liz a c ió n ; s e n te n c ia c o n d ic ió n ; in c r e m e n t o )
{ s e n t e n c i a l ; s e n t e n c ia 2 ; . . . }
Página | 27
Programación de microcontroladores PIC en lenguaje C
v o id m a in (v o id ){
in t i ;
f o r ( i = 0 ; i < 1 0 ; i+ + ) p r i n t f ( “ %d " , i ) ;
Resultado:
Output ! <=> II S ll
BuJd Versión Centre) Frndin Files MPLAB SIM SIM Uaitl
|01 23456789
Ejemplo:
v o id m a in (v o id ){
in t i= 0 ;
w h ile (i< 10) p r in t f(" % d " ,i+ + );
}
Resultado:
*_| Output o 'E
Buid ' Vefiion Control Findr Res WPLAB SIW SIM Uarll
|0123456789
v o id m a in (v o id ){
in t i= 0 ;
^ Pr in tf("% d " , i + + ) ; w h ile (i< 1 0 );
Resultado:
Página | 28
1. Introducción a la programación en C
O u tp u r
1.5.5 Break
Cuando un bucle encuentra una sentencia break se finaliza el bucle en el que se encuentre
(if, for, while, etc.)
1.5.5 Continué
Cuando un bucle encuentra una sentencia continué se salta las sentencias que le siguen
hasta la siguiente condición de test.
v o id m a in (v o id ){
in t i ;
fo r (i= 0;i< 10;i+ + ){
i f (i< 5 ){
p r in tf( " x " );
c o n t in u é ;
}
p r i n t f ( "%d " , i ) ;
}
>
Resultado:
i)J Output - -L
xxxaS 6 7 8 91
Página | 29
programación de microcontroladores P1C en lenguaje C
Se va comprobando la variable con cada una de las constantes. Break y default son
opcionales.
Ejemplo:
b i t b=0;
s v itc h ( b ) {
c a s e 0: p r in tf("b is fa ls e " ) ;
break;
case 1: p r in tf("b is tr u e ");
brea k ;
}
1.6. Vectores
1.6.1 Vectores unidimensionales
La forma general de un vector unidimensional es:
t y p e v a r name [s iz e ] ;
Código fuente
# in c lu d e < s t r in g . h >
v o id m a in (v o id ){
ch a r s t r [ 1 0 ] ;
s t r c p y ( s t r , " E s t o es una p r u e b a " ) ;
p r i n t f ( "% s" , s t r ) ;
}
Resultado:
?_______________________ Q u tp u t o ¡ b ¡| ^ a » |
Página | 30
1. Introducción a la programación en C
Ejemplo:
v o id m a in (v o id }{
in t a r r a y [5 ][4 ];
in t i / j ;
f o r ( i =0 ;i< 5 ;i+ + ) f o r ( j = 0 ;j < 4 ;j ++) a r r a y [i] [j ] = i * j ;
f o r ( i = 0 ; i < 5 ; i ++ ) {
f o r (j= 0 ;j< 4 ;j+ + ) p r i n t f ( "%02d " #a r r a y [ i ] [ j ] ) ;
p r i n t f ( "\ n ") ;
}
}
Resultado:
Output •' |-»r^|
Build Veiiion Contra) Fmd in File; MPLABSIM SIM Uartl
ÍOO00 00 00
CIO01 02 03
00 02 04 0G
00 03 0G09
00 04 0812
Página | 31
Programación de microcontroladores PIC en lenguaje C
1.7. Punteros
Un puntero es una variable que contiene la dirección de memoria de otra variable.
tipo ‘variable
Por ejemplo, para declarar un puntero de nombre ptr a variables de tipo entero se usa ínt
*ptr;
Una vez declarado, para acceder a la dirección de una variable usamos el símbolo &,
mientras que el operador * devuelve el valor almacenado en la dirección apuntada por la
variable.
Código fuente A
void main(void){
int *a,b;
b=6 ;
a=&b;
printf("%d",* a ) ;
}
Resultado:
OutpUt | cu 1; S ||—£?—|
Los punteros se pueden incrementar y decrementar, lo que es muy útil para acceder a
elementos dentro de vectores o tablas.
Por ejemplo, al escribir o++, dependiendo del tipo de dato al que apunta, al incrementarse
se suma 1 si es char, 2 si es entero, etc.
También se puede incrementar el valor al que apunta el puntero: (*a)++. En este caso se
incrementa en una unidad, independientemente del tipo de dato.
Página | 32
1. Introducción a la programación en C
En el caso de datos de tipo vector, el nombre del vector es un puntero al primer elemento
del mismo.
En el siguiente ejemplo, ambas instrucciones printf muestran el mismo resultado.
Código fuente B
v o id m a in (v o id ){
in t a [5 ]= {l, 2 , 3 , 4 , 5 };
in t *p ;
p=a;
p r i n t f ( " % d \ n " , * (p + 3 ) ) ; p r i n t f ( "%d \ n " /a [ 3 ] ) ;
Resultado:
13 Output - _ i_
Build Versión Control Find in Files MPLAB SÍM SIM Uaitl
4
4
1.8.1. Estructuras
Las estructuras sirven para agrupar distintos datos dentro de un mismo contenedor, para
poder acceder a ellos de forma más sencilla, mediante un nombre de objeto común. Dentro
de la estructura, cada elemento puede tener su propio tipo de dato.
atruct etiqueta{
type elemento!.;
type elemento2;
type elementon;
} lista de variables;
etiqueta es el nombre de la estructura mientras que lista de variables es la lista con los
nombres de las variables declaradas de ese tipo de estructura.
En el siguiente ejemplo se declara una estructura llamada card de tipo catalog. que agrupa
5 campos de datos.
Ejemplo:
struct catalogf
char author[40];
Página | 33
Programación de microcontroladores PIC en lenguaje C
Para acceder a los campos de la variable card se utiliza el punto, que separa el nombre de la
variable de los elementos que la componen:
[Link]='w';
[Link]=12;
printf(n%s",[Link]);
Una vez definida la estructura se pueden declarar más variables del mismo tipo, incluso
vectores de estructuras como en el caso de la variable bigcat que se muestra a
continuación:
struct catalog card2,card3,bigcat[3];
bigcat[2] .data=12;
1.8.2. Uniones
Una unión es una única posición de memoria que se comparte entre dos o más variables.
Las uniones son útiles para ahorrar espacio de memoria y para acceder a la posición de
memoria con diferentes formatos.
Para declarar una unión se procede de forma similar a una estructura:
unión etiqueta{
type elementol;
type elemento2;
type elementon;
} lista de variables;
En el siguiente ejemplo se declara una variable temp que está formada por la unión
de un vector de tres caracteres, un entero de 16 bits y un real de 32 bits.
unión u_type{
int i ;
char c [3];
double d;
} temp;
El entero usa dos bytes, el vector de char usa 3 y el double usa los 4.
Página | 34
1. Introducción a la programación en C
unión sample{
unsigned char bytes[2];
signed short word;
} si
Utilizando la unión podemos acceder a los 16 bytes: [Link]; o a cada uno de los bytes
independientemente: si.b yte s [o] ,• si.b y te s [i] ;
Página | 35
2. Puertos de entrada y salida digitales
2.1. LED y Pulsadores
2.2. Visualizadores numéricos de 7 segmentos
2.3. Exploración de teclado matricial
2.4. Control de Pantallas LCD
Los puertos digitales de entrada y salida son los periféricos más sencillos de que dispone el
microcontrolador, y mediante los cuales es posible controlar otros dispositivos y
monitorizar su estado.
El PIC16F877A tiene los terminales de entrada/salida divididos en 5 puertos (desde el
PORTA hasta el PORTE), algunos disponen de hasta 8 terminales. Los terminales se pueden
Página | 37
Programación de microcontroladores PIC en lenguaje C
Para aumentar la flexibilidad del PIC la mayoría de los pines están multiplexados con
funciones alternativas, de modo que cuando un periférico como, por ejemplo, la USART
(Transmisión Serie) está funcionando sus pines no podrán ser utilizados como l/O de
propósito general. En el caso de los puertos multiplexados con el convertidor A/D, la
configuración como analógicos o digitales se realiza mediante el registro ADCON1. Cuando
se selecciona como analógico, estos bits se leen como "0".
El registro PORT está formado por los biestables que almacenan los datos que se van a
mostrar en la salida. Sin embargo, cuando se lee el registro PORT, el resultado no son los
datos almacenados en los biestables, sino los niveles presentes en los pines de
entrada/salida.
+5V
Página | 38
2. Puertos de entrada y salida digitales
Tras pulsación
Comienzo
SECUENCIA 1 SECUENCIA 2
RB3 RB2 RB1 RBO RB3 RB2 RB1RB0
+0.5 seg. o o o -O O O • *
+0.5 seg. ¿c
o o 0 +0.5 seg. C° ° • ] ♦0 5 seg.
o o o o o • I
+0.5 seg. KT
'♦ o o o o +0.5 seg.
5o e • oy
Solución:
Código fuente
//ARCHIVOS d e d e f i n i c i o n e s
#include <htc.h> //Incluimos librería del micro a usar
#include "ports.h"
ttdefine _XTAL_FREQ 4000000 //Oscilador Interno de 4MHZ
__CONFIG(WRTOFF & WDTE_OFF & PWRTE_OFF & FOSC_XT & LVP_OFF); //Configuración
//del PIC
//Variables
bit CAMBIAR=0; //Flag para cambiar la secuencia de los LED
/ / (SECUENCIA1 si CAMBIAR=0) y (SECUENCIA2 si CAMBIAR=1) - Empieza con la
//SECUENCIA1
unsigned char SECUENCIAl=0xll; //Secuencia 1 empieza con LED DO
//encendido
unsigned char SECUENCIA2=0x09; //Secuencia 2 empieza con LEDs D3-D0
//encendidos
//PROGRAMA PRINCIPAL
void main()
{ //INICIALIZACIONES PARA EL PIC
set_all_digital(); //Desactivamos PORTA como entradas analógicas
wh ile(1)
{ if (RA4 == 0) { //Se ha presionado el pulsador
CAMBIAR=~CAMBIAR; //Cambiar secuencia
}
if(CAMBIAR==0){
P0RTB=SECUENCIA1;
__d e l a y m s (500); //Esperar 500 ms
r°l_8 (SECUENCIA1,1); //Rotar un bit a la izquierda en SECUKNCIA1
else{
PORTB=SECUENCIA2;
__delay ms(500); //Esperar 500 ms
SECUENCIA2 = ~SECUENCIA2; //Cambiar LED encendidos en SECUENCIA2
}
}
Página | 39
Programación de microcontroladores PIC en lenguaje C
//PROGRAMA FRINCIPAL
v o id n a in (
/ / D e s a c t iv a r PORTA como e n t r a d a s a n a l ó g i c a s
set a l l d i g i t a l O ;
TR IS A =0 x l0 ; / / C o n fig u r a r RA4 como e n t r a d a
TRISB=0x00; / / C o n fig u r a r RBO como s a l i d a
FORTB=0; //Todos l o s l e d a p agados
ESTAD0=1; //Em pieza con l a s e ñ a l a c t i v a d a
w h ile (1 ) {
if(E S T A D 0 = = 1 ){ / / S i s e ñ a l a c t iv a d a
p u n to ( ) ;
p u n to ( ) ;
p u n to () ;
ra ya ();
ra ya ();
ra ya ();
p u n to () ;
p u n to ( ) ;
p u n to ( ) ;
pau sa O ; }
e l s e {PORTB=0? } / / S i s e ñ a l d e s a c t iv a d a to d o s l o s l e d a p a ga d o s
}
}
RA4
RBO
m ¥ 1 TJUi n
0.0 1000000 0 2000000.0 30000000 4000000.0 5000000.0
La duración de cada punto será de 10 ms y cada raya de 30 ms. El silencio entre símbolos
(punto/raya) serán 10 ms, mientras que la separación entre caracteres serán 30 ms y entre
palabras de 70 ms.
Página | 42
2. Puertos de entrada y salida digitales
Solución:
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h t c .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
ft in c lu d e " p o r t s . h "
t fd e f in e _XTAL_FREQ 4000000 / / O s c i l a d o r I n t e r n o d e 4MHZ
CONFIG(WRT_OFF & WDTE_OFF & PWRTE_OFF & FOSC_XT & L V P _ O F F );
v o i d m o rse (c h a r t x t S t r i n g [ ] ) ;
// PROGRAMA PRIN C IPA L
/ / D u ra c ió n d e 1 e le m e n t o : 10 ms
/ / P u n to = 1 e le m e n to
//R aya = 3 e le m e n to s
/ / E s p a c io e n t r e s ím b o lo s = 1 e le m e n to
/ / E s p a c io e n t r e c a r a c t e r e s = 3 e le m e n t o s
/ / E s p a c io e n t r e p a l a b r a s = 7 e le m e n t o s
v o i d m a in ( ) {
s e t_ a ll_ d ig ita l(); / / D e s a c t i v a r PORTA como e n t r a d a s a n a l ó g i c a s
TR IS B = 0 x 0 0 ; / / C o n fig u r a r RB0 como s a l i d a
RB0=0; //Todos lo s le d apagados
m o r s e ( " H o la M u n d o ");
w h ile ( 1) ;
}
/ / D e f i n i c i ó n de p u n to s y r a y a s
//Para c a r a c t e r e s a lfa n u m é r ic o s , 3 MSB b i t s d e f in e n e l número de s ím b o lo s (1 a 5'
/ / P a ra c a r a c t e r e s de p u n tu a c ió n ( ' , ' y 2 MSB b i t s i n d i c a n 6 s ím b o lo s
/ / P u n to :0, r a y a : 1;
//LSB b i t s a lm a cen a d o s en o rd e n i n v e r s o d e modo qu e e l b i t 0 = p r i m e r s ím b o lo
/ / E je m p lo , F = = 4 s ím b o lo s = 0010, p o r l o t a n t o s e a lm a c e n a como 0100
/ / 0 0 0 x x x x x 0 s ím b o lo s
/ / 0 0 1 x x x x ? 1 s ím b o lo s x = no im p o r t a , ? = d a t o d e l s ím b o lo = 0 ó 1 )
/ / 0 1 0 x x x ? ? 2 s ím b o lo s
//011 x x ? ? ? 3 s ím b o lo s
//100 x ? ? ? ? 4 s ím b o lo s
//101 ? ? ? ? ? 5 s ím b o lo s
/ / l l ? ? ? ? ? ? 6 s ím b o lo s
c h a r T a b la [] = {ObOlOOOOlO, // 0 = A " . - »
OblOOOOOOl, // 1 = B
O blO O O O lO l, // 2 = C
ObOllOOOOl, // 3 = D »- . . "
ObOOlOOOOO, // 4 = E ". »
OblOOOOlOO, // 5 a F
O b O llO O O ll, // 6 a G » - - ."
OblOOOOOOO, I I 7 = H » ___ '•
ObOlOOOOOO, // 8 a I " . .11
O b lO O O lllO , II 9 = J .-- «i
O b O llO O lO l, I I 10 a K
OblOOOOOlO, // 11 = I*
O bO lO O O O ll, I I 12 a M " - - »
ObOlOOOOOl, // 13 = N " - .»
Página | 43
Programación de microcontroladores PIC en lenguaje C
OblOlOOOOO, // 31 = 5 ii ii
Página | 44
2. Puertos de entrada y salida digitales
1 + • & ! <a.l®U ; ¡M f b lH ls ia l
+5V
Página | 45
Programación de microcontroladores PIC en lenguaje C
Solución:
Se generan tres funciones: una para el punto, otra para la raya y la última para la pausa
entre las dos señales. En cada función se genera una onda cuadrada de semiperiodo 2 ms
(__delay_ms(2))que activa el zumbador durante un tiempo controlado por un for. Mediante
la interrupción externa producida por RBO/INT se deja de enviar la señal al zumbador al
cambiar el terminal RC2 de salida a entrada.
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h tc .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
#d e f i n e _XTAL_FREQ 4000000 / / O s c ila d o r I n t e r n o de 4MHZ
__ CONFIG(WRT_OFF & WDTE_OFF & PWRTE_OFF & FO SCXT & L V P_O F F);
//DEFINICION DE VARIABLES
in t x;
//DEFINICION DE FUNCIONES
v o id p u n to (v o id ){ //Fu n ción p a ra g e n e r a r e l pu n to
f o r (x = 0 ;x < 1 0 0 ;x + + ){
RC2 = -RC2;
__ d e la y ms ( 2 ) ;
}
__ d e la y m s( 2 0 0 ) ;
}
v o id r a y a (v o id ){ //Fu n ción p a ra g e n e r a r l a ra y a
f o r (x = 0 ; x < 2 5 0 ; x + + ){
RC2 = -RC2;
___d e la y ms ( 2 ) ;
}
__ d e la y m s( 2 0 0 ) ;
} ;
v o id p a u s a (v o id ){ //Fu n ción p a ra g e n e r a r l a pau sa e n t r e d o s SOS
__ d e la y _ m s (5 0 0 );
//PROGRAMA PRINCIPAL
v o id m a in (v o id ){
TRISB = ObOOOOOOOl; / / C o n fig u r a r RB0 como e n tra d a
TRISC = ObOOOOOOOO; / C o n fig u r a r RC2 como s a l i d a
RC2=1;
G IE =1; / / H a b i l i t a r in t e r r u p c io n e s ( R e g i s t r o INTCON)
INTE=1; / / H a b i l i t a r i n t e r r u p c ió n de RB0 ( R e g i s t r o INTCON)
INTEDG=0 ; / / In t e r r u p c ió n e x t e r n a RBO/INT p o r f l a n c o de b a ja d a
w h ile ( 1) {
p u n to () ;
p u n to () ?
p u n to () ;
ra ya () ;
ra ya ();
ra ya ();
p u n to ( ) ;
p u n to ( ) ;
p u n to ();
pausa ( ) ;
Página | 46
2. Puertos de entrada y salida digitales
//INTERRUPCIÓN
/ / I n t e r r u p c ió n p o r RBO /IN T
s t a t i c v o id in te r r u p t i s r ( v o i d ) {
if(IN T F ){
IN T F = 0 ; / / D e s a c t i v a r e l FLAG d e l a i n t e r r u p c i ó n de RBO
TRISC = ObOOOOOlOO; / / C o n fig u r a r RC2 como e n t r a d a p a r a p a r a r
}
}
I I I f l l i l i l í
í l
1____________
9COWCOO 'jtocoooo i caíame ueooocoo nocox.o 11500000.0 laxOOCCO 125CD3XC ixoáxoc 133)0x0.3 U000B00C '« — I
1LA9SJM P1G6F377A pcO VWhbi ZDCC [Link] bankO
Página | 47
Programación de microcontroladores PIC en lenguaje C
Solución:
Debido al inversor 74LS540 hay que enviar el complemento del código 7 segmentos de la
letra E al PORTD.
Página | 48
2. Puertos de entrada y salida digitales
Código fuente
//ARCHIVOS DE DEFINICIONES
# i n c l u d e < h t c . h> / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
# in c lu d e " p o r t s . h "
# d e f i n e _XTAL_FREQ 4000000 / / O s c i l a d o r I n t e r n o d e 4MHZ
__ CONFIG(WRT_OFF & WDTE_OFF & PWRTE OFF & F O S C X T & LVP O F F );
u n s ig n e d c h a r D IG IT O ; / / D ig it o que s e q u ie r e sacar
//PROGRAMA P R IN C IPA L
v o id m a in (v o id ){
s e t _ a l l _ d i g i t a l () ; / / D e s a c t iv a PORTA como e n t r a d a s a n a l ó g i c a s
TRISA=ObOOOOOOOO ; / / C o n fig u r a e l PORTA como s a l i d a s
T R IS D =0 x0 0 ; / / C o n fig u r a e l PORTD como s a l i d a s
P O R T A =l; / / A c t i v a r d i s p l a y d e RAO
D IG ITO =0x0E ; / / C a r g a r E en D IG ITO
w h ile (1) {
P O R T D = cod igo [D IG IT O ] ; / / S aca e l D ÍG ITO p o r e l p u e r t o D
__ d e la y _ m s ( 1 0 0 0 ) ; / / D í g i t o m o s t r a d o d u r a n t e 1 seg u n d o
PORTD= OxFF; //Apagar e l d is p la y
__ d e la y _ m s ( 1 0 0 0 ) ; / / D is p la y a p a g a d o d u r a n t e 1 seg u n d o
}
■ logn Anatyici________________________________________________
Tiggei Posfion Tigrjn PC ■ TmeBa:r Mods
Slatt o Cenlei En«J [ New |[~Oeat ) Cye - Sir*ie > a rK
Página | 49
Programación de microcontroladores PIC en lenguaje C
limitan la corriente que circula por los segmentos, mientras que las resistencias Rb = 47 O
deben garantizar la saturación de los transistores que activan los terminales de selección de
cada elemento. Los transistores actúan como interruptores y van a saturación con un nivel
lógico T en los terminales del puerto A y a corte con un nivel lógico '0'. La frecuencia
mínima de las señales en cada uno de terminales de selección (RA3, RA2, R A I y RAO) debe
estar entre 40 Hz y 200 Hz para que no se perciba parpadeo alguno. Cada elemento está
seleccionado durante una cuarta parte del tiempo. Si consideramos una frecuencia de 50
Hz, cada uno de los displays se refrescará cada 20 ms y estará seleccionado durante 5 ms.
Código fuente 1
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h t c .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
tt in c lu d e " p o r t s . h '1
# d e f i n e _XTAL_FREQ 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
__ CONFIG(W RTOFF & WDTE_OFF & PWRTEOFF & F O S C X T & LVP OFF) ; / / C o n fig u r a c ió n
/ / d e l P IC
//PROGRAMA PRINCIPAL
v o i d m a in () {
//IN IC IA LIZ A C IO N E S PARA EL PIC
s e t_ a ll_ d ig ita l(); / / D e s a c tiv a m o s PORTA como e n t r a d a s
/ / a n a ló g ic a s
TR IS A =0x00 ; / / T e r m in a le s PORTA como s a l i d a s
TRISD=OxOO; / / T e r m in a le s PORTD como s a l i d a s
Página | 50
2. Puertos de entrada y salida digitales
w h ile ( 1) {
/ / C ó d ig o p a r a m o s t r a r l o s d í g i t o s y a c t i v a r l o s d i splay3
R A 3 = 0 ;R A 2 = 0 ;R A 1 = 0 ;R A 0 = 1 ; / / A c tiv a m o s D ISPLAY 0 y los otros desactivados
PORTD = OxCO; / / M ostram os p o r p u e r to D e l d ígito 0
__ d e l a y m s ( 5 ) ; / / R e t a r d o d e 5 ms p a r a e v itar el p a rpadeo
Código fuente 2
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h t c .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
# in c lu d e " p o r t s . h "
# d e fin e XTA LFREQ 4000000 / / O s c i l a d o r I n t e r n o d e 4MHZ
— CONFIG(WRT_OFF í W DTEOFF & PWRTE OFF & F O S C X T & L V P O F F ) ; / / C o n fig u r a c ió n
/ / d e l P IC
Página | 51
Programación de microcontroladores PIC en lenguaje C
u n s ig n e d c h a r x = 0 ; / / ín d ic e de lo s c ó d ig o s
w h ile (1) {
fo r (x = 0 ;x < 4 ;x + + ){
P O R T A = d is p la y [x ]; / / A c tiv a r d is p la y
P O R T D = c o d ig o [x ]; / / e n v ia r c ó d i g o
__ d e l a y m s ( 5 ) ; / / D is p la y y c ó d i g o a c t i v a d o 5 ms
}
}
>
Página | 52
2. Puertos de entrada y salida digitales
LECTURA TECLADO
Si RB0 = 0 y tecla ;0 ' pulsada => RB4 = 0
tecla '0 no pulsada => RB4 = 1
Para explorar un teclado matricial se envían señales hacia las filas de la matriz por las líneas
de exploración y se recoge información por las columnas, que entonces constituyen las
líneas de retorno. Básicamente se parte de que, si no hay ninguna tecla pulsada, todas las
líneas de retorno están en el nivel lógico '1'. Las líneas de exploración son puestas (sucesiva
o simultáneamente) a '0'. Este valor lógico solo aparece en la línea de retorno donde está la
tecla pulsada, mientras que las restantes líneas de retorno mantienen el valor '1'. Con la
información enviada hacia la matriz y la que retorna, se conforma un código único para
cada tecla, llamado código de exploración. Para garantizar que las líneas de retorno
permanezcan en T si no hay tecla pulsada, se conectan resistencias entre cada línea de
retorno y la tensión de alimentación (VDD).
El código que retornará el teclado será el valor de la tecla pulsada. Conectando al puerto D
un display de 7 segmentos (véase figura del ejemplo 2.2.1) se podrá ver dicho valor en el
display.
Configuración
Como se van a utilizar las resistencias internas de polarización del puerto B, hay que
indicarlo en el registro OPTION_REG (véase apéndice A2.2)
Con OPTION_REG=Ox7F se habilitan dichas resistencias.
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h t c .h > / / In c lu im o s lib r e r ía d e l m ic r o a u s a r
# in c lu d e " p o r t s . h "
# d e f i n e _XTAL_FREQ 4000000 / / O s c i l a d o r I n t e r n o d e 4MHZ
__ CONFIG(W RTOFF & WDTE_OFF & PWRTE_OFF & FOSC_XT & LVP OFF) ;
//DEFINICIÓN DE VARIABLES
/ / T a b la con e l c ó d ig o de 7 s e g m e n to s co m p le m en ta d o p a r a l o s d í g i t o s
/ / d el 0 a l F y apagado.
u nsign ed ch ar c o d ig o [] ={0 x C 0 ,0 xF 9 , 0xA4, 0xB0,0 x 9 9 ,0 x 9 2 ,0 x 8 2 ,0xF8,0x80,
0 x 9 8 ,0 x 8 8 ,0 x 8 3 ,0xC6, O xAl,0 x 8 6 ,0x8E,0xFF>;
u n s ig n e d c h a r t e c l a ; / / ín d ic e de l i s t a de c ó d ig o
Página | 53
Programación de microcontroladores PIC en lenguaje C
w h ile ( 1 ) { / / B u c le i n f i n i t o .
PORTB=OxFE; // S aca 0 a F i l a 1
if(R B 4 == 0 ) { t e c l a = 0 ; }
if(R B 5 == 0 ) { t e c l a = 1 ; }
i f ( R B 6 == 0 ) { t e c l a = 2 ; }
if(R B 7 == 0 ) { t e c l a = 3 ; }
PORTB=0xFD; // S aca 0 a F i l a 2
i f ÍRB4 == 0 ) { t e c l a = 4 ; }
if(R B 5 == 0 ) { t e c l a = 5 ; }
i f ( R B 6 == 0 ) { t e c l a = 6 ; }
if(R B 7 == 0 ) { t e c l a = 7 ; }
PORTB=0xFB; // S aca 0 a F i l a 3
if (R B 4 == 0 ) { t e c l a = 8 ; }
if (R B 5 == 0 ) { t e c l a = 9 ; }
i f ( R B 6 == 0 ) { t e c l a = 1 0 ; }
if(R B 7 == 0 ) { t e c l a = 1 1 ; }
PORTB=0xF7; // S aca 0 a F i l a 4
if (R B 4 == 0 ) { t e c l a = 1 2 ; }
if (R B 5 == 0 ) { t e c l a = 1 3 ; }
if ( R B 6 -= 0 ) { t e c l a = 1 4 ;}
if(R B 7 == 0 ) { t e c l a = 1 5 ; }
PORTD = c o d i g o [ t e c l a ] ; / / S a c a r c ó d i g o de 7 seg m en tos a l d i s p l a y
i f ( (RB4 t a RB5 && RB6 && R B 7)== 1 ) { t e c l a = 1 6 ; } / /A pagado e l d i s p l a y
}
}
Página | 54
2. Puertos de entrada y salida digitales
Figura 2.17: Conexión del PIC16F877A con la pantalla LCD HITACHI HD 44780.
Página | 55
Programación de microcontroladores PIC en lenguaje C
Las posiciones de la DDRAM para la primera fila son las direcciones 0x00 a OxOF. Para la
segunda fila comienzan en la 0x40 y terminan en ia 0x4F
Cuando se envía una instrucción o un dato al display es necesario esperar un cierto tiempo
antes de enviar el siguiente, para que el display pueda procesarlo adecuadamente. Esto se
puede hacer monitorizando el flag de Busy o respetando los tiempos de ejecución indicados
por el fabricante.
Solución:
En la línea 1 aparecerá el texto "LA PRIMERA LÍNEA" y en la línea 2 el texto "La segunda
línea".
Al crear el proyecto hay que cargar además del fichero con el programa los ficheros Icd.c y
Icd.h
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h tc .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r .
# in c lu d e ''I c d . h " / / In c lu im o s l i b r e r í a de l a p a n t a l l a l c d .
# d e f i n e _XTAL_FREQ 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
__ CONFIG(W RTOFF í WDTE_OFF & PWRTE_OFF & FOSC_XT & L V P O F F );
Página | 56
2. Puertos de entrada y salida digitales
w h ile (1 ) {
l c d _ g o t o ( 0 x 0 0 ); / / E s c r ib e en l a p r im e r a l í n e a de l a p a n t a l l a
//LCD (d e 0x00 a OxOF)
l c d _ p u t s ( "L A PRIMERA L I N E A " ) ; / / P r e s e n ta c ió n de l a p a n t a lla .
l c d _ g o t o (0 x 4 0 ); / / E s c r ib e en l a seg u n d a l í n e a de l a
/ / p a n t a l l a LCD (d e 0x40 a 0x4F)
l c d _ p u t s ( " L a seg u n d a l i n e a " ) ; / / P r e s e n ta c ió n de l a p a n t a lla .
}
}
Hay que crear los caracteres Ñ y ñ ya que no están disponibles en la CGROM. Para ello los
vamos a crear en la CGRAM.
OxOE :: L 0x00
0x11 : □ OxOE [I : □
0x11 0x16 J m
0x19 nn - 0x19 nn u
0x15 □ __ 0x11 n ■
0x13 _ _ 0x11 n
Oxll i _ 0x11 n ■
0x00 ... cursor 0x00 cursor
Figura 2.18: Caracteres ñ y ñ .
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h tc .h >
# in c lu d e " l c d . h "
__ CONFIG(W RTOFF & WDTE_OFF & PWRTE_OFF & FOSC_XT & LVP O F F );
/ / D e f i n i c i ó n d e c a r a c t e r e s en a r r a y s de 8 b y t e s (5 x 8 )
/ / s ó lo s e t ie n e n en c u e n ta l o s ú l t i m o s 5 b i t s .
u n s ig n e d c h a r MAY[ 8 ] = {0 x 0 E , 0 x 1 1 ,0 x 1 1 ,0 x 1 9 ,0 x 1 5 ,0 x 1 3 ,0 x 1 1 , 0 x 0 0 };
u n s ig n e d c h a r M IN [ 8 ] = { 0 x 0 0 , OxOE,0 x 1 6 ,0 x 1 9 ,0 x 1 1 ,0 x 1 1 ,0 x 1 1 ,0 x 0 0 } ;
Página | 57
Programación de microcontroladores PIC en lenguaje C
//PARAMETR02: C a r á c t e r b itm a p (8 b y t e s ) . (5 x 8 )
L c d D e fin e C h a r (u n s ig n e d c h a r charnum , c h a r v a l ú e s [ ] ) {
in t i ;
/ / s e le c c io n a p o s i c i ó n CGRAM
LCD_RS=0;
l c d w r it e (0 x 4 0 + 8 * c h a r n u m ) ; / / d isp C m d (0x40 + ch a rn u m * 8 ) ;
/ / in t r o d u c e e l c a r á c t e r en CGRAM
f o r ( i =0 ; i < 8 ; i+ + ) {
lc d _ p u t c h (v a lú e s [i]) ;
}
}
//PROGRAMA PRINC IPAL
v o id m a in (v o id ){
lc d _ in it (); / / I n i c i a l i z a l a p a n t a l l a LCD.
lc d c le a r (); / / B o rr a e l c o n t e n id o d e l a p a n t a l l a LCD
L c d D e fin e C h a r (0 ,M A Y ); / / In t r o d u c e e l n u evo c a r á c t e r Ñ m a y ú s cu la
/ / en p o s i c i ó n 0 y nom bre MAY
L c d D e fin e C h a r (1 ,M I N ); / / In t r o d u c e e l n u evo c a r á c t e r ñ m in ú s c u la
/ / en p o s i c i ó n 1 y nom bre MIN
l c d g o t o ( 0x 0 0 ) ; / / S e le c c io n a l a p r im e r a l í n e a p a r a e s c r i b i r
l c d _ p u t s ( "PAMPLONA IR U " ) ;
lc d _ p u t c h ( 0 x 0 0 ) ; / / E s c r ib e l a Ñ
lc d _ p u t s ( " A " ) ;
Solución:
Al crear el proyecto hay que cargar además del fichero.c con el programa los ficheros Icd.c y
Icd.h
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h tc .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r .
# in c lu d e " I c d . h " / / In c lu im o s l i b r e r í a d e l a p a n t a l l a l c d .
# d e fin e XTALFREQ 4000000 / / O s c ila d o r I n t e r n o de 4MHZ
__ CONFIG(W RTOFF & WDTE_OFF & PWRTEOFF & F0SC_XT & L V P O F F ) ;
//DEFINICION DE VARIABLES
u n s ig n e d c h a r x ,s e g u n d o s , d e c e n a s ,u n id a d e s ; / / V a r ia b le s que usarem os
//PROGRAMA PRINCIPAL
v o i d m ain ( v o i d ) {
lc d _ in it(); / / I n i c i a l i z a l a p a n t a l l a LCD.
lc d c le a r O ; / / B o rra e l c o n t e n id o de l a p a n t a l l a lc d .
Página | 58
2. Puertos de entrada y salida digitales
l c d _ g o t o (0 x 0 4 ) ; / / E s c r ib e en l a p a n t a l l a LCD l a p r e s e n ta c ió n
/ / in ic ia l.
l c d _ p u t s ( "SEGUNDOS") ; / / P r e s e n ta c ió n d e l a p a n t a lla ,
w h ile (1 ) {
fo r (x = 0 ;x < 6 0 ;x + + ){
segu ndos=x; / / A c t iv a r d is p la y
/ / C ó d ig o qu e n os s i r v e p a r a p a s a r l a v a r i a b l e s e g u n d o s a BDC
decenas=segu n dos/10; //Guardam os l a s d e c e n a s d e segu n do
s egu n do s =s e gu ndo s %1 0 ;
u n id a d e s = s e g u n d o s ; //Guardam os l a s u n id a d e s de segu n do
//Sumamos 0x30 p a r a o b t e n e r su c ó d i g o a s c i i .
d e c e n a s = d e c e n a s + 0 x 3 0;
u n id a d e s = u n id a d e s + 0 x 3 0 ;
/ / C ó d ig o p a r a m o s t r a r l o s v a l o r e s p o r l a p a n t a l l a l c d .
l c d g o t o (0 x 4 7 );
lc d _ p u t c h (d e c e n a s );
l c d _ g o t o (0 x 4 8 );
lc d _ p u tc h (u n id a d e s );
__ d e l a y m s (1 0 0 0 ); / / R e t a r d o de 1 seg u n d o
}
}
}
Página | 59
3. Temporizadores
3.1. Tem porizador 0
3.2. Tem porizador 1
3.3. Tem porizador 2
3.4. Watchdog
El PIC 16F877A tiene tres temporizadores, TimerO, Tim erl y Timer2, que se pueden utilizar
para crear retardos, realizar tareas periódicas, generar señales PWM o contar pulsos
externos. Al tratarse de dispositivos hardware independientes de la CPU, todas estas
funciones tienen lugar de manera simultánea, y a la vez que el micro puede estar realizando
otra tarea.
RAO/ANO
RA1/AN1
RA2/AN2/VREF VCVREF
RA3/AN3/VREF»
RA4/ /C10UT < “
RA5/AN4/SSS/C20UT
TOCKI
3 RBOÍJNT) Entrada de flancos
9 RB1^-<
RB2 , para TMRO en
RB3/PGM
RB4 I modo contador
RB5 I
RB6/PGC
RB7/PQD
Rcom
RC 1óso/TICKI
01SI/CCP2 -
RC1
2F/CTCP
RC3/SCK/SCL
T1CKI
Entrada de flancos
para TMR1 en
modo contador
La configuración de los
temporizadores se realiza
mediante la carga de
ciertos registros presentes
en RAM
Página | 61
Programación de microcontroladores PIC en lenguaje C
3.1. Temporizador 0
El Temporizador 0 dispone de un contador/temporizador de 8 bits además de un predivisor de
8 bits programable. La fuente de pulsos puede ser interna o externa. En este segundo caso, se
sincroniza con el reloj interno y es posible seleccionar el flanco en que se produce la cuenta.
El funcionamiento como temporizador se selecciona poniendo a cero el bit TOCS del registro
OPTION. En este modo el temporizador se incrementa en cada ciclo de instrucción (sin
tener en cuenta el pre-divisor). Cuando se escribe en el registro TMRO, la cuenta se inhibe
durante los dos siguientes ciclos.
El modo contador se selecciona poniendo a "1" el bit TOCS. En este modo cuenta los pulsos
que se aplican al pin TOCKI. El flanco se determina mediante el bit TOSE del registro OPTION.
Para asignar el pre-divisor al Temporizador 0 es necesario borrar el bit PSA del registro
OPTION. En otro caso se asigna al Watchdog.
Cuando la cuenta se desborda (pasa de OxFF a 0x00) se pone a 1 el flag TOIF del registro
INTCON. TOIF debe ser borrado por la rutina de atención a la interrupción para rehabilitar
esta interrupción.
I
TO SE TOCS
NOTA: Para ser precisos, habría que añadir 2T¡ en eí cálculo de la temporización ya que cada vez que se
recarga el TMRO se pierden dos ciclos de máquina hasta el siguiente incremento como se explica en e ma™
de referencia de Microchip (DS33023). Sin embargo, en los ejercicios propuestos se considerará despreci
este tiempo.
Página | 62
3. Temporizadores
Vss VDD
4 7 00
PIC16F877A
OSC1______ O SC2
Figura 3.3: C onexión del LED al PIC16F877A para encenderlo y apagarlo con el T imer O.
Solución:
Configuración
Página | 63
Programación de microcontroladores PIC en lenguaje C
Para conseguir que el tiempo de desbordamiento sea de 50 ms hay que cargar TMRO con
N tmro = 60 .
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h t c .h > / / in c lu im o s l i b r e r í a d e l m ic r o a u s a r
# d e f i n e _XTAL_FREQ 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
__ CONFIG(WRT_OFF & WDTE_OFF & PWRTE_OFF & FOSC_XT & L V P O F F ) ;
//PROGRAMA PRINCIPAL
void main(void){
unsigned char cont; / / C o n ta d o r de d e s b o r d a m ie n to d e TMRO
TRISB=0x00; / / C o n fig u r a e l PORTB como s a l i d a s
PORTB=0; // Todos l o s l e d a p a ga d o s
OPTION_REG=OxC7; //TMRO como t e m p o r iz a d o r con p r e d i v i s o r P=256
TMR0=60; / / P a ra qu e Td sea n 50ms
while(1){
if(T0IF){
T0IF=0; / / D e s a c t iv a r e l FLAG de TMRO
TMR0=60; / / R e c a r g a r TMRO
cont++; / / In c re m e n ta r c o n ta d o r de d e s b o rd a m ien to de TMRO
if(cont==20){ / / S i s e han l l e g a d o a 20 d e s b o r d a m ie n t o
// (1 seg u n d o )
PORTBbi ts.RB1 ~ P O R T B b its . RB1; //Cambia e s t a d o de RB1
cont=0; // R e i n i c i a c o n t a d o r de d e s b o r d a m ie n to s
¡ + j¡ _ SIS) M * |H |# |& |
FBI
1
L
50X000 100X00.0 15000000 xocococ rsxcnoo
Solución:
Página | 64
3. Temporizadores
Configuración
Para conseguir la cadencia de 2 segundos será necesario un contador cont que cuente 40
interrupciones.
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h t c .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
# in c lu d e " t i m e r s . h " / / In c lu im o s l i b r e r í a d e t im e r s
# d e fin e XTA LF R E Q 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
CONFIG (WRT_OFF & WDTE OFF & PWRTE OFF & FOSC XT & L V P _ O F F );
Página | 65
Programación da microconrroladoras PIC an langnaia C
j~ Oxraris
pi
Figura 3.6: Conexiones con el PIC16F877A del pulsador que introduce los pulsos externos al T imer 0
Y DE los displays de 7 segmentos que muestran los pulsos introducidos .
Solución:
En este ejercicio se utiliza el temporizador 0 como contador de los pulsos que entran por
RA4/T0CKI.
Con cada pulso se desborda el TimerO y se produce la interrupción que permite incrementar
la cuenta de los displays.
Página | 66
3. Temporizadores
Configuración
Con OPTION_REG = O b lllllO O O = 0xF8 el TimerO actúa como contador de los pulsos
externos que entran por TOCKI. El pre-divisor vale P = 1 ya que se asigna al Watchdog.
Cargando TMRO con N tmro = 255, el desbordamiento se producirá con cada pulso externo.
Código fuente
//ARCHIVOS DE DEFINICIONES
# i n c lu d e < h t c .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
# i n c lu d e " t i m e r s . h " / / In c lu im o s l i b r e r í a d e t im e r s
# i n c lu d e " p o r t s . h " / / In c lu im o s l i b r e r í a de p u e rto s
# d e fin e X TA LF R E Q 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
CONFIG(WRT OFF & WDTE OFF PWRTE OFF & FOSC XT & LVP O F F );
u n s ig n e d c h a r c o d i g o [1 = {0 x C 0 ,0 x F 9 ,0 x A 4 ,O x B O ,0x99, 0 x 9 2 ,0 x 8 2 ,0 x F 8 , 0 x 8 0 , 0 x 9 0 } ;
u n s ig n e d c h a r c o n t = 0 ; / / C o n ta d o r d e i n t e r r u p c i o n e s
u n s ig n e d c h a r C 2 =0,C 1 =0; / / L leva m o s l a c u e n ta d e 00 a 99
e i () ; / / H a b ilit a r in te r r u p c io n e s
T 0 IE = 1 ; / / H a b i l i t a r i n t e r r u p c i ó n d e TMRO
w h ile (1 ){ / / B u cle i n f i n i t o
/ / C ó d ig o p a r a m o s t r a r l o s d í g i t o s
RA 1=0;RA 0=1; / / A c tiv a m o s D IS PLA Y 0 y l o s o t r o s d e s a c t i v a d o s
PORTD = c o d i g o [ C l ] ; //M ostram os p o r p u e r to D l a s u n id a d e s
__ d e l a y m s( 5 ) ; / / R e ta rd o d e 5 ms p a r a e v i t a r e l p a r p a d e o
Página | 67
programación de microcontroladores PIC en lenguaje C
if(C 2 = = 1 0 ){ / / S i hemos l l e g a d o a 10 d e c e n a s
C2 = 0 ; / / R esetea m o s l a s d e c e n a s
}
}
}
}
3.2. Temporizador 1
El Temporizador 1 es un módulo que contiene un temporizador/contador de 16 bits
accesible mediante dos registros de 8 bits (TMR1H:TMR1L). Cuando se desborda (pasando
de OxFFFF a 0x0000) se activa el flag de interrupción (TMR1IF). Esta interrupción se puede
habilitar o deshabilitar mediante el bit TMR1IE.
Página | 68
3. Temporizadores
8 bits 8 bits
F ig u r a 3.8: R e p r e s e n t a c ió n en b l o q u e s d e l f u n c io n a m ie n t o d e l T im e r 1.
Solución:
La cadencia de cambio de 500 ms se conseguirá con una función de retardo de 500 ms. Dicha
función de retardo se realizará con el temporizador 1 sin utilizar las interrupciones del mismo.
Configuración
Página | 69
Programación de microcontroladores PIC en lenguaje C
Con T1CON = 0x31 = ObOOllOOOl el Tim erl actúa como temporizador (Ti = 4/4 MHz = 1 ps)
y predivisor P = 8.
Para 500 ms, el valor con el que hay que cargar el temporizador 1 es:
TMR1 = 3036 = OxOBDC => TMR1H = OxOB y TMR1L = OxDC
Código fuente
//ARCHIVOS DE DEFINICIONES
# i n c lu d e < h t c . h> / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
# in c lu d e " t i m e r s . h " / / In c lu im o s l i b r e r í a de t im e r s
# in c lu d e " p o r t s . h " / / In c lu im o s l i b r e r í a de p u e r t o s
# d e f in e XTA LFREQ 4000000 / / O s c ila d o r I n t e r n o de 4MHZ
//DEFINICIÓN DE VARIABLES
/ / T a b la co n e l c ó d ig o d e 7 s eg m en to s co m plem en tad o p a r a l a s c ifr a s d e 0 a F.
/ / (tam año b y t e )
u n s ig n e d c h a r c o d i g o [ ] = {0 x C 0 ,0 x F 9 ,0 x A 4 , OxBO,0 x 9 9 ,0 x 9 2 ,0 x 8 2 ,0 x F 8 ,0x80,
0 x 9 0 ,0 x 8 8 ,0 x 8 3 ,0 x C 6 ,O x A l,0 x 8 6 ,0x8E>;
u n s ig n e d c h a r x ; / / í n d i c e d e l i s t a de c ó d ig o
// DEFINICION DE FUNCIONES
/ / F u n ció n de r e t a r d o de SOOmseg
v o i d D E L A Y 5 0 0 m s (void ){
s e t tim e r l(O x O B D C ); / / A ju s t a l o s r e g i s t r o s c o n t a d o r e s d e l T i m e r l
s e t u p _ t im e r l(T l_ O N | T 1 I N T | T 1 D I V 8 ) ; / / T im er 1 ON co n c o n t a d o r i n t e r n o
//y p r e d i v i s o r 8
w h ile (T M R 1 IF == 0) c o n t in u é ; / / E sp era m ie n t r a s no s e d e s b o r d e e l
/ / T im er 1
TM R1IF=0;
}
// PROGRAMA PRINCIPAL
v o id m a in (v o id ){
s e t a l l d i g i t a l () ; / / D e s a c t iv a PORTA como e n t r a d a s a n a l ó g i c a s
TR ISA = ObOOOOOOOO; / / C o n fig u r a e l PORTA como s a l i d a s
TRISD =0x00; / / C o n fig u r a e l PORTD como s a l i d a s
PO R T A=l; / / A c t i v a r d i s p l a y de RAO
x=0; / / ín d ic e de l a l i s t a p a r a l a p r im e r a c i f r a .
w h ile (1 ) {
P O R T D = c o d ig o [x ]; //Saca e l v a l o r que c o rr e s p o n d e p o r e l p u e r to D
D ELAY500m s(); / / E sp era 500 ms
X+ + ; / / In c re m e n ta í n d i c e de l a l i s t a d e c ó d i g o s
Página | 70
3. Temporizadores
if< x = = 1 6 ){ / / S i s e ha b a r r i d o to d a l a l i s t a
x =0 ; / / R e s e t e a r í n d i c e de l a l i s t a
}
}
}
roniD oco
- I — j r
1 i 1 1
100X0.0 7TXOOC0 00X00 4OXTO.0 WXttl.O 01X010 7UXCOO (0X000 ooctcoo (OOOCCi :
Figura 3.10: Conexiones del PIC16F877Aa los 4 displays ( multiplexados) del letrero
Y A LOS PULSADORES DE MARCHA Y PARADA.
Página | 71
p
Solución:
Se utilizará el temporizador 1 con interrupciones para conseguir ia
e l temporizador 0 sio interropcionet para
activado cada displav para q u eco parpadee. ^ haV <H* m antener
Configuración
Con TlCON=0x31=0b00110001 el Tim erl actúa como temporizador (Ti = 4/4 MHz = 1 ps),
con predivisor P=8 y habilitado.
Código fuente
//ARCHIVOS DE DEFINICIONES
# i n c lu d e < h t c . h> / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
# d e f i n e _XTAL_FREQ 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
__ CONFIG(W RTOFF & WDTEOFF & PWRTEOFF & FO S C X T & L V P O F F ); / / C o n fig u r a c ió n
/ / d e l P IC
/ / V a r ia b le s g l o b a l e s p a r a qu e sea n a c c e s i b l e s en l a i n t e r r u p c i ó n
/ / T a b la con e l c ó d ig o 7 se gm e n to s com plem en tad o
u n s ig n e d c h a r D 4=0x89, D3=0xC0, D 2 = 0 x C 7 ,D l= 0 x 8 8 ; / / c ó d ig o 7 segm en t0 s d e H O L A
u n s ig n e d c h a r AUX; / / v a r ia b le a u x i l i a r p a ra l a r o t a c ió n d e l l e t r e r o ,
u n s ig n e d c h a r c o n t = 0 ; / / C o n ta d o r de i n t e r r u p c i o n e s
b i t ESTADO; / / F la g p a r a a c t i v a r o d e s a c t i v a r e l d e s p la z a m ie n t o
//del le t r e r o
//(MARCHA es ESTADO=l) y (PARADA es ESTADO=0)
//PROGRAMA PRINCIPAL
v o i d m a in ( ) {
ADCONl = ObOOOOOHO; / / D e s a c tiv a m o s PORTA como e n t r a d a s a n a l ó g i c a s
T R IS A = 0 x l0 ; //PORTA con RA4 como e n t r a d a y r e s t o como s a l i d a s
TRISB = 0 x 0 1 ; / / T e rm in a l RB0 como e n t r a d a
TRISD =0x00; / / T e r m in a le s PORTD como s a l i d a s
Página | 72
3. Temporizadores
w h ile (1 ) {
i f ( R A 4 == 0 ) { //S e ha p r e s io n a d o l a MARCHA
ESTADO=l //Ponem os l e t r e r o en MARCHA
}
if(R B O == 0 ) { //S e ha p r e s io n a d o l a t e c l a de PARADA
ESTADO = 0; //Ponem os l e t r e r o en PARADA
D 4=0x89;
D3=0xC0;
D2=0xC7;
D l= 0 x 8 8 ; / / R es etea m o s e l l e t r e r o p a r a em p eza r HOLA
}
/ / C ó d ig o p a r a m o s t r a r l o s d í g i t o s
RA3 = 0 ; RA2 = 0 ; RAI = 0 ; RAO = 1 ; / / A c tiv a m o s D ISPLAY 0 y l o s o t r o s d e s a c t i v a d o s
PORTD = D I ; //M ostram os p o r p u e r to D l a l e t r a qu e h ay en D I
__ d e l a y m s ( 5 ) ; / / R e ta r d o de 5 ms p a r a e v i t a r e l p a rp a d e o
__ d e la y _ m s ( 5 ) ; / / R e ta rd o d e 5 ms p a r a e v i t a r e l p a rp a d e o
__ d e l a y m s ( 5 ) ; / / R e ta rd o d e 5 ms p a r a e v i t a r e l p a rp a d e o
__ d e l a y m s ( 5 ) ; / / R e ta rd o de 5 ms p a r a e v i t a r e l p a rp a d e o
}
//INTERRUPCIÓN
s t a t i c v o id in te r r u p t i s r ( ) {
if(T M R 1 IF ){ / / S i l a i n t e r r u p c i ó n l a ha g e n e r a d o TMR1,
/ / e je c u ta m o s e l c ó d i g o
TMR11F= 0; / / D e s a c tiv a m o s e l FLAG d e l a i n t e r r u p c i ó n
//de TMRl
TMRlH=0x0B;
TMRlL=0xDC;
if(E S T A D O ){ / / S i e l l e t r e r o e s t á en m archa
co n t+ + ; // In crem en ta m o s l a c u e n t a de i n t e r r u p c i o n e s
i f ( c o n t == 2 ) { / / S i s e ha c o m p le ta d o e l segu n d o = 500ms * 2
/ / in te r r u p c io n e s
cont = 0 ; / / R es etea m o s l a c u e n ta d e i n t e r r u p c i o n e s
AUX = D4; // Rotam os l a s l e t r a s
D4 = D3;
D3 = D2;
D2 = DI?
D I = AUX;
Página | 73
Programación de microcontroladores PIC en lenguaje C
+5V
Figura 3.11: Conexiones del PIC16F877A. Los pulsos que salen por RBO (generados por T imer O)
son los pulsos externos que ENTRAN POR T1CKI AL TlMERl.
Solución:
Se utilizará el timerO para generar los pulsos que encienden y apagan el led DO. Se utilizará el
timerl como contador de los 30 pulsos generados por el timerO para encender o apagar el led DI.
Configuración
Página | 74
3. Temporizadores
Código fuente
//ARCHIVOS DE DEFINICIONES
# i n c l u d e < h t c .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u sa r
# in c lu d e " t im e r s .h " / / In c lu im o s l i b r e r í a d e t im e r s
# in c lu d e " p o r t s .h " / / In c lu im o s l i b r e r í a de p u e r to s
# d e fin e X T A L F R E Q 4000000 / / O s c ila d o r I n t e r n o de 4MHZ
__ CONFIG(WRT_OFF & W DTEOFF & PWRTE_OFF & FOSC XT & LVP O F F );
//D E F IN IC IÓ N DE VARIABLES
u n s ig n e d c h a r c o n t ; / / C o n ta d o r d e d e s b o r d a m ie n to de TMRO
//PROGRAMA P R IN C IP A L
v o id m a in (v o id ){
TR ISB = 0b00000000; / / C o n fig u r a e l PORTB como s a l i d a s
T R IS C = 0 x F F ; / / C o n fig u r a e l PORTC como e n t r a d a s
PORTB=0; / / T od os l o s l e d a p a ga d o s
/ / C o n fig u r a c ió n d e l TIMER0 p a r a p r o d u c i r i n t e r r u p c i o n e s c a d a 50 m s.
setu p _tim er0 (R T C C _IN T E R N A L | R T C C _D IV 2 5 6 ) ; //TIMER0 como t e m p o r iz a d o r
/ / con p r e d i v i s o r P=256
s e t t i m e r O (6 0 ); / / P a ra que Td sea n 50ms
e i () ; / / H a b ilit a r in te r r u p c io n e s
T 0 IE = 1 ; / / H a b i l i t a r i n t e r r u p c i ó n d e TMR0
T 0 IF = 0 ; / / D e s a c t iv a r e l FLAG de TMR0
/ / C o n fig u r a c ió n d e l TIMER1 p a r a p r o d u c i r i n t e r r u p c i o n e s c a d a 30 p u ls o s e x t e r n o s
s e ttim e r l(0 x F F E 2 );
s e t u p _ t im e r l(T l_ O N | T 1 _ E X T | T 1 _ D IV 1 ); //TIM ERl c o n t a d o r p u ls o s e x t e r n o s
/ / p o r T 1 C K I, co n P=1 y ON
P E IE = 1 ; / / H a b i l i t a r i n t e r r u p c i ó n de TMR1
TM R1IE=1; / / H a b i l i t a r i n t e r r u p c i ó n de TMR1
TM R 1IF =0; / / D e s a c t iv a r e l FLAG d e TMR1
w h ile (l); / / B u cle i n f i n i t o .
}
//INTERRUPCIÓN p o r Tim erO y t i m e r l
s t a t i c v o id in te r r u p t i s r ( v o i d ) {
i f ( T 0 I F && ! T M R 1 IF ){
T 0 IF = 0 ; / / D e s a c t iv a r e l FLAG de l a i n t e r r u p c i ó n de TMR0
TMR0=60; / / R e c a r g a r TMR0
c o n t+ + ; / / In c r e m e n ta r c o n t a d o r de i n t e r r u p c i o n e s
i f (c o n t = = 1 0 ) { //10 i n t e r r u p c i o n e s ca d a 50 ms da l u g a r a 500 ms
P O R T B b its . RB0 = -P O R T B b its.R B 0 ; //Cam bia e s t a d o de RB0
c o n t= 0 ; / / R e i n i c i a r c o n t a d o r d e d e s b o r d a m ie n to s
}
}
i f(T M R 1 IF == 1 ) {
TM R 1IF =0; / / D e s a c t iv a r e l FLAG de l a in t e r r u p c ió n de TMR1
s e t_ tim e r l(0 x F F E 2 ); / / R e c a r g a r TMR1
PO R T B b its.R B 1 = -P O R T B b its .R B 1 ; //Cambia e s t a d o de RB1
}
Página | 75
Programación de microcontroladores PIC en lenguaje C
+5V
Figura 3.12: Conexiones con ee PIC16F877A del oscilador externo de 32.76 KHz para controlar el T imer I.
Solución:
Configuración
Con T1CON = 0x3F = O b O O llllll el Tim erI actúa como contador de pulsos externos, con
predivisor P = 8 y habilitado. Los pulsos externos que entran son generados por el oscilador
externo de 32.76 KHz y cuyo periodo es de 30.52 ps.
Para que se desborde o se produzca interrupción cada 5 segundos hay que cargar el
temporizador 1 con:
TMRl = 65536----------- —--------- = 45061 = 0xB005 => TM1H = OxBO y TMR1L = 0x05
8* (1 / 32.76KHz)
Con cada interrupción se cambiarán los LED encendidos y apagados.
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h tc .h > / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
ffd e fin e XTAL FREQ 4000000 / / O s c ila d o r I n t e r n o de 4MHZ
__ CONFIG(W RTOFF & WDTEOFF & PWRTE_OFF & FOSC_XT & L V P _O F F );
Página | 76
3. Temporizadores
//PROGRAMA P R IN C IP A L
v o id m a in (v o id ){
T R IS B = ObOOOOOOOO; / / C o n fig u r a e l PORTB como s a l i d a s
PORTB=0b00001001; / / E n c e n d id o s D3-D0 y a p a ga d o s D2-D1
Se puede observar el funcionamiento mediante el analizador lógico del simulador. Para ello
se ha definido un estímulo de tipo reloj por RCO con un tiempo de subida y bajada idéntico
correspondiente a aproximadamente un semiperiodo de la señal de 32.76 KHz.
RCO
RBO
RB1
RB2
RB3
0 .0 5 0 0 0 .0 1 0 0 0 0 .0 1 5 0 0 0 ,0 2 0 0 0 0 .0 2 5 0 0 0 .0 30000 0
Nota: Para acelerar la simulación se ha ajustado el contador del Timer 1 para una
cadencia de 5 ms.
Página | 77
Programación de microcontroladores PIC en lenguaje C
3.3. Temporizador 2
El temporizador 2 se usa también para establecer la base de tiempo cuando el módulo CCP
se utiliza para generar ondas PWM.
El postdivisor cuenta el número de veces que el registro TMR2 coincide con el registro PR2,
lo que ayuda a reducir la carga de la CPU.
8 b its
8 b its
R e g is tro s a s o c ia d o s al Tim er 2
Reoistro Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 BitO Ver APENDICE 2
INTCON GIE PEIE TOIE INTE RBIE TOIF INTF RBIF A2.5
PIR1 PSPIF ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF A2.7
PIE1 PSPIE ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE A2.6
TMR2 Registro de módulo de Timer2
T2CON |t OUTPS3| TOUTPS2 It OUTPS i It OUTPS cI TMR20N |t 2CKPS1 IT2CKPS0 A2.4
PR2 Reqistro de periodo de Timer2
Página | 78
3. Temporizadores
+5V
f = 50Hz
10ms
< -W
„ 20ms
F igura 3.15: O btener por el terminal RB3 una onda cuadrada de 50 Hz.
Solución:
Configuración
Página | 79
Programación de microcontroladores PIC en lenguaje C
Código fuente
//ARCHIVOS DE DEFINICIONES
#include<htc.h> //Incluimos librería del micro a usar
#define _XTAL_FREQ 4000000 / /Oscilador Interno de 4MHZ
CONFIG (WRT OFF & WDTEOFF & PW RTEOFF & FO S C X T & LVP OFF) ;
//DEFINICION DE VARIABLES
i n t XJ
//DEFINICION DE FUNCIONES
// F u n ció n d e 1 ms
v o i d D E L A Y lm s (v o id ){
w h ile (T M R 2 IF == 0 ) ¡ / / E s p e ra m ie n t r a s no s e d e s b o r d e e l T im e r 2
’ TMR2IF=0; / / D e s a c t iv a r e l FLAG de TMR2
}
//PROGRAMA PRIN C IPA L
v o id m a in (v o id ){
TR IS B =0x00; / / C o n fig u r a e l PORTB como s a l i d a s
PORTB=0; / / N i v e l b a j o RB3
T2C0N = O b O lO O llO l; //TMR2 co n P l= 4 y P2=10 y e n c e n d id o
PR2 = 24; / / C a rga p a r a 1 ms
w h ile (lí{
f o r ( x = 0 ;x < 1 0 ;x + + ){ / / E sp era d u r a n t e
D ELAYlm s( ) ; / / 1 0 ms
}
RB3 = -R B 3 ; //C am biar e s t a d o d e RB3
}
}
Página | 80
3. Temporizadores
F igura 3.18: Conexiones del PIC16F877A a los 4 displays (multiplexados ) del cronómetro
Y A LOS PULSADORES DE MARCHA Y PARADA.
Solución:
Página | 81
Programación de microcontroladores PIC en lenguaje C
configuración
Código fuente
//ARCHIVOS DE DEFINICIONES
# in c lu d e < h t c . h> / / In c lu im o s l i b r e r i a d e l m ic r o a u s a r
# in c lu d e " t i m e r s . h " / / In c lu im o s l i b r e r í a de t im e r s
# d e f in e _XTAL_FREQ 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
__CONFIG(WRT_OFF & WDTE_OFF & P W R T E O F F & F O S C X T & L V P O F F ) ; //Configuración
/ / d e l P IC
/ / V a r ia b le s g l o b a l e s p a r a qu e sea n a c c e s i b l e s en l a i n t e r r u p c i ó n
u n s ig n e d c h a r c o n t = 0 ; / / C o n ta d o r de i n t e r r u p c i o n e s
u n s ig n e d c h a r S 2=0, S 1=0, C2=0, C 1=0; / / L le v a m o s l a c u e n ta de 0 0 .0 0 a 5 9 .9 9
b i t ESTADO; / / F la g p a r a a c t i v a r o d e s a c t i v a r l a cu e n ta
//(MARCHA es ESTADO=l) y (PARADA e s ESTADO=0)
u n s ig n e d c h a r ROTADOR; / / M áscara con e l 1 qu e se r o t a p a r a a c tiv a r
/ / lo s d i s p l a y s .
u n s ig n e d c h a r DISPLAYS; / / C o n tie n e e l v a l o r d e l d i s p l a y qu e se a c t iv a
u n s ig n e d c h a r x ; / / d e f i n i c i ó n de una v a r i a b l e 16 b i t s s in
/ / s ig n o
//PROGRAMA PRINCIPAL
v o id m a in (v o id ){
//CONFIGURACIÓN
ADCONl=0b00000110; / / D e s a c tiv a m o s PORTA como e n t r a d a s a n a l ó g i c a s
T R IS A = 0 x l0 ; //PORTA co n RA4 como e n t r a d a y r e s t o como s a l i d a s
TR IS B =0x01; / / T e rm in a l RB0 como e n t r a d a
TR ISD =0x00; / / T e r m in a le s PORTD como s a l i d a s
e i () ; / / In t e r r u p c io n e s G lo b a le s h a b i l i t a d a s
PEIEsl; / / I n t e r r u p c ió n p o r TMR2 h a b i l i t a d a
TMR2IE=1; / / In t e r r u p c ió n p o r TMR2 h a b i l i t a d a
s e tu p tim e r 2 (T 2 _ON¡T2_PRED_ DIV4|T2 POST D IV IO ) ; //TIMER2 co n P l= 4 y P2 = 10
/ / y e n c e n d id o
s e t t i m e r 2 (1 2 4 ); / / C arga p a ra 5 ms
ESTADO = 0; //Em pieza en PARADO e l c r o n ó m e tro
ROTADOR = 0x11; / /M áscara con 1 en e l b i t 0 y 1 en e l b i t 4.
DISPLAYS = 0;
Página | 82
3. Temporizadores
w h ile ( 1 )
{ if(RA4 == 0) //Se ha p r e s io n a d o l a MARCHA
{ ESTADO=l; //Ponemos e l c r o n o en MARCHA
S 2 = 0 ;S 1 = 0 ;C 2 = 0 ;C 1 = 0 ; / / R esetea m o s e l c r o n ó m e tro
}
if(R B O == 0) //Se ha p r e s io n a d o l a t e c l a de PARADA
{ ESTADO = 0; //Ponemos e l c r o n o en PARADA
}
/ / C ó d ig o p a r a m o s t r a r l o s d í g i t o s
D ISPLA YS = ROTADOR & OxOF
if(D IS P L A Y S = = 1 )
{RA3 = 0 ; RA2 = 0 ; RA1=0; RA0 = 1 ; //Se a c t i v a D ISPLAY 0 y l o s o t r o s
/ / d e s a c t iv a d o s
PORTD = c o d i g o [ C l ] ; //Se m u es tra p o r p u e rto D l a s c e n t é s im a s
//de segu ndo
}
if(D IS P L A Y S = = 2 )
{RA3 = 0 ; RA 2=0; RA1 = 1 ; RA0 = 0 ; //Se a c t i v a D ISPLAY 1 y l o s o t r o s
/ / d e s a c t iv a d o s
PORTD = c o d i g o [ C 2 ] ; //Se m u es tra p o r p u e r to D l a s d éc im a s
//de segu ndo
}
if(D IS P L A Y S = = 4 )
{R A 3 = 0 ; RA 2=1; RA1=0; RA0=0; //Se a c t i v a D ISPLAY 2 y l o s o t r o s
/ / d e s a c t iv a d o s
PORTD = c o d i g o l [ S I ] ; //Se m u es tra p o r p u e r to D l a s u n id a d e s
//de segu ndo
}
if(D IS P L A Y S = = 8 )
{R A 3 = 1 ; RA 2=0; RA1=0; RA0=0; //Se a c t i v a D ISPLAY 3 y l o s o t r o s
/ / d e s a c t iv a d o s
PORTD = c o d i g o [ S 2 ] ; //Se m u es tra p o r p u e r to D l a s d e c e n a s
//de segu ndo
}
>
}
//ATENCIÓN A LAS INTERRUPCIONES
s t a t ic v o id in te r r u p t i s r ( )
{
if(T M R 2 IF ){ //Comprueba s i e s l a i n t e r r u p c i ó n d e l TMR2
TM R 2IF=0; / / D e s a c t iv a e l FLAG d e l a i n t e r r u p c i ó n de TMR2
R O T A 1 I (ROTADOR); //Cada 5 ms r o t a l a m á sc a ra qu e a c t i v a l o s
/ / d is p la y s
if(E S T A D O ){ / / S i e l c r o n ó m e tr o e s t á en marcha
c o n t+ + ; / / In c r e m e n ta l a c u e n ta de i n t e r r u p c i o n e s
i f ( c o n t == 2 ) { //Comprueba s i han t r a n s c u r r i d o 2
/ / i n t e r r u p c i o n e s (1 0 ms)
cont = 0 ; / / R e s e te a l a c u e n ta d e i n t e r r u p c i o n e s
C1+ + ; / / In c r e m e n ta l a s c e n t é s im a s d e segu ndo
i f ( C l == 1 0 ) { / / S i han l l e g a d o a 10 c e n t é s im a s d e segu ndo
C1 = 0; / / R e s e te a l a s c e n t é s im a s d e segu ndo
C2 + + ; / / In c r e m e n ta l a s d éc im a s d e segu ndo
i f ( C 2 == 1 0 ) { / / S i han l l e g a d o a 10 d éc im a s de segu ndo
C2 = 0; / / R e s e te a l a s d éc im a s d e segu ndo
S1 + + ; / / In c r e m e n ta l a s u n id a d e s de segu ndo
i f (S I == 1 0 ) { / / S i han l l e g a d o a 10 u n id a d e s
//de segu ndo
SI = 0 ; / / R e s e te a l a s u n id a d e s segu ndo
Página | 83
Programación de microcontroladores PIC en lenguaje C
S2 + + ; / / In c r e m e n ta l a s d e c e n a s d e
/ / seg u n d o
if(S 2 == 6 ) { / / S i han l l e g a d o a 6 d e c e n a s
/ / d e seg u n d o
S2 = 0 ; / / R e s e te a l a s d e c e n a s de
// s egun do
}
}
}
}
}
}
}
}
3.4. WATCHDOG
\ La función del Watchdog es impedir que el sistema entre en un bucle infinito, provocando
un RESET cuando esto sucede. El Watchdog es un oscilador RC interno independiente del
oscilador principal del microcontrolador, por lo que funciona incluso cuando se detiene la
ejecución mediante la instrucción SLEEP.
Página | 84
3. Temporizadores
+5V
Solución:
La vuelta al estado inicial se consigue dejando que el Watchdog se desborde (al cabo de
18 ms ya que el postdivisor está asignado al TIMER 0) y resetee al microcontrolador.
Página | 85
Programación de microcontroladores PIC en lenguaje C
rriHiflo fuente
#include<htc.h> / / In c lu im o s l i b r e r í a d e l m ic r o
td e fin e XTA LFREQ 4000000 / / O s c ila d o r I n t e r n o de 4MHZ
CONFIG(WRT_OFF WDTE_ON & PWRTE_OFF &r FOSC XT & LVP OFF) ;
//PROGRAMA PR IN C IPA L
v o id m a in (v o id ){
CLRWDT( ) ; / / R e s e t d e l W atch dog
TRISB = ObOOOOOOOO; / / C o n fig u r a e l PORTB como s a l i d a s
PORTB= 0x00; / / T o d o s l o s l e d a p a ga d o s
i f ( R A 4 == 0) { //S e ha p r e s io n a d o l a MARCHA
/ / C o n fig u r a c ió n d e l TIMER 0 p a r a p r o d u c i r i n t e r r u p c i o n e s ca d a 50 m s.
OPTION_REG=OxC7; //TIMER0 como t e m p o r iz a d o r con p r e d i v i s o r P=256
G IE = 1 ; / / H a b ilit a r in te r r u p c io n e s
T 0 IE = 1 ; / / H a b i l i t a r i n t e r r u p c i ó n d e TMR0
T 0 IF = 0 ; / / D e s a c t iv a r e l FLAG de TMR0
/ / C o n fig u r a c ió n d e l TIMER1 p a r a p r o d u c i r i n t e r r u p c i o n e s ca d a 500 ms
TlCON=0x3 0; / / C o n fig u r a r TIMER 1 como t e m p o r iz a d o r , co n
//P =8 y p a ra d o
P E IE = 1 ; / / H a b i l i t a r i n t e r r u p c i ó n d e TMR1
TMR1IE=1; / / H a b i l i t a r i n t e r r u p c i ó n d e TMR1
TM R1IF=0; / / D e s a c t iv a r e l FLAG d e TMR1
TMR0=60; // Para que Td de TMR0 sean 50ms y em piece e l TMR0
TMRlH=0x0B; / / P a ra qu e Td d e T im e r 1 sea n 500 m s.
TMRlL=0xDC;
TMR10N=1; / / A c t iv a d o e l TIMER 1
PORTB=0xFF; // T o d o s l o s L ed s e n c e n d id o s .
MASCARA^ O b llO O O O ll; //RB3-RB2 a p a ga d o s y RB1-RB0 e n c e n d id o s .
w h ile { 1 ) {
CLRWDT( ) ; / / R e s e t d e l W atch dog
}
}
}
//INTERRUPCIÓN p o r Tim erO y t i m e r l
s t a t i c v o id in te r r u p t i s r ( v o i d ) {
if(T 0 IF ! T M R 1 IF ){
T 0 IF = 0 ; / / D e s a c t iv a r e l FLAG de l a i n t e r r u p c ió n de TMR0
TMR0=60; / / R e c a r g a r TMR0
c o n t 0 ++; / / In c r e m e n ta r c o n t a d o r de i n t e r r u p c i o n e s d e
/ / T im er 0.
i f ( c o n t 0 == 1 0 ) { //10 i n t e r r u p c i o n e s ca d a 50 ms da l u g a r a
//500 ms
MASCARA = -MASCARA;
PORTB = MASCARA; //Cam bia e s t a d o d e RB0
c o n t0=0 ; / / R e i n i c i a r c o n t a d o r de d e s b o r d a m ie n t o s
}
}
if(T M R 1 IF == 1 ) {
TM R1IF=0; / / D e s a c t iv a r e l FLAG de l a i n t e r r u p c i ó n de TMR1
TMRlH=0x0B; / / R e c a r g a r TMR1
TMRlL=0xDC;
c o n t l+ + ; / / In crem en ta r c o n ta d o r de i n t e r r u p c io n e s de T im e r 1.
if(c o n tl= = 20) { //20 i n t e r r u p c i o n e s ca d a 500 ms da l u g a r a lO s
TMR10N=0; / / D e s a c t iv a r e l TIMER
Página | 86
3. Temporizadores
G IE = 0 ; / / D e s h a b ilita r in te r r u p c io n e s
w h ile (l); / / B u c le i n f i n i t o
//Como y a t r a s c u r r i e r o n l o s 10 s e g u n d o s , n os quedamos en e s t e b u c le i n f i n i t o
//sin r e s e t e a r e l W a tch d o g h a s ta que d e s b o r d e y r e i n i c i e e l m i c r o c o n t r o l a d o r .
//Tras 18 m seg ( v a l o r t í p i c o ) e l m ic ro se r e s e t e a r á p o r d esborda m ien to d e l Watchdog
}
}
}
Comprobamos el funcionamiento mediante el cronómetro del simulador:
Stopwatch : =, r s
Página | 87
j
4. Módulos de Captura, Comparación y
Modulación de Anchura de Pulsos (PWM)
4.1. Módulo Captura
4.2. Módulo Comparación
4.3. Módulo PWM
Página | 89
programación de microcontroladores PIC en lenguaje C
4 .1 . Módulo Captura
Los módulos CCP trabajando en modo captura permiten que al producirse un evento se
almacene el valor de 16 bits del contador asociado al Timer 1 en los registros CCPRxL y
CCPRxH del módulo CCPx. Los eventos a detectar estarán relacionados con la señal en el
terminal de entrada del módulo CCPx a elegir entre un flanco de bajada, un flanco de
subida, cuatro flancos de subida o 16 flancos de subida. El valor almacenado en los registros
del módulo permanecerá hasta que se produzca un nuevo evento.
MÓDULO CCP EN MODO CAPTURA
(pulsos externos)
Solución:
Página | 90
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
oscilador, en este caso un oscilador de cristal a 4 MHz a las entradas OSC1 y OSC2 tal y
como aparece en la figura inferior.
El Interruptor se conectará a una entrada digital del mlcrocontrolador. En este caso se ha
utilizado la entrada RBO, que se corresponde con la entrada de Interrupción externa del
microcontrolador, lo que permitirá al programa funcionar en modo interrupción en caso de ser
necesario.
La utilización del módulo captura Implica que la señal periódica deberá estar conectada a
uno de los terminales asociados a estos módulos. En este caso se utilizará el módulo CCP1
por lo que la señal de entrada se conectará al terminal RC2.
Figura 4.3: Esquema de conexiones del PIC16F877A para determinar el periodo de una señal.
b) Para la determinación del período de la señal se capturará el valor del TIMER1 entre dos
flancos de subida consecutivos (también se puede realizar la captura en los flancos de
bajada). Así, conocido el valor de cada incremento del TIMER1 y los valores capturados para
cada uno de los flancos consecutivos se puede obtener el tiempo transcurrido en un
periodo T de la señal.
Configuración
El módulo CCP se configurará en modo captura para la detección de flancos de subida con
predlvisor 1, lo que permitirá la detección de cada uno de los flancos de la señal de entrada
por RC2.
El Timer 1 asociado al modo captura del módulo CCP se configura como temporlzador con
predlvisor 1 por lo que se incrementará cada 4 ciclos de reloj (1 ciclo de Instrucción), es
decir, cada mlcrosegundo.
Página | 91
Programación de microcontroladores PIC en lenguaje C
código fuente
# in c lu d e < h tc .h >
# in c lu d e < s t d i o . h >
# in c lu d e " c c p . h "
# in c lu d e " t i m e r s . h "
t y p e d e f u n ió n {
u n s ig n e d c h a r b y t e s [ 2 ] ;
u n s ig n e d i n t e n t e r o ; } u b y t e 2 ;
u b y te 2 P e r i o d o l , P e r i o d o 2 ;
v o id C a p tu r a (v o id );
v o id m a in (v o id ){
T R IS B b it s .T R IS B 0 = 1 ; //RB0 c o n f i g u r a d o como e n t r a d a
T R I S C b it s . T R IS C 2 = 1 ; / /RC2 c o n f i g u r a d o como e n t r a d a
d i(); / / D e s h a b ilita r la s in te r r u p c io n e s
w h ile (1 ){
w h i l e (PORTBbits .RB 0==0) CapturaO; //Rea l i z a r la ca p t u r a m i e n t r a s
//RB0 no p u ls a d o
}
}
v o id C a p tu r a (v o id ){
s e tu p c c p l(C C P _ O F F ); / / R e s e t e a e l m ódu lo CCP1
s e t u p t im e r l(T 1 _ I N T | T 1 _ D I V 1 | T 1 _ 0 F F ) ; / / C o n fig u r a r e l T i m e r l como tem p,
/ / p r e d = l, d e t e n i d o
s e t _ t i m e r l (0 x 0 0 ); / /P on er a c e r o e l c o n ta d o r d e l T im e r l
P I R l b i t s . C C P1IF =0; / / P o n e r a c e r o e l f l a g de c a p t u r a
s e tu p _c c p l(C C P _C A P T Ü R E _ R E ); //Modo c a p t u r a co n f l a n c o d e s u b id a
s ta r t_ tim e r l( ) ; / / A rra n c a r e l T im e r l
w h ile (P IR lb its .C C P 1 IF = = 0 ); //C om probar s i ha l l e g a d o un f l a n c o
P e r io d o l. e n te r o = g e t_ c c p l(v a lu é ); / / C o p ia e l v a l o r d e l a c a p t u r a
P I R l b i t s . C C P1IF=0; / / B a ja e l f l a g d e c a p t u r a
w h ile (P IR lb its .C C P 1 IF = = 0 ); / / co m p rob a r s i ha l l e g a d o un n u e vo
/ / fla n c o
P e r io d o 2 . e n t e r o = g e t _ c c p l ( v a l u é ) ; / / C o p ia e l v a l o r d e l a c a p t u r a
P e r io d o l. e n te r o = P e r io d o 2 . e n t e r o - P e r i o d o l . e n t e r o ; / / c a lc u la l a d i f e r e n c i a
s e tu p c c p l(C C P OFF) ; / / R e s e t e a e l m ó du lo CCP1
s to p t i m e r l ( ) ; / / D e t ie n e e l T i m e r l
p r i n t f ( "P e r io d o = % d m ic r o s e g u n d o s \ n " , P e r i o d o l . e n t e r o ) ; / / M u estra e l p e r i o d o
}
v o i d p u t c h (u n s ig n e d c h a r b y t e ) {
TXSTA=0x2 6;
//RCSTA|=0x80; //
R C S T A b its . SPEN=1;
TXREG=byte;
w h i l e ( ! T X I F )c o nti n u é ;
T X IF = 0 ;
>
Página | 92
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
Figura 4.5: Configuración de los estímulos externos para simular el ejercicio 4.1.1.
Si se ajusta una señal de entrada con período 1 ms a la entrada de RC2 se obtiene que tras
activar el pulsador RBO se ha guardado en la variable Periodol el valor 0x03E8 (1000 en
decimal) que es el período de la señal en microsegundos.
Una vez ejecutado el programa se pueden observar las señales en RBO y RC2 mediante el
analizador lógico (menú View/Logic Analyzer), el mensaje que indica el período en la
pestaña SIM U artl de la ventana output y el valor de la variable en la ventana Watch (menú
ViewlWatch).
Página | 93
Programación de microcontroladores PIC en lenguaje C
Logic Analyzer Q E
nnuuuirjui
-E bytes
entero
d) Dado que el período se calcula según los Incrementos del TIMER1 y el TIMER1 está
configurado para incrementarse cada ps, la resolución del sistema será de ± lp s .
e) Las frecuencias máximas y mínimas del sistema vendrán determinadas por el intervalo de
tiempo almacenado en la variable perlodo2 que se corresponden con los incrementos en
mlcrosegundos capturados del TIM ERl. Así pues, los valores mínimo (0x0000) y máximo
(OxFFFF) corresponderán a las frecuencias de 1 MHz y 15.259 Hz respectivamente.
Modifica el programa del apartado b) para que funcione mediante las interrupciones
asociadas a RBO y al módulo CAPTURA.
¿Sería posible modificar el programa para mejorar la resolución del sistema? Indica cómo,
en caso de ser posible.
Indica qué modificaciones habría que introducir en el programa para que el sistema
pudiera capturar frecuencias menores a las indicadas en el apartado e).
Página | 94
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
F igura 4.7: F uncionamiento del sistema medidor de distancias del ejercicio 4.1.2.
JUUUL
ju iiiT L
Figura 4.8: C onexiones del sistema medidor de distancias del ejercicio 4.1.2 con el microcontrolador .
Código fuente
# in c lu d e < h t c .h >
# i n c lu d e < s td io .h >
Página | 95
Programación de microcontroladores PIC en lenguaje C
t y p e d e f u n ió n {
u n s ig n e d c h a r b y t e s [ 2 ] ;
u n s ig n e d i n t e n t e r o ; } u b y t e 2 ;
u b y te 2 N;
v o i d C a p t u r a (v o id ) ;
v o id m a in (v o id ){
TMR1H=0; / / B o rra r lo s c o n ta d o r e s d e l T im e r l
TMR1L=0;
TlCON=0x20; / / C o n fig u r a r e l T i m e r l
CCP1CON=0; / / R e s e t e a r e l m ódu lo CCP1
TRISA=0X10; / / C o n fig u r a r RA4 como e n t r a d a
TRISCbits.TRISC2 = 1 ; / / C o n fig u r a r RC2 como e n t r a d a
PIElbits.TMR1IE=0; / / I n h a b i l i t a r i n t e r r u p c i ó n d e l T im e r l
PIElbits.CCP1IE=0 ; / / I n h a b i l i t a r i n t e r r u p c i ó n d e l m ódu lo CCP1.
PIR1=0; / / P o n e r a 0 l a s b a n d e ra s ( f l a g s ) d e i n t e r r u p c i ó n .
CCP1CON=OX04; / / C o n fig u r a r e l m ódu lo CCP1 en modo c a p t u r a , f l a n c o
//de b a ja d a en RC2
while(PORTAbits.RA4==1) / / E s p e r a r a qu e b a j e RA4
TICONbits.TMR10N=1; / / I n i c i a r e l c o n t e o d e l TMR1
Captura();
}
v o id C a p tu r a (v o id ){
P I R l b i t s . C C P 1 IF = 0 ; / / P o n e r a 0 e l i n d i c a d o r de c a p t u r a .
w h i l e ( P I R l b i t s . C C P 1 I F = = 0) ; / / ¿C C P1IF = 1?
P I R l b i t s . C C P 1 IF = 0 ; / / p o n e r a 0 e l i n d i c a d o r de c a p t u r a
N . b y t e s [ 0 ] =CCPR1L; / / g u a rd a r e l v a l o r c a p tu r a d o en NH y N L.
N . b y t e s [ 1 ] =CCPR1H;
p r i n t f ( "N=%d, d is t a n c i a = % 5 . 3 f
m \n ", N . e n t e r o , 4 * ( f l o a t ) N . e n t e r o *0 0 0 0 0 0 1 *3 4 0 / 2 );
}
v o i d p u t c h (u n s ig n e d c h a r b y t e )
{
TXSTA=0x26;
//RCSTA|=0x80; //
R C S T A b its . SPEN=1;
TXREG =byte;
w h i l e ( ! T X I F )c o n t in u é ;
T X IF = 0 ;
>
Se pide:
a) Calcula la distancia entre las paredes si al final de la captura se tiene en N el valor 40E2h
b) Calcula la máxima distancia que se podrá medir con dicho sistema.
Solución:
a) Calcula la distancia entre las paredes si al final de la captura se tiene en N el valor 40E2h
Página | 96
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
El Tim erl empieza con sus registros a cero, con predivisor P = 4 y como temporizador cuenta
impulsos de duración Ti = 4/Fosc = 4/4 MHz = 1 ps.
La captura se hace con el primer impulso que entra por RC2, luego el tiempo empleado por el
tono en recorrer 2 veces la longitud L es:
Tiempo = N * P * Ti = 40E2h * 4 * lp s = 66440 ps
Luego:
2L = velocidad del sonido * Tiempo => 2L = 340 m/s * 66,44 ms => L = 11,29 m
Trigger
SkWH:
Tx
Echo
Página | 97
Programación de microcontroladores PIC en lenguaje C
La duración del pulso será proporcional a la distancia recorrida por el sonido en el viaje de
¡da y vuelta y vendrá dada por la fórmula:
D _ (T*340)
2
Donde T es la duración del pulso en segundos y 340 m/s es la velocidad aproximada del
sonido en el aire a 20 °C.
Se pide:
Solución:
Página | 98
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
F igura 4.10: C onexiones del sensor de ultrasonidos HC-SR04 con el microcontrolador para el ejercicio 4.1.3.
b) Para la determinación de la anchura del pulso se capturará el valor del TIMER1 entre un
flanco de subida y un flanco de bajada. Así, conocido el valor de cada incremento del
TIMER1 y los valores capturados para cada uno de los flancos se puede obtener la duración
del pulso.
Configuración
El terminal RBO se configurará para funcionar mediante interrupción por flanco de subida
(por defecto) y se encargará de la generación de los pulsos por la salida RCO (trigger).
El módulo CCP se configurará en modo captura para la detección de flancos de subida con
predivisor 1 lo que permitirá la detección del primer flanco de subida y a continuación se
configurará para la detección de flancos de bajada permitiendo detectar el final del pulso
por RC2.
El Timer 1 asociado al modo captura del módulo CCP se configura como temporizador con
predivisor 1 por lo que se incrementará cada 4 ciclos de reloj (1 ciclo de instrucción), es
decir, cada microsegundo.
Código fuente
Página | 99
Programación de microcontroladores PIC en lenguaje C
# d e f i n e _XTAL_FREQ 4000000
t ypedef unión {
un s i g n e d char b y t e s [2];
u n s i g n e d int entero;} ubyte2;
u b y te 2 D i s t , D is tT e m p ;
float Distancia;
u n s i g n e d char Aux;
void Pulsador(void);
void F l a n c o (void);
void Tempor(void);
void Trigger(void);
v o i d m ain(void){
Aux=0;
T1CON=0;
CCP1CON=0;
T R I S B b it s ,T R IS B 0 = 1 ; / / C o n fig u r a r RB0 y RC2 como e n tr a d a , RC0 como s a l i d a
T R IS C b its .T R IS C O L O ;
T R IS C b it s ,T R IS C 2 = 1 ;
e i(); / / H a b ilit a r in te r r u p c io n e s g lo b a le s
O P T IO N _R E G b its. INTEDG=0; / / I n t e r r u p c i ó n e x t e r n a como f l a n c o de b a ja d a
P I E l b i t s . TM R 1IE=1; / / H a b i l i t a r l a s i n t e r r u p c i o n e s de CCP1 y
T im e r l
P I E l b i t s . C C P1IE =1;
P IR 1 = 0 ; / / P o n e r a c e r o l o s f l a g s de i n t e r r u p c i ó n
w h ile (1 ) ;
}
v o i d p u t c h (u n s ig n e d c h a r b y t e )
(
TXSTA=0x26;
//RCSTA|=0x80; //
RCSTAbi t s . SPEN=1;
TXREG =byte;
w h i l e ( 1T X I F )c o n t in u é ;
T X IF = 0 ;
}
v o id in te r r u p t IS R (v o id ){
}
v o id P u ls a d o r (v o id ){
IN T C O N b its . IN T F = 0 ; / / B a ja e l f l a g de i n t e r r u p c i ó n
i f (A u x = = l) r e t u r n ; //Comprueba s i e s t á r e a l i z a n d o una m e d ic ió n
T r ig g e r ( ) ; //G en era e l p u ls o de t r i g g e r
PIRlbits.CCP1IF=0; / / B a ja e l f l a g d e l m ódulo CCP1
CCPlCON=0x05; / / C o n fig u r a r e l CCP1 en modo c a p t u r a
[Link]=1; / / H a b ilit a in te r r u p c io n e s de lo s p e r i f é r i c o s
TMR1L=0; / / R e s e te a e l T im e r l
TMR1H=0;
Página | 100
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
T I C O N b it s . TMR10N=1; / / I n i c i a e l c o n t e o d e l T im e r l
A u x = l; / / A c t iv a e l i n d i c a d o r de m edida en c u rs o
}
v o i d F la n c o ( v o i d ) { / / C a lc u la l a d i s t a n c i a
P I R l b i t s . C C P1IF=0
i f (C C P lC O N b it s .C C P lM O = = l){
D i s t . b y t e s [ 0 ] =CCPR1L;
D i s t . b y t e s [ 1 ] =CCPR1H;
CC PlC O N =0x04;
}
e ls e {
T 1CONb i t s . TMR10N= 0;
D is t T e m p . b y t e s [ 0 ] =CCPR1L;
D i s t T e m p . b y t e s [ 1 ] =CCPR1H;
D i s t . e n t e r o = D is t T e m p . e n t e r o - D i s t . e n t e r o ;
CCP1CON=0;
IN T C O N b it s . PE IE =0 ;
D i s t a n c i a = ( f l o a t ) D i s t . e n t e r o * 3 4 0 .0 / 2 .0 *0 .0 0 0 0 0 1 ;
p r i n t f ( " D is t a n c ia = % 5 . 3 f m \n ", D i s t a n c i a ) ;
__ delay__m s (5 0 ) ;
A u x=0;
}
}
v o id T e m p o r (v o id ){
P I R l b i t s . TM R 1IF =0; / / B a ja e l f l a g
T1CON=0; / / P a ra e l T im e r l
CCP1CON=0; / / R e s e te a e l CCP1
D is t . e n te ro = 0 ;
Aux=0 ;
}
v o id T r i g g e r ( v o i d ) {
P O R T C b it s . RC 0=1; / / P u ls o de d is p a r o
__ d e l a y u s ( 1 0 ) ;
P O R T C b its .R C 0 = 0 ;
Página | 101
Programación de microcontroladores PIC en lenguaje C
FIGURA 4.11: CONFIGURACIÓN DE LOS ESTÍMULOS EXTERNOS PARA LA SIMULACIÓN DEL EJERCICIO 4.1.3.
Tcolbars *
i
j CPU Registeis
Cali St«k
; Disassembly listing
EEPROM
j File Registeis
* Flash Data
: Hardware Stack
• LCD P<*el
Locáis
Memory
Program Memory
l SFR / Penpherals
Spccul Function Regatéis
Watch
SimuLitcr Trace
Srmulator log>c Analyier
F igura 4.12: Configuración de las señales a visualizar para la simulación del ejercicio 4.1.3.
Una vez ejecutado el programa y activada la condición de disparo (pulsar RBO) se puede observar la señal en
los term inales RBO, RCO y RC2.
Página | 102
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
d) La duración del pulso viene determinada por los incrementos del TIMER1, que está
configurado para incrementarse cada microsegundo. Por lo tanto, el sistema no detectará
variaciones en la anchura del pulso menores a 1 microsegundo. Así pues, aplicando la
fórmula para obtener la distancia se obtiene que para 1 microsegundo se han recorrido
0.068 cm por lo que en este caso sí se satisface la resolución de 0.3 cm del dispositivo HC-
SR04. Sin embargo, la representación del resultado en cm limita la resolución real del
sistema a ±1 cm.
Se pide:
Página | 103
Programación de microcontroladores PIC en lenguaje C
¿Cuáles serán las velocidades máxima y mínima que se podrán detectar utilizando el
sistema propuesto?
Solución:
a) Para utilizar el módulo de captura será necesario conectar la entrada del módulo CCPx
(RCx) al fotodiodo. En este caso se utilizará el módulo CCP1 por lo que se deberá conectar el
fotodiodo a la entrada RC2.
Configuración
El módulo CCP se configurará en modo captura para la detección de flancos de subida con
predivisor 1 lo que permitirá la detección del tiempo entre dos flancos de subida
consecutivos (tiempo de duración de rejilla).
i El Timer 1 asociado al modo captura del módulo CCP se configura como temporizador con
predivisor 1 por lo que se incrementará cada 4 ciclos de reloj (1 ciclo de instrucción), es
decir, cada microsegundo.
Como se necesita calcular la velocidad en rps se utilizará la siguiente fórmula.
10• » / , 62500 vueltas ¡
rp s =
ttmri s
1 - ™ . . 1 0 re/" ' “ /,v u e lt a
Código fuente
t t in c lu d e < h tc .h >
# i n c lu d e < s t d i o . h >
# i n e lu d e " t i m e r s . h "
# in e lu d e " c c p . h "
t y p e d e f u n ió n {
u n s ig n e d c h a r b y t e s [ 2 ] ;
u n s ig n e d i n t e n t e r o ; } u b y t e 2 ;
u b y te 2 V e l , D iv , T ,T te m p ;
f l o a t V e lo c id a d ;
v o id C a p t u r a (v o id );
v o id m a in (v o id ){
d i(); / / D e s h a b ilita in te r r u p c io n e s
C a p tu ra ( ) ; / / C a lc u la l a v e l o c i d a d
w h ile (1 );
}
v o i d p u t c h (u n s ig n e d c h a r b y t e ) { / / F u n ció n p a r a p e r m i t i r e l u so d e p r i n t f con
/ / e l p u e r to s e r ie
TXSTA=0x26;
R C S T A b its . SPEN=1;
Página | 104
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
T X R E G = b y te;
w h i l e ( ! T X IF )c o n tin u é ;
T X IF = 0 ;
}
v o id C a p t u r a (v o id ){
s e tu p c c p l(C C P _ O F F ); / / R e s e t a l m ódulo CCP1
s e t u p _ t i m e r l (T 1 _ IN T |T1_DIV11 T l_O F F ) / / T im e r l como t e m p o r iz a d o r ,
/ / p r e d = l y d e t e n id o .
s e t t i m e r l ( 0x 0 0 ) ;
P I R l b i t s . C C P 1 IF = 0 ; / / P o n er a 0 e l in d i c a d o r (fla g ) de
ca p tu ra
s e t u p c c p l(C C P CAPTURE RE) ; ; / / S e le c c io n a r modo c a p t u r a con 1 f l a n c o
//de s u b id a
s ta r t_ tim e r l( ) ; / / A rr a n c a r e l TIMER1
w h i l e ( P I R l b i t s . C C P 1 I F = = 0) ; //Comprobar s i ha l l e g a d o un n uevo
/ / fla n c o de s u b id a
T . e n t e r o = C C P R l; // R ecu p era l a p r im e r a c a p tu r a
P IR lb its .C C P 1 IF = 0 ;
w h ile (P IR lb its .C C P 1 IF = = 0 ) ; //Comprobar s i ha l l e g a d o un n uevo
/ / fla n c o de s u b id a
T te m p . e n t e r o = C C P R l; / / R ecu p era l a segu nda c a p tu r a
T .e n t e r o = T t e m p .e n t e r o - T . e n te r o ;
s e tu p _ c c p l(C C P O F F ); / / R e s e t a l m ódulo CCP1
s to p tim e r l(); / / P a ra e l T im e r 1
V e l . e n tero = 6 2 5 0 0 / T . e n t e r o ; / / V e lo c id a d en rp s
V e lo c id a d = 6 2 5 0 0 . 0 / T . e n t e r o ;
p r i n t f ( " V e lo c id a d = % d rp s ( % 5 . 3 f ) " , »1 . e n t e r o , V e l o c i d a d ) ;
}
b) Para la simulación del programa del apartado b) será necesario seleccionar la
herramienta MPLABSIM del menú Debugger/Select Tool y ajustar la frecuencia del oscilador
a 4MHz (menú debugger/ settings).
La generación de las señales de entrada se realizará mediante el menú debugger/ Stimulus
/N e w Workbook donde se creará una señal periódica de entrada por RC2. En este caso se
elegirá una señal periódica de 1 ms por lo que aplicando la fórmula vista en el apartado a)
se obtiene que dicha señal representa una velocidad de 62.5 rps.
100000.0 120000.0
Página | 105
Programación de microcontroladores PIC en lenguaje C
Página | 106
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
Figura 4.16: E s q u e m a d e b l o q u e s d e l m ó d u l o c o m p a r a c ió n .
Solución:
Para la realización del programa es necesario configurar el Timerl como temporizador de
16 bits empleando los registros CCPR1H y CCPR1L para almacenar el módulo de conteo.
Para ello se programa el módulo CCP1 en modo comparador, usando la variante de generar
un reset al Tim erl cuando la comparación entre los registros CCPR1 y TMR1 sea positiva. En
este ejemplo, el Tim erl se programa como temporizador, con un factor de división de 1
para su pre-divisor (se incrementa cada microsegundo) por lo que en el módulo de
comparación se deberá cargar el valor de 5000 equivalente a un semiperiodo de la señal,
que es cuando se debe cambiar.
Código fuente
t t in c lu d e < h t c .h >
__ CONFIG (FOSC_HS & WDTEOFF & LVP OFF & PWRTE ON) ;
# d e fin e X T A L F R E Q 4000000
v o id m a in (v o id ){
T1CON=0; / / T im e r l como te m p o r iz a d o r , p r e d = l ( l p s ) , d e t e n id o .
CCP1CON=0; / / R e s e t a l módulo CCP1.
INTCON= 0 ; / / D e s h a b ilit a in t e r r u p c i o n e s .
T R I S B b i t s . T R IS B 3 = 0 ; / / C o n fig u r a r e l t e r m in a l RB3 como s a l i d a .
Página | 107
Programación de microcontroladores PIC en lenguaje C
Una vez ejecutado el programa se puede observar la señal a la salida del terminal RB3 y
obtener su período aproximado utilizando los cursores.
Página | 108
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
Solución:
Página | 109
Programación de microcontroladores PIC en lenguaje C
P U LSA D O R
b) Para contar las piezas que pasan por la cinta transportadora se utilizará el TIMER1
configurado en modo contador de pulsos (flancos de subida) por el terminal RC0/T1CKI que
se incrementará cada vez que se detecte una pieza y que combinado con el módulo
comparador permitirá evaluar si se ha llegado al número de piezas deseado.
Configuración
El terminal RBO se configurará para funcionar mediante interrupción por flanco de subida
(por defecto).
El TIMER1 se configurará en modo contador por RCO con predivisor 1 (un incremento por
cada pieza).
El módulo CCP se configurará en modo comparador de forma que la salida RC2, que
controla el motor, pase a estado bajo ('0') cuando se alcance el valor 10 almacenado en los
registros del comparador.
Código guente
# i n c l u d e < h t c .h >
# in c lu d e < s td io .h >
t t in c lu d e " i n t e r r u p t s . h"
# in c lu d e " p o r t s .h "
# in c lu d e " t i m e r s . h "
# in c lu d e " c c p . h "
CONFIG (FOSC_HS & WDTE OFF & LVP__OFF & PWRTE ON) ;
í d e f i n e _XTAL~FREQ 4000000
# d e f i n e P i e z a s 10;
v o id P u ls a d o r (v o id );
v o id C o m p a r a (v o id ) ;
Página | 110
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
v o id m a in (v o id ){
e n a b l e _ i n t (GLOBAL |IN T_E X T |IN T_CC P1) ; / / H a b ilit a i n t e r r u p c io n e s
b i t c l e a r (T R IS C , 2 ) ; / / C o n fig u r a r e l te r m in a l RC2 como
/ / s a lid a .
O P T IO N _R E G b its . INTEDG=0; / / In t e r r u p c ió n e x t e r n a p o r fla n c o
//de b a ja d a .
w h ile ( 1 ) ;
}
v o id in te r r u p t IS R (v o id ){
i f ( IN T C O N b its . IN T F = = l& & IN T C O N b its . IN TE ) P u ls a d o r O ; //Comprueba s i se ha
/ / p u lsa d o RBO
e ls e if ( P I R l b i t s . C C P lIF = = l& & P IE lb it s . CCP1IE) C o m p ara O ; //Comprueba
/ / in te rru p c ió n CCP1
}
v o id P u ls a d o r (v o id ){
IN T C O N b it s .IN T F = 0 ; / / B a ja e l f l a g de i n t e r r u p c i ó n p o r RBO
if(P O R T C b its .R C 2 = = l) re tu r n ; //Comprueba s i e l m o to r e s t á p a ra d o .
P IR 1 = 0 ; / / Pon er a 0 la s b a n d era s de
/ / in te r r u p c ió n .
e n a b le _ in t (P E R I P H E R A L ); ; / / H a b ilit a in te r r u p c io n e s de p e r i f é r i c o s
s e tu p _ tim e r l(T lE X T | T 1 _ D IV 1 | T I / / T im e rl c o n ta d o r de p u ls o s , p r e d = l ,
/ / d e t e n id o .
s e t t i m e r l ( 0x 0 0 ) ; //Pone a 0 l o s c o n ta d o r e s d e l TIMER1
s e t_ c c p l(P ie z a s ); //Carga l o s v a l o r e s p a ra e l módulo
/7com parador
s e t u p _ c c p l(C C P COMPARE FALL) ; / / S e le c c io n a r modo co m p a rad or, con
/ / p u esta a 'O 'd e RC2
s ta rt t im e r l( ) ; / / In ic ia e l co n teo d e l T im e r l.
}
v o i d C o m p a r a (v o id ){
P IR lb its .C C P 1 IF = 0 ; / / B a ja e l f l a g d e l módulo CCP1
s e t u p c c p l(C C P OFF) ; / / R e s e t a l módulo CCP1
s to p tim e r l(); / / Para e l T im e r l.
d is a b le _ in t (P E R IP H E R A L ) ; / / D e s h a b ilit a l a s i n t e r r u p c i o n e s de
/ / p e r ifé r ic o s .
}
c) Para la simulación del programa del apartado b) será necesario seleccionar la
herramienta MPLABStM del menú debugger y ajustar la frecuencia del oscilador a 4MHz
(menú debugger/settings).
La simulación del pulsador se realizará mediante el menú debugger / Stimulus / New
Workbook donde se creará un estímulo asincronos asociados a la entrada RBO (pulsador) y
un estímulo periódico asociado al fotodetector RCO (fotodetector). Para facilitar la
simulación se seleccionará una señal de frecuencia elevada en RC2 (por ejemplo 100 KHz).
Página | 111
Programación de microcontroladores PIC en lenguaje C
= j
d
Bejr End
— i S'AlSlart (5) Novel
O pc - '«f/Utel OPC • Fc-Aitd
O Cyelo « dee ¿1ndUotaao O Oyelo - des
i OFr> • » OPt> - “
F igura 4.21: Configuración de los estímulos externos para la simulación del ejercicio 4.2.2.
[+ «¡1 Q M I H ■■"I
4 .3 . M ó d u io PW M
Cuando el módulo CCPx funciona en modo PWM permite generar a través de su terminal
asociado una señal cuadrada periódica con ciclo de trabajo variable con una resolución
máxima de 10 bits en el mejor de los casos. El período de la señal vendrá fijado por la
Página | 112
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
CCPxCON<5:4>
T |
3Ü L
Comparador f
Terminal
' -H - - — Del registro CCPx / RCy
Entrada reloj Pre-DIVISOR TRISC<y>
interno Fosc/4"* TM R 2
1 ,4 ,1 6
3E =T
im n a r a r ln r I 1 ■■
T2CKPS1 '.T2CKPS0 I Co™paradOr
MÓDULO TIM ER2 >1"
(N) | PR2 l
T = (N p R 2 + 1) * P * 4 * Tose T on = M * P * Tose
Figura 4.23: Esquema de bloques del módulo pw m .
Figura 4.24: Conexiones con el microcontrolador para la generación de un tono de 1 KHz del ejercicio 4.3.1.
Se pide:
Página | 113
Programación de microcontroladores PIC en lenguaje C
b) Indica la frecuencia máxima y mínima de las señales PWM que pueden ser generadas
con dicho sistema.
a) Para la generación de una señal periódica con frecuencia 1 KHz y ciclo de trabajo 50 % se
utilizará el módulo CCP1 asociado al Timer 2 cuya salida se corresponde con el terminal RC2.
Configuración
El período T de la señal PWM se fija mediante el valor N depositado en el registro PR2. Así
pues, para una señal de frecuencia 1 KHz tenemos un período T = 1 ms.
Si se escoge el factor de división del pre-divisor del Timer2 P=4, el valor que hay que colocar
en el registro PR2 es N = 249.
Utilizando solo el registro CCPR1L (Ms) para fijar el valor de T on de los pulsos. Los bits
CCP1C0N<5:4> (M2) se mantendrán permanentemente en 0. Entonces:
Código fuente
# i n c l u d e < h t c .h >
v o id m a in (v o id ){
T2CON=0x01; / / P ro g ra m a r p o s t - d i v i s o r = 1, T im er2 d e t e n i d o y p r e -
/ / d i v i s o r = 4.
CCP1CON=0; / / R e s e t a l m ódu lo CCP1
TMR2 = 0; / / P o n e r a 0 e l T im er2
CCPR1L=125; //La s e ñ a l PWM s a l d r á co n 50%
PR 2 =249; //M ódu lo de c o n t e o d e l T im er2 que es e l p e r í o d o d e l a
/ / s e ñ a l PWM.
P I E l b i t s . TMR2IE=0 ; / / I n h a b i l i t a r i n t e r r u p c i ó n d e l T im er2
P I E l b i t s . CCP1IE=0 ; / / I n h a b i l i t a r i n t e r r u p c i ó n d e l m ódu lo CCP1.
T R IS C b i t s . TRISC2 = 0 ; / / C o n fig u r a r e l t e r m in a l CCP1/RC2 como s a l i d a .
P IR 1 = 0 ; / / D e s a c t iv a r l a s b a n d e ra s ( f l a g s ) d e i n t e r r u p c i ó n .
CCPlCON=0x0C; / / E l m ódulo CCP1 en modo PWM con l o s b i t s
//DC1B1: DC1B0 en 0 (M 2 = 0 ).
T2C O N [Link] R 20N =1; / / I n i c i a r c o n t e o d e l T im e r 2 .
w h ile (1 );
}
Página | 114
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
b) Las frecuencias máximas y mínimas de la señal PWM vendrán determinadas por los
valores de configuración de la temporización del Timer 2 sin tener en cuenta el postdivisor.
Así pues, tomando los valores máximos y mínimos para cada caso se obtiene:
c) Para observar la señal generada por el terminal RC2 es necesario acceder al menú
view/Simulator Logic Analyzer donde pulsando en el botón channels se agregará el canal
correspondiente al pin RC2.
Una vez ejecutado el programa o ejecutándolo en modo animóte se puede observar la señal
a la salida del terminal RC2 y comprobar su período y ciclo de trabajo.
Logic Analyzer j = ¡, s
Tngger Positrón Tngger PC » Time Base Mode
S ta itC Ceniet " End Now Cleai Cyc v Simple Chame!;
lí+ <e| 0 . 1 ® . ! : 1 * í M H la ia l 3
Página | 115
Programación de microcontroladores PIC en lenguaje C
c) Indica la resolución (variación mínima del ciclo de trabajo de la señal PWM) del
sistema propuesto
Solución:
a) Para la generación de una señal periódica con ciclo de trabajo variable se utilizará el
módulo CCPx del mlcrocontrolador asociado al Timer 2. Para la modificación del ciclo de
trabajo se utilizará la interrupción externa conectando el pulsador al terminal RBO del
microcontrolador.
Configuración
Si se escoge P = 1, el valor que hay que colocar en el registro PR2 será N = 99.
La duración TON de los pulsos queda determinada por el valor M de los 10 bits distribuidos
entre los 8 bits del registro CCPR1L (que constituyen los 8 bits más significativos de M, es
decir, Ms) y los 2 bits CCP1C0N<5:4>, que forman los 2 bits menos significativos de M, es
decir, M2.
Como solo es necesario variar el ciclo de trabajo entre el 25 %, 50 % y 100 % solo será
necesario utilizar el registro CCPR1L (Ms) para fijar el valor de T o n . Los bits CCP1C0 N<5:4>
se mantendrán permanentemente en 0.
Entonces inicialmente:
T on = 4 * Ms * P * T 0Sc => 25% * 0,1 ms = 4 * Ms * 1 * 0,25 ps => Ms = 25
La duración (variable) de los pulsos PWM se logra colocando un valor entre 0 y 99 en el
registro CCPR1L. En este caso la duración de los pulsos se incrementará en un factor de 2
por lo que bastará con rotar el valor del registro CCPR1L una posición hacia la izquierda por
cada pulsación hasta que alcance el valor de 100.
Código fuente
# in c lu d e < h t c .h >
# in c lu d e < s t d i o . h >
# in c lu d e " t i m e r s . h "
# in e lu d e " c c p .h "
t y p e d e f u n ió n {
u n s ig n e d c h a r b y t e s [ 2 ] ;
u n s ig n e d i n t e n t e r o ; } u b y t e 2 ;
Página | 116
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
u b yte2 D u tC y ;
v o i d I n ic _ p w n ( v o i d ) ;
v o id m a i n ( v o i d ) {
D u tC y .b y te s [0 ]= 2 5 ;
I n ic _ p w n ( ) ; / / p r o g r a m a r e l m ódulo CCP1 en modo PWM pa ra g e n e r a r
//u na s e ñ a l PWM de p e r io d o 0 ,1 ms y c i c l o de t r a b a jo d e l 25%.
IN TC O N =0x90; / / H a b i l i t a i n t e r r u p c io n e s g l o b a l e s e in t e r r u p c ió n e x te r n a
w h ile (1 ) ;
}
v o i d p u t c h (u n s ig n e d c h a r b y t e ) {
T X S TA =0x26;
R C S T A b it s . S PEN=1;
T X R E G = b yte;
w h i l e (!TXIF ) c o n t i n u é ;
T X IF = 0 ;
}
v o id I n i c p w n ( v o i d ) {
s e t u p _ t im e r 2 (T 2 POST DIV1 |T2 0FF |T2_PRED_DIV1) ; //Tim er2 d e t e n id o ,
//PRED=P0STD=1
s e t u p _ c c p l (CCP_OFF) ; / / R es et a l módulo C C Pl.
s e t _ p w m l_ d u t y (D u tC y . e n t e r o < < 2 ) ; / /S eñal PWM s a ld r á con c i c l o de t r a b a j o
//25 %.
s e t _ t i m e r 2 (9 9 ) ; //M ódulo de c o n te o d e l Tim er2 que es e l p e r i o d o de
/ / la sen PWM
T R I S C b i t s . T R IS C 2 = 0 ; //Poner e l te r m in a l CCPl como s a l i d a .
s e t u p c c p l(C C P P W M ); / / E l módulo CCPl en modo PWM
s t a r t t im e r 2 ( ) ; / / I n i c i a r c o n te o d e l Tim er2
}
v o id in t e r r u p t I S R ( v o i d ) {
i f (IN T C O N b it s . IN T F = = 0 ) re tu r n ; //Comprueba l a i n t e r r u p c i ó n e x t e r n a
IN T C O N b it s . IN T F = 0; //B aja e l in d ic a d o r de in t e r r u p c i ó n
/ / e x te rn a
DutCy . b y t e s [0 ] « = 1 ; / / M u lt ip lic a p o r 2 e l c i c l o de t r a b a j o
i f (D u t C y . b y t e s [0 ]> 1 0 0 ) D u tC y .b y te i [0 ]= 2 5 ; //Comprueba s i e l c i c l o de
/ / t r a b a jo es d e l 1 0 0 %
s e t _ p w m l_ d u t y (D u tC y . e n t e r o < < 2 ) ; / / A ju s ta e l c i c l o d e t r a b a j o
p r i n t f ( "D C =% d\n ", C C PR 1L );
}
Página | 117
Programación de microcontroladores PIC en lenguaje C
Página | 118
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
Solución:
PULSADOR
b) Para la generación de una señal periódica con ciclo de trabajo variable se utilizará el
módulo CCPx del microcontrolador asociado al Timer 2. Para la modificación del ciclo de
Página | 119
Programación de microcontroladores PIC en lenguaje C
Configuración
El período T de la señal PWM se fija mediante el valor N depositado en el registro PR2. Así,
para una frecuencia superior a 20 kHz se tendrá un período T < 50 ps.
T = ( N + 1 ) * P * 4 * Tosc => 50 ps = (N + 1) * P * 4 * 0,25 ps => 100 = (N + 1) * P
donde P es el factor de división del pre-divisor del Timer2, P = 1,4,15.
Si se escoge P = 1, el valor que hay que colocar en el registro PR2 será N = 49.
La duración TON de los pulsos queda determinada por el valor M de los 10 bits distribuidos
entre los 8 bits del registro CCPR1L (que constituyen los 8 bits más significativos de M, es
decir, Ms) y los 2 bits CCP1C0N<5:4>, que forman los 2 bits menos significativos de M, es
| decir, M2.
Como sólo es necesario variar el ciclo de trabajo entre el 25%, 50%, 75 % y 100% se
utilizará una tabla donde se almacenarán los valores que se cargarán en el registro CCPR1L
(Mg) y en los bits CCP1C0N<5:4> para ajustar el valor de T on.
Los valores para cada ciclo de trabajo se obtienen utilizando la siguiente fórmula:
T on = DC * T = (M8:M2) * P * Tosc
Código fuente
# i n c l u d e < h t c .h >
# in c lu d e < s t d io .h >
t y p e d e f u n ió n {
u n s ig n e d c h a r b y t e s [ 2 ] ;
u n s ig n e d i n t e n t e r o ; } u b y t e 2 ;
u n s ig n e d c h a r C o n ta d o r ;
/ / T a b la co n l o s v a l o r e s qu e h a y que c a r g a r en CCPR1L
u n s ig n e d c h a r T a b l a l [ 5 ] = { 0 x 3 2 , 0 x 2 5 , 0 x 1 9 , 0 x 0 C ,0 x 0 0 } ;
void I n i c p w n ( v o i d ) ;
v o i d Ton p w m ( v o i d ) ;
i n t m a in ( )
{
C o n ta d o r= 5 ; / / I n i c i a e l c o n t a d o r co n e l número de v a l o r e s q u e pu ede
/ / tom a r e l DC.
In ic p w n ( ) ; / / p ro g ra m a r e l m ódulo CCP1 en modo PWM p a r a g e n e r a r PWM
//de 20 kH z, DC=0
INTCON=0x90; / / H a b ilit a in te r r u p c io n e s g lo b a le s e in te r r u p c ió n e x te rn a
Página | 120
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
Página | 121
Programación de microcontroladores PIC en lenguaje C
si sol mi mi fu mi re do lu sol la re si
Frecuencias (Hz)
Sol: 391,995
La: 440
Si: 493,883
Do: 523,25
Re: 587,33
M i: 659,26
Fa : 689,46
Página | 122
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
El período T de la señal PWM se fija mediante el valor N depositado en el registro PR2. Así,
se puede obtener el valor a asignar a PR2 para cada nota utilizando la fórmula:
T = (N + 1) * P * lp s
donde P es el factor de división del pre-divisor del Timer2, P = 1, 4,16.
Se escoge P = 16 ya que N > 255 y se obtienen los siguientes valores para cada nota:
Para controlar la duración de cada una de las notas se utilizará el temporizador TIMER1 en
modo temporizador para contabilizar 250 ms funcionando en modo interrupción.
Página | 123
Programación de microcontroladores PIC en lenguaje C
Código fuente
# in c lu d e < h t c .h >
// D e f i n i c i ó n d e l o s v a l o r e s de PR2 p a r a c a d a n o t a
# d e f i n e S o l 158
# d e f in e La 141
# d e fin e S i 126
# d e f i n e Do 117
# d e f i n e Re 105
# d e fin e Mi 94
# d e f i n e Fa 90
# d e fin e S ile n c io 0
# d e f i n e F in OxFF
/ / D e fin ic ió n de la d u r a c ió n d e ca d a t i p o de n o ta ( m ú l t i p l o de 0 .2 5 se g u n d o s )
# d e f i n e C o rc h e a 1
# d e fin e N e gra 2
# d e f i n e B la n c a 4
v o id P u ls a d o r (v o id );
v o id T e m p o r (v o id );
v o id T o n p w m (v o id );
v o id In ic _ p w m (v o id );
u n s ig n e d c h a r T a b la P , Tem po;
u n s ig n e d i n t T ie m p o l= 6 0 0 0 0 ; / / A ju s t e d e l Tiem po
/ / T a b la c o n l a p a r t i t u r a
c o n s t c h a r N o t a s [6 0] = { S i l e n c i o , B l a n c a , S o l , N e g r a ,D o ,N e g r a ,D o ,C o r c h e a ,
R e, C o r c h e a ,D o ,C o r c h e a , S i , C o r c h e a ,L a ,B la n c a ,L a ,N e g r a ,
R e , N e g r a , R e , C o r c h e a , M i , C o r c h e a ,R e ,C o r c h e a , Do,
C o r c h e a , S i , B l a n c a , S o l , N e g r a ,M i , N e g r a ,
M i,C o r c h e a ,F a ,C o r c h e a , M i,C o r c h e a ,R e ,C o r c h e a ,
Do,N e g r a , L a , N e g r a , Sol,N e g r a ,L a ,N e g r a ,
Re,Negra,Si,Negra,Do,Blanca, Fin};
i n t m a in ( ) {
INTC0N= 0 x 9 0 ; / / H a b ilit a in te r r u p c io n e s g lo b a le s e in te r r u p c ió n e x te rn a
w h ile (1 ) {
w h ile (P O R T B b it s . R B 0 = = 1 ); //Comprueba e l e s t a d o d e l a t a r j e t a ON/OFF
IN T C O N b it s . P E IE = 0 ; / / D e s h a b i l i t a i n t e r r u p c i o n e s de p e r i f é r i c o s
T1CON=0; / / p a ra e l TIMER1, e l TIMER2 y e l M ódu lo CCPl
T2CON=0;
CCP1CON=0;
}
v o id in te r r u p t IS R (v o id ){
i f ( IN T C O N b it s . IN T F = = 1 ) P u ls a d o r ( ) ; //Comprueba s i ha s a l t a d o la
/ / in te r r u p c ió n e x te rn a
e ls e if(P IR lb it s .T M R lIF = = l) T e m p o r( ) ; //Comprueba s i ha s a l t a d o la
/ / in te r r u p c ió n TIM ERl
v o id P u ls a d o r (v o id ){
IN T C O N b its .IN T F = 0 ; / / B a ja e l f l a g d e i n t e r r u p c i ó n
if(P O R T B b it s .R B 0 = = 0 ) r e t u r n ; //Comprueba e l p u ls a d o r
I n i c p w m (); / / p ro g ra m a r m ódulo CCPl con l a p r im e r a
/ / n o ta
}
Página | 124
4. Módulos de Captura, Comparación y Modulación de Anchura de Pulsos (PWM)
v o id T e m p o r (v o id ){
P I R l b i t s . T M R 1 IF = 0 ; / / B a ja e l f l a g de i n t e r r u p c ió n d e l TIMER1
T M R l= T ie m p o l; / / R e c a rg a e l v a l o r de l o s c o n ta d o re s d e l TIMER1
/ / p a ra v o l v e r a c o n t a r 0 .2 5 s
i f ( - -T e m p o = = 0 ) Ton p w m (); / /D ecrem enta e l c o n ta d o r d e l tiem p o de n o ta
}
/ / ************************************************ ****************************
/ / In ic _ p w m : P r o g r a m a r e l m ódu lo CCP1 en modo PWM, e i n i c i a r l a m e lo d ía .
/ / ************************************************ ****************************
v o id In ic _ p w m ( v o i d ) {
T2C O N=0x02; / / P ro g ra m a r p o s t - d i v i s o r = 1, Tim er2 d e t e n id o , y p r e -
/ / d i v i s o r = 16.
T lC O N = 0 x 3 0 ; / / P ro g ra m a r p r e d i v i s o r = 8, T im e r l d e t e n id o
T M R l= T ie m p o l; //C a rga e l v a l o r de l o s c o n ta d o r e s d e l TIMER1 p a ra c o n t a r
/ / 0 .2 5 s
// TM R1=100; / / C a rga e l v a l o r de l o s c o n t a d o r e s d e l TIMER1 p a ra c o n t a r
/ / 0 .2 5 s
Página | 125
5. Módulos analógicos
5.1. Módulo generador de tensión de referencia (CVref)
5.2. Módulos comparadores de tensión
5.3. Módulo conversor analógico digital (CAD)
entrada V in* por los comparadores analógicos o como tensión de salida de referencia por
RA2/AN2 siempre y cuando se utilice como salida conectada a una carga de alta
impedancia, aunque está realmente pensado para utilizarse simplemente como
comprobación del valor de tensión entregado al comparador. El módulo CVref proporciona
dos rangos de ajuste de tensión y puede ser apagado en caso de no ser utilizado para
reducir el consumo de energía. La configuración de este módulo se realiza mediante el
registro CVRCON (A2.12).
V dd 16 ETAPAS
Página | 127
Programación de microcontroladores PIC en lenguaje C
Solución:
Para generar la señal diente de sierra se hará uso del generador de tensión de referencia
Integrado en el mlcrocontrolador PIC16F877A.
Configuración
Para la generación de la tensión de referencia habrá que tener en cuenta también el tiempo de
respuesta definido por el fabricante, en este caso 10 ps. Los valores de tensión de referencia
vendrán dados en función del modo de funcionamiento por las siguientes fórmulas:
Código fuente
# in c lu d e < h tc .h >
# in c lu d e " a n a l o g . h "
# d e f i n e _XTAL_FREQ 4000000 / / O s c i l a d o r I n t e r n o d e 4MHZ
CONFIG(WRT_OFF & WDTEJDFF & P W R T E O F F & F O S C X T & L V P O F F ) ;
u n s ig n e d c h a r i ;
d i () ; //Se d e s h a b i l i t a n in te r r u p c io n e s
w h ile ( 1 ) {
}
}
Página | 128
5. Módulos analógicos
Modifica el program a de form a que permita conmutar entre un ajuste en rango alto y un
ajuste en rango bajo. Este modo de funcionamiento se conmutará mediante un pulsador
conectado a RBO.
Modifica e l program a de form a que se muestre la tensión generada con dos decimales y el
modo "fino/grueso" de ajuste de la tensión de salida en una pantalla LCD.
RA4 o RA5
BUS DE
DATOS
■ CMIF
DEL OTRO
INTCON PIE2 COMPARADOR
t
PEIE CMIF
Página | 129
Programación de microcontroladores PIC en lenguaje C
Solución:
b)
Configuración
Para configurar el módulo comparador analógico será necesario ajustar el registro CMCON
(véase anexo A2.13). Esto se realizará mediante la definición de diferentes constantes que
se utilizarán para definir el modo de funcionamiento y se incluirán en el archivo de
definiciones "analog.h". Las constantes harán referencia a la configuración de los
comparadores del recuadro inferior y serán las siguientes:
Página | 130
5. Módulos analógicos
# d e fin e CA RESET 0x 00
# d e fin e CA A0 A3 NC NC ON A4 0x 01
# d e fin e CA A0 A3 Al A2 0x 02
# d e fin e CA A0 A3 Al A2 ON A4 A5 0x03
# d e fin e CA A0 A3 Al A3 0x04
# d e fin e CA A0 A3 Al A3 ON A4 A5 0x05
# d e fin e CA A0 VR Al VR 0x06
# d e fin e CA A3 VR A2 VR OxOE
# d e fin e CA NC NC NC NC OFF 0x07
# d e fin e CA C 1 IN V 0x 10
# d e fin e CA C 2 IN V 0x 20
RA1/AN1 • RA1/AN1 - _ •
RAIZAN1 —----- —
RA2WI2 A 'A,,t SP RA2ZAN2 -Ó----- —
RAE/AN4/SS;C20UT
Two Comraon Referen ce Comparators Two Common Reference Comparators with Outputs
CM2;CM0 = 100 CM2:CM0 = 101
Vv-
RA0/AN0 ■
RA3/AN3 v cC
+
RA4/T0CKI/C1OUT
RA1/AN1 -
v •»-
RA2>‘AN2 - RAIZAN! —-----
C2
RA2/AN2 -2 - + /
RA5/ANMSS/C20UT
One Independen! Compar3tor with Output Four Inputs Multiplexed to Two Comparators
CM2:CM0 = 0 3 1 CM2:CM0 = 110
Página | 131
Programación de microcontroladores PIC en lenguaje C
Una vez definidas las constantes se utilizará una macro, que también se incluirá en el
archivo de definiciones "analog.h", para ajustar la configuración del módulo. La macro
tendrá la siguiente estructura:
# d e f i n e SETUP_COMPARATOR(CONFIG_COMPARATOR) \
CMCON=CONFIG_COMPARATOR;
Código fuente
# i n e l u d e < h t c .h >
# in e lu d e " a n a lo g .h "
v o id m a in (v o id ){
T R IS B = 0 x F E ; / / T e r m in a l RB0 como s a l i d a
\ di O; //S e d e s h a b i l i t a n i n t e r r u p c i o n e s
' SETUP_COMPARATOR (C A _A O _A3_NC _NC_O N _A41CAC 1IN V) ; / / C o n fig u r a e l
/ / co m p a ra d or 1 co n
/ / e n t r a d a s p o r RAO y
//RA3 y s a l i d a
/ / i n v e r t i d a p o r RA4
w h i l e ( 1 ) {_
i f ( C lO U T ) RB0 = 1 ;
e ls e RB 0 = 0;
}
}
Modificar el programa para que el led se active cuando la señal en B es mayor que en A.
Solución:
Página 1 132
5. Módulos analógicos
Figura 5.5: Esquema de conexiones con el microcontrolador para comparar el valor de una señal de entrada
ANALÓGICA CON UN VALOR DE REFERENCIA PROPUESTO EN EL EJERCICIO 5.2.2.
Configuración
Si se sustituye C V E F = 2 . 2 V y C V
r = 4 . 4 V y se despeja se obtiene que CVR = 8. Una vez
r s r c
Por otro lado, se deberá configurar el módulo comparador 1 con entradas analógicas por
RAO/ANO/CUN- y RA3-/AN3/C1IN+ y salida RA4/C10UT habilitada. Se utilizarán para ello las
siguientes instrucciones.
T R IS A 4 = 0 ; //Se h a b i l i t a l a s a l i d a p o r RA4
s e t a dc in p u t s (AN0 A N 1 A N 3 ) ¡ //Se h a b i l i t a n e n tra d a s a n a ló g ic a s ANO,
//AN1 y AN3
SETUP COMPARATOR( CA_A0 A3_NC NC_ON A4) // C o n fig u ra e l coinp arador a n a ló g ic o 1
//con e n tra d a s p o r R A O (-) y R A 3 U )
//y s a l i d a p o r RA4
Página 1 133
Programación de microcontroladores PIC en lenguaje C
Código fu en te
# in c lu d e < h tc .h >
# in c lu d e "a n a lo g .h "
# d e f i n e _XTAL_FREQ 4000000 / / O s c i l a d o r I n t e r n o d e 4MHZ
__ CONFIG(WRT_OFF & WDTE_OFF & PWRTE_OFF & FOSC_XT & L V P _ O F F );
v o id m a in (v o id ){
d i () ; //S e d e s h a b i l i t a n i n t e r r u p c i o n e s
SET_CVREF(CVR_ON | CVR_HIGH | CVR_OUT__ON | 8 ) ; / / A ju s t e d e l a t e n s i ó n de
/ / r e fe r e n c ia
T R IS A 4 = 0 ; //Se h a b i l i t a l a s a l i d a p o r RA4
s e t_ a d c _ in p u t s (A N 0 _ A N 1 _ A N 3 ) ; //Se h a b i l i t a n e n t r a d a s a n a l ó g i c a s
ANO, AN1 y AN3
SETUPCOMPARATOR(CA A0 A 3_N C _N C _O N _A 4); / / C o n fig u r a e l c o m p a ra d o r
/ / a n a ló g ic o 1 c o n e n t r a d a s p o r
/ /RAO( - ) y R A 3 ( + ) y s a l i d a p o r RA4
w h ile (1 );
}
M odificar el programa para que se ilumine el led cuando la señal de entrada sea inferior a
0.5V.
Solución:
Página | 134
5. Módulos analógicos
+5V
£ 470Í2
nrrtlNC nc Iíhsj
1KÍ2 VDD
lO O n F .
TSL251RD
VW\r
[2ZI: NC j---- iOUT C7J------- RA1 RA5 —VWV— —
e n : nc I— vDD||Ejs- DO
+5V
-sn GND NC C5J PIC16F877A
470Q
RA3
Vss
OSC1 OSC2
4MHz
—Of-
20pF 20pF
I I
Figura 5.6: Esquema de conexiones con el microcontrolador para utilizar
EL SENSOR DE LUMINOSIDAD TSL251RD PROPUESTO EN EL EJERCICIO 5.2.3.
b) Para la realización del sistema será necesaria la utilización de uno de los comparadores
analógicos de los que dispone el PIC16F877A con sus entradas conectadas a las señales
analógicas (salida del TSL251RD y tensión de referencia del potenciómetro). En este caso se
utilizará el comparador 2 como se observa en las conexiones de la figura superior con su
salida habilitada por RA5, que permitirá de forma automática encender el LED cuando la
tensión de salida del sensor de luminosidad supere el valor de referencia.
Configuración
Código fu en te
# in c lu d e < h t c .h >
# in c lu d e " a n a l o g . h "
Página | 135
Programación de microcontroladores P1C en lenguaje C
d i() ; //Se d e s h a b i l i t a n i n t e r r u p c i o n e s
T R IS A 5 = 0 ; //Se h a b i l i t a l a s a l i d a p o r RA5
s e t a d c i n p u t s (AN0_AN1_AN3) ; //S e h a b i l i t a n e n t r a d a s a n a l ó g i c a s
SETUP COMPARATOR (CA_A O _A 3_A 1_A 3_O NI_A4__A5)
_A 4_A 5) ; / / C o n fig u r a e l c o m p a r a d o r 2
/ / co n e n t r a d a s p o r R A l ( - ) y
// R A 3(+ ) y s a l i d a p o r RA5
w h ile (1 );
}
Para iniciar una conversión A/D hay que activar el bit de control GO/DONE#. Cuando el
resultado de la conversión está ya disponible en ADRESH y ADRESL se desactiva
automáticamente el bit de estado GO/DONE# y se activa el bit ADIF del registro PIR1 para
solicitar interrupción. Si el bit ADIE del registro PIE1 está activo y el sistema de interrupción
del microcontrolador está habilitado el microcontrolador recibe una solicitud de
interrupción.
Página | 136
5. Módulos analógicos
Registros de control
A N O /R AO
DONE#
A N 1 /R A 1 K >
A N 2 A /R E F -/R A 2 IS >
A N 3 /V r b ^ / R A 3 CS>
A N 4 /R A 5
Solución:
Configuración
Para la creación de la función será necesario definir diferentes constantes que determinen el
modo de trabajo del módulo y que permitan ajustar los registros de configuración ADCONO y
ADCON1. Así, se definirá la constante ADCLK_FREQ_DIV que tomará el valor de la constante
_XTAL_FREQ dividida por 1.25 MHz de forma que permita obtener el factor divisor a aplicar al
reloj principal en el caso de que el CAD trabaja con dicho reloj y cumplir con las especificaciones
de funcionamiento del fabricante. También se definirá la constante ADCLK_RC que seleccionará
el reloj interno del CAD. Estas constantes junto con la definición de la función setup_adc se
incluirán en el fichero analog.h que tendrá la siguiente estructura.
t d e f i n e A D C C L K R C OxCl
# d e f i n e ADC_FREQ_DIV ( f l o a t ) (_XTAL_FREQ/1250000)
e x t e r n v o i d s e t u p a d c ( u n s i g n e d c h a r mode) ;
Página | 137
Programación de microcontroladores PIC en lenguaje C
Además se utilizará una función adicional set_adc_¡nputs() que permitirá definir las
entradas analógicas con las que se trabajará. Para ello se definirán nuevas constantes que
permitirán ajustar el registro de configuración ADCON1 y que se incluirán junto con la
definición de la función también en el fichero analog.h.
Código fuente
//Ajusta las entradas analógicas/digitales
extern void set_adc_inputs(unsigned char analog){ //Selecciona las entradas
//analógicas
ADCONl=(ADCONl&OxFO)|analog;
}
//Selecciona el modo de reloj del CAD, ajusta el canal 0, enciende el módulo y
//ajusta a la izquierda
extern void setup_adc(unsigned char mode){ //Selecciona el modo de reloj
if (mode==0x00){ //CAD apagado
ADCONO = 0x0 0;
ADCONl&=0x06; //E/S digitales
}
e l s e if (m o d e = = 0 x C l){ //Reloj RC
ADCONO=0xCl; //con ajuste derecho
ADCONl&=0xBF;
}
e ls e {
if(A D C _ F R E Q _ D IV < = 1 ){ //Fose <= 1.25MHz
ADCONO= 0x01; //ADCS1=0, ADCS0=0, Canal 0,
//Módulo encendido
ADCONl&=0xBF; //ADFM=1(ajuste a la derecha), ADCS2=0
}
e ls e if(A D C _ F R E Q _ D IV < = 2 ){ //Fose <= 2.5MHz
ADCONO=0x01; //ADCS1=0, ADCS0=0, Canal 0,
//Módulo encendido
ADCON1|=0xC0; //ADFM=1(ajuste a la derecha), ADCS2=1
}
Página | 138
5. Módulos analógicos
Solución:
Figura 5.8: Esquema de conexiones con el microcontrolador para convertir una señal de entrada analógica.
Página | 139
Programación de microcontroladores PIC en lenguaje C
b)
Configuración
Una vez configurado el módulo CAD en el canal 0 utilizando la función del ejemplo anterior
setup_adc() y habiendo esperado el tiempo de adquisición es necesario lanzar la conversión
poniendo a '1' el bit GO del registro ADCONO. Para esto se definirá la macro
START_ADC_CONV. Por último se creará una función que recoja el valor obtenido tras la
conversión read_adc().
# d e f i n e START_ADC_CONV GO=l / / L a n za una c o n v e r s i ó n a n a l ó g i c o d i g i t a l
e x t e r n u n s ig n e d i n t r e a d _ a d c ( v o i d ) ;
// R e c o g e e l v a l o r d e l a c o n v e r s i ó n d e 10 b i t s
e x t e r n u n s ig n e d i n t r e a d _ a d c ( ) {
w h ile (G O )c o n t in u é ; / / e s p e r a a qu e f i n a l i c e la c o n v e r s ió n
r e t u r n ( (A D R E S H «2 ) + (ADRESL>> 6 ) ) ;
}
Una vez creada la función anterior junto con las que se mostraron en el ejemplo anterior
solo será necesario ir llamándolas una tras otra desde el programa principal para obtener el
valor de la conversión. Es necesario también un último detalle que consiste en configurar el
puerto B como salidas ya que por defecto se configurarán como entradas al arrancar el
microcontrolador. Para ello basta con utilizar la instrucción:
TRISB = 0x00;
Código fuente
# in c lu d e < h t c .h >
# in e lu d e "a n a lo g .h "
void main(void){
int x;
di () ; //S e d e s h a b i l i t a n i n t e r r u p c i o n e s
TRISB = 0x00; / / P u e r to B c o n f i g u r a d o como s a l i d a
setup_adc (A D C C L K O S C ); / / I n i c i a l i z a e l m ódu lo CAD en e l c a n a l 0
s e t a d c i n p u t s (A N O );
_d e l a y u s (50); / / E s p e ra e l tie m p o de a d q u i s i c i ó n (a p r o x 44us)
while(1){
START_ADC_CONV; / / L a n za l a c o n v e r s i ó n
x=read_adc(); / / O b tie n e e l v a l o r d e l a c o n v e r s ió n
PORTB = (x>>6);
Página | 140
5. Módulos analógicos
Solución:
En el ejemplo anterior no era necesario seleccionar el canal ya que se trabajaba con el canal
0, que es el que se establece por defecto al arrancar el módulo, pero ahora será necesaria
una función que permita seleccionar el canal a convertir de entre las 8 entradas posibles.
Configuración
Para ello se definirá en "analog.h" la estructura de una nueva función que permita
seleccionar el canal analógico set_adc_channel():
e x te rn v o id s e t _ a d c _ c h a n n e l(u n s ig n e d ch a r ch a n n el) ;
e x t e r n v o i d s e t _ a d c _ c h a n n e l(u n s ig n e d ch a r ch a n n el) {
ADCONO = ( ADCONO&0xC7) | ( (ch a n n el% 8 ) « 3 ) ;
De esta manera únicamente será necesario crear un array de tipo int para ir almacenando
los valores obtenidos tras la conversión de cada canal y utilizar un contador que indique el
canal a convertir en cada momento.
Código fuente
v o id m a in (v o id ){
u n s ig n e d c h a r i ;
in t t a b la [8] ;
i =0 ;
di O ; //Se d e s h a b i l i t a n i n t e r r u p c io n e s
s e t u p a d c (A D C C L K O S C ) ; / / I n i c i a l i z a e l m ódulo CAD
s e t _ a d c _ in p u t s (A L L _ A N A L O G );
Página | 141
Programación de microcontroiadores PIC en lenguaje C
w h ile (1 ) {
s e t _ a d c _ c h a n n e l(i% 8 ) ;
__ d e l a y u s ( 5 0 ) ; / / E s p e ra e l t ie m p o d e a d q u i s i c i ó n
START_ADC_CONV; / / L a n za l a c o n v e r s i ó n
t a b l a [i% 8 ] = r e a d _ a d c ( ) ; / / O b tie n e e l v a l o r d e l a c o n v e r s i ó n
i+ + ;
}
}
Solución:
Figura 5.9: Esquema de conexiones con el microcontrolador para utilizar el sensor de temperatura
ANALÓGICO TC1047 PROPUESTO EN EL EJERCICIO 5.3.4.
Página | 142
5. Módulos analógicos
b) Para realizar el programa será necesario configurar el módulo CAD con entrada analógica
por RAO además de definir los terminales del puerto D como salidas. El manejo de la
pantalla LCD se realizará utilizando las funciones definidas en la librería "Icd.h".
Configuración
El módulo CAD se configurará con entrada analógica por RAO y utilizando el reloj interno del
microcontrolador mediante las siguientes instrucciones:
Para representar el valor de temperatura en la pantalla LCD será necesario convertir el valor
de tensión leído a la salida del sensor a °C utilizando la siguiente fórmula:
v o i d p u t c h (c h a r x ) {
le d p u t c h (x );
}
Código fuente
# in c lu d e < h t c .h >
# in c lu d e < s t d i o . h >
# in c lu d e " a n a l o g . h "
# in c lu d e " I c d . h "
v o id p u tc h (c h a r );
v o id m a in (v o id ){
f l o a t tem p; // V a r ia b le p a ra a lm a cen a r l a te m p e ra tu ra
l e d i n i t (); / / I n i c i a l i z a c i ó n de l a p a n t a l l a LCD
d i () ; //Se d e s h a b i l i t a n i n t e r r u p c i o n e s
s e tu p _a d c(A D C _C L K _O S C ); / / I n i c i a l i z a e l módulo CAD
s e t _ a d c _ in p u t s (A N O ); //Se c o n f ig u r a RAO como e n tra d a
/ / a n a ló g ic a
s e t_ a d c _ c h a n n e l( 0 ) ; //Se s e l e c c i o n a e l c a n a l de e n tra d a
/ / a n a ló g ic o en RAO
w h ile (1) {
START_ADC_CONV; //Lanza l a c o n v e r s ió n
t e m p = (flo a t )r e a d a d e () ; // R ecoge e l v a l o r de l a c o n v e r s ió n
temp= ( ( t e m p *4 . 8 8 ) - 5 0 0 ) /10; / / C o n v ie r t e e l v a l o r a g ra d o s
Página | 143
Programación de microcontroladores PIC en lenguaje C
l c d g o t o ( 0) ; / / P o s ic io n a e l c u r s o r a l i n i c i o d e l a
/ / p a n t a l l a LCD
p r i n t f ( "Temp = % .2 f C " ,te m p ) / / M u e s tra e l v a l o r d e t e m p e r a t u r e p o r
/ / la p a n t a l l a LCD
__ d e l a y m s ( 5 0 0 ) ; / / E s p e ra m e d io S egu n do a n t e s d e l a n z a r
/ / o tr a c o n v e r s ió n
}
}
v o i d p u t c h (c h a r x ) {
lc d _ p u tc h (x );
}
Página | 144
6. Módulos de comunicaciones
En este capítulo se presentan los módulos de comunicaciones serie que integra el
microcontrolador PIC16F877A. En particular, el PIC16F877A integra dos módulos de
comunicaciones serie independientes que utilizan los terminales asociados al PORTC. Estos
módulos son el módulo USART (Universal Synchronous Asynchronous Receiver Transmitter)
y el módulo MSSP (Master Synchronous Serial Port).
Con respecto al módulo transmisor, el bit TXIF del registro PIR1 se pone a '0' cada vez que
escribimos un nuevo dato sobre el registro TXREG y, pasa a '1' cuando el contenido de este
buffer se copia sobre el TSR para dar inicio a la transmisión del nuevo carácter. En este
momento, si se desea, se puede provocar una interrupción al controlador. El bit TRMT del
registro TXSTA, indica el estado del registro de desplazamiento TSR. Se pone a '1' cuando se
encuentra vacío, sin nada que transmitir.
Página | 145
Programación de microcontroladores PIC en lenguaje C
Pueden realizarse transmisiones de 9 bits por cada carácter. En este caso, los 8 bits de menos
peso se cargan en el registro TXREG mientras que el noveno (bit 8) se carga en el bit TX9D del
registro TXSTA. Esta característica se habilita mediante el bit TX9 del mismo registro.
El módulo transmisor se habilita mediante el bit TXEN. En ese momento interviene el circuito
generador de baudios, que determina la frecuencia o ritmo con el que se transmite cada bit.
La frecuencia del circuito generador de baudios, que determinará la velocidad de
comunicación, se establece mediante el registro SPBRG asociado al generador de baudios,
una serie de bits de control y el oscilador principal del sistema (Fose). Por último, el bit SPEN
habilita la puerta serie y configura el terminal RC6/TX/CK, que puede actuar como línea TX de
transmisión de datos en el modo asincrono o como línea CK de reloj en el modo síncrono.
Página | 146
6. Módulos de comunicaciones
Siempre que en el registro RCREG haya un carácter disponible, el bit RCIF del registro PIR1
se pone a nivel 'Y . En este momento, si el bit RCIE del registro PIE1 estuviera también a
nivel ‘Y , se generaría una interrupción por recepción de un carácter.
El sistema de recepción se habilita mediante el bit CREN. El circuito generador de baudios
(el mismo utilizado en la sección de transmisión) determina la frecuencia o ritmo con la que
se recibe cada bit.
6.1.1. Crea una macro que permita configurar del módulo USART
en modo asincrono
Solución:
En este ejemplo se va a configurar el módulo USART para comunicaciones en modo
asincrono de forma genérica. Para ello se creará una macro que permitirá introducir los
valores necesarios en los registros de configuración.
Configuración
Para la creación de la macro será necesario definir diferentes constantes que determinen el
modo de trabajo del módulo y que permitan ajustar los registros de configuración TXSTA,
RCSTA y SPBRG. En este caso se definirá una máscara que ajuste el modo de trabajo en alta
velocidad HIGH_SPEED = 0x04 y otra que ajuste el modo de funcionamiento en 9 bits
NINE_BITS=0x40. Estas máscaras se utilizarán junto con la función OR (|) para ajustar los
registros de configuración TXSTA y RCSTA. El registro SPBRG que determinará la velocidad
del módulo obtiene su valor a partir del oscilador principal y el modo de funcionamiento a
alta o baja velocidad a partir de las siguientes fórmulas:
Página | 147
Programación de microcontroiadores PIC en lenguaje C
Así pues, la macro para configurar el módulo USART en modo asincrono tendrá la siguiente
estructura:
Para utilizar esta función será suficiente con incluir el código fuente que aparece a
continuación dentro del programa o de una forma más elegante incluir el código en un
archivo de definiciones denominado usart.h y añadirlo a nuestro programa principal
mediante la sentencia ffinclude "usart.h"
Código fuente
(tifn d e f _S E R IA L_H _
# d e fin e _S E R IA L _H _
# d e fin e H IG H SPEE D 0x04 //Modo a l t a v e l o c i d a d
# d e fin e LOW_SPEED 0 //Modo b a j a v e l o c i d a d
# d e fin e N I N E B I T S 0x40 //Modo t r a n s m is ió n 9 b i t s
# d e fin e E IG H T B IT S 0 //Modo t r a n s m is ió n 8 b i t s
# d e fin e _XTAL_FREQ 4000000 / / F r e c u e n c ia d e l o s c i l a d o r p r i n c i p a l
# d e fin e R X P I N TRISC7 / / D e fin e e l p i n RC7 como p i n p a r a
/ / r e c e p c ió n de d a t o s
# d e fin e T X P I N T R IS C 6 / / D e fin e e l p in RC6 como p i n p a r a
/ / t r a n s m is ió n de d a t o s
v o i d p u t c h (u n s ig n e d c h a r ) ; / / D e f i n i c i ó n de l a fu n c ió n p u tc h
# e n d if
Simulación
Página | 148
6. Módulos de comunicaciones
V/atch
Solución:
o)
Consideraciones eléctricas
Página | 149
Programación de microcontroladores PIC en lenguaje C
b)
Configuración
v o i d p u t c h (u n s ig n e d c h a r b y t e ) {
El envío de datos utilizando la función putch se realiza byte a byte por lo que para enviar
una cadena de caracteres sería necesario llamar a la función putch de forma consecutiva
por cada carácter a enviar utilizando un código similar al inferior:
v o id m a in (v o id ){
c o n s t u n s ig n e d c h a r t e x t o [ 1 1 ] = " H o la M u n d o !";
u n s ig n e d c h a r i = 0 ;
IN IT _ U S A R T (9 6 0 0 ,HIGH_SPEED, E IG H T_B ITS ) ; / / C o n fig u r a e l m odu lo USART
w h ile (1 ) {
fo r (i= 0 ;i< ll;i+ + ){ / / E n v ía l a ca d en a de c a r a c t e r e s
p u tc h ( t e x t o [ i ] ) ;
}
}
}
Aunque el envío de la cadena de caracteres de la forma indicada anteriormente es
completamente válida existe una librería en C denominada stdio.h que integra funciones
que facilitan esta tarea. En particular la función printf se encarga de dar formato a una
cadena de caracteres y enviarla a través del puerto de salida llamando a la función putch las
veces que sean necesarias hasta completar la cadena.
En este caso se utilizará la sentencia printf("\n Hola Mundo!\n"); a la que se le han añadido
los caracteres especiales de salto de línea "\n" al comienzo y al final del texto.
Código fuente
# i n c lu d e < s td io .h > / / L i b r e r í a con fu n c io n e s p a r a e l c o n t r o l de
/ / e n tra d a s y s a l i d a s
# in c lu d e < h t c .h > / / L i b r e r í a que i n c l u y e l a s d e f i n i c i o n e s d e l
/ / m ic r o c o n t r o la d o r
Página | 150
6. Módulos de comunicaciones
v o id m a in (v o id ){
Simulación
Figura 6.5: Configuración de MPLAB SIM para utilizar el módulo USART y simulación del ejercicio 6.1.2.
[Link] [Link]
Una vez instalado el programa HERCULES se configurará del puerto serie de comunicaciones
para que coincida con la configuración del módulo USART (9600 baudios, 8 bits y sin
paridad) y se abrirá el puerto de comunicaciones. Al ejecutar el programa se observa su
funcionamiento en la ventana de HERCULES como se muestra en la figura inferior.
Página | 151
Programación de microcontroladores PIC en lenguaje C
Solución:
Configuración
Para recibir los caracteres del módulo USART se creará una nueva función getche que se
encargará de recoger el dato recibido del registro RCREG. La función tendrá la siguiente
estructura:
u n s ig n e d c h a r g e t c h e ( v o i d )
La definición de esta nueva función se deberá incluir en el archivo usart.h y el código que se
muestra a continuación se incluirá en el archivo usart.c junto con la función putch.
Página | 152
6. Módulos de comunicaciones
u n s ig n e d c h a r g e t c h e O {
Como la función getche recibe los datos byte a byte es necesario llamar a la función las
veces necesarias hasta recoger todos los caracteres correspondientes tanto al nombre
como a la edad hasta encontrar el carácter especial de salto de línea (LF) o retorno de carro
(CR). De esto se encargará la función gets() incluida en la librería stdio.h, al igual que lo
hacía la función printf con la función putch. La función getsQ recibe como parámetro un
puntero a una cadena de caracteres donde almacenará los datos recibidos a través del
teclado hasta encontrar los caracteres especiales LF o CR.
Al recibir el dato de la edad en forma de cadena de caracteres puede ser necesario para
trabajar con este valor convertirlo a un número entero para lo que se puede utilizar en este
caso la función ato¡() incluida en la librería stdlib.h que convierte el valor ascii a entero.
e _ d a d = a t o i(e d a d );
Por último, el programa mostrará un mensaje utilizando la función fprintff) que construirá
una cadena de caracteres utilizando las dos variables buf y e_dad.
Código fuente
t fin c lu d e < h t c .h >
t fin c lu d e < s t d i o . h >
# in c lu d e < s t d l i b . h > / / L i b r e r í a con fu n c io n e s a d i c i o n a l e s a t o i ( )
t fin c lu d e " u s a r t . h "
v o i d m a in ( v o i d ) {
u n s ig n e d c h a r b u f [ 8 0 ] , e d a d [ 3 ] , e_ d a d ;
d i(); / / D e s a b i l i t a in t e r r u p c i o n e s
w h ile (1 ) {
p r i n t f ( " \ n H o la ] ¿Como t e LL am as?") //M en saje de s a l i d a
g e ts (b u f); //Alm acena l a r e s p u e s t a d e l
/ / u s u a rio en b u f
p r i n t f ( " \ n ¿C u an tos años t i e n e s ? " ) ; //M ensaje de s a l i d a
g e ts (e d a d ); //Alm acena l a r e s p u e s t a d e l
/ / u s u a rio en edad
e _ d a d = a to i(e d a d ); / / C o n v ie r t e l a edad a número
/ / e n te ro
p r i n t f (" \ n H o la %s d e %3i a ñ o s . \ n " / b u f ,e _ d a d ); / / R esp u esta
Página | 153
Programación de microcontroladores PIC en lenguaje C
Simulación
Solución:
Configuración
Para mostrar los mensajes se utilizará la función printf() y para guardad los datos recibidos
la función gets() combinada con la función atoif) que convierte de ascii a entero tal y como
se ha mostrado en el ejemplo anterior.
Además, será necesario utilizar la función rand() incluida en la librería stdlib.h que permite
generar un número aleatorio entre 0 y 32767. Esta función se combina junto con la función
Página | 154
6. Módulos de comunicaciones
Código fuente
# i n c lu d e < h t c .h >
# i n c lu d e < s t d i o . h >
# in c lu d e < s t d l i b . h > / / L i b r e r í a con fu n c io n e s a d i c i o n a l e s a t o i ( )
# in c lu d e " u s a r t . h "
v o id m a in (v o id ){
u n s ig n e d c h a r v a l o r , num[1 0 ] , n u m e r o , i , a c i e r t o ; / / d e f i n i c i ó n de
/ / v a r ia b le s
d i (); //desabilita interrupciones
T0C S=0; / / a rra n c a e l tim erO
I N I T U S A R T (9 6 0 0 ,HIGH SPEED ,E IG H T_B ITS); / / C o n fig u ra e l m odulo USART -
//Preferencias definidas en usart.h
w h ile (1 ) {
p r i n t f ( " \ n A d iv in a un numero d e l 0 a l 991 " ) ; //M en sa je de s a l i d a
Página | 155
Programación de microcontroladores PIC en lenguaje C
Simulación
Realiza un programa que utilice el módulo USART para implementar un juego en el que el
usuario tenga que adivinar una palabra. El usuario irá introduciendo caracteres en
mayúsculas y el programa le indicará si la palabra contiene ese carácter y la posición o
posiciones que ocupa en la palabra.
El módulo MSSP tiene asociados tres registros. El registro de status SSPSTAT (A2.17) y dos
registros de control SSPCON (A2.18) y SSPCON2 (A2.19) que determinarán el
Página | 156
6. Módulos de comunicaciones
funcionamiento del mismo en modo l2C o SPI tanto funcionando en modo maestro como en
modo esclavo.
Los terminales del microcontrolador asociados al módulo MSSP son los siguientes:
Solución:
Página | 157
Programación de microcontroladores PIC en lenguaje C
Configuración
La función de configuración deberá configurar los pines SDA y SCL para su control a través
del módulo MSSP (TRISC4 = 1; TRISC3 = 1;), ajustar el registro SSPCON (A2.18) para
encender el módulo y establecer modo maestro (SSPCON = 0x28), ajustar la velocidad del
reloj (SSPADD = OxOA), bajar los flags (SSPCON2 = 0;) y habilitar el control de velocidad
(SSPSTAT=0x80;).
Código fuente
v o id i2 c _ s ta r t(){
i 2 c _ i d l e () ; //Comprueba qu e e s t á l i b r e
S S P C O N 2 b its .S E N = l; / / E n v ía l a c o n d i c i ó n de i n i c i o
w h ile (S S P C O N 2 b it s . SEN==1) ; / / E s p e ra a qu e s e e n v íe
w h ile (S S P I F = = 0 ) ; //Comprueba que s e ha e n v ia d o
S S P IF = 0 ; / / B a ja e l f l a g
>
Envía secuencia de Restart
v o id i 2 c _ r e s t a r t () {
S S P C O N 2 b its. RSEN=1; / / E n v ía l a s e c u e n c ia r e s t a r t
w h ile (S S P C O N 2 b it s . R S E N ); / / E sp era a qu e s e e n v íe
w h i l e ( S S P IF = = 0 ) ; //Comprueba que s e ha e n v ia d o
S S P IF = 0 ; / / B a ja e l f l a g
}
Envía Secuencia de Stop
v o id i2 c _ s to p (){
S S P C O N 2 b its. PEN=1; / / E n v ía l a s e c u e n c ia de S to p
w h ile (S S P C O N 2 b it s .P E N ); / / E s p e ra a que s e e n v í e
w h ile (S S P IF = = 0 ); //Comprueba q u e s e ha e n v ia d o
S S P IF = 0 ; / / B a ja e l f l a g
}
Página | 158
6. Módulos de comunicaciones
Solución:
a) Para el funcionamiento del microcontrolador será necesario conectar correctamente las
entradas VDD y VSS a +5 V y 0 V respectivamente y el oscilador, en este caso un oscilador de
cristal a 4 MHz, a las entradas 0SC1 y 0SC2 tal y como aparece en la figura inferior. El
sensor de temperatura TC74 se conectará siguiendo las indicaciones de la hoja de
Página | 159
Programación de microcontroladores PIC en lenguaje C
especificaciones con sus salidas SDA y SCL conectadas a los terminales de comunicaciones
l2C del microcontrolador RC4 y RC3 respectivamente. Se utilizarán además dos resistencias
de pull-up conectadas a las líneas de comunicaciones l2C que mantendrán estas líneas en
alto '5 V' cuando estén sin utilizar. La conexión de la pantalla LCD se realizará siguiendo las
instrucciones del fabricante para utilizar el modo de comunicaciones de 4 bits a través de
los terminales RD0-RD4.
Configuración
Para leer el valor de la temperatura del módulo TC74 es necesario seguir las instrucciones
del fabricante. El protocolo a seguir para leer la temperatura se detalla en la figura inferior.
Read Byte Format
s Address WR ACK Command ACK Address RD i ACK Data NACK
S -
7 Bits 8 Bits 7 Bits 8 Bits
Slave Address Command Byte: selects Slave Address- repeated Data Byte: reads from
which register you are due to change ¡n data- the register set by the
reading from. flow direction. command byte.
F ig u r a 6.11: E s q u e m a p a r a la l e c t u r a d e d a t o s u t il iz a n d o e l s e n s o r d e t e m p e r a t u r a d ig it a l TC74.
Página | 160
6. Módulos de comunicaciones
# d e f i n e WRITE 0
# d e f i n e READ 1
s ig n e d c h a r T C 7 4 _ i2 c r e a d b y t e (u n s ig n e d c h a r a d d , u n s ig n e d ch a r d a t o ) {
s i g n e d c h a r tem p = 0 ;
i 2c _ s t a r t ( ) ; / / E n vía l a s e c u e n c ia de S t a r t (S)
if(i2 c _ w r ite (a d d + W R IT E )= = 0 ) { / / E n vía l a d i r . d e l m ódulo TC74
//en modo e s c r i t u r a
re tu r n 0 ; / / R e to rn a 0 en c a s o de e r r o r
}
If(i2 c _ w r ite (d a to )= = 0 ) { / / E n vía e l r e g i s t r o que se va
//a l e e r (d a t o )
re tu r n 0; / / R eto rn a 0 en c a s o de e r r o r
}
i 2c _ r e s t a r t ( ) ; / / E n vía l a s e c u e n c ia de R e s t a r t
i f ( i 2 c _ w r i t e ( add+READ)= = 0) { / / E n vía l a d i r e c c i ó n d e l m ódulo TC74
//en modo l e c t u r a
re tu r n 0; / / D evu elv e 0 en c a so de e r r o r
}
te m p = i2 c _ r e a d ( ) ; //Guarda e l v a l o r de r e c i b i d o
i 2c_sen d n ack ( ) ; / / E n vía s e c u e n c ia NACK
i 2c _ s to p (); / / E n vía s e c u e n c ia de S to p
r e t u r n tem p; / / D evu elv e e l v a l o r o b t e n id o
}
Una vez obtenido el valor de la temperatura se deberá representar en la pantalla LCD. Para
ello se hará uso de la función printf incluida en la librería "stdio.h" como ya se comentó en
ejemplos anteriores.
Código fuente
# in c lu d e < h t c .h >
# in c lu d e ,,i 2 c . h "
tr in c lu d e " l c d . h "
# in c lu d e " s t d i o . h "
# in c lu d e "T C 7 4 .h "
# d e fin e X TA LF R E Q 4000000 / / O s c ila d o r I n t e r n o de 4MHZ
# d e f i n e TC74ADDRESS 0x9A / / D ir e c c ió n d e l m ódulo TC74
# d e f i n e TC74 TEMP REG 0x00 / / D ir e c c ió n d e l r e g i s t r o de
/ / tem p era tu ra
__ CONFIG(WRT_OFF & WDTE_OFF & PWRTE_OFF & FOSCXT & L V P_O F F);
v o i d p u t c h (u n s ig n e d c h a r x ) ; / / D e fin ic ió n de l a fu n c ió n p u tch
v o id m a in (v o id ){ / /Fu n ción p r i n c i p a l
s ig n e d c h a r tem p; / / V a r ia b le p a ra a lm a cen a r l a
/ / tem p era tu ra
d i () ; / / D e s h a b ilit a i n t e r r u p c i o n e s
l c d i n i t () ; / / I n i c i a l a p a n t a l l a LCD
i 2c _ i n i t ( ) ; / / I n i c i a e l m ódulo I2C
w h i1 e ( 1 ) { / / B u cle i n f i n i t o
tem p = T C 7 4 _i2 c_read b yte (TC74_ADDRESS TC74TEMPREG) ? // L ee l a te m p e ra tu ra
/ / d e l TC74
if(t e m p != 0 ){ //Comprueba que se haya l e í d o c o r r e c t a m e n t e
lc d _ g o to (0 ); / / P o s ic io n a e l c u r s o r a l co m ien zo de l a LCD
p r i n t f ( "Temp = %+d C " , t e m p ); //M u estra l a tem p e ra tu ra
__ d e l a y m s (1 0 0 ); / / E sp era lOOms p a ra v o l v e r a l e e r Temp
}
Página | 161
Programación de microcontroladores PIC en lenguaje C
v o i d p u t c h (u n s ig n e d c h a r x ) { lc d p u t c h (x ); }
Figura 6.12: E s q u e m a d e c o n e x io n e s c o n e l m ic r o c o n t r o l a d o r p a r a u t il iz a r
LA MEMORIA E E P R O M 2 4 L C 2 5 6 PROPUESTO EN EL EJERCICIO 6 .2 .3 .
Página | 162
6. Módulos de comunicaciones
LEER BYTE
Configuración
Página | 163
Programación de microcontroladores PIC en lenguaje C
Código fuente
# i n c l u d e < h t c .h >
# i n c l u d e l,i 2 c . h " / / L i b r e r í a co n l a s r u t i n a s a s o c ia d a s a l m ó du lo i 2 c
# i n c l u d e "2 4 L C 2 5 6 . h " / / L i b r e r í a co n l a s r u t i n a s a s o c ia d a s a l a m em oria
//EEPROM
__ CONFIG(W RT_0FF & WDTE_OFF & PWRTE_OFF & F0SC_XT & LVP_0FF) ?
v o i d p u t c h (u n s ig n e d c h a r x ) ;
v o id m a in (v o id ){
u n s ig n e d c h a r d a t o , i ; / / D e f i n i c i ó n de v a r i a b l e s de p ro g ra m a
di (); //S e d e s h a b i l i t a n l a s i n t e r r u p c i o n e s
i 2c _ in it ();
d a to = E E P R O M _ i2 c _ r e a d b y te ( EEPROM_ADDRESS, EEPROMREG); / / L ectu ra d e l v a lo r
/ / a lm a cen a d o
d a to + + ; //Se in c r e m e n ta e l v a l o r en 1
i=E E P R O M _i2c_w ritebyte(E E PR O M _A D D R E S S , EEPROM REG, d a t o ) ; //S e e s c r i b e e l
/ / n u evo v a l o r
w h ile (l); / / F in d e l p rog ra m a
}
Realiza un programa que permita borrar todos los registros de la memoria EEPROM
(ponerlos a OxFF).
Realiza un programa que permita ir almacenando los valores de temperatura mostrados
en el ejercicio 6.2.2 en la memoria EEPROM cada hora y permita mostrarlos en la pantalla
LCD al accionar un pulsador.
Página | 164
7. Módulos periféricos
7.1. Memoria interna EEPROM
7.2. Circuito de Reset
7.3. Perro Guardián
MACROS
FUNCIONES
Página | 165
Programación de microcontroladores PIC en lenguaje C
e e p r o m _ w r it e (u n s ig n e d c h a r a d d r , u n s ig n e d c h a r v a l u é ) {
E E P R O M W R ITE (ad dr, v a l u é ) ;
}
u n s ig n e d c h a r e e p r o m _ r e a d (u n s ig n e d c h a r a d d r ) {
w h i l e (WR) c o n t in u é ;
r e t u r n EEPRO M _RE AD (addr);
}
Solución:
Para la realización del programa será necesario iniciar el registro 0x00 de la EEPROM interna
en el momento de programación asignándole el valor 0x00 utilizando la siguiente macro:
Código fu en te
# i n c l u d e < h t c . h> / / In c lu im o s l i b r e r í a d e l m ic r o a u s a r
__ CONFIG(WRT_OFF & WDTE_OFF & PWRTE_OFF & FOSC_XT & L V P O F F ) ;
# d e f i n e _XTAL_FREQ 4000000 / / O s c ila d o r I n t e r n o d e 4MHZ
u n s ig n e d c h a r s [ 1 0 ] j
v o id m a in (v o id ){
u n s ig n e d c h a r d a t a ;
EEPROM DATA( 0 x 0 0 , O x F F ,O x F F ,O x F F ,O x F F ,O x F F ,O x F F ,O x F F ); / / In ic ia liz a e l
/ / c o n ta d o r a ' 0 '
d i () ; //Se d e s h a b i l i t a n i n t e r r u p c i o n e s
d a ta = eep ro m _ rea d ( 0 ) ; //S e l e e e l c o n t a d o r
d a ta + + ; //Se in c r e m e n ta e l c o n t a d o r
e e p r o m w r i t e ( 0 , d a ta ); //Se a lm a cen a e l c o n t a d o r
NO P( ) ; / / F in d e l p ro g ra m a
Simulación
Página | 166
7. Módulos periféricos
Cada vez que hace un 'reset' y se vuelve a ejecutar el programa el valor almacenado en el
registro de memoria 0x00 se incrementa en 1.
Figura 7.1: Simulación de la escritura en la memoria EEPROM interna propuesto en el ejercicio 7.1.1.
Realiza un programa que almacene los números del 0 al 255 en cada una de las posiciones
de la memoria EEPROM.
El estado de algunos registros no se modifica ante un Reset pero muchos otros ven alterado
su valor ante un Reset (véase Anexo 2). En la figura inferior se muestra un diagrama
simplificado del circuito de Reset.
Página | 167
Programación de microcontroladores PIC en lenguaje C
1. Conexión de la alimentación.
2. Caída de tensión por debajo de los límites permitidos.
3. Desbordamiento del perro guardián sin encontrarse en modo bajo consumo.
Los motivos 1 y 2 vienen reflejados en los bits POR y BOR del registro PCON (A2.16) y el
tercer motivo se refleja en el bit TO del registro STATUS (A2.1).
Configuración
Para verificar el origen del reset será necesario habilitar los motivos de reset en la palabra
de configuración (A2.20) del microcontrolador utilizando la directiva __CONFIG de la
siguiente manera:
__ CONFIG (WRT_OFF S: WDTE_ON & PWRTE_OFF & FOSC_XT & BORENON & LVP_OFF) ;
La verificación del origen de reset se realizará comprobando el estado de los bits asociados
a cada uno de los motivos anteriores y enviando a través del módulo USART un mensaje
que indique dicho motivo. Para ello se empleará la librería utilizada en el ejemplo 6.2.1
"usart.h".
Código fuente
# in c lu d e < s td io .h >
# in c lu d e < h t c .h >
# in c lu d e "u s a r t.h "
v o id m a in (v o id ){
I N I T U S A R T (9 6 0 0 ,HIGH_SPEED, E IG H T_B ITS ) ; / / C o n fig u r a e l m odu lo USART
i f ( ín P O R ){ / / C o m p ro b a ción d e i n i c i o p o r
// c o n e x ió n
n P O R = l;
p r in tf("\ n R e s e t p o r e n c e n d id o I\ n ") ; / / E s c r itu r a a t r a v é s d e l p u e rto
/ / s e r ie
}
if(!n B O R ){ / / C o m p ro b a ción d e i n i c i o por
/ / c a íd a de t e n s i ó n
n B O R =l;
p r in t f(" \ n R e s e t p o r c a i d a de t e n s i ó n ! \ n " ) ; / / E s c r itu r a a t r a v é s
/ / d el p u e rto s e r ie
}
Página | 168
7. Módulos periféricos
i f (!n T O ){
p r in tf("\ n R e s e t p o r d e s b o rd a m ie n to d e l W D T !\ n "); / / E s c r it u r a p u e r to
/ / s e r ie
}
w h ile (1) ;
}
Simulación
Para la simulación del programa se utilizará MPLABSIM® y se habilitará la pestaña SIM Uart
de la ventana OUTPUT para visualizar los mensajes. En la figura inferior se muestra el valor
de los registros antes de comenzar la ejecución del programa.
13 Watch X
Add SFñ ADCONO ▼ | Add Symbol| _p:tiing:bits ▼
Figura 7.3: Simulación del sistema para la detección del origen de RESET propuesto en el ejercicio 7.2.1 (W atch).
Para poder observar el reset producido por el desbordamiento del WatchDog es necesario
modificar la configuración del simulador desde el menú Degugger/Settings. En la ventana
que aparece se deberá seleccionar la pestaña Break Optíons y en WDT Timeout elegir la
opción Reset como se muestra en la figura inferior.
Figura 7.4: Configuración de MPLAB SIM para la simulación del ejercicio 7.2.1.
Una vez ajustado el parámetro anterior se pueden generarán los diferentes reset desde el
menú Debugger/Reset y ejecutar el programa mientras se observa la ventana OUTPUT que
deberá mostrar los mensajes que aparecen en la figura inferior.
Página | 169
Programación de microcontroladores PIC en lenguaje C
Omput_______________________ _ i o II O llüSbl
lu id Vellón Control ¡Findin Res ;1*ÍS a B S Í m J SIMUartl
Figura 7.5: Simulación del programa de detección de origen de RESET propuesto en el ejercicio 7.2.1.
Página | 170
A l. Librerías en C
A l.l. p o rts
A l . 2. ¡n te rru p ts
A l . 3. tim e rs
A l . 4. ccp
A l . 5. a n a lo g
A l . 6. u sa rt
A l . 7. ¡2c
A l . 8. Icd
A l.l. ports
ports.h
//CONSTANTES, MACROS Y FUNCIONES PARA LOS PUERTOS DE ENTRADA Y SALIDA DIGITALES
A l.2. iníermpts
interrupts.h
//CONSTANTES, MACROS Y FUNCIONES PARA LOS PUERTOS DE ENTRADA
Página | 171
Programación de microcontroladores P1C en lenguaje C
A1.3. timers
timers.h
Página | 172
Anexos
A1.4. ccp
ccp.h
//CONSTANTES, MACROS Y FUNCIONES PARA LOS MODULOS CCP
tfdefine CCPOFF 0x00
^define CCPCAPTUREFE 0x04
#define CCPCAPTURERE 0x05
#define CCPCAPTUREDIV4 0x06
#define CCP_CAPTURE_DIV16 0x07
#define CCPCOMPARERISE 0x08
#define CCPCOMPAREFALL 0x09
#define CCPCOMPAREINT OxOA
#define CCP_COMPARE_SPECIAL OxOB
#define CCPPWM OxOC
#define setup_ccpl(valué) CCPlCON=value
#define set pwml_duty(valué) CCPR1L= (value»2) ; \
CCPlCON=(CCPICON&OxCF)|((value&0x0003)«4)
#define get_ccpl(valué) CCPR1
#define setccpl(valué) CCPRl=value
#define setup_ccp2(valué) CCP2CON=value
«define set_pwm2_duty(valué) CCPR2L= (value»2) ; \
CCP2CON=(CCP2CON&OXCF)|((value&0x0003)«4)
«define get_ccp2(valué) CCPR2
#define set_ccp2(valué) CCPR2=value
A l. 5. analog
analog.h
//CONSTANTES, MACEOS Y FUNCIONES PARA EL CONVERSOR ANALÓGICO DIGITAL
Sdefine ADCOFF 0x00
«define ALL_DIGITAL 0x06
#define ALL_ANALOG 0x00
#define ALLA N A L O G V 0x01
#define ALLANALOG V V- 0x08
Página | 173
Programación de microcontroladores PIC en lenguaje C
#define SETUPCOMPARATOR(CONFIG_COMPARATOR) \
CMCON=CONFIG_COMPARATOR;
Página | 174
Anexos
analog.c
# in c lu d e < h tc .h >
# in c lu d e " a n a lo g .h "
Página | 175
Programación de microcontroladores PIC en lenguaje C
#define RX_PXN TRXSC7 //Define el pin RC7 como pin para recepción de datos
#define TX_PIN TRISC6 //Define el pin RC6 como pin para transmisión de datos
#endif
usart.c
#include <htc.h>
Página | 176
Anexos
A l. 7. i2c.h / ¡2c.€
i2c.h
#include <htc.h>
#define WRITE 0
#define READ 1
¡2c.c
#include <htc.h>
#include ui2c.h"
void i2c_init(){
TRISC3 = 1; //SLC
TRISC4 = 1; //SDA
SSPADD = OxOA; //Reloj a lOOKHz
SSPSTAT = 0x80; //Habilita el control de velocidad del módulo
SSPCON2 = 0x00; //Baja los flags
SSPCON = 0x28; //Modo maestro, módulo I2C encendido
}
//Envía la secuencia de Start
void i2c_start(){
i2c_idle(); //Comprueba que está libre
[Link]=1; //Envía la condición de inicio
while([Link]==l) ; //Espera a que se envíe
while(SSPIF==0); //Comprueba que se ha enviado
SSPIF=0; //Baja el flag
}
//Envía la secuencia de (re)start
void i2c_restart(){
SSPCON2bi [Link]=1; //Envía la secuencia restart
while([Link]) ; //Espera a que se envíe
while(SSPIF==0); //Comprueba que se ha enviado
SSPIF=0; //Baja el flag
}
//Envía la secuencia de Stop
void i2c_stop(){
[Link]=1; //Envía la secuencia de Stop
while([Link]); //Espera a que se envíe
while(SSPIF==0); //Comprueba que se ha enviado
SSPIF=0; //Baja el flag
}
Página | 177
Programación de microcontroladores PIC en lenguaje C
Void i2c_idle(){
while ( ( SSPC0N2 & OxlF ) | SSPSTATbits.R_nW ) ; //Comprueba que el módulo está libre
}
//Lee un byte
void i2c_sendnack(){
[Link]=1;
SSPC0N2b [Link]=1;
while([Link]==1);
A 1 .8 . Icd.h / Icd.c
Icd.h
/* Escribe un byte en la pantalla LCD en modo 4 bits */
extern void lcdwrite(unsigned char);
Página | 178
Anexos
e x te r n v o id lc d _ p u tc h (c h a r) ;
/* E s ta b le c e l a p o s ic ió n d e l cu rsor */
Icd.c
/*
* Rutinas para trabajar con la pantalla LCD Hitachi HD44780.
* Utiliza comunicaciones en modo 4 bit de la siguiente forma:
* PORTD bits 0-3 conectados a los bits de datos 4-7 de la LCD (high nibble)
* PORTD bit 4 conectado a la entrada LCD RS (selección de registro)
* PORTD bit 5 conectado a la entrada LCD RW (lectura/escritura)
* PORTD bit 6 conectado a la entrada LCD EN (reloj)
* PORTD bit 7 conectado a la entrada LCD ON bit (LCD power)
*/
#ifndef XTALFREQ
//Se asume una frecuencia de trabajo de 4MHz a menos que se haya especificado
//con anterioridad
«define XTALFREQ 4000000
#endif
«inelude <htc.h>
«inelude “lcd.h"
Página | 179
Programación de microcontroladores PIC en lenguaje C
/* D esp la za e l c u rs o r a l a p o s ic ió n in d ic a d a */
v o id lc d _ g o to (u n s ig n e d char p o s ) {
LCDRS = 0;
l c d w r it e (0 x 8 0 + p o s );
}
in i t _ v a l u e = 0x3;
TRISD=0;
RD7=1; //enciende l a p a n t a lla LCD
LCD_RS = 0;
LCD_EN = 0;
LCDRW = 0;
__ d e l a y m s (1 5 ); //espera 15ms
LCDDATA = (LCDDATA & OxFO) | in it_ v a lu e ; //en vía e l conunando de i n i c i o
LCDSTROBE( ) ;
__ d e l a y m s ( 5 ) ;
LCDSTROBE( ) ;
__ d e la y _ u s ( 2 0 0 ) ;
LCDSTROBE( ) ;
__ d e la y u s (2 00 ) ;
LCDDATA = (LCD_DATA & OxFO) | 2; //Modo 4 b i t s
LCDSTROBE( ) ;
l c d _ w r i t e (0 x 2 8 ); //Longitu d d e l c a r á c t e r
lc d _ w r it e (O x F ); / / D isp la y On, Cursor On, Cursor B lin k
lc d _ c le a r ( ) ; //Limpia l a p a n ta lla
l c d w r i t e ( 0x 6 ) ; //Modo de en trada On
}
Página | 180
A2. Registros de Funciones Especiales (SFRs)
A2.1. STATUS
A2.2. OPTION_REG
A2.3. T I CON
A2.4. T2CON
A2.5. INTCON
A2.6. PIE1
A2. 7. PIR1
A2.8. PIE2 y PIR2
A2.9. CCPxCON
A2.10. ADCONO
A 2 .ll. ADCON1
A2.12. CVRCON
A2.13. CMCON
A2.14. TXSTA
A2.15. RCSTA
A2.16. PCON
A2.17. SSPSTAT
A2.18. SSPCON
A2.19. SSPCON2
A2.20. PALABRA DE CONFIGURACION
A2.1. STATUS
R/W-0 R/W-0 R/W-0 R-1 R-1 R/W-x R/W-x R/W-x Valores de los bits después de un reset
R egistro S T A T U S
(d ireccio ne s 03h, IRP RP1 RPO TO# PD# Z DC R = el bit se puede leer
C
W = el bit se puede escribir Nota:
83h, 103h, 183h) bit 7 bitO x = Valor desconocido TO# = 7 0 j
bit 7 IRP: Selecciona el Banco de Memoria de datos en el bit 2 Z (Z ero): Indicador de cero
direccionamiento indirecto.
1 = Si el resultado de una operación antmética o lógica es cero
0 = Bancos 0 y 1 (OOh - FFh) (256 bytes) 0 = Si el resultado de una operación aritmética o lógica es no
1 = Bancos 2 y 3 (1 OOh - 1FFh) (256 bytes) es cero
bit 6-5 RP1 :RP0: Seleccionan el Banco de Memoria bit 1 DC (D ig it carry/bo rrow ): Indicador de acarreo o
de datos en el direccionamiento directo. préstamo auxiliar en las operaciones aritméticas de suma o
resta (instrucciones ADDWF, ADDLW, SUBLW, SUBWF)
00 = Banco 0 (OOh - 7Fh) (128 bytes)
1 = Si hay acarreo del bit 3 al 4 en el resultado de una
01 = Banco 1 (80h - FFh) (128 bytes) operación aritmética de suma binaria o si no hay préstamo en
110 = Banco2(1 OOh-17Fh) (128 bytes) una operación de resta
' 11 = Banco 3 (180h - 1FFh) (128 bytes) 0 = Si no hay acarreo en la suma o si hay préstamo del bit 4 al
bit 3 en una operación de resta
bit 4 TO# (T im e -o u t ) : Indicador de desbordamiento del
perro guardián W TD (W atch d og Timer) bit 0 C (C arry/bo rro w ): Indicador de acarreo o préstamo en las
0 = Cuando se desborda el WTD operaciones aritméticas de suma o resta (instrucciones
ADDWF. ADDLW. SUBLW, SUBWF)
1 = Después de un reset por encendido (pov/er-up ) y con
las instrucciones CLRWDT y SLEEP 1 = Si hay acarreo en el resultado de una operación aritmética
de suma binaria o si no hay préstamo en una operación de
bit 3 PD# (P o w e r-d o w n ): Indicador de modo de bajo resta
consumo. 0 = Si no hay acarreo en la suma o si hay préstamo en una
0 = Cuando entra en bajo consumo con la instrucción operación de resta
SLEEP
1 = Después del encendido o con la instrucción CLRWDT
Página | 181
Programación de microcontroladores PIC en lenguaje C
bit 7 RBPU#: Habilita/deshabilita las resistencias internas de bit 3 PSA: asigna el pre-divisor al TimerO (P SA = 0) o al
Pull-up del puerto B. Perro Guardián WDT (P SA =1)
A 2 3 . TICO iM
U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
Registro T1CON
(dirección 0x10 de la T1CKPS1 T1CKPS0 T10SCEN T1SYNC# TMR1CS TMR10N j
memoria de datos RAM) B it 7 B it 6 B it 5 B it 4 B it 3 B it 2 B it 1 BitO
bit 7-6 No implementados: s e leerían com o '0'. bit 2 T1SYNC: Bit de control de la sin cro n izació n del
reloj externo del Tim erl
bit 5-4 T1CKPS1 :T1CKPS0: B its de sele cció n del factor de Cuando TM R1CS=1:
d ivisió n del pre-divisor para la entrada de reloj del Tim erl 1 = No sincroniza la entrada de reloj externo
0 = Sincroniza la entrada de reloj externo
T 1C K P S 1 -T 1C K P S 0 Factor de división Cuando TM R 1C S = 0:
00 1 Este bit s e ignora, pues TIMER1 u sa el reloj
01 2 interno que ya está sincronizado.
10 4
11 8 bit 1 TMR1CS: Bit de se le cció n de reloj para el TIM ER 1
1 = Reloj externo del pin RC0/T1O SÓ /T1CKI
bit 3 T10 S C EN : B it de habilitación (enable) del oscilado r (flancos de subida)
extem o (T 1 0 S C ) del TMR1 0 = Reloj interno (FOSC/4)
1 = O scila d o r habilitado
0 = O scilla d o r apagado bit 0 TMR10N: Bit para arranque/paro del Tim ert.
1 = Tim erl cuenta p u lsos
0 = Tim erl parado
Página | 182
Anexos
A 2 .4 . T2COÍM
bit 7 No implementado: S e lee com o 0 bit 2 TMR20N: Bit de paro/arranque del TMR2
1 = Timer2 on (habilitado)
bit 6:3 TOUTPS3:TOUTPSO: B its de selección del factor 0 = Timer2 off (no habilitado)
de división del post>divisor del Timer2
bit 1:0 T2CKPS1 :T2CKPS0: Bits de selección del factor de
TO U TP S3-TO U TP SO Factor de división división del pre-divisor del Timer2
0000 1
0001 2 T2 CK PS1 -T2 CK P S0 Factor de división
0010 3 00 1
0011 4 01 4
0100 5 1x 16
0101 6
0110 7
0111 8
1000 9
1001 10
1010 11
1011 12
1100 13
1101 14
1110 16
1111 16
R egistro INTCON
(dire cciones OBh, G IE P E IE T O IE IN T E R B IE T O IF IN T F R B IF
Página | 183
Programación de microcontroladores PIC en lenguaje C
(dirección 8Ch) PSPIE(’ ) ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE
bit 7 bitO
bit 7 PSP1E(1) : Permiso de interrupción para el puerto bit 3 SSPIE: Permiso de interrupción para el puerto serie
paralelo Esclavo (PSP) al realizar una operación de lectura síncrono (SSP)
/escritura 1 = Habilita la interrupción
1 = Habilita la interrupción 0 = Inhabilita la interrupción
0 = Inhabilita la interrupción
bit 2 CCP1IE: Permiso de interrupción para el módulo CCP1
bit 6 ADIE: Permiso de interrupción para el conversor A/D al cuando se produce una captura o comparación
finalizar la conversión 1 = Habilita la interrupción
1 = Habilita la interrupción 0 = Inhabilita la interrupción
0 = Inhabilita la interrupción
bit 1 TMR21E: Permiso de interrupción para el TMR2 con su
bit 5 RCIE: Permiso de interrupción para el receptor del desbordamiento.
USART cuando el bufferse llena 1 = Habilita la interrupción
1 = Habilita la interrupción 0 = Inhabilita la interrupción
0 = Inhabilita la interrupción
bit 0 TMR1IE: Permiso de interrupción para el TMR1 con su
bit 4 TXIE: Permiso de interrupción para el transmisor del desbordamiento.
USART cuando el buffer se vacía 1 = Habilita la interrupción
1 = Habilita la interrupción 0 = Inhabilita la interrupción
0 = Inhabilita la interrupción
Nota: P S P IE no existe en los PIC16F873/873A/876/876A
(m odelos de 28 term inales que no tienen el P S P )__________
b it 7 b it 0
bit 7 PSPIF'1) : Señalizador (de interrupción) del puerto bit 2 CCP1IF: Señalizador (de interrupción) del módulo CCP1
paralelo Esclavo (PSP) al realizar una operación de lectura MODO CAPTURA:
/escritura 1 = El registro del CCP captura el valor del registro TMR1
1 = Se ha producido una operación de R/W (desactivar por (valor del Timerl) (desactivar por software)
software) 0 = No se produce la captura del registro TMR1
0 = No se ha producido operación de R/W. MODO COMPARACIÓN:
1 = Coinciden el valor del CCP con el valor del TMR1
bit 6 ADIF: Señalizador (de interrupción) del conversor A/D al
0 = No coinciden
finalizar la conversión
MODO PWM (modulación de pulsos en anchura): no se usa
1 = La conversión A/D está completada
0 = La conversión A/D no está completada bit 1 TMR2IF: Señalizador (de interrupción) por coincidencia
de TMR2 con PR2
bit 5 RCIF: Señalizador (de interrupción) del receptor del
1 = Se produce la coincidencia
USART cuando el bufferse llena
0 = No se produce la coincidencia
1 = Buffer lleno
0 = Buffer no lleno bit 0 TMR1IF: Señalizador (de interrupción) por
bit 4 TXIF: Señalizador (de interrupción) del transmisor del desbordamiento (overflow) del TMR1
1 = Desbordamiento del TMR1 (desactivar por software)
USART cuando el bufferse vacía
0 = No desbordamiento del registro TMR1
1 = Buffer vacío
0 = Buffer no vacío Note 1: PSPIE no existe en los PIC16F873/873A/876/876A
bit 3 SSPIF: Señalizador (de interrupción) del puerto serie (modelos de 28 terminales que no tienen el PSP)
síncrono (SSP)
1 = Se ha producido la condición de interrupción del SSP, es
decir, se ha producido una transmisión/recepción (desactivar
por software antes de salir de la RAI)
0 = No se produce condición de in6terrupción de SSP
Página | 184
Anexos
A2.9. CCPxCON
Bits
3-0 Bits de selección del modo de funcionamiento del módulo CCPx j
CCPxMO
00 00 Módulo CCPx desactivado (resetea el módulo CCPx)
00 Modo Captura Captura cada flanco de bajada
01 Modo Captura Captura cada flanco de subida
01
10 Modo Captura Captura cada 4 flancos de subida
11 Modo Captura Captura cada 16 flancos de subida
El terminal CCPx es iniciado en bajo 0 y se pone en alto t cuando el resultado de la
Modo comparación es positivo, es decir, cuando TMR1 alcanza el valor del registro de16 bits
00
Comparación ([Link]). El bit CCPxIF se activa y se pone a 1
El terminal CCPx es iniciado en alto T y se pone en bajo 0' cuando el resultado de la
Modo comparación es positivo, es decir, cuando TMR1 alcanza el valor del registro de16 bits
01
Comparación (CCPRxH:CCPRxL). El bit CCPxIF se activa y se pone a 1 '
10 El bit CCPIF es puesto a 1 cuando el resultado de la comparación es positivo, es decir, generación
10 Modo de interrupción software cuando se produce la igualdad. El terminal CCPx no se ve afectado
Comparación
Página | 185
Programación de microcontroladores PIC en lenguaje C
A2.10. ADCONO
R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 U-0 R/W-0
R E G IS T R O ADCONO ADCS1 A D C S0 CH S2 CH S1 ADON
CH S0 G O /D O N E#
(dirección 1Fh)
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bitO
bit 7-6 ADCS1:ADCS0: Selección del reloj para bit 5-3 CHS2:CHS0:
la conversión A/D (en los PIC16F87x y Selección del canal de conversión
versiones “antiguas”) y junto con ADCS2 que 000 = Canal 0 100 = Canal 4
está en ADCON1 (en los PIC16F87x A) 001 = Canal 1 101= Canal 5
010 = Canal 2 110 = Canal 6
Frecuencia del reloj del
A D C S1 :A D C S0
Fuente convertidor A/D
011= Canal 3 111= Canal 7
de reloj
A DCS2 = 0 A D CS2 = 1 bit 2 GO/DONE#:
Oscilador Estado de la conversión
00 Fosc/2 Fosc/4
principal Si ADON=1:
01 Oscilador
Fosc/8
1 = Conversión en progreso
Fosc/16
principal 0 = Conversión finalizada
Oscilador
10
principal
Fosc/32 Fosc/64 bit 0 ADON:
167 KHz
Bit de encendido del convertidor A/D
Oscilador 167 KHz
11 RC a a 1 = Módulo A/D encendido
interno 500 KHz 500 KHz 0 = Módulo A/D apagado
A 2 .ll. ADCON1
R/W-0 R/W-0 U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0
(d irecció n 9Fh)
bit 7
bit 7 ADFM : Selección de formato del bit 3-0 PCFG3:PCFG0: Configuración de las
resultado entradas al módulo A/D
1 = Ajuste a la derecha PCFG 3
AN7 AN6 AN5 AN4 AN3 AN2 AN1 ANO
0 = Ajuste a la izquierda V M f. V (tE F-
RE2 RE1 REO RA5 RA3 RA2 RA1 RAO
PCFG 0
A D FM = 0 T 1 A D FM = 1
0000 A A A A A A A A V dd Vss
j Resultado 10 bits h 0001 A A A A V „ f r. A A A RA3 V ss
0010 D D D A A A A A Veo vss
0011 D D D A A A A RA3 V ss
I I I II I I lYl N°H°H-I |j|o|o|o|o|oj 111 I 11 I 0100 D D D D A D A A V od Vss
0101 D D D D D A A RA3 Vss
A D R ESH A D R ESL A D R ESH A D R ESL -
011x D D D D D D D D
1110 A v 00 Vss
(No existe en los PlC16F87x y versiones D D D D D D D
D: digital y A; analógica
Página | 186
Anexos
A2.12. CVRCON
R/W-0 R'W-fl
R E G IS T R O C V R C O N
(d irecció n 9Dh)
A2.13. CMCON
Página | 187
Programación de microcontroladores PIC en lenguaje C
A 2 .1 4 . TXSTA
RAV-0 R-1 RW-0
REGISTRO TXSTA
(dirección 0810 SYHC ^ TRIrTT J TX90
bit 1 bit O
B t 7 C S R C : Bit para la selección de reloj Bit 2 BRGH Selección del modo de funcionamiento
Modo asincrono del generador interno.
Se ignora Modo asincrono
Modo síncrono 1 = Alta velocidad
i = Master (reloj generado por el módulo BRG) 0= Baia velocidad
0= Slave (reloj externo) Modo síncrono
Bit 6 TX9 Habilitación de la transferencia en Se ignora
modo 9 bits Bit 1 TRMT: Indicador de estado del registro de
1 = Transmisión 9 bits desplazamiento de transmisión
0 = Transmisión 8 bils 1 = Registro T S R vacio
Bit 5 TXEN Habilitación de la transmisión O = Registro T S R lleno
1 = Transmisión habilitada Bit O TX9D. Noveno bit de transmisión de datos
0 = Transmisión deshabitada (puede ser el bit de pandad).
Bit 4 S Y N C Selección de modo
1 = Síncrono
O = Asincrono
A2.15. RCSTA
REGISTRO RCSTA
(dirección 18h)
Bit 7 SPEN; Bit para la selección de reloj. Bit 3 ADDEN Detección de dirección
1 = USART ON Modo asincrono 9-bits (RX9=1)
0 = USART OFF 1 = Permite detección de dirección, habilita la interrupción y la
Bit 6 RX9: Habilitación de la recepción en modo 9 carga del buffer de recepción cuando RSR<Q> está a T
bits 0 = Deshabita la detección de dirección, se reciben todos los
1 =Tx9bits 0 = Tx8bits bits y el bit 9 puede utilizarse como bit de pandad
Bit 5 SREN Recepción de 1 bit Bit 2 FERR- Indicador de error de trama
Modo asincrono 1 = Error
Se ignora 0 = Sin error
Modo síncrono - Master Bit 1 OERR: Error por desbordamiento del registro de
1 = Habilitada O = Deshabitada desplazamiento
Modo síncrono - Slave 1 = Error
Se ignora 0 = Sin error
Bit 4 CREN Recepción continua Bit 0 RX9D: Noveno bit de recepción de datos (puede
Modo asincrono ser el bit de pandad)
1 = Habilitada 0 = Deshabitada
Modo síncrono
1 = Habilitada mientras hasta que CREN es 0
O = Deshabitada
A2.16. PCON
U-0 U-0 U-0 U-0 U-0 U-0 RAV-0 R/W-1
R e g istro P CO N
PO R» BOR»
(d irecció n 8Eh)
bit 7 bitO
bit 7-2 Unimplemented: No implementado. Se lee como ’0‘
bit 1 POR (Po w er-o n R e se t Sta tu s bit): Indica si el reset es por encendido o conexión de la alimentación.
0 = Cuando se produce el reset por encendido (debe ponerse a 1 por software después de que ocurra el reset por encendido)
1 = No se produce reset por encendido
bit 0 BOR (Brow n -o ut R e s e t Statu s bit): Indica si el reset es por caída de tensión.
0 = Cuando se produce el reset por caída de tensión (debe ponerse a 1 por software después de que ocurra el reset por caída
de tensión)
1 = No se produce reset por caída de tensión
Página l 188
Anexos
A 2 .1 7 . S S P S T A T
MODO SPI
R/W-0 R/W-0 R-0 R-0 R-0 R-0 R-0 R-0 Valores de los bits después de un rese'
Registro SS P S T A T SMP CKE D/Á P S R/W UA BF R = el bitse puetíeleer ¡
(dirección 94h) W = el bitse puede escribid
bit 7 bitO x = Valor desconocido
1 = Transmite cuando la señal de reloj pasa de '1' a ‘0’. Sólo en modo recepción
0 = Transmite cuando la señal de reloj pasa de '0’ a '1 1 = Recepción completa, SSPBUF lleno
Se utiliza sóloenmodoPC.
bit 4 P (S t o p bit): Bit de parada
Se utiliza sólo en modo PC. Se pone a 0 cuando el módulo
| MSSP está des habilitado (SSPEN=0)
modo i2c
R/W-0 R/W-0 R-0 R-0 R-0 R-0 R-0 R-0 |Valores de los bits después de un resetj
Registro SS P S T A T SMP CKE D/Á P S R/W UA BF R = elbitse puede leer
(dirección 94h) W = el bitse puede escribir
bit 7 bitO x = Valor desconocido
bit 7 SMP (Slew rate control bit;.- Control de velocidad bit 3 S (S ta rt bit): Bit de inicio
1 = Indica que se ha recibido un bit de inicio.
Maestro o esclavo 0 = Indica que no se ha detectado bit de inicio.
1 = Control habilitado para velocidades estándar (100KHz Se pone a '0' en un Reseto al apagar el módulo
y 1 MHz)
0 = Control deshabilitado para modo alta velocidad (400 bit 2 R/W (R e ad /W rite in fo rm a tio n b'rt)
KHz). Esclavo Maestro
1=Lectura. 1 = Transmisión en curso
bit 6 CKE (S M B U S S e l e c t bit) 0 = Escritura 0 = No hay transmisión en curso
1 = Habilita entradas específicas SMBus.
0 = Deshablllta entradas específicas SMBus. bit 1 UA (U pd a te a d d r e s s b'rt): Sólo para modo 10-bit
esclavo)
bit 5 D/A (D a ta / A d d re s s bit)
1 = El usuario debe actualizarla dirección SSPADD.
Reservado en modo maestro 0 = No se necesita actualizarla dirección SSPADD
Esclavo
bit 0 BF (B u ffe r fu li s t a t u s bit): Bit indicadorde buffer lleno.
1 =EI último byte reclbidoes un dato.
Modo Transmisión
0 = El último byte recibidoes una dirección.
1 = Recepción completa, SSPBUFIIeno
bit 4 P (S t o p bit): Bit de parada. 0 = Recepción incompleta. SSPBUFvacio
1 = Indica que se ha recibido un bit de stop. Modo Recepción
0 = Indica que no se ha detectado bit de stop. 1 = Transmisión en proceso, SSPBUFIIeno
Se pone a '0' en un Reseto al apagar el módulo 0 = Transmisión completa, SSPBUF vacio
Página | 189
Programación de microcontroladores PIC en lenguaje C
A2.18. SSPCON
MODO SPI
R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 [valores de los bits después de un resetj
Registro SSPCO N R = el bitse puede leer
W C O L SSPO V SSPEN CKP SSPM3 SSPM2 SSPM1 SSPMO
(dirección 14h) W = el bit se puede escribir
x = Valor desconocido
bit 7 W C O L (W rite C o llis io n D e t e c t b it): bit indicador de bit 4 CKP ( d o c k p o la r ity s e l e c t b it ): Bit de selección de
colisión. polaridad del reloj.
1 = Colisión en el envío de datos (debe limpiarse por
1 = Estado alto ‘1’ inactivo.
software).
0 = Estado bajo ‘0’ inactivo.
0 = No hay colisión.
bits 3:0 SSPM3:SSPM0 ( S y n c h r o n o u s s e r i a l p o r t m o d e
bit 6 SSPOV ( R e c e iv e O v e rflo w In d ic a to r bit): bit
s e l e c t b it s ) : Bits de selección del modo de funcionamiento
indicador de desbordamiento.
del módulo SPI
SPJ esclavó
1 = Hay colisión en la recepción de datos (debe limpiarse
0101 = SPI esclavo dock = SCK, control SS deshabilitado
por software.
0 = No hay desbordamiento. 0100 = SPI esclavo dock = SCK, control SS habilitado
bit 5 SSPEN ( S y n c h r o n o u s S e r ia l P o r t E n a b le bit): 0100 = SPI maestro, dock = TMR2/2
Habilita el módulo MSSP.
1 = Habilita el módulo MSSP y asocia los terminales SCK, 0100 = SPI maestro, dock = Fose/ 64
SDO. SDI y SS al módulo. 0100 = SPI maestro,dock= Fose/16
0 = Deshabilita el módulo MSSP y configura los terminales
0100 = SPI maestro, dock = Fose/4
como puertos E JS .
Cuando se habilita el módulo sus pines se deben configurar B resto de combinaciones están reservadas o se utilizan
adecuadamente comoentradas/salidas únicamente en modo l2C
MODO l2C
R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 |Valores de los bits después de un reseij
Registro SSPCO N R = elbitse puede leer
W CO L SSPO V SSPEN CKP SSPM3 SSPM2 SSPf.11 SSPMO
W = el bitse puede escribir
(dirección 14h) x = Valor desconocido
bit 7 W C O L (W rite C o llis io n D e t e c t b it): bit indicador de bit 4 CKP ( S C K r e le a s e c o n t r o l b it): Bit de liberación de
colisión. reloj.
Transmisión Master/Slave 1 = Libera reloj.
1 = Colisión en el envío de datos (debe limpiarse por 0 = Mantiene el reloj en bajo.
software).
0 = No hay colisión. bits 3:0 SSPM3 rSSPMO ( S y n c h r o n o u s s e r ia l p o rt m o d e
s e l e c t b its ): Bits de selección del modo de funcionamiento
bit 6 SSPOV ( R e c e iv e O v e rflo w In d ic a to r bit): bit
del módulo LC
indicador de desbordamiento.
Modo recepción 1111 = l2C esclavo, 10-bitcon interrupciones Start&Stop
1 = Hay colisión en la recepción de datos (debe limpiarse
por software. 1110 = l2C esclavo, 7-bltcpm omterri'copmes Start& Stop
0 = No hay desbordamiento. 1011 = I2C maestro controlado por Firmware
bit 5 SSPEN ( S y n c h r o n o u s S e r ia l P o rt E n a b le bit):
1000 = l2C maestro,clock= Fosc/(4*(SSPADD+1))
Habilita el módulo MSSP.
1 = Habilita"iTmódulo MSSP y asocia los terminales SDA 0111 = l2C esclavo, direcciones 10-bit
SCL al módulo. 0110= l2C esclavo, direcciones 7-bit
0 = Deshabilita el módulo MSSP y configura los terminales
como puertos E/S. B resto de combinaciones están reservadas o se utilizan
únicamente en modo SPI
Cuando se habilita el módulo sus pines SDA y SCL se deben
configurar adecuadamente comoentradas/salidas
Página | 190
Anexos
A 2 .1 9 . S SP C O N 2
MODO l2C
R/W-0 R/W-0 RWf-0 RIW-0 R/VJ-0 RW-0 RW-0 RW-0 ¡Valores délos bits después de un resed
Registro S S P C O N 2 GCEN ACKSTAT ACKDT ACKEN RCEN PEN RSEN SEN R =elbitse puede leer
(dirección 91h) W = e l bitse puedeescribirj
b it 7 b itO x = Valor desconocido
bit 7 GCEN (G e n e r a l c a li e n a b le bit) - Modo esclavo. bit 3 RCEN ( R e c e iv e e n a b le bit) - Modo maestro
1 = Habilita interrupciones cuando recibe OOOOh (general 1 = Habilita el modo de recepción l2C.
calladdress). 0 = Recepción deshabilitada.
0 = Deshabilita interrupciones al recibir OOOOh.
bit 2 PEN (S to p co n d itio n e n a b le bit) - Modo maestro
bit 6 ACKSTAT (A c k n o w le d g e s ta t u s bit) 1 = Inicia la secuencia de Stop. Se pone a '0’ al finalizar
Afedo transmisión maestro 0 = Secuencia de Stop deshabilitada.
1 = No se ha recibido confirmación de recepción del
esclavo. bit 1 RSEN (R e p e a t e d s ta rt c o n d itio n e n a b le d bit) - Modo
0 = Se ha recibido confirmación de recepción del esclavo. maestro
1 = Inicia la secuencia de Restar! Se pone a '0' al finalizar.
bit 5 ACKDT (A c k n o w le d g e data bit) 0 = Secuencia de Restartdeshabilitada.
Atodo recepción maestro
1 = No confirmar bit 0 SEN (S ta rt co n d itio n e n a b le d /stre tch bit)
0 = Confirmar Modo maestro
Valor transmitido cuando el usuario inicia una secuencia de 1 = Inicia la secuencia de Star! Se pone a ‘0’ al finalizar.
confirmaciónal final de la recepción. 0 = Secuencia de Start deshabilitada.
bit 4 ACKEN (A c k n o w le d g e s e q u e n c e e n a b le bit) Modo egc[avo
Afecto recepción maestre? 1 =Stretch de reloj habilitado en recepción y transmisión.
1 = Inicia la secuencia de confirmación. Se pone a 0 al 0 =Stretch de reloj habilitado en transmisión.
finalizar.
0 = Secuencia de confirmación desactivada.
Página | 191
A3. Introducción a MPLAB-IDE/MPLAB-SIM
con Hi-Tech
A3.0. Instalación
A3.1. Configuración
A3.2. Creación del proyecto
A3.3. Creación del fichero fuente
A3.4. Compilación del proyecto
A3.5. Simulación del proyecto
A3.6. Observando el funcionamiento
A3.7. Generador de estímulos
A3.0. Instalación
Para utilizar el entorno de programación MPLAB IDE es necesario instalar el programa, en particular
se utilizará el software "MPLAB IDE v.8.89" que se puede descargar desde la página de microchip en
la sección downloads.
[Link]
[Link]
Página | 193
Programación de microcontroladores PIC en lenguaje C
A3.1. Configuración
Es importante que los bits de la palabra de configuración tengan los valores adecuados en función
de la aplicación. Eso se puede hacer de dos formas:
1) entrando en:
Configure > Configuraron Bits
Si se necesita cambiar alguna de las opciones que aparecen se deberá desactivar la casilla:
"Configuration Bits set in code" (figura inferior), ya que si está activada solo admite como palabra
de configuración la que venga especificada en el programa fuente.
I Configuration Bits 0 B ®
0 Configuraron Bits sel in code.
=r~ r Cscillacor \—
V.&zc'r.áca Direr c-~
Pov/er Up [Link] Cíf
3rown Out Deteco On
rr 1:': Ve Icace Frcorar. Di¿'¿oled
Daca El Read Procecc Off
Flash Frocrar Wnte Write Prccection
Code Procecc Off
Este método tiene la ventaja frente al camino Configure > Configuration Bits (comentado
anteriormente) de que al estar escrito en el programa fuente siempre va a determinar la palabra de
configuración, aunque se realicen modificaciones en el programa o se cambie de ordenador o de ICD2.
Página | 194
Anexos
BHB88B
3) Seleccionar la herramienta a utilizar ("Active Toolsuite") que debe ser Microchip HI-TECH
Universal ToolSuite. Al hacerlo, nos aparecen en la ventana siguiente las herramientas disponibles
(Toolsuite Contents), como se puede observar en la siguiente figura. Esas herramientas deben ser:
HI-TECH ANSI C Compilen Y en la ventana siguiente (Location) debe figurar la trayectoria completa
de esos tres programas ejecutables:
Página | 195
Programación de microcontroladores PIC en lenguaje C
Si esa trayectoria está incompleta o es errónea se debe pulsar "Browse" para localizarlo.
4) El siguiente paso es asignarle un nombre al proyecto. Debe estar en el mismo directorio donde se
encuentres los programas con el código fuente en caso de que ya existan y es conveniente darle el
mismo nombre para localizar mejor todo lo concerniente a un mismo ejercicio.
Para eso, en ia ventana "Create New Project File", pulsar en "Browse" y acceder al subdirectorio en
el que se esté trabajando.
5) La pantalla siguiente pregunta qué ficheros se van a incorporar al proyecto. En el caso de que ya
existan se deben seleccionar y añadir (pulsar en "Add"). Es conveniente que en la ventana de la
derecha y a la izquierda de la trayectoria figure una "A" (indica automático).
Página | 196
Anexos
Aparece entonces una pantalla con un resumen del proyecto que se va a crear:
Project W izard
Sumrnary
Proiecl Parameters
Device PIC16F877A
ÍAlo new workspace will be created. and (he new proiec» added
lha( workspace
Ayuda
Si esos datos no son correctos se deberá pulsar "Atrás" y corregir donde sea oportuno. Si son
correctos, se puede pulsar en "Finalizar" con lo que se terminará de crear el proyecto y se saldrá del
"Project Wizard".
Página | 197
Programación de microcontroladores PIC en lenguaje C
Una vez creado el proyecto se abrirá MPLAB junto con las ventanas de navegador del proyecto y la
ventana "Output" además de aparecer una nueva barra de herramientas como la que aparece a
continuación, que permitirán compilar el código fuente.
Se pueden añadir archivos y salvar proyectos pulsando el botón derecho del ratón desde la ventana
de proyecto. Los ficheros también se pueden borrar manualmente seleccionándolos y utilizando el
botón derecho del ratón.
Para crear el programa se puede utilizar cualquier editor de texto en caracteres ASCII y hay que
tener en cuenta las normas programación en C. descritas en el primer capítulo.
Página | 198
Anexos
En la siguiente figura se puede observar que el fichero no tiene todavía un nombre (untitled) y que
todo el texto tiene el mismo color.
Al guardar el fichero debe tener la extensión ",c". Para eso hay que tener cuidado con el formato y
en la ventana "tipo" debe estar seleccionada la opción: "All Source Files".
Guardar como s s
1 C -ja tó ra , ' El n i o t e ? m i*
|Untiled i Guardar |
Enccdng ¡ANSI v
Tras guardar el programa fuente, el texto aparece en diferentes colores, que diferencian las
instrucciones, los comentarios, constantes, etc, como se puede ver a continuación. Esos colores se
pueden configurar a gusto del usuario. Para más información acudir a: Help > MPLAB Editor Help.
Página | 199
Programación de microcontroladores PIC en lenguaje C
El caso más común cuando se empieza a trabajar con MPLAB es que, tras intentar compilar, en la
pantalla aparezca un mensaje semejante a este:
B u i l d C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P R U E B A S \ H i - l f o r d e v i c e
16F877A
U s i n g d r i v e r C : \ A r c h i v o s d e p r o g r a m a \ H I - T E C H S o f t w a r e \ P I C C \ 9 .8 3 \ b i n \ p i c c . e x e
M a k e : T h e t a r g e t " C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P R U E B A S \ P 3 _ l .p l "
i s o u t o f date.
E x e c u t i n g : " C : \ A r c h i v o s d e p r o g r a m a \ H I - T E C H S o f t w a r e \ P I C C \ 9 .8 3 \ b i n \ p i c c . e x e " --
p a s s l " C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P R U E B A S \ P 3 _ l .C " - g --
c h i p = 1 6 F 8 7 7 A - P - - r u n t i m e = d e f a u l t , + c l e a r , + i n i t , -kee p , + o s c c a l , - d o w n l o a d , -
r e s e t b i t s , - s t a c k c a l l , + c l i b - - o p t = d e f a u l t , + a sm, - d e b u g , - s p e e d , + s p a c e , 9 - - w a r n = 0 -
D D E B U G =1 - - d o u b l e = 2 4 - -f l o a t = 2 4 - - a d d r q u a l = i g n o r e - g - - a s m l i s t
errformat=Error [%n] %£; % l . % c %s " " - - m s g f o r m a t = A d v i s o r y [ % n ] %s "
w a r n f o r m a t = W a r n i n g [%n] %f; % l . % c % s"
E r r o r [192] C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P R U E B A S \ P 3 _ l . C; 1 4 . 1
u n d e f i n e d i d e n t i f i e r "TRIS"
E r r o r [192] C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P R U E B A S \ P 3 _ l . C ; 2 4 . 5
u n d e f i n e d i d e n t i f i e r "i"
E r r o r [312] C:\Documents and S e t t in g s \ c m iz . IE E \ E s c rito rio \ P R U E B A S \ P 3 _ l. C/ 2 6 . 1
expected
E r r o r [195] C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P R U E B A S \ P 3 _ l .C; 2 9 . 0
Página | 200
Anexos
expression syntax
E r r o r [300] C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P P . U E B A S \ P 3 l.C; 29.0
une x p e c t e d e n d o f file
En la última línea se puede leer: "BUILD FAILED", es decir, el compilador HI-TECH no ha sido capaz
de generar un fichero hexadecimal y por tanto no se podrá simular el comportamiento del
programa ni mucho menos grabarlo en la memoria del PIC.
Además, en la pantalla "output" también podemos tener disponible otras informaciones, como
"messages", "warnings" y "errors". De estos tres tipos, el más Importante, porque impide la
generación del fichero hexadecimal son los "errors", mientras que los otros dos tipos no impiden el
ensamblado del programa fuente. Pasemos a comentarlos a continuación:
Es importante tener en cuenta que la eliminación de estos errores simplemente permite obtener un
fichero ejecutable, pero no aporta ninguna Información acerca de si el programa funcionará o no
correctamente.
° A d verten cias (W arning). Estos mensajes no impiden la obtención del fichero hexadecimal,
pero advierten de algo que al programa ensamblador le parece extraño. Es conveniente
comprobarlos todos.
Para tratar los mensajes, el camino más rápido es hacer doble clic en la línea del fichero "output"
en la que está el mensaje. Eso hace que el cursor se ponga en la línea del programa fuente que da
lugar a la aparición de ese mensaje permitiendo corregirlo. A continuación, el fichero fuente se
graba de nuevo, "File > Save", y se vuelve a ensamblar: "Project > Build Air'. El proceso se repite
hasta que estén corregidos todos, momento en el que HI-TECH consigue generar el fichero
hexadecimal, apareciendo una pantalla donde se puede leer"BUILDSUCCEEDED".
M a k e : T h e t a r g e t " C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z . I E E \ E s c r i t o r i o \ P R U E B A S \ P 3 _ l .pl"
i s o u t o f d a te.
E x e c u t i n g : " C : \ A r c h i v o s d e p r o g r a m a \ H I - T E C H S o f t w a r e \ P I C C \ 9 .8 3 \ b i n \ p i c c .e x e " --
p a s s l " C : \ D o c u m e n t s a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r i o \ P R U E B A S \ P 3 _ l .C" -q - -
c h i p = 1 6 F 8 7 7 A - P - - r u n t i m e = d e f a u l t , + c l e a r , +init, -keep, + o s c c a l , - d o w n l o a d , -
r e s e t b i t s , - s t a c k c a l l , + c l i b - - o p t =default,+asm,-debug,-speed,+space,9 --warn=0 -
D __ D E B U G = 1 - - d o u b l e = 2 4 - - f l o a t = 2 4 - - a d d r q u a l = i g n o r e -g - - a s m l i s t
e r r f o r m a t = E r r o r [in] if; i l . i c is" " - - m s g f o r m a t = A d v i s o r y [ i n ] is"
w a r n f o r m a t = W a r n i n g [in] if; i l . i c is"
E x e c u t i n g : " C : \ A r c h i v o s d e p r o g r a m a \ H I - T E C H S o f t w a r e \ P I C C \ 9 .8 3 \ b i n \ p i c c . e x e " -
o H i - l . c o f - m H i - l . m a p ~ - s u m m a r y = d e f a u l t , - p s e c t , - c l a s s , + m e m , - h e x - - o u t p u t = d e f a u l t ,-
inhx032 P3_l.pl - -chip=16F877A -P - - r u n t i m e = d e f a u l t , + clear, + i n i t , - k e e p , + o s c c a l , -
Página | 201
Programación de microcontroladores PIC en lenguaje C
download,-resetbits,-stackcall,+clib - - o p t = d e f a u l t , +asm, - d e b u g , - s p e e d , + s p a c e , 9 --
w a r n = 0 - D __D E B U G = 1 - - d o u b l e = 2 4 ~ - f l o a t = 2 4 - - a d d r q u a l = i g n o r e - g - - a s m l i s t
e r r f o r m a t = E r r o r [in] if; t i . t e t s" ”- - m s g f o r m a t = A d v i s o r y [ i n ] is "
w a r n f o r m a t = W a r n i n g [in] if; t i . t e is "
HI-TECH C C o m p i l e r f o r P I C 1 0 / 1 2 / 1 6 M C U s (Lite Mode) V9.83
Copyright (C) 2 0 1 1 M i c r o c h i p T e c h n o l o g y Inc.
(1273) Omniscient Code G e n e r a t i o n not available in Lite mode (warning)
M e m o r y Summary:
Program space u sed 7l h ( 113) of 2 0 0 Oh w o r d s < 1.4i)
Data space used 8h ( 8) of 1 7 Oh bytes < 2 .2 i)
E E P R O M space used Oh ( 0) of 1 0 Oh bytes ( [Link])
Configuration bits used lh ( 1) of (100. Oi)
lh word
ID L o c ation space used Oh ( 0) of 4h bytes ( [Link])
Loaded C:\Documents a n d S e t t i n g s \ c r u i z .I E E \ E s c r i t o r io \ P R U E B A S \ H i - 1 . c o f .
Este último apartado que hace referencia a la utilización de la memoria del PIC cobra especial
importancia a la hora de desarrollar aplicaciones complejas ya que será un indicador de la
necesidad de migrar hacia un microcontrolador con mayores prestaciones. Esta información
también está accesible de forma gráfica a través del menú ViewIMemory Usage Gauge como se
muestra en la siguiente figura.
Página | 202
Anexos
o
o
0038 2208 120A USA O AD3A00 1903 2904 3A64 •"...... :•••)d:
O
0040 1903 2846 3A0D1903 2846 2SEE0825 0 034 ..F(.:.. F(.(%...
0048 1383 0800 00A9 0A84 0800 OOAA3002 00A2
OpcodeHex M
achine Sym
bolic
Esta simulación se puede realizar utilizando el simulador por software MPLAB-SIM que viene
incluido con MPLAB IDE, como se explicará a continuación.
MPLAB-SIM es un simulador para los microcontroladores PIC que viene integrado en el entorno
MPLAB IDE. Permite modificar el programa y ejecutarlo a continuación, introducir estímulos
externos y observar la ejecución del programa objeto.
Para arrancar el simulador es necesario indicar que se va a utilizar la herramienta MPLAB SIM y para
ello se accederá al menú:
Página | 203
Programación de microcontroladores PIC en lenguaje C
Nuestro programa está listo para ser ejecutado. Debemos introducir ahora la frecuencia que va a
tener el oscilador.
Debugger > Settings > Osc/Trace
En primer lugar, es conveniente que el simulador empiece por ejecutar la primera instrucción del
programa, para eso se debe realizar un "reset'' del procesador:
O también se puede actuar sobre el teclado o sobre el ¡cono correspondiente de la siguiente lista:
Página | 204
Anexos
En la siguiente pantalla aparece una flecha verde en el margen izquierdo de la ventana donde está
escrito el programa fuente. La flecha apuntará siempre a la primera instrucción que se va a ejecu ar
en cuanto se dé la orden de ejecución.
A partir de aquí existen tres posibilidades de ejecutar el programa: paso a paso, en modo animado
V total.
1) Paso a paso (Step). En esta modalidad, la CPU ejecuta las instrucciones una a una cada vez que
se acceda al menú:
Debugger > Step Into
Ejecutando el programa de esta manera es posible observar el valor de las variables colocando el
cursor sobre ellas.
Página | 205
Programación de microcontroladores PIC en lenguaje C
2) Modo animado (Anímate). En este caso, la CPU ejecuta las instrucciones una tras otra sin
esperar. Se activa en el menú:
También en este caso se puede observar el valor de las variables en ese instante colocando el
cursor sobre ellas.
3) Total (Run). En este modo, la CPU ejecuta el programa completo, es decir desde la primera hasta
la última instrucción. Se activa en:
Debugger > Run
En este caso, si al colocar el cursor sobre una variable no aparecerá el valor que tiene en ese
instante. Para observarlo, primero se deberá detener la ejecución del programa.
Página | 206
Anexos
Cualquiera de esas posibilidades proporciona información acerca del estado del microcontrolador
durante la ejecución del programa. El inconveniente es que tanto el contenido de los registros
como su dirección pueden estar en hexadecimal por lo que es bastante engorroso. Además, hay
que tener en cuenta que en programas complejos pueden ser muchos los valores que cambian con
cada instrucción, lo que dificulta el seguimiento de unas pocas variables.
Con eso aparecerá una nueva ventana como se observa en la siguiente figura en la que se pueden
seleccionar tanto los registros de funciones especiales (SFR) como los símbolos (variables) que se
quieren visualizar.
Página | 207
Programación de microcontroladores PIC en lenguaje C
Una vez que se tiene en la ventana el símbolo se puede escoger el formato en el que aparecerá
representado seleccionándolo y apretando el botón derecho del ratón para entrar en sus
propiedades. Ahí se podrán escoger varias opciones:
Symbol: símbolo
Size: número de bits a observar
Format: formato (aquí podemos escoger también un solo bit, binario, decimal, ascii...)
También se puede situar el cursor sobre la barra "address" y actuar sobre el botón derecho del
ratón. Eso permitirá escoger entre diferentes formatos de presentación como se muestra en la
figura inferior.
Address. .. S y n fc o l M am e
✓ Address .•\esulrada
I ✓ Symbol Ñame
<✓ V a lu é
\/ Hex
<✓ Decimal
- v« Binary
_ y' Char
✓ Update
Comment
More..
Página | 208
Anexos
Además de visualizar el valor que se almacena en cada uno de los registros o variables del
programa a veces es conveniente ver cómo evolucionan durante la ejecución del mismo. Para eso
se puede utilizar el visualizador de señales "Simulator Logic Analyzer" que se encuentra en el menú
View.
Esta utilidad permite mostrar el valor que han ido tomando una o varias señales cuando se detiene
la ejecución del programa o cuando este se ejecuta en modo animado. Para ello basta con pulsar el
botón Channels y elegir el terminal que se desea visualizar o bien agrupar varios terminales de
forma conjunta formando un bus de datos.
Logic Analyzer ! _E
Trigget Posilion TnggetPC= Time Base Mode
S lo t® C e n t e i EndO Now Clear Cyc v Simple Channels
1+ .gil q j q J qa|yl#¡& |
I______I_____ I____ I I I
008 005 00F 001
i i i i i i i i 1 i i * i i i i i i i i i i i— i— i— i— i— i— i— i— |— i— i— |— |— |— i— i— |— [-
0,0 200,0 400,0 600,0 800,0 1000,0 1200,0 1400,0
Página | 209
Programación de microcontroladores PIC en lenguaje C
El simulador MPLAB SIM dispone también de una herramienta que permite simular estímulos
externos tales como pulsadores, entradas de reloj etc. Este simulador evalúa los estímulos y genera
todas las respuestas en los límites de cada ciclo de instrucción (Tcy = 4-Tosc). Por ese motivo,
algunos sucesos físicos no pueden simularse con precisión, en particular los sucesos puramente
asincronos y los sucesos de periodo más corto que un ciclo de instrucción.
Los estímulos permiten generar señales para el simulador y serán de gran uti i a a a ora
probar el funcionamiento de los programas cuando no se dispongan de herramientas a icion
como por ejemplo debuggers.
Debugger > Stimulus > New Workbook
Ptbuggf , Prcg-tmmer Tool: [Link] V/indon Hdp
SetectTool Checksum: 0x7d7d t- tí- p) 0* (P ® © I
■d E CJi Q 3 0
Ckar Menú
Stimulus - [Untitleó]
Hit
Sltp Into Arjrxh P»i/ n e g-Je tA d v s^ re d fV i/F le g Ja OoAStmA.1 IWji’tiliU lun Pegi’a >iae
Step Ovtr
Wiih U-4i Ccnrxtíi/Wtüage
Strp Out
6'tlkpcmtJ_
StopWitch
Complci Bfukpomti
itimulus New Woikbock
Proflh Oppn Woikbook
Otar Cede Covcragr Save WoiVbook
Refreih PM Si. e Woikbook Ai
Cloie Wefibook
ir r
Si se deséa eliminar un estímulo, basta con seleccionar la línea y pulsar en "Delete Row".
Una vez definidos todos los estímulos necesarios pueden activarse mientras se va simulando la
ejecución del programa. Basta con pulsar con el ratón en el botón correspondiente, por eso es
conveniente mantener abierta la ventana de los estímulos durante la simulación.
Página | 211
Programación de microcontroladores PIC en lenguaje C
Stimuius - [Untitled]
i A !Vn íh P r / Regisler Action; Advanced Pm / Registe Q ockStm ulu! Regislei Inieclón Registo Trace
Define T nggers
Enab'e Condtion Type Re-ArmDelay RCO PORTD Cllck heie lo Add Signáis • /s
a C0ND1 Cont 100 cyc 1
0 C0MD2 1x FF
□
□
Define Conditions
■ f S tim u iu s ■ (U n t it le d )
Acynch Pin /Regnfer Aclions Advanced Pin /Registei ClockStim Remeter Iniechon Reg'Cter Trace
Begn End
Al Stail
(§) Never
hex/label
O pc - hex/label O PC
dec
O Cytle ■ dec O Cyde -
Página | 212
Anexos
Esta opción permite almacenar en un archivo de texto los valores que van tom ando los registros,
permitiendo seleccionar el momento de comienzo y el formato en el que se alm acenarán.
P ágin a | 213
Programación de microcontroladores PIC en lenguaje C
Mediante esta herramienta es posible modificar los valores que van tomando las variables y
registros durante la ejecución del programa utilizando controles como barras de desplazamiento o
botones que aparecen en la pestaña "Dynamic Data Control" o los cuadros de control en la pestaña
"Dynamic Data Input".
DynamicDataControl DynamicData Input DynamicDataView
UserDefinedGroup 1 UserDefrnedGmup 2 User Defint
p| decimal □ Input 1 □ Input 1
Descnption 1
Esta herramienta también permite visualizar los valores almacenados en memoria de forma gráfica.
DMCI - Data Monitor Control Interface
r Q g£ O ~ p
Configurabon fie:
Página | 214
O pc HxOct C h a r D ec Hx Oct Html C hr
Este libro, elaborado por tres profesores del área de Tecnología Electrónica de la Universidad
Pública de Navarra, está pensado para servir de Introducción y apoyo práctico a todos
aquellos estudiantes de ingeniería y personas en general interesadas en el diseño electrónico
mediante la utilización de sistemas microcontroladores de 8 bits. Asi, el libro se estructura en
diferentes capítulos en los que m ediante la realización de ejercicios de diferente complejidad
se revisan los m ódulos que se encuentran generalmente integrados en estos sistemas, como
por ejem plo los puertos d g entrada /salid y d ig italesStlmDorizadores/cSñvefsór ^ á n á ^ ^ ^
com paradores y c o m u n fra c iQ b ^ n-1^ '
La m etodología empleada p e rn ^ ^ p
básicos de programación de fo á ^
ni elem entos adicionales. Todo eíl
gratuita MPLAB IDE®, que ¡ntegra un simulador: y a la
de form a online en la sección de descargas del libro e
Maícombo
9 788426 724274
MICROCONTROLADORES
La u tiliz a c ió n de m icro controlad ores perm ite resolver de manera sencilla gran cantidad
p ob le m as ele ctró n ico s cotid ia nos asociados con el control de dispositivos* sensores
ma' , a , ° reSt E c o n o c im ie n to del fun cionam iento y la programación de estos sistemas
e m b e b id o s inte gran una parte fun dam enta l del currículo para los estudiantes de ingeniería*
es p ro p o rc io n a una visión actual de la tecnología utilizada en la industria y les prepara-'para
la re a liz a c ió n de fu tu ro s proyectos basados en sistemas embebidos.
Este lib ro , elab ora do por tres profesores del área de Tecnología Electrónica de laíiíniversida
P ú b lic a de N avarra, está pensado para servir de introducción y apoyo práctico a; todo
a q u e llo s e s tu d ia n te s de ingeniería y personas en general interesadas en ef diseño eledjflnibo
m e d ia n te la u tiliz a c ió n de sistem as m icrocontroladores de 8 bits. Así, el libro se estructura
d ife re n te s c a p ítu lo s en los que m ediante la realización de ejercicios de diferente complejii
se re visa n los m ó d u lo s que se encuentran generalm ente integrados en estos sistemas¡ <^on
p o r e je m p lo los pu ertos de entrada/salida digitales, tem porizadores, conversores analógico
c o m p a ra d o re s y c o m u n ic a c io n e s serie.
Los ejemplos y ejercicios del libro están basados en la arquitectura del PIC16F877
se pueden extrapolar fácilmente a otro tipo de microcontroladores gracias al em¡á)ép
la programación en lenguaje de alto nivel ‘C . No obstante, las estructuras básica?
programación de este lenguaje se revisan en el primer capítulo del libro para aquellos m§!3
familiarizados con el mismo, mientras que los capítulos siguientes están orientado^
resolución de problemas prácticos.
La metodología empleada permite seguir los ejemplos propuestos a partir de los conocimiento,
básicos de programación de los primeros capítulos y sin la necesidad de utilizar hardwa
ni elementos adicionales. Todo ello gracias a la utilización de la h e d ie n te M B m
gratuita MPLAB ID E®, que integra un simulador, y a la descarga de los maten
de forma online en la sección de descargas del libro en [Link]
Síguenos en:
M a rco n ib o
[Link] I