BASIC PARABASIC PARABASIC PARABASIC PARA
MICROCONTROLADORES PICMICROCONTROLADORES PICMICROCONTROLADORES PICMICROCONTROLADORES PIC
Christian Bodington Esteva
Ingeniero en Electrónica
i
CONTENIDO
Prólogo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
Capítulo I. Herramientas de Diseño. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Capítulo II. MicroCode Studio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8
Capitulo III. Microcontroladores PIC.
3.1.- ¿Que es un PIC? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21
3.2.- El Oscilador Externo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25
3.3.- El Circuito de Reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.4.- Consideraciones técnicas de diseño. . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.4.1.- Estado Lógico de un pin I/O. . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.4.2. Lectura de un estado lógico en un pin I/O. . . . . . . . . . . . . . . 33
3.4.3. El Opto-acoplador. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4.4. Fuente de poder, 5Vdc / 3.3Vdc. . . . . . . . . . . . . . . . . . . . . . . 37
Capítulo IV. Estructura de un programa. Componentes y operadores en
PicBasic.
4.1.- Estructura de un programa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.2.- Subrutinas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
4.3.- Componentes y operadores en PicBasic. . . . . . . . . . . . . . . . . . . . . . . .41
ii
4.3.1.- Define. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3.2.- Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42
4.3.3.- Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.3.4.- Constantes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.3.5.- Símbolos o Alias. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.3.6.- Operadores Aritméticos. . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
4.3.7.- Operadores Binarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45
4.3.8.- Operadores de Comparación. . . . . . . . . . . . . . . . . . . . . . . . 46
4.3.9.- Operadores Lógicos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Capitulo V. Primeros Programas con el PIC16F84.
5.1.- Proyecto #1. Implementación de las instrucciones de programa High,
Low Goto y Pause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47
5.2.- Proyecto #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.3.- Proyecto #3. Implementación de la instrucción If-Them-Else. . . . . . . .60
5.4.- Proyecto #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.5.- Proyecto #5. Implementación de la instrucción For-Next. . . . . . . . . . . 65
5.6.- Proyecto #6. Implementación de la instrucción Frecout. . . . . . . . . . . . 68
5.7.- Proyecto #7. Implementación de la instrucción Button . . . . . . . . . . . . .76
5.7.1.- Proyecto #7.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
5.7.2.- Proyecto #7.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
5.7.3.- Proyecto #7.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
iii
5.8.- Proyecto #8. Implementación de la instrucción Branch . . . . . . . . . . . . 91
5.9.- Proyecto #9. Implementación de la instrucción PWM . . . . . . . . . . . . . 94
Capitulo VI. Módulos LCD.
6.1.- Pantallas LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
6.2.- Identificación de los pines de una pantalla LCD . . . . . . . . . . . . . . . . . 98
6.3.- Conexión de una pantalla LCD en Pic Basic. . . . . . . . . . . . . . . . . . . . 99
6.4.- Proyecto #10. Implementación de la instrucción Lcdout . . . . . . . . . . 103
6.5.- Proyecto #11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.6.- Proyecto #12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
6.7.- Proyecto #13. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .111
6.8.- Proyecto #14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .114
6.9.- Proyecto #15. Implementación de la instrucción Count. . . . . . . . . . . 115
6.10.- Proyecto #16. Implementación de la instrucción Pulsin. . . . . . . . . . 122
6.11.- Proyecto #17. Implementación de la instrucción Pot. . . . . . . . . . . . 124
6.12.- Memoria CGRAM en la Pantalla LCD. . . . . . . . . . . . . . . . . . . . . . . .127
6.13.- Proyecto #18. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
6.14.- Proyecto #19. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
Capitulo VII. Teclado Matricial.
7.1.- Teclado Matricial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
7.2.- Proyecto #20. Aplicación de un teclado 3x4. . . . . . . . . . . . . . . . . . . .154
iv
Capitulo VIII. Memoria de Datos.
8.1.- Memoria de Datos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .157
8.2.- Proyecto #21. Implementación de la instrucción Read. . . . . . . . . . . .161
8.3.- Proyecto #22. Implementación de la instrucción Write. . . . . . . . . . . .163
8.4.- Proyecto #23. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .165
8.5.- Proyecto #24. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .168
Capitulo IX. Interrupciones.
9.1.- ¿Qué son las Interrupciones?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
9.2.- Fuentes de Interrupciones. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
9.3.- Registro INTCON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
9.4.- Activación de interrupción a través del pin RB0/INT. . . . . . . . . . . . . . 177
9.5.- Proyecto #25. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
9.6.- Interrupción TMR0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .180
9.7.- Registro OPTION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181
9.8.- Proyecto #26. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
9.9.- Interrupción por cambio de estado de uno de los pines más
significativos del puerto B (RB4-RB7). . . . . . . . . . . . . . . . . . . . . . . . . . . . .186
9.10.- Proyecto #27. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .187
Capitulo X. Memoria Serial I2C.
10.1.- ¿Qué es el bus I2C?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .190
10.2.- Proyecto #28. Implementación de las instrucciones I2Cwrite, I2Cread . . 192
v
10.3.- Proyecto #29. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .196
10.4.- Proyecto #30. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198
Capitulo XI. Conversor A/D en el PIC16F877.
11.1.- Conversor A/D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .202
11.2.- El registro ADCON0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209
11.3.- El registro ADCON1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210
11.4.- Proyecto #31. Implementación de la instrucción ADCin. . . . . . . . . . 214
Capitulo XII. Comunicación Serial. Transmisión y Recepción de Datos.
12.1.- Comunicación Serial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
12.2.- Instrucción SerIn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
12.3.- Proyecto #32. Implementación de la instrucción SerIn. . . . . . . . . . . 221
12.4.- Instrucción SerOut. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233
12.5.- Proyecto #33. Implementación de la instrucción SerOut. . . . . . . . . .233
12.6.- Proyecto #34 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .240
Capitulo XIII. Servomotor.
13.1.- ¿Qué es un Servomotor?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .268
13.2.- Proyecto #35. Implementación de la instrucción PauseUs. . . . . . . . .272
13.3.- Proyecto #36. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .276
13.4.- Proyecto #37. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .280
13.5.- Proyecto #38. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .283
vi
Capitulo XIV. Módulos RF para comunicaciones.
14.1.- Módulos RF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .293
14.2.- Proyecto #39. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .296
14.3.- Proyecto #40. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .300
14.4.- Proyecto #41. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .305
Capitulo XV. Instrucciones de programa de PicBasic.
@. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
ADCin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
Asm… EndAsm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .311
Branch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .312
Button. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Call. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .315
ClearWDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .316
Count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
DTMFout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
EEPROM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .321
End. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
FreqOut. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .321
For… Next. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .323
Gosub. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
vii
Goto. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .324
High. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .324
I2Cread. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
I2Cwrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .326
IF-Then-Else. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
Input. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .328
LCDin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .329
LCDout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .330
Low. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331
NAP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Pause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .333
PauseUs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .333
Pot. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
PulsIn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
PulsOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
Random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .337
Read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
Reverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .340
Select Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .340
SerIn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .342
viii
SerOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .343
Sleep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .344
Swap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .344
Toggle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .345
While-Wend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
Write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .347
Apéndice A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .348
Apéndice B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .358
Apéndice C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .360
Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .362
Prólogo
Emprender el estudio de microcontroladores para el desarrollo de proyectos
electrónicos que sean la base para nuevas ideas es el objetivo primordial de
esta primera edición, en la cual nos hemos concentrado en dar al lector
algunas herramientas fundamentales con las cuales esperamos abrir un
campo de conocimiento en la electrónica de control, a través de un sin
numero de posibilidades de diseño a partir de una serie de ejemplos prácticos
desarrollados en lenguaje Basic para Microcontroladores PIC.
De toda la gama de posibilidades entre las familias de microcontroladores PIC
que ofrece Microchip Inc., hemos elegido para empezar el microcontrolador
más popular de toda la serie, el PIC16F84, que será utilizado en este libro
para estudiar algunas de sus características a través del desarrollo de
actividades que en principio no requieren un nivel de conocimiento elevado y
a través del cual daremos los pasos necesarios para adentrarnos en las
gamas mas altas, de las que se ha seleccionado el microcontrolador
PIC16F877 para la realización de proyectos electrónicos de nivel medio y
avanzado, y en los que podremos manejar dispositivos periféricos que le dan
un gran valor agregado a cada uno de nuestros proyectos y abren
posibilidades de desarrollo muy interesantes al lector.
Además, hemos considerado proporcionar la información adecuada referente
a las herramientas de desarrollo más importantes en la actualidad, para
programación en lenguaje Basic para microcontroladores PIC. En esta
ocasión iniciamos con el estudio del compilador PicBasic Pro, de la empresa
microEngineering Labs, Inc., la cual ofrece una de las herramientas mas
populares en el área, debido a que cuenta con una gran variedad de
instrucciones que hacen de la programación de microcontroladores una tarea
fácil y muy productiva a la hora de desarrollar proyectos que involucren
periféricos como pantallas LCD, teclados matriciales, sensores de
temperatura, presión, gas, humedad, memorias de datos entre otros, y donde
una de las características más relevantes es el considerable ahorro de
tiempo, lo que se traduce en efectividad y menos líneas de programa, de tal
2
manera que el diseñador puede prestar mayor atención a los detalles,
logrando así perfeccionar su desempeño en cualquiera de las funciones que
desee programar.
Otra de las herramientas que hemos decidido incorporar a la obra, es el
programador de microcontroladores PIC P16Pro/PicAll, de la página oficial de
PicallW, de Boban Dobaj, Diseñador. Este programador soporta una gran
cantidad de modelos de las series 12, 16 y 18 de Microchip. Su construcción
es sumamente sencilla y de muy bajo costo, además de una serie de ventajas
entre las cuales podemos mencionar la alta velocidad de transferencia de
datos hacia el dispositivo al momento de ser grabado.
Cada capítulo contiene teoría sobre la cual se pretende estudiar el
funcionamiento de los microcontroladores y periféricos conectados a él. Para
ello hemos desarrollado una serie de prácticas en las que el lector deberá
hacer montajes de circuitos en base a los diagramas esquemáticos siguiendo
las instrucciones y leyendo detenidamente los comentarios de cada línea de
programa.
Esperamos con esto proporcionar al lector una base sólida de conocimientos
para el desarrollo de proyectos electrónicos, proyectos de robótica y todo
aquello que represente una innovación científica en este campo.
Finalmente, el agradecimiento para todos nuestros colaboradores en la
edición de esta publicación, quienes se han encargado de revisar cada
detalle, proyectos e ideas plasmadas en cada capitulo.
Ingeniero en Información, Maria del Carmen Lara T.
Ingeniero en Electrónica, Jesús Frank Phorlakis.
Técnico Superior en Electricidad, Raúl Mastropasqua.
3
Herramientas de Diseño Capitulo I
En la elaboración de proyectos electrónicos con microcontroladores PIC,
resulta muy importante considerar una serie de herramientas, las cuales
vamos a describir a continuación:
Software: para la programación en Lenguaje Basic, contamos con una gran
variedad de posibilidades en el mercado, y entre las cuales hemos elegido
para esta primera edición, el Ambiente Integrado de Desarrollo Microcode
Studio (IDE) de microEngineering Labs, Inc., además del compilador Basic,
PICBasic Compiler, o PICBasic Pro Compiler. Con estas dos herramientas
estaremos realizando la programación en cada uno de los proyectos
propuestos a partir del capítulo V.
Figura 1.1.
(Fuente: http://www.microengineeringlabs.com)
4
• Programador de Microcontroladores PIC: es una herramienta
indispensable con la cual podemos grabar el código generado por el
compilador PicBasic para poner en funcionamiento cada uno de los
proyectos propuestos en cada capítulo. Existen en internet una gran
cantidad de modelos de programadores para microcontroladores PIC,
de muy bajo costo y fácil construcción. Consideramos una buena
experiencia realizar el montaje de cualquiera de estos diseños, aunque
en esta oportunidad nuestra recomendación es el programador
P16Pro/Picallw. Los detalles para la construcción de este programador
están contenidos en el apéndice A.
Figura 1.2.
5
• Placa de prototipos: proporciona al diseñador conexiones sin
soldaduras, con lo cual se hace más práctico el desarrollo de los
proyectos electrónicos propuestos a lo largo de cada capítulo.
Figura 1.3.
• Multímetro digital: este instrumento de medición será muy útil durante
la elaboración de los circuitos propuetos en cada capítulo.
Figura 1.4.
6
• Fuente de poder regulada con salida de voltaje variable. En el capítulo
III se propone la construcción de una fuente de poder regulada a 5 Vdc
y 3.3 Vdc.
Figura 1.5.
• Herramientas de corte, extractor de circuitos integrados, cable rígido
para conexiones en la placa de prototipos.
Figura 1.6.
7
• Osciloscopio: este instrumento se requiere para el desarrollo de
algunas prácticas en las cuales se hace necesario medir las señales
generadas desde el microcontrolador.
Figura 1.7.
• Componentes electrónicos: microcontroladores PIC en los modelos
definidos en cada ejemplo práctico, resistencias, diodos, servomotores,
condensadores, cristales y otros componentes de fácil adquisición.
Cada proyecto cuenta con una tabla en la cual se decriben los
componentes electrónicos que deberán ser utilizados en el cada
montaje.
Figura 1.7.
8
Microcode Studio Capitulo II
Microcode Studio (IDE), es un Ambiente Integrado de Desarrollo de
MECANIQUE, diseñado especialmente para microEngineering Labs, Inc.,
de libre adquisición a través de la página Web
http://www.microengineeringlabs.com
Figura 2.1.
(Fuente: http://www.microengineeringlabs.com)
Descargar este programa es muy sencillo y esto lo podemos hacer
ingresando a la siguiente dirección:
http://www.microengineeringlabs.com/resources/win_ide.htm
En esta página se puede encontrar una sección destinada para la descarga
del archivo instalador, como se observa en la figura 2.2:
9
Figura 2.2.
(Fuente: http://www.microengineeringlabs.com)
Además de esta herramienta, es necesario adquirir el compilador PicBasic,
(Figura 2.3). Se puede acceder directamente a la página de productos de
microEngineering Labs a través de la dirección:
http://www.melabs.com/products/index.htm
Figura 2.3.
(Fuente: http://www.microengineeringlabs.com)
Es posible descargar una versión DEMO del compilador PIC Basic, con la
cual se pueden compilar programas con un máximo de 31 líneas de código, a
través de la dirección: http://www.melabs.com/pbpdemo.htm
10
Figura 2.4.
(Fuente: http://www.melabs.com)
Para empezar la descarga del archivo de instalación del compilador, solo hay
que hacer clic en el link señalado en la figura 2.4, e indicar la ruta en la cual
se desea que el archivo de instalación sea almacenado.
Nota Importante: Es necesario adquirir una de las versiones completas del
compilador Basic, para no tener límites en la cantidad de líneas del programa
a compilar.
En la figura 2.5 se puede observar el archivo descargado para la versión
disponible del software Microcode Studio, y en la figura 2.6 se puede observar
el archivo del compilador PicBasic Pro en su versión de prueba.
Figura 2.5. Figura 2.6.
Haga clic en el Link aquí
señalado, para descargar la
versión Demo de PicBasic.
Pro
11
El proceso de instalación es muy sencillo. El primer paso será ejecutar el
archivo mcsinstall.exe, el cual es el responsable de iniciar el proceso de
instalación de Microcode Studio:
Figura 2.7.
Seguidamente Microcode Studio le da la bienvenida en la ventana que se
muestra a continuación:
Figura 2.8.
12
Haga clic en el botón “Next” y podrá ver en la siguiente ventana el acuerdo de
licencia para Microcode Studio:
Figura 2.9.
La ruta por defecto para la instalación de Microcode Studio es C:Archivos de
programaMecaniqueMCS. Esta ruta puede ser cambiada haciendo clic en el
botón “Browse”, a través del cual se podrá ubicar la nueva carpeta en la cual
deberá ser instalado el software:
Figura 2.10.
Nombre de la carpeta en la cual se
encontrará el archivo ejecutable de
Microcode Studio.
13
Pulse “Next” para iniciar la copia de archivos (figura 2.11), y finalmente espere
que se complete la instalación (figura 2.12).
Figura 2.11.
Figura 2.12.
14
Una vez instalado Microcode Studio, es importante tomar en cuenta que antes
de iniciar este software, es necesario instalar el compilador Basic, el cual es
indispensable para la generación del código que será cargado en el
microcontrolador PIC.
Instalación del compilador PicBasic Pro:
Para dar inicio a la instalación del compilador Pic Basic, será necesario
ejecutar el archivo denominado “pbpdemo.exe” para el caso de la versión de
demostración. La figura 2.13 muestra la ventana de inicio del proceso de
instalación, en la cual se da la bienvenida al usuario y le invita a cerrar
cualquier otra aplicación que se encuentre en uso en ese momento.
Figura 2.13.
En la siguiente ventana se debe especificar la unidad de disco duro en la cual
se instalará el compilador y el nombre de la carpeta que va a contener los
archivos a ser instalados. El software de instalación del compilador establece
por defecto la ruta indicada en la figura 2.14.
15
Figura 2.14.
Seguidamente se debe especificar el nombre de la carpeta que va a contener
los accesos directos a los archivos que ofrecen información adicional acerca
del compilador PicBasic. Este paso puede ser omitido seleccionando la opción
“Don’t create a Start Menu Folder”:
Figura 2.15.
16
Una vez seleccionadas las rutas de instalación del compilador, se debe hacer
clic en el botón “Install” (figura 2.16), para dar inicio a la copia de archivos.
Figura 2.16.
Figura 2.17.
17
Figura 2.18.
Finalmente se puede ver en la ventana de la figura 2.18, un mensaje en el
cual se confirma que el compilador PICBasic Pro ha sido instalado
satisfactoriamente. Deshabilite la opción “Install Microcode Studio IDE” y
seguidamente haga clic en el botón “Finish”.
Nota: Puede descargar la documentación completa del compilador PicBasic a
través de la dirección: http://www.melabs.com/support/index.htm
18
Integración de Microcode Studio y Pic Basic Pro:
Es importante integrar Microcode Studio con el compilador PicBasic Pro,
indicando la ruta en la cual se encuentra instalado. Para esto debemos iniciar
el software y seguir las siguientes instrucciones:
1. Desde el menú de Inicio de Windows ejecute “Microcode Studio”.
Figura 2.19.
2. Haga clic en el menú “View” y seleccione la opción “Compile and
Program Options”.
Figura 2.20.
19
3. En la pestaña “Compiler” haga clic en el botón “Find Automatically”
para una ubicación automática del compilador, o si lo prefiere haga clic
en “Find Manually” para ubicar el compilador manualmente.
Figura 2.21.
4. En la pestaña “Programmer” se pide la ubicación del software del
programador que estaremos utilizando para grabar los
microcontroladores.
Figura 2.22.
20
Se debe ubicar en la lista el programador “PICALL Programmer”, haciendo
clic en el botón denominado “Add New Programmer” (Figura 2.22), y
seguidamente se debe seleccionar de la lista de opciones, como se puede
observar en la figura 2.23:
Figura 2.23.
Por último, al hacer clic en el botón “Next”, el software realizará la búsqueda
automática de la carpeta que contiene el archivo ejecutable del programador
Picall, el cual ha debido ser instalado según el procedimiento descrito en el
Apéndice A.
21
Microcontroladores PIC Capitulo III
3.1. Que es un PIC?
Los PIC son una familia de microcontroladores desarrollados y fabricados por
la empresa Microchip Technologies Inc., los cuales cuentan con una
tecnología tipo RISC (Reduced Instruction Set Computer) y poseen en su
arquitectura interna características especiales que varían según el modelo de
PIC que deseamos utilizar.
Podríamos decir que estos dispositivos se asemejan a una computadora pero
de tamaño muy reducido, ya que cuentan con casi los mismos recursos que
éstas, es decir, poseen memoria de programa, memoria RAM, memoria de
datos, puertos de entrada o salida, temporizadores y en algunos casos
cuentan con recursos adicionales como convertidores A/D, comparadores,
USART (Universal Synchronous/Asynchronous Receiver/Transmitter),
comunicación serie I2C, entre otros.
Con todas estas características es lógico pensar que este dispositivo pasa a
ser el corazón del circuito a ser controlado. Esto significa que el
microcontrolador es el encargado de dirigir todos los procesos de un circuito
electrónico, en base a las instrucciones de programa o rutinas que definen
funciones específicas de control, donde las mismas serán realizadas en
lenguaje Basic para microcontroladores PIC. Es por esta razón que
consideramos muy importante estudiar la arquitectura interna del
microcontrolador que se desea programar y aunque esta tarea pueda parecer
difícil, el Lenguaje Basic para microcontroladores PIC la hace sumamente
sencilla.
El diseño de programas para microcontroladores PIC va acompañado
normalmente con un previo estudio del diseño del hardware que hará que
nuestros proyectos se pongan en marcha. Es decir, resulta absolutamente
necesario saber cual será la función específica de cada pin; por ejemplo, en el
caso de los puertos I/O (IN/OUT) a ser utilizados en el microcontrolador, es
importante definir sus funciones antes de empezar a programar, ya que éstos
pueden ser configurados a conveniencia como entrada o como salida de
datos de forma independiente. También podemos destinar un puerto completo
22
del microcontrolador para el control de dispositivos periféricos como pantallas
LCD, teclados, motores paso a paso, leds, servomotores entre otros. De ahí la
importancia de establecer cual será la función de cada puerto del
microcontrolador PIC elegido para nuestros proyectos.
Otra decisión importante será elegir convenientemente el modelo de
microcontrolador a ser utilizado, ya que hay una gran gama de modelos que
pueden ser adaptados a necesidades específicas de diseño.
Figura 3.1.
Los microcontroladores PIC comúnmente más utilizados son los siguientes:
• PIC12C508 y PIC12C509, tienen memoria de programa EPROM,
oscilador interno, y son muy utilizados en diseños de pequeños
circuitos.
• PIC16F84A, tiene memoria de programa tipo FLASH, oscilador
externo, 13 pines I/O entre otras características que estaremos
estudiando a lo largo del contenido de esta obra. Este PIC ha
resultado ser uno de los más populares de toda la serie.
• PIC16F87X, incluyen un gran número de mejoras en comparación
con el PIC16F84, debido principalmente a que cuentan con un
numero de pines I/O superior a éste, además de otras
características relevantes. Por ejemplo, con esta serie de
microcontroladores contamos con una mayor capacidad en cuanto
a memoria de programa y memoria de datos.
23
• PIC18F4XX, estos microcontroladores resultan muy útiles cuando
deseamos diseñar proyectos más avanzados.
Cada uno de estos microcontroladores cuenta con una completa hoja de
datos que puede ser descargada de la página oficial de Microchip:
http://www.microchip.com
Estas características influyen directamente al momento de decidir que modelo
de microcontrolador PIC deseamos utilizar en nuestros proyectos, según sea
el objetivo de diseño del circuito que deseamos realizar.
El microcontrolador PIC16F84 es uno de los microcontroladores más
populares y en algunos casos, el preferido por estudiantes para dar inicio al
estudio de la programación de microcontroladores, seguido del PIC16F877 el
cual posee más recursos importantes que estaremos estudiando a
continuación.
Antes de empezar a revisar todo lo referente a la programación de
microcontroladores PIC, consideramos importante recordar algunas de las
características de éstos dispositivos, para tener una base de conocimientos
básicos para poder realizar un programa de control de un diseño
completamente personalizado.
Para empezar, veamos algunas características del microcontrolador
PIC16F84:
• Microcontrolador de 8 Bits.
• Memoria de programa tipo Flash de 1024 palabras de 14 bits.
• Memoria RAM de 68 bytes.
• Memoria EEPROM de datos de 64 bytes.
• Velocidad de operación de hasta 20 Mhz.
• Cuatro fuentes de interrupción.
• Posee 13 pines I/O (pines de entrada o salida).
24
Diagrama de pines del PIC16F84:
Figura 3.2.
PIN Identificación Descripción del Pin
1 RA2 Pin de Entrada/Salida (I/O) del puerto A
2 RA3 Pin de Entrada/Salida (I/O) del puerto A
3 RA4/TOCKI Pin de Entrada/Salida (I/O) del puerto A
4 MCLR Reset y entrada de voltaje de programación.
5 Vss Pin de Alimentación a Tierra (GND)
6 RB0/INT Pin de Entrada/Salida (I/O) del puerto B
7 RB1 Pin de Entrada/Salida (I/O) del puerto B
8 RB2 Pin de Entrada/Salida (I/O) del puerto B
9 RB3 Pin de Entrada/Salida (I/O) del puerto B
10 RB4 Pin de Entrada/Salida (I/O) del puerto B
11 RB5 Pin de Entrada/Salida (I/O) del puerto B
12 RB6 Pin de Entrada/Salida (I/O) del puerto B
13 RB7 Pin de Entrada/Salida (I/O) del puerto B
14 Vdd Pin de Alimentación de 5Vdc
15 OCS2/CLKOUT Salida del oscilador a cristal.
16 OSC1/CLKIN Entrada del oscilador a cristal o fuente externa de reloj.
17 RA0 Pin de Entrada/Salida (I/O) del puerto A
18 RA1 Pin de Entrada/Salida (I/O) del puerto A
Tabla 3.1
25
El microcontrolador PIC16F84 cuenta con dos puertos I/O, el puerto A, el cual
consta de cinco pines I/O y el puerto B, el cual consta de ocho pines I/O como
se puede observar en la figura 3.3:
Figura 3.3.
En total se cuenta con trece pines I/O, los cuales pueden ser programados
como entrada o salida según convenga al momento de diseñar un circuito de
control.
Los pines correspondientes al oscilador (OSC1 y OSC2) y al reset (MCLR)
deben ser siempre tomados en cuenta en el diseño de nuestros proyectos. Es
por este motivo que damos inicio al estudio de algunos circuitos
indispensables para el correcto funcionamiento del microcontrolador PIC.
3.2. El Oscilador Externo.
Es un circuito indispensable para el funcionamiento del microcontrolador y el
cual además, define la velocidad a la cual va a trabajar. Para hacer funcionar
nuestro diseño podemos elegir entre las siguientes cuatro opciones:
• Oscilador LP: Oscilador de bajo consumo (Low Power).
• Oscilador XT: Cristal / Resonador.
26
• Oscilador HS: Oscilador de alta velocidad (High Speed).
• Oscilador RC: Resistencia / Condensador.
En los modos de oscilador LP, XT y HS el cristal debe ser conectado a los
pines 15 y 16, Osc2/CLKout y Osc1/CLKin respectivamente, como se muestra
en la figura 3.4.
Figura 3.4.
Los valores de los condensadores cerámicos vienen dados según la tabla que
se muestra a continuación:
Modo Frecuencia Osc1/CLKin Osc2/CLKout
LP
32 kHz
200 kHz
68 - 100 pF
15 - 33 pF
68 - 100 pF
15 - 33 pF
XT
2 MHz
4 MHz
15 - 33 pF
15 - 33 pF
15 - 33 pF
15 - 33 pF
HS
4 MHz
10 MHz
15 - 33 pF
15 - 33 pF
15 - 33 pF
15 - 33 pF
Tabla 3.2
27
Por ejemplo, para un oscilador tipo XT, podemos utilizar un cristal de cuarzo
como el de la figura 3.5.
Figura 3.5.
Al conectar el microcontrolador a la fuente de alimentación de 5 Vdc y medir
la señal de salida del oscilador XT con un osciloscopio, en el pin 15
(Osc2/CLKout) del microcontrolador, podremos ver la onda generada bajo los
siguientes parámetros de medición seleccionados en el equipo:
• Voltios/Div: 200mV
• Time/Div: 100ns
Figura 3.6.
28
La lectura de la frecuencia y período en este caso sería la siguiente:
• Frecuencia: 3,972 Mhz
• Período: 251,71 ns
Cristal de cuarzo TTL: Este tipo de cristal consta de cuatro pines, de los
cuales solo tres están implementados de la siguiente manera:
Figura 3.7.
Pin 1: NC (Este pin no se encuentra conectado internamente)
Pin 7: GND
Pin 8: Salida TTL
Pin 14: +5Vdc
En su salida se obtiene un tren de pulsos como se puede observar en la figura
3.8, bajo los siguientes parámetros de medición seleccionados en un
osciloscopio:
• Voltios/Div: 2V
• Time/Div: 100ns
29
Figura 3.8.
La lectura de la frecuencia y período en este caso sería la siguiente:
• Frecuencia: 3,999 Mhz
• Período: 250,013 ns
El oscilador externo en modo RC resulta ser el más sencillo de todos y por
ende el más económico. Su configuración lo hace menos preciso debido a
que existe una tolerancia de error en sus componentes, sin olvidar también
que la temperatura puede afectar la operación de este tipo de oscilador.
Los valores recomendados para este oscilador son los siguientes:
• 5 Kohm ≤ R1 ≤ 100 Kohm
• C1 > 20 pF
30
Figura 3.9.
3.3. Circuito de Reset: El Pin denominado MCLR (Master Clear), siempre
debe ser tomado en cuenta cuando se diseña un circuito con
microcontroladores PIC. A través de este Pin se podrá reiniciar el dispositivo,
si a éste se le aplica un nivel lógico bajo (0V), por lo tanto resulta importante
destacar que para que un programa cargado en un microcontrolador se
mantenga en ejecución, el Pin MCLR debe estar siempre en un nivel lógico
alto (5V).
Si deseamos tener control externo del reset de un microcontrolador PIC,
debemos considerar el circuito de la figura 3.10:
31
Figura 3.10.
Este circuito permite reiniciar el microcontrolador cada vez que el pulsador P1
es presionado.
3.4. Consideraciones técnicas de diseño:
A continuación veremos algunos circuitos básicos que deben ser tomados en
cuenta para el desarrollo de prácticas con microcontroladores PIC. Estos
circuitos son muy útiles cuando deseamos visualizar el resultado de una
acción programada en el microcontrolador.
3.4.1. Estado Lógico de un pin I/O:
Una manera muy sencilla de ver el estado lógico de un pin configurado como
salida en cualquiera de los puertos de microcontrolador es a través del uso de
LEDs, como se observa en los circuitos de la figura 3.11.
32
En el primer circuito, el LED se iluminará solo cuando el estado lógico del pin
de salida del puerto sea igual a “1”, es decir, 5 voltios.
En el segundo circuito, el LED se iluminará solo cuando el estado lógico de la
salida del puerto sea igual a “0”, es decir, 0 voltios.
Figura 3.11.
Esto significa que si deseamos realizar un programa en Lenguaje Basic
encargado de cambiar el estado lógico de un pin específico, en cualquiera de
los puertos de un microcontrolador, una forma “básica” de visualizar este
cambio es a través del uso de LEDs.
33
3.4.2. Lectura de un estado lógico en un pin I/O:
El microcontrolador también nos permite capturar datos o señales externas
para luego ser procesadas y convertidas en respuestas que pueden definir
una acción específica en nuestros circuitos de prueba. Un ejemplo común
podría ser el uso de un pulsador para hacer destellar un led cada vez que
éste sea presionado.
Si deseamos introducir un nivel lógico bajo (0V), o alto (5V), a una de las
entradas de un microcontrolador a través de un pulsador, podríamos
considerar los circuitos de la figura 3.12, los cuales nos proporcionan dos
formas diferentes de hacerlo:
Figura 3.12.
34
El primer circuito en la figura 3.12 mantiene un nivel lógico alto (5V) mientras
el pulsador permanece abierto. Al presionar el pulsador, el nivel lógico en el
pin I/O del puerto pasa a ser bajo (0V).
El segundo circuito de la figura 3.12 mantiene un nivel lógico bajo (0V)
mientras el pulsador permanece abierto. Al presionar el pulsador, el nivel
lógico en el pin I/O del puerto pasa a ser alto (5V).
3.4.3. El Opto-acoplador:
El opto-acoplador es un componente muy útil cuando se requiere acoplar
circuitos electrónicos digitales con etapas de manejo de potencia o con otros
circuitos.
Este componente en una de sus versiones, se compone básicamente de un
diodo LED el cual se encarga de iluminar un fototransistor, para que éste
conduzca corriente a través del colector.
Figura 3.13.
35
En la configuración de la figura 3.13, cuando en el pin I/O aplicamos un 1
lógico (5V), el LED del opto-acoplador enciende y el fototransistor conduce la
corriente a tierra; por lo tanto, en la salida tendremos un 0 lógico (0V).
Si apagamos el LED, el transistor no conduce, de tal manera que en la salida
tendremos un 1 lógico (5V).
En la configuración de la figura 3.14, cuando en el pin I/O aplicamos un 1
lógico (5V), el LED del opto-acoplador enciende y el fototransistor conduce
para poner en la salida un 1 lógico (5V). Mientras haya un 0 lógico en la
entrada, el fototransistor permanecerá abierto entre el emisor y colector,
dando como resultado un 0 lógico (0V) en la salida.
Figura 3.14.
Una configuración muy común para el control de dispositivos de potencia
como motores eléctricos, luces incandescentes, solenoides, etc., se puede ver
en la figura 3.15, la cual se basa en cualquiera de los dos circuitos antes
mencionados (figura 3.13 y figura 3.14), en la cual se ha incluido un relé a
36
través del cual circulará la corriente necesaria entre sus contactos, para hacer
funcionar cualquiera de estos dispositivos de potencia.
Figura 3.15.
37
3.4.4. Fuente de poder, 5Vdc / 3.3Vdc:
En caso de no disponer de una fuente de poder regulada, proponemos la
construccion de un diseño sencillo que podemos implementar en todos los
proyectos propuestos. En la figura 3.16 se puede observar el diseño de una
fuente regulada con salidas de voltaje de +5 Vdc y +3.3 Vdc:
Figura 3.16.
38
Estructura de un programa.
Componentes y operadores en PicBasic. Capitulo IV
4.1.- Estructura de un programa: Para que nuestros programas tengan una
apariencia ordenada y se facilite la comprensión del mismo ante otros
programadores que deseen realizar mejoras a éste, es necesario establecer
una estructura que nos permita identificar fácilmente cada una de las partes
que lo componen.
Figura 4.1.
En la figura 4.1 se puede observar la estructura básica de un programa hecho
en Microcode Studio, y en la cual hemos identificado las cuatro secciones que
consideramos más importantes para lograr un programa bien estructurado.
A
B C D
39
Sección A: Corresponde al encabezado del programa, en el cual se debe
considerar información básica del mismo, como el nombre, la identificación
de autor, Copyright, fecha de elaboración o fecha de los últimos cambios
realizados, versión del programa que se está realizando, e incluso una breve
descripción acerca del objetivo del programa y su aplicación en un
determinado circuito electrónico.
Es importante resaltar que cada línea del encabezado debe empezar con una
comilla simple, en forma de comentario (ver “Sección D”).
Sección B: Esta sección empieza en la columna cero del editor de texto de
Microcode Studio, y en ella se pueden declarar las definiciones (concepto que
estudiaremos mas adelante) y las etiquetas de cada una de las subrutinas
que serán programadas.
Las etiquetas identifican puntos específicos o subrutinas dentro de un
programa. Son definidas por el programador y deben tener al final de cada
una de ellas el símbolo de “dos puntos”, que definen el final de la misma.
Sección C: Estará destinada para las instrucciones de programa y la misma
está separada de la columna cero del editor de texto por una tabulación, es
decir, cuando el cursor se encuentra en la columna cero, presionamos una
vez la tecla “TAB”, y de esta manera establecemos un espacio mínimo,
siempre igual o superior entre la sección B y C.
Sección D: Esta destinada para realizar comentarios acerca de la función que
estará cumpliendo una instrucción específica en nuestro programa. Cada
comentario debe empezar siempre con una comilla simple como se muestra a
continuación:
' Define el Oscilador para un Cristal
' de 4 Mhz.
Cuando un comentario es demasiado extenso, podemos continuar el mismo
en la siguiente línea, siempre que la frase comience con su respectiva comilla.
40
Los comentarios ayudan al diseñador a identificar cada línea de programa o
cada una de las funciones de cada subrutina, garantizando así una buena
documentación en cada uno de los programas que realizamos.
4.2.- Subrutinas: Una subrutina se presenta como un algoritmo separado del
algoritmo principal, y estará destinado a resolver una tarea específica. Las
subrutinas pueden ser referidas cada vez que sea necesario, llamando a la
etiqueta que corresponde a ésta, la cual debe ir siempre al inicio de la misma.
Led1:
For Z = 0 To 9
LED = Encendido
Pause 1000
LED = Apagado
Pause 1000
Next Z
GoTo Inicio
End
Subrutina
Etiqueta
41
4.3.- Componentes y operadores en PicBasic.
PIC Basic cuenta con una serie de herramientas de programación entre las
cuales podemos mencionar las etiquetas, variables, identificadores,
constantes, comentarios, símbolos entre otras.
Algunas de estas herramientas son de uso obligatorio a la hora de realizar un
programa, y otras que no son de uso obligatorio, nos facilitarán el trabajo
considerablemente.
4.3.1.- Define: La directiva “Define” resulta muy importante en la
programación de microcontroladores con PicBasic, ya que establece una
serie de parámetros que de no ser tomados en cuenta, causará que nuestros
programas sencillamente no funcionen en la mayoría de los casos.
Esta serie de parámetros están directamente relacionados con dispositivos
externos al microcontrolador. Por ejemplo, si deseamos utilizar un oscilador
de diferente frecuencia al valor establecido por defecto (4 Mhz), será
conveniente entonces definir la velocidad del mismo utilizando la directiva:
Define Osc {frecuencia}
De igual forma deben ser considerados estos parámetros para el uso de
dispositivos como pantallas LCD, donde se deberán definir los puertos de
conexión para el bus de datos y bus de control. Así mismo ocurre para el caso
de las comunicaciones seriales o I2C, donde los parámetros también deben
ser definidos. Veamos a continuación la tabla de parámetros para el uso de la
instrucción Define.
42
Parámetro Descripción
OSC {frecuencia} Frecuencia del Oscilador en Mhz
LCD_DREG {puerto} Puerto de datos LCD
LCD_DBIT {bit} Bit inicial del puerto de datos
LCD_RSREG {puerto} Puerto para RS (Register Select)
LCD_RSBIT {bit} Pin del Puerto para RS
LCD_EREG {puerto} Puerto para E (Enable)
LCD_EBIT {bit} Pin del Puerto para E
LCD_RWREG {puerto} Puerto para RW (Read/Write)
LCD_RWBIT {pin} Pin del puerto para RW
LCD_LINES {líneas} Número de líneas de la LCD (1,2 o 4)
I2C_SCLOUT 1 Interface de Reloj I2C Bipolar
I2C_SLOW 1
Cuando en la transferencia es utilizado un
oscilador mas lento que 8 Mhz.
Tabla 4.1.
4.3.2.- Variables: En las variables podemos almacenar datos temporalmente,
los cuales podrán ser consultados o modificados cada vez que sea necesario.
Regularmente la definición de variables se hace al inicio del programa y para
ello se utiliza la palabra VAR seguida por el tipo de variable según la tabla
que mostramos a continuación:
Nombre de
la Variable
VAR
Tipo de
Variable
Descripción
A1 Var Bit Toma los valores 0 y 1 unicamente
Temp Var Byte Toma valores entre 0 y 255 (8 bits)
dig1 Var Word Toma valores entre 0 y 65535 (16 bits)
Tabla 4.2.
El nombre de la variable es elegido por el programador y el tipo de variable se
define según el tipo de dato que se desea almacenar temporalmente.
43
4.3.3.- Arrays: Las variables Arrays tienen un determinado número de
“elementos”, definido según el tamaño de la variable. Las variables Arrays tipo
Bit, pueden almacenar 256 elementos; las variables Arrays tipo Byte pueden
almacenar hasta 96 elementos y las variables Arrays tipo Word hasta 48
elementos, los cuales a su vez pueden ser accesados en cualquiera de los
tres casos a través de un índice. Este índice se específica entre corchetes
como se muestra en los siguientes ejemplos:
Para declarar una variable Array utilizamos el siguiente formato:
Dato Var Byte[7]
El primer elemento de esta variable es Dato[0] y el último elemento es
Dato[7], lo cual significa que hemos declarado una variable array de 8
elementos. En este caso podemos almacenar un byte en cada elemento,
siempre especificando el índice.
Ejemplo: Almacenar en cada elemento de la variable “Dato” los valores 200,
15, 56, 75, 80, 20, 33, 45.
Dato[0] = 200
Dato[1] = 15
Dato[2] = 56
Dato[3] = 75
Dato[4] = 80
Dato[5] = 20
Dato[6] = 33
Dato[7] = 45
En algunos casos se debe verificar la hoja de datos del microcontrolador, ya
que la cantidad de elementos que se pueden almacenar en variables arrays
tipo Byte o Word puede variar según el modelo del mismo.
44
4.3.4.- Constantes: Ayudan a identificar un valor constante en nuestro
programa, facilitando aún más la comprensión del mismo a la hora de verificar
su funcionamiento. En la tabla 4.3 se puede observar la forma de declarar una
constante.
Nombre de la
Constante
CON
Valor de la
Constante
Temp_Max CON 150
Temp_Min CON 55
Tabla 4.3.
4.3.5.- Símbolos o Alias: Proveen un nombre único y específico a elementos
o variables dentro de nuestro programa. Para definir un símbolo, utilizamos la
palabra “Symbol”, seguida del alias del elemento, el símbolo de igualdad “=”, y
por último el elemento en cuestión:
Symbol {alias} = {elemento}
Por ejemplo, si deseamos controlar un motor DC a través de uno de los pines
del puerto A de un microcontrolador, resultaría mucho mas sencillo referirse a
este pin como “Motor”, en vez de referirse a él como “PortA.0”.
Entonces,
Symbol Motor = PORTA.0
Veamos otros ejemplos:
Symbol Relay = PORTB.0
Symbol Sensor = PORTA.0
Symbol LED = PORTA.1
Symbol RC0 = PORTC.0
45
4.3.6.- Operadores Aritméticos: Entre los operadores aritméticos más
utilizados tenemos los que se muestran en la siguiente tabla:
Operador Descripción Operador Descripción
+ Suma ABS Valor Absoluto
- Resta SIN Seno del Angulo
* Multiplicación COS Coseno del Angulo
/ División MIN Minimo de un número
// Residuo MAX Máximo de un número
<< Desplaza a la Izquierda REV Invertir un Bit
>> Desplaza a la Derecha DIG
Valor de un digito para un
número decimal
= Asignación de Valores
Tabla 4.4.
4.3.7.- Operadores Binarios: En la siguiente tabla veremos los operadores
binarios proporcionados para el Lenguaje PicBasic:
Operrador Descripción
& AND Lógico
| OR Lógico
^ XOR Lógico
˜ NOT Lógico
&/ NAND Lógico
|/ NOR Lógico
^/ NXOR Lógico
Tabla 4.5.
Con estos operadores resulta muy sencillo realizar operaciones binarias,
como lo demuestra el siguiente ejemplo:
Si aplicamos una AND lógica, donde deseamos filtrar los siete bits más
significativos del valor almacenado en la siguiente variable:
Var1 = %00101001
Entonces,
Var1 = Var1 & %00000001
46
El resultado de esta operación es Var1 = %00000001
4.3.8.- Operadores de Comparación: Los operadores de comparación
normalmente son utilizados con la instrucción If…Them… para realizar
comparaciones entre variables o datos extraídos de alguna operación
aritmética.
Operador Descripción
= Igual
<> Diferente
< Menor que
> Mayor que
<= Menor o igual que
>= Mayor o igual que
Tabla 4.6.
4.3.9.- Operadores Lógicos: Los operadores lógicos son utilizados para
establecer condiciones entre variables y son utilizados de la misma manera
que los operadores de comparación.
Operador Descripción
AND AND Lógico
OR OR Lógico
XOR XOR Lógico
NOT NOT Lógico
NOT AND NAND Lógico
NOT OR NOR Lógico
NOT XOR NXOR Lógico
Tabla 4.7.
Ejemplo:
If Var1 = 1 and Var2 = 3 And Var3 = 5 Then Goto inicio
La condición saltará a la etiqueta “inicio” solo si se cumplen las tres
condiciones.
47
Primeros Programas con el PIC16F84 Capitulo V
Para aprender a programar un microcontrolador resulta importante dar inicio
al tema con ejemplos prácticos y sencillos, que nos ayuden a comprender el
funcionamiento de la arquitectura del PIC y las instrucciones de programa que
se están empleando.
El primer paso entonces será realizar el montaje del circuito con base en los
conocimientos adquiridos en las páginas anteriores. Se debe tomar en cuenta
que aunque en los diagramas de los circuitos que se muestran a continuación,
no están presentes los pines de alimentación “Vcc” y “Gnd”, éstos deben ser
conectados debidamente a la fuente de alimentación de 5 Voltios.
A medida que se van proponiendo ejemplos de aplicación práctica, estaremos
estudiando la sintaxis de las instrucciones empleadas en cada proyecto para
facilitar la comprensión general de éste, referente a la programación y diseño
electrónico.
5.1.- Proyecto #1: A continuación realice el montaje de la figura 5.1, en base
al cual realizaremos la programación necesaria para encender dos Leds
conectados a los puertos del microcontrolador:
Figura 5.1.
48
Proyecto # 1
Componentes Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
LED 2
Resistencia de 220 Ohm 2
Fuente regulada de 5 Vdc 1
Tabla 5.1.
• El Led 1 se encuentra conectado en el pin RA0 del puerto A, el cual
deberá ser configurado como “Salida”.
• El Led 2 se encuentra conectado en el pin RB0 del puerto B, el cual
deberá ser configurado igualmente como “Salida”.
Note que el ánodo del diodo LED se encuentra conectado al pin de salida del
puerto, por lo tanto para que encienda el LED debemos hacer salir un 1 lógico
por el pin correspondiente.
Como los pines de los puertos pueden ser configurados como “entradas” o
como “salidas”, es importante tomar en cuenta los registros de configuración
de puertos, los cuales para el caso específico del PIC16F84 son dos:
TrisA (registro de configuración I/O del puerto A), es un registro de 8 bits, de
los cuales los tres más significativos no se encuentran implementados en este
modelo de microcontrolador, ya que como se puede observar en el diagrama
de pines del dispositivo (figura 3.2), el puerto A solo cuenta con 5 pines (RA0,
RA1, RA2, RA3 y RA4).
49
Un ejemplo de configuración de los pines I/O del puerto A es el siguiente:
1 1 1 1 0
RA4 RA3 RA2 RA1 RA0
Registro TrisA
Figura 5.2.
1 = Entrada (Al configurar un bit del registro TrisA en “1”, éste se comporta como entrada).
0 = Salida (Al configurar un bit del registro TrisA en “0”, éste se comporta como salida).
Al ver la figura 5.2, se puede observar que el pin RA0 ha sido configurado
como salida y el resto de los pines como entrada.
En PicBasic, este paso se realiza de la siguiente manera:
TrisA = %11110 (“%” para expresar la configuración en Binario), ó:
TrisA = $1E (“$” para expresar la configuración en Hexadecimal)
TrisB, es un registro de 8 bits en el cual se configuran los pines del puerto B,
ya sea como entrada o como salida, por ejemplo:
1 1 1 1 1 1 1 0
RB7 RB6 RB5 RA4 RA3 RA2 RA1 RA0
Registro TrisB
Figura 5.3.
1 = Entrada (Al configurar un bit del registro TrisB en “1”, éste se comporta como entrada).
0 = Salida (Al configurar un bit del registro TrisB en “0”, éste se comporta como salida).
Bit menos
significativo
Bit menos
significativo
“Recordemos entonces que como el Led 1 se encuentra conectado en el pin RA0,
el bit correspondiente a este pin en el registro TrisA ha sido configurado como
salida”.
50
Para el caso particular del puerto B, se puede observar que el pin RB0 ha sido
configurado como salida y el resto de los pines como entrada.
“Consideramos importante configurar los pines que no estarán en uso como
entrada, ya que de esta forma podemos evitar daños en el hardware interno
del microcontrolador al experimentar con éste en un tablero de pruebas.”
La configuración en PicBasic para el registro TrisB, ajustada al ejemplo de la
figura 5.3 sería entonces la siguiente:
TrisB = %11111110 (si se desea hacer la notación en binario), ó:
TrisB = $FE (si se desea hacer la notación en hexadecimal)
Antes de verificar el programa propuesto para este ejemplo, veremos la
sintaxis de las instrucciones utilizadas en él, para tener una idea clara de la
función que cumple cada instrucción. Esta información puede ser
complementada en el capítulo XV, en el cual encontrará la descripción de
cada una de las instrucciones utilizadas en cada proyecto planteado en esta
edición.
Sintaxis de las Instrucciones empleadas en el programa:
HIGH
Sintaxis: HIGH pin
La instrucción “High” pone en uno lógico un pin I/O específico.
51
LOW
Sintaxis: LOW pin
La instrucción “LOW” coloca en cero lógico un pin I/O específico.
GOTO
Sintaxis: GOTO etiqueta
La instrucción “Goto” continúa la ejecución de un programa a partir de la
etiqueta especificada (Esta instrucción no tiene retorno).
PAUSE
Sintaxis: PAUSE periodo
La instrucción “Pause” realiza una pausa en el programa por un periodo
definido en milisegundos.
Veamos el programa en PicBasic:
'****************************************
'* Nombre : Proyecto1.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
52
TRISA = %11110 ' Configuración el Puerto A
TRISB = %11111110 ' Configuración el Puerto B
PORTA = 0 ' Inicializa el puerto "A", es decir,
' se ponen todos los pines en cero.
PORTB = 0 ' Inicializa el puerto "B".
Inicio: ' Etiqueta de Inicio del programa
High PORTA.0 ' Enciente el Led conectado en el pin RA0
Pause 1000 ' Hace una pausa de 1000 milisegundos = 1
' Seg.
Low PORTA.0 ' Apaga el Led conectado en el pin RA0
Pause 1000 ' Hace una pausa de 1000 milisegundos = 1
' Seg.
High PORTB.0 ' Enciente el Led conectado en el pin RB0
Pause 1000 ' Hace una pausa de 1000 milisegundos = 1
' Seg.
Low PORTB.0 ' Apaga el Led conectado en el pin RB0
Pause 1000 ' Hace una pausa de 1000 milisegundos = 1
' Seg.
GoTo Inicio ' Salta a la etiqueta "Inicio" y se repite el
' proceso.
End
La instrucción “High” se encarga de poner un nivel lógico alto en el pin
especificado seguidamente. En este caso, primero se escribe el puerto y
seguido de un punto, se especifica el número del pin en el puerto que
deseamos utilizar.
La instrucción “Low” es responsable en este caso de poner el pin
especificado en un nivel lógico bajo. Al igual que en la instrucción “High”, se
debe especificar el puerto y el pin del puerto a ser utilizado.
La instrucción “GoTo” realiza un salto hacia una etiqueta específica; en este
caso el programa salta a la etiqueta “Inicio” para empezar de nuevo todo el
proceso.
53
Al escribir el programa en el editor de texto de Microcode Studio, se debe
grabar el mismo con el nombre de su preferencia para que éste pueda ser
compilado y al mismo tiempo pueda ser enviado al microcontrolador.
Observe que para este programa, hemos designado el nombre
“Proyecto1.pbp” (figura 5.4).
Figura 5.4.
Antes de compilar el programa, se debe asegurar de seleccionar el modelo
apropiado de microcontrolador PIC, como se observa en la figura 5.5. Luego
se compila el programa y se verifica que éste no tenga errores.
54
Figura 5.5.
Seguidamente, se debe proceder a cargar el programa compilado en el
microcontrolador con la ayuda del programador de microcontroladores Pic.
Al hacer clic en el icono “Compilar y Grabar en el PIC” (ver figura 5.5), el
compilador habrá generado un archivo de nombre “Ejemplo1.hex” y
seguidamente se abrirá el software “Picall/P16Pro”, como se observa en la
figura 5.6:
Figura 5.6.
En este momento el microcontrolador deberá estar montado en la base del
programador en la posición indicada por la figura 5.6.
Compilar
Compilar y
Grabar en
el PIC
Modelo
del uC.
55
Antes de programar el microcontrolador, también resulta conveniente verificar
los fusibles de programación, accediendo al botón “Config”, el cual puede ser
visualizado en la figura 5.6.
En esta sección se debe configurar el tipo de oscilador utilizado en nuestro
circuito, así como otras opciones disponibles que comentaremos a
continuación (ver figura 5.7).
Figura 5.7.
En la figura 5.7 se pueden observar tres secciones llamadas “Oscillator”,
“Hardware” y “Protection”:
• En la sección “Oscillator”, debemos seleccionar el tipo de oscilador
utilizado en nuestro circuito electrónico, el cual en este caso es del tipo
XT, debido a que el cristal que hemos elegido es de 4 Mhz.
• En la sección “Hardware” es posible activar el temporizador “Perro
Guardián”, el cual se encarga de reiniciar el microcontrolador en caso
de fallas o bloqueos en el programa. Para utilizar el “Watchdog” es
necesario diseñar el programa bajo ciertos parámetros, de forma que
podamos reiniciar el temporizador “Watchdog” antes de que éste se
desborde y provoque un “Reset” en el sistema. Si nuestro programa
llegara a fallar, el temporizador Watchdog completaría su conteo y se
desbordaría, provocando un “Reset” del sistema.
56
• En la sección “Hardware” también disponemos de la opción “Power Up
Timer”, la cual una vez activada en el microcontrolador, hará que éste
no pueda iniciar el programa hasta tanto el voltaje aplicado al circuito
sea estable y seguro (ver figura 5.8).
0
1
2
3
4
5
6
1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61
Tiempo
Voltios
Figura 5.8.
• En la sección “Protection”, tenemos la posibilidad de proteger el código
de programa almacenado en la memoria del microcontrolador.
Finalmente hacemos clic en el botón “Program” (ver figura 5.6), para
descargar el programa “Proyecto1.hex” en el microcontrolador;
inmediatamente se podrá ver el proceso de grabación y verificación de datos,
para luego culminar con el montaje del microcontrolador en el circuito de
prueba.
Estos pasos se deben aplicar en cada uno de los proyectos aquí planteados,
o cada vez que se desee realizar una modificación a un programa para
obtener siempre mejores resultados sobre el objetivo propuesto en cada
actividad.
57
5.2.- Proyecto #2: En este ejemplo conectaremos un Led en cada pin del
puerto B, el cual a su vez deberá ser configurado como salida para garantizar
el correcto funcionamiento del mismo. En la figura 5.9 podemos observar en
detalle la conexión del circuito eléctrico que deberá ser montado.
Figura 5.9.
Proyecto # 2
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor de 33 pF 2
LED 8
Resistencia de 220 Ohm 8
Fuente regulada de 5 Vdc 1
Tabla 5.2.
58
En el proyecto #1 se pudo observar como es posible encender un led
conectado a un pin del puerto A o B en un PIC16F84A, utilizando las
instrucciones High y Low. También existen otras formas de poner un “1” o un
“0” lógico en un pin configurado como salida; esto se puede lograr de varias
maneras:
PORTA.0 = 1 ' RA0 = 1 -> (es igual a High PortA.0)
PORTA.0 = 0 ' RA0 = 0 -> (es igual a Low PortA.0)
Cuando deseamos poner varios pines de un mismo puerto en “1”, podemos
utilizar las siguientes opciones:
PORTB = %10101010 ' RB7 = 1, RB5 = 1, RB3 = 1, RB1 = 1
' RB6 = 0, RB4 = 0, RB2 = 0, RB0 = 0
Este mismo ejemplo de configuración en hexadecimal:
PORTB = $AA ' RB7 = 1, RB5 = 1, RB3 = 1, RB1 = 1
' RB6 = 0, RB4 = 0, RB2 = 0, RB0 = 0
Recordemos que el símbolo “%” expresa la notación en binario, por lo cual se
deben expresar los ocho bits a ser cargados en el registro “PortB”. Otra forma
de expresar este ejemplo sería colocando la notación en hexadecimal con el
símbolo “$”, seguido del valor calculado.
Basados en esta información podemos lograr encender y apagar varios leds
simultáneamente conectados a uno de los puertos del microcontrolador como
lo muestra el montaje de la figura 5.9.
Veamos el siguiente programa:
'****************************************
'* Nombre : Proyecto2.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
59
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISB = %00000000 ' Configura el Puerto B como Salida
PORTB = %00000000 ' Inicializa el puerto "B".
Inicio: ' Etiqueta de Inicio del programa
PORTB = %01010101 ' Enciente las salidas RB0, RB2, RB4 y RB6, al
' mismo tiempo apaga RB1, RB3, RB5 y RB7.
Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 Seg.
PORTB = %10101010 ' Enciente las salidas RB1, RB3, RB5 y RB7, al
' mismo tiempo apaga RB0, RB2, RB4 y RB6.
Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 Seg.
GoTo Inicio ' Salta a la etiqueta "Inicio" y se repite el
' proceso.
End
Este programa enciende primero las salidas pares del puerto B y apaga las
salidas impares, genera una pausa de 1 segundo (1000 ms) y seguidamente
hace el proceso inverso en las salidas, es decir, enciende las salidas impares
y apaga las salidas pares para generar nuevamente otra pausa de 1 segundo
y así repetir el proceso completo al generar un salto a la etiqueta “Inicio”.
60
5.3.- Proyecto #3: Los pines en los puertos de un microcontrolador pueden
ser configurados también como entradas, como se detalla en el contenido del
proyecto #1, donde se explica claramente que al poner un “1” en un bit de un
registro de configuración de puerto, ya sea TRISA o TRISB, para el caso del
PIC16F84A, éste se comportará como entrada. Realice el montaje de la figura
5.10 y analice el programa que se muestra a continuación.
Figura 5.10.
Proyecto # 3
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
LED 1
Resistencia de 220 Ohm 1
Resistencia de 10K Ohm 1
Pulsador Normalmente Abierto 1
Fuente regulada de 5 Vdc 1
Tabla 5.3.
61
IF – THEM – ELSE
Sintaxis: If expresión 1 {AND / OR expresión 2} Then etiqueta
Con la instrucción If – Them podemos tomar decisiones a lo largo de un
programa, basadas en condiciones específicas definidas por el programador.
El siguiente programa hace destellar un LED conectado en RB0, solo cuado el
pulsador es activado:
'****************************************
'* Nombre : Proyecto3.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISA = %11111 ' configura el Puerto A como Entrada
TRISB = %00000000 ' Configura el Puerto B como Salida
PORTB = $00 ' Inicializa el puerto B
Inicio:
If PORTA.0 = 1 Then PORTB.0 = 1 ' Pregunta si RA0 = 1, si se cumple
' la condición entonces enciende el Led.
Pause 1000 ' Hace una pausa de 1 segundo (1000 ms)
Low PORTB.0 ' Apaga el Led
Pause 1000 ' Hace una pausa de 1 segundo (1000 ms)
GoTo inicio ' Salta a la etiqueta "Inicio"
End
Para verificar si el pulsador está activado, se pregunta si RA0 = 1. Esto es
posible gracias a la instrucción “IF” la cual genera un resultado siempre que la
condición planteada se cumpla, y para lo cual debemos utilizar
necesariamente su complemento “Then” seguido de la acción a ser tomada.
62
En este caso si el pulsador ha sido activado, entonces RA0 = 1, es decir, se
cumple la condición y por lo tanto RB0 = 1, es decir, el LED enciende.
5.4.- Proyecto #4: En este ejemplo empleamos un microcontrolador
PIC16F877A, con el cual nos hemos planteado la lectura de ocho pulsadores
conectados al puerto B, de tal manera que al activar uno de ellos podemos
mostrar un dígito decimal en un Display de siete segmentos.
Figura 5.11.
63
Proyecto # 4
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Resistencia de 220 Ohm 8
Resistencia de 10K Ohm 8
Pulsador Normalmente Abierto 8
Display de 7 Segmentos - Cátodo común 1
Fuente regulada de 5 Vdc 1
Tabla 5.4.
En el diagrama esquemático de la figura 5.11 se pueden observar ocho
pulsadores normalmente abiertos, los cuales una vez activados generan un
estado lógico alto en el puerto seleccionado (puerto “B”), el cual ha sido
configurado como entrada.
El display de 7 segmentos de cátodo común, se encuentra conectado al
puerto “D”, donde el bit menos significativo RB0 corresponde al segmento “a”
del display, RB1 corresponde al segmento “b”, RB2 corresponde al segmento
“c”, RB3 corresponde al segmento “d”, RB4 corresponde al segmento “e”, RB5
corresponde al segmento “f” y RB6 corresponde al segmento “g”.
El siguiente programa es una forma básica de tomar una lectura de cada
pulsador conectado al puerto “B” y generar un resultado en el puerto de salida
al cual hemos conectado un display de 7 segmentos:
'****************************************
'* Nombre : Proyecto4.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
64
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISB = $FF ' Configura el Puerto B como Entrada
TrisD = $00 ' Configura el Puerto D como Salida
Inicio:
' A continuación se verifica cada pin del puerto B,
' si hay un 1 lógico en alguna de las entradas el
' puerto D se actualiza con el dato correspondiente
' para generar en el Display un dígito decimal.
' gfedcba
' |||||||
If PORTB.0 = 1 Then PortD = %00111111 ' Enciende los segmentos correspondientes
' al dígito “cero” en el display.
If PORTB.1 = 1 Then PortD = %00000110 ' Enciende los segmentos correspondientes
' al dígito “uno” en el display.
If PORTB.2 = 1 Then PortD = %01011011 ' Enciende los segmentos correspondientes
' al dígito “dos” en el display.
If PORTB.3 = 1 Then PortD = %01001111 ' Enciende los segmentos correspondientes
' al dígito “tres” en el display.
If PORTB.4 = 1 Then PortD = %01100110 ' Enciende los segmentos correspondientes
' al dígito “cuatro” en el display.
If PORTB.5 = 1 Then PortD = %01101101 ' Enciende los segmentos correspondientes
' al dígito “cinco” en el display.
If PORTB.6 = 1 Then PortD = %01111101 ' Enciende los segmentos correspondientes
' al dígito “seis” en el display.
If PORTB.7 = 1 Then PortD = %00000111 ' Enciende los segmentos correspondientes
' al dígito “siete” en el display.
GoTo Inicio ' Salta a la etiqueta "Inicio"
End
65
5.5.- Proyecto #5: En el ejemplo a continuación se realiza un conteo
ascendente desde cero hasta nueve en un display de 7 segmentos conectado
al puerto “D” de un PIC16F877A.
Figura 5.12.
Proyecto # 5
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Resistencia de 220 Ohm 8
Display de 7 Segmentos - Cátodo común 1
Fuente regulada de 5 Vdc 1
Tabla 5.5.
66
FOR… NEXT
Sintaxis: For variable = inicio to final {step {-} incremento}
*
*
Instrucciones…
*
*
Next { variable}
La instrucción For…Next se encarga de hacer repeticiones de instrucciones
que permanecen dentro del lazo For… Next.
El parámetro Step afecta el incremento según el valor asignado después de
esta palabra. Si este parámetro es omitido, el incremento es en una unidad.
Analice el siguiente programa:
'****************************************
'* Nombre : Proyecto5.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
I Var Byte ' Declaración de la Variable "I" tipo Byte
' Constantes para definir cada dígito decimal en el Display:
' gfedcba
' |||||||
Cero CON %00111111
Uno CON %00000110
Dos CON %01011011
Tres CON %01001111
Cuatro CON %01100110
Cinco CON %01101101
Seis CON %01111101
Siete CON %00000111
67
Ocho CON %01111111
Nueve CON %01100111
' Configuración del Puerto de Salida:
TrisD = $00 ' Configura el Puerto D como Salida
Inicio:
For I = 0 To 9 ' Repetición de Instrucciones dentro del Lazo
' For - Next
Call Digito ' Salto con Retorno hacia la etiqueta "Digito"
Pause 1000 ' Pausa de 1 segundo (1000 ms)
Next I
GoTo Inicio ' Salta a la etiqueta "Inicio"
Digito:
' Verificación del dígito a ser mostrado en el Display el cual
' se corresponde con el valor almacenado en la variable "I".
If I = 0 Then PortD = cero
If I = 1 Then PortD = Uno
If I = 2 Then PortD = dos
If I = 3 Then PortD = tres
If I = 4 Then PortD = cuatro
If I = 5 Then PortD = cinco
If I = 6 Then PortD = seis
If I = 7 Then PortD = siete
If I = 8 Then PortD = ocho
If I = 9 Then PortD = nueve
Return ' Retorna una línea después del salto con retorno (Call)
End
Al iniciar el conteo en el display de 7 segmentos, se puede observar un
conteo ascendente que da inicio en cero y se va incrementando en una
unidad cada segundo hasta llegar a nueve.
Si deseamos realizar el incremento en más de una unidad por vez, tan solo
debemos incluir la directiva “Step”, seguido del incremento, es decir, si
queremos realizar un incremento de dos unidades por vez, entonces el lazo
For – Next se compone de la siguiente manera:
68
For I = 0 To 9 Step 2 ' Repetición de Instrucciones dentro del Lazo
' For – Next con incremento en dos unidades.
Call Digito ' Salto con Retorno hacia la etiqueta "Digito"
Pause 1000 ' Pausa de 1 segundo (1000 ms)
Next I
Esto significa que el conteo arranca en cero y cada segundo transcurrido se
podrán ver los dígitos: “2”, “4”, “6” y “8”.
Para realizar un conteo regresivo, el lazo For – Next se compone de la
siguiente forma:
For I = 9 To 0 Step -1 ' Repetición de Instrucciones dentro del Lazo
' For – Next.
Call Digito ' Salto con Retorno hacia la etiqueta "Digito"
Pause 1000 ' Pausa de 1 segundo (1000 ms)
Next I
En este caso en conteo inicia en nueve y decrece en una unidad hasta llegar
a cero.
5.6.- Proyecto #6: PicBasic cuenta con una instrucción capaz de generar
tonos DTMF (Dual Tone Multifrecuency - Multifrecuencia de doble tono), tonos
que se utilizan en telefonía para marcar una serie de números y así poder
establecer la comunicación entre dos o más personas. Una aplicación
interesante para esta instrucción podría ser el discado de números telefónicos
en sistemas de alarma cuando ha sido activado un dispositivo de supervisión,
para luego generar un mensaje de voz que nos alerte de dicho evento.
Realice el montaje de la figura 5.13 y analice el programa que se muestra a
continuación, el cual genera tonos DTMF consecutivos de una serie de dígitos
predefinidos. Es muy importante considerar que para generar los tonos
adecuadamente el oscilador externo debe ser de 10 Mhz o superior.
69
Figura 5.13.
Proyecto # 6
Componente Cantidad
PIC16F84A 1
Cristal de 10 Mhz 1
Capacitor cerámico de 33 pF 2
Capcitor Electrolítico de 10 uF 2
Parlante de 8 Ohm 1
Fuente regulada de 5 Vdc 1
Tabla 5.6.
En la tabla 5.7 se puede observar la frecuencia baja y la frecuencia alta de
cada digito entre cero y quince, los cuales se corresponden a su vez con cada
uno de los dígitos de un teclado telefónico, como se puede observar en la
segunda columna de la misma tabla.
Esto quiere decir que si generamos las frecuencias correspondientes al dígito
“1” utilizando la instrucción “DTMFout”, obtendremos las mismas frecuencias
baja y alta que se generan al pulsar el dígito “1” de cualquier teléfono de tonos
DTMF. Si deseáramos generar desde el microcontrolador el tono DTMF
70
correspondiente al dígito “0” de un teclado telefónico, entonces, según la tabla
5.7, el dígito a introducir en la instrucción “DTMFout” deberá ser el “10”.
Dígito en la
Instrucción
DTMFout
Dígito en un
Teclado
Telefónico
Frecuencias
Bajas
Frecuencias
Altas
1 1 697 HZ 1209 HZ
2 2 697 HZ 1336 HZ
3 3 697 HZ 1477 HZ
4 4 770 HZ 1209 HZ
5 5 770 HZ 1336 HZ
6 6 770 HZ 1477 HZ
7 7 852 HZ 1209 HZ
8 8 852 HZ 1336 HZ
9 9 852 HZ 1477 HZ
10 0 941 HZ 1209 HZ
11 * 941 HZ 1336 HZ
12 # 941 HZ 1477 HZ
13 A 697 HZ 1633 HZ
14 B 770 HZ 1633 HZ
15 C 852 HZ 1633 HZ
0 D 941 HZ 1633 HZ
Tabla 5.7.
Figura 5.14.
71
Antes de empezar a programar, vamos a verificar la sintaxis de la instrucción
DTMFout:
DTMFout
Sintaxis: DTMFout pin, {On-ms, Off-ms}, [tono, tono,...tono]
La instrucción DTMFout genera tonos DTMF en secuencia y a través de un
puerto cualquiera del microcontrolador.
Pin: especifica el pin del puerto en el cual se emitirán los tonos DTMF.
On-ms: es una variable o constante que especifica la duración de cada tono
en milisegundos. En caso de no utilizar este parámetro, el tiempo por defecto
de cada tono es de 200 ms.
Off-ms: es una variable o constante que especifica el tiempo en milisegundos
del silencio que hay entre cada tono. En caso de no utilizar este parámetro, el
tiempo en silencio entre cada tono por defecto será de 50 ms.
Tono: puede ser una variable o constante entre 0 y 15, que especifica el tono
que debe ser generado.
72
Programa en Pic Basic:
'****************************************
'* Nombre : Proyecto6.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
Define Osc 10 ' Define el Oscilador en 10 Mhz.
TRISA = $FE ' Configura el pin RA0 como Salida
' y el resto de los pines como entrada.
Inicio:
DTMFOut PORTA.0, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
Pause 2000 ' Genera una pausa de 2 segundos.
DTMFOut PORTA.0, 400, 150, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
Pause 2000 ' Genera una pausa de 2 segundos.
GoTo Inicio ' Salta a la etiqueta "Inicio".
End
73
Observe que en la primera instrucción “DTMFout”, después de la etiqueta
“Inicio”, no se especifica la duración de cada tono y el tiempo en silencio entre
cada tono. Esto significa que el microcontrolador genera cada tono con una
duración de 200 milisegundos por defecto, y un tiempo en silencio entre cada
tono de 50 milisegundos como se muestra en las figuras 5.15 y 5.16
respectivamente:
Figura 5.15.
74
Figura 5.16.
La segunda instrucción “DTMFout”, después de la etiqueta “Inicio”, tiene
definido un tiempo de duración para cada tono de 400 milisegundos (figura
5.17), y un tiempo de espera entre cada tono de 150 milisegundos (figura
5.18). Estos tiempos pueden ser ajustados a conveniencia cada vez que sea
necesario.
75
Figura 5.17.
Figura 5.18.
76
5.7.- Proyecto #7: En este proyecto estudiaremos la instrucción “Button”, la
cual es utilizada para la eliminación de rebotes en pulsadores o para efectuar
repeticiones en un botón, como sucede en el caso de los teclados de las
computadoras, en las cuales si dejamos presionado un botón o tecla, la
misma se repite indefinidamente a una frecuencia específica, la cual puede
ser variada fácilmente como lo demostraremos a continuación.
Antes de empezar, veamos la sintaxis de la instrucción Button:
Button
Sintaxis: Button pin, estado, retardo, rango, variable, acción, etiqueta
La instrucción “Button” elimina los rebotes de un “pulsador” o “switch”, y
genera auto-repetición.
Pin: especifica el pin del puerto en el cual será conectado el pulsador.
Estado: indica cual es estado lógico que debe ocurrir cuando el pulsador es
presionado (0 o 1). Si es 0, el pulsador deberá ser activo-bajo y si es 1, el
pulsador deberá ser activo-alto (Ver figura 5.19).
77
Figura 5.19.
Retardo: es una variable o constante (0 – 255) que especifica cuantos ciclos
deben pasar antes de efectuar la auto-repetición. Este campo tiene dos
funciones especiales: si el campo retardo es igual 0, no permite anti-rebote y
no permite auto-repetición. Si el campo retardo es igual a 255, permite el anti-
rebote pero no permite la auto-repetición.
Rango: es una variable o constante (0 – 255) que especifica el número de
ciclos entre auto-repeticiones.
Variable: es una variable auxiliar tipo Byte, definida también al inicio del
programa para uso exclusivo de la instrucción Button, por lo cual no deberá
ser utilizada con otro fin en el programa. Siempre debe ser inicializada antes
del comando Button.
Acción: indica el estado del botón cuando éste no es presionado.
78
Etiqueta: la instrucción realiza un salto a la etiqueta definida en este campo
cuando el pulsador no ha sido presionado.
Adicionalmente utilizaremos la instrucción “Pulsout” en el ejemplo, para
generar pulsos de tiempo definido.
PULSout
Sintaxis: PULSout pin, nivel, variable
La instrucción “PULSout”, genera pulsos con una duración definida en
decenas de microsegundos. (Tiene una resolución de 10 microsegundos
para un oscilador de 4 Mhz, y una resolución de 2 microsegundos para un
oscilador de 20 Mhz).
79
Para este proyecto hemos preparado tres ejemplos los cuales están basados
en el circuito de la figura 5.20.
Figura 5.20.
Proyecto # 7 - 7.1 - 7.2 - 7.3
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Resistencia de 10K Ohm 1
Pulsador Normalmente Abierto 1
Fuente regulada de 5 Vdc 1
Tabla 5.8.
80
Se puede observar en el diagrama esquemático, que mientras el pulsador
permanece abierto, hay un cero lógico en el pin RB0, el cual debemos
configurar como entrada en el programa. Cuando el pulsador sea presionado,
el estado lógico en el pin RB0 será un uno lógico.
La salida a través de la cual se van a generar los pulsos será el pin RB1, en el
cual hemos conectado un osciloscopio para poder ver el resultado de las
señales generadas a partir de las especificaciones dadas en cada ejemplo a
continuación.
5.7.1.- Proyecto #7.1: Para el primer ejemplo, se pide generar un pulso de
1.5 milisegundos una vez presionado el botón. Luego, pasados 20
milisegundos con el botón presionado, debe empezar una auto-repetición de
este pulso cada 10 milisegundos.
Veamos el siguiente programa:
Define Osc 4
TRISB = %11111101 ' Configuración del puerto B
A Var Byte ' declaración de la variable A para la instrucción Button.
A = 0 ' inicializa la variable A
PORTB.1 = 0 ' Inicializa la Salida RB0
Inicio:
Button PORTB.0,1,2,1,A,0,Tiempo
PulsOut PORTB.1,150 ' Genera un pulso de 1.5ms o 150 decenas de
' microsegundos.
Tiempo:
Pause 10 ' Pausa de 10 milisegundos
GoTo Inicio ' Salta a inicio
End
81
Ahora analicemos la secuencia del programa:
• Mientras el pulsador permanece abierto, la instrucción Button salta a la
etiqueta especificada, la cual en este caso hemos denominado
“Tiempo”. Seguidamente el programa completa el ciclo ejecutando las
instrucciones que siguen, y finalmente retorna a la etiqueta inicio.
• Si es presionado el pulsador, se genera el primer pulso a través de la
instrucción “Pulsout PortB.1, 150” (figura 5.21), y el programa continúa
su curso hasta completar el primer ciclo. En este punto la auto-
repetición aún no comienza, ya que hemos especificado en la
instrucción Button, que ésta debe comenzar al terminar el segundo
ciclo:
Button PORTB.0,1,2,1,A,0,Tiempo
Figura 5.21.
82
Al terminar el primer ciclo de programa, han transcurrido los primeros 10
milisegundos. Con el segundo ciclo de programa ocurre nuevamente el salto a
la etiqueta “Tiempo”, produciéndose una nueva pausa de 10 milisegundos,
para un tiempo de espera antes de ejecutar la auto-repetición de 20
milisegundos.
Figura 5.22.
• Cumplidos los dos ciclos especificados en el campo “retardo” de la
instrucción Button, la instrucción empieza la auto-repetición cada “un
ciclo”, ya que así lo hemos especificado en el campo “rango” de la
instrucción:
Button PORTB.0,1,2,1,A,0,Tiempo
83
En la figura 5.22 se puede apreciar la lectura de la señal producida por el
programa al activar el pulsador. Observe que el tiempo entre el primer pulso y
la auto-repetición es de 20 milisegundos, y que el tiempo entre cada auto-
repetición es de 10 milisegundos (figura 5.23).
Figura 5.23.
84
En la figura 5.24 se puede observar la señal generada al activar el pulsador,
en la cual se ve la auto-repetición del pulso de 1.5 milisegundos, la cual
permanecerá hasta que el pulsador sea liberado.
Figura 5.24.
85
5.7.2.- Proyecto #7.2: Para el siguiente ejemplo se pretende generar el
mismo pulso de 1.5 milisegundos indefinidamente cada 20 milisegundos,
siempre y cuando el pulsador permanezca activado.
Analice el siguiente programa:
Define Osc 4
TRISB = %11111101 ' Configuración del puerto B
A Var Byte ' declaración de la variable A
A = 0 ' inicializa la variable A
PORTB.1 = 0 ' Inicializa la Salida RB0
Inicio:
Button PORTB.0,1,2,2,A,0,Tiempo
PulsOut PORTB.1,150 ' Genera un pulso de 1.5ms o 150 decenas de
' microsegundos.
Tiempo:
Pause 10 ' Pausa de 10 milisegundos
GoTo Inicio ' Salta a inicio
End
Observe en el programa que el único cambio para lograr el objetivo, ha sido
aumentar en una unidad el campo “rango” de la instrucción Button, lo cual
significa que se deben esperar dos ciclos de programa entre cada auto-
repetición para producir el pulso de 1.5 milisegundos.
Button PORTB.0,1,2,2,A,0,Tiempo
La secuencia para este programa es la siguiente:
• Mientras el pulsador permanece abierto, al igual que en el ejemplo
anterior, la instrucción Button hace un salto a la etiqueta “Tiempo” por
cada ciclo de programa.
• Cuando activamos el pulsador, se genera el primer pulso de 1.5
milisegundos gracias a la instrucción Pulsout; luego se genera una
86
pausa de 10 milisegundos y finaliza el primer ciclo con un salto a la
etiqueta “Inicio”. En el segundo ciclo, la instrucción Button verifica el
conteo de los ciclos, el cual es controlado por la variable “A”,
determinando que aún no se puede empezar la auto-repetición hasta
tanto no haya culminado el segundo ciclo, de tal manera que ocurre
nuevamente el salto a la etiqueta “Tiempo”, y se produce una nueva
pausa de 10 milisegundos.
• Culminados los dos ciclos definidos en el campo “retardo” de la
instrucción Button para el anti-rebote, se produce el primer pulso de
1.5 milisegundos de la auto-repetición.
• Ahora podemos ver en el osciloscopio (figura 5.25), la señal generada
al activar el pulsador, y en la cual se produce un pulso de 1.5
milisegundos, cada 20 milisegundos.
Figura 5.25.
87
5.7.3.- Proyecto #7.3: En este ejemplo se debe generar un pulso de 2.5
milisegundos, con un tiempo para anti-rebotes en el pulsador de 30
milisegundos, y un tiempo entre cada auto-repetición de 10 milisegundos.
Analice el siguiente programa:
Define Osc 4
TRISB = %11111101 ' Configuración del puerto B
A Var Byte ' declaración de la variable A
A = 0 ' inicializa la variable A
PORTB.1 = 0 ' Inicializa la Salida RB0
Inicio:
Button PORTB.0,1,3,1,A,0,Tiempo
PulsOut PORTB.1,250 ' Genera un pulso de 2.5ms o 250 decenas de
' microsegundos.
Tiempo:
Pause 10 ' Pausa de 10 milisegundos
GoTo Inicio ' Salta a inicio
End
En este caso se puede observar que los parámetros en la instrucción Button
han sido configurados para que el tiempo en anti-rebote dure tres ciclos de
programa, y para la auto-repetición un ciclo de programa.
Entonces, la secuencia de programa es la siguiente:
• Al activar el botón, se genera un pulso de 2.5 milisegundos.
• Debido a que el campo “retardo” en la instrucción Button es igual a
tres, la instrucción ejecutará la auto-repetición después de cumplir con
los tres ciclos de programa, pasando por la subrutina “Tiempo” en cada
ciclo, lo cual da como resultado un retardo de 30 milisegundos.
• Al culminar el tercer ciclo de programa, empieza la auto-repetición,
generando un pulso de 2.5 milisegundos por cada ciclo de programa,
88
es decir, aproximadamente cada 10 milisegundos. La auto-repetición
se mantiene siempre y cuando el pulsador permanezca activo.
En la figura 5.26 se puede observar la señal generada al activar el pulsador,
al igual que la medición del tiempo en el pulso generado por la instrucción
“Pulsout”, igual a 2.5 milisegundos.
Figura 5.26.
89
En la figura 5.27, se puede apreciar el tiempo de espera generado por la
instrucción “Button”, igual a 30 milisegundos, para evitar los rebotes en el
pulsador. También se puede observar claramente, que una vez culminado
este tiempo, se genera una auto-repetición del pulso, la cual se mantiene
siempre que el pulsador se encuentre presionado.
Figura 5.27.
90
Observe en la figura 5.28 la medición del tiempo entre cada auto-repetición.
Figura 5.28.
91
5.8.- Proyecto #8: En este proyecto estudiaremos la instrucción “Branch”, con
un ejemplo sencillo basado en el circuito de la figura 5.29, en el cual se debe
iluminar cada Led en forma consecutiva por cada segundo transcurrido.
Figura 5.29.
Proyecto # 8
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
LED 3
Resistencia de 220 Ohm 3
Fuente regulada de 5 Vdc 1
Tabla 5.9.
92
Branch
Sintaxis: Branch Variable,[Etiqueta1, Etiqueta2,…EtiquetaN]
La instrucción Branch hace un salto a una etiqueta dependiendo del valor de
la variable, es decir, si la variable es igual a 0, el salto se hace a la etiqueta 1;
si la variable es igual a 1, el salto se hace a la etiqueta 2; si la variable es
igual a 2, el salto se hace a la etiqueta 3, y así sucesivamente.
Analice el siguiente programa:
'****************************************
'* Nombre : Proyecto8.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
I var Byte ' Declaración de la variable “I”
TRISB = $00 ' Configura el puerto B como salida
PORTB = $00 ' Inicializa el puerto B
I = 0 ' Inicializa la variable I
Inicio:
Branch I,[Led1,Led2,Led3]
Led1:
PORTB = %00000001 ' enciende el led en RB0
Pause 1000 ' pause de 1 segundo
PORTB = %00000000 ' apaga el led
I = I + 1 ' suma 1 a la variable I
GoTo inicio ' salta a inicio
Led2:
PORTB = %00000010 ' enciende el led en RB1
Pause 1000 ' pause de 1 segundo
PORTB = %00000000 ' apaga el Led
I = I + 1 ' suma 1 a la variable I
GoTo inicio ' salta a inicio
93
Led3:
PORTB = %00000100 ' enciende el led en RB2
Pause 1000 ' pause de 1 segundo
PORTB = %00000000 ' apaga el Led
I = 0 ' Inicializa la variable I
GoTo Inicio ' salta a inicio
End
Observe en el programa que a partir de la etiqueta “Inicio”, la instrucción
“Branch” hace un salto a la etiqueta especificada según el valor cargado en la
variable “I”, que se corresponde con la posición de la etiqueta que hemos
designado entre los corchetes.
Entonces, si I = 0, la instrucción hace un salto a la etiqueta “Led1”; si I = 1, la
instrucción hace un salto a la etiqueta “Led2”; si I = 2, entonces la instrucción
hace un salto a la etiqueta “Led3”.
94
5.9.- Proyecto #9: La instrucción “PWM”, puede ser usada para generar
voltajes analógicos implementando el circuito conectado al pin RB0 de la
figura 5.30. A continuación realizaremos un ejemplo de aplicación de la
instrucción PWM para generar un voltaje determinado, aplicando una serie de
cálculos sencillos.
Figura 5.30.
Proyecto # 9
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Resistencia de 10K Ohm 1
Capcitor Electrolítico de 10 uF 1
Fuente regulada de 5 Vdc 1
Tabla 5.10.
95
PWM
Sintaxis: PWM pin, nivel, ciclo
La instrucción PWM envía pulsos PWM (Pulse Width Modulation) a un pin
específico.
Pin: especifica el pin del puerto en el cual se genera PWM.
Nivel: es una variable o constante que determina la duración del pulso en su
nivel alto, es decir, partiendo de nivel = 1, si se incrementa este valor, el
ancho de pulso positivo se incrementa, hasta nivel = 254, donde el ciclo de
trabajo es aproximadamente 100%. Cuando nivel = 0, la salida se mantiene
en cero lógico; cuando nivel = 255, la salida se mantiene en uno lógico.
Ciclo: es una variable o constante en el cual se define el número de ciclos en
un pin específico.
PWM es una abreviación de Pulse Width Modulation, o modulación por ancho
de pulso, y es un método utilizado normalmente para el control de velocidad
de motores eléctricos, o para regular voltajes en fuentes conmutadas entre
otras aplicaciones. Este control se lleva a cabo modificando el ancho de pulso
o ciclo de trabajo de la señal generada.
En nuestro ejemplo, para generar un voltaje específico en una de las salidas
de un microcontrolador a través de la instrucción PWM, podemos aplicar la
siguiente fórmula:
255
nivelVfuente
Vout
∗
=
donde,
Vout: voltaje de salida.
Vfuente: voltaje de la fuente de alimentación del circuito.
Nivel: constante entre 0 y 255.
96
Por ejemplo, si deseamos obtener Vout = 3.5V, entonces,
1795,178
5
2555.3255
≈=
∗
=
∗
=
V
V
Vfuente
Vout
nivel
El valor a ser cargado en el campo “nivel” de la instrucción es 179. Al medir el
voltaje en la salida del circuito de la figura 5.30, podemos comprobar que éste
se aproxima al valor deseado de 3.5 voltios.
El programa a ser cargado en el microcontrolador es el siguiente:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
Inicio:
PWM PORTB.0,179,100 ' Señal PWM
GoTo Inicio ' Salto a inicio
End
97
Módulos LCD Capitulo VI
6.1.- Pantallas LCD: Las pantallas LCD alfanuméricas, son las más utilizadas
hoy en día en el desarrollo de proyectos o equipos electrónicos en los cuales
se hace necesario visualizar mensajes de texto cortos, que proporcionen la
información adecuada sobre un evento determinado. Las pantallas más
comunes suelen ser de 1x16, de 2x16 y de 4x16 (Filas x Columnas). Todas
estas configuraciones también se encuentran para 20 columnas y hasta para
40 columnas. Aunque en esta edición solo estudiaremos el uso de pantallas
alfanuméricas, también resulta interesante mencionar que existen en el
mercado pantallas gráficas (GLCD), como la que se observa en la figura 6.3, y
donde se debe aplicar un método de control diferente al de las pantallas
alfanuméricas.
Figura 6.1. Pantalla LCD 2x16.
Figura 6.2. Pantalla LCD 4x16.
Figura 6.3. Pantalla GLCD (Graphic Liquid Crystal
Display) de 128x64 pixel.
98
6.2.- Identificación de los pines de una pantalla LCD: Veamos a
continuación la descripción de cada uno de los pines de una pantalla LCD:
Figura 6.4. Pinout de un módulo
LCD con conexión a Vcc, Gnd y
Control de contraste.
Pin 1, 2 y 3: como se puede observar en la figura 6.4, en la mayoría de las
pantallas LCD, el Pin No. 1 y 2 corresponden a la alimentación de la pantalla,
GND y Vcc, donde el voltaje máximo comúnmente soportado es de 5 Vdc. El
Pin No.3 corresponde al control de contraste de la pantalla.
Pin 4: "RS" (trabaja paralelamente al Bus de datos del modulo LCD, Pines 7 al
14, es decir, cuando RS es cero, el dato presente en el bus corresponde a un
registro de control o instrucción, pero cuando RS es uno, el dato presente en
el bus corresponde a un registro de datos o caracter alfanumérico.
Pin 5: "R/W" (Read/Write), este pin es utilizado para leer un dato desde la
pantalla LCD o para escribir un dato en la pantalla LCD. Si R/W = 0, esta
condición indica que podemos escribir un dato en la pantalla. Si R/W = 1, esta
condición nos permite leer un dato desde la pantalla LCD.
Pin 6: "E" (Enable), este es el pin de habilitación, es decir, si E = 0 el módulo
LCD se encuentra inhabilitado para recibir datos, pero si E = 1, el módulo LCD
se encuentra habilitado para trabajar, de tal manera que podemos escribir o
leer desde el modulo LCD.
99
Pin 7 al14: "Bus de Datos”, el Pin 7 hasta el Pin 14 representan 8 líneas que
se utilizan para colocar el dato que representa una instrucción para el modulo
LCD o un carácter alfanumérico.
Pin 15-16: "BackLight", en muchos modelos de LCD, los pines 15 y 16 son
respectivamente el “Ánodo” y el “Cátodo”, aunque se pueden encontrar en el
mercado modelos de pantallas LCD donde esta condición es configurable
desde la parte posterior del circuito impreso a través de “Jumpers”, o
conexiones donde podemos invertir los Pines, de manera tal que el Pin 15 sea
el “Cátodo” y el Pin 16 el “Ánodo”, como se muestra en la figura 6.5.
Figura 6.5.
6.3.- Conexión de una pantalla LCD en Pic Basic: Una pantalla LCD puede
ser conectada a un microcontrolador utilizando los ocho bits del bus de datos
(D0 a D7) o solamente los cuatro bits mas significativos del bus de datos (D4
a D7). Al emplear los ocho bits, estos deberán estar conectados en un solo
puerto y nunca en puertos diferentes. Si deseamos trabajar solo con los
cuatro bits más significativos del bus, estos deberán ser conectados en los
cuatro bits menos significativos de un puerto o en los cuatro bits más
significativos del puerto seleccionado.
Los pines E (Pin 6) y RS (Pin 4) pueden estar conectados en cualquier puerto
del microcontrolador. Por último, el Pin R/W deberá estar conectado a tierra
(GND) para indicar a la pantalla LCD que estaremos escribiendo, esto debido
a que estaremos trabajando inicialmente solo con la instrucción “Lcdout”.
100
Un dato interesante resulta ser el hecho de que las pantallas LCD pueden ser
controladas utilizando dos configuraciones distintas para el bus de datos:
• La primera configuración es a 8 bits de datos, lo cual requiere
que conectemos todos los pines del bus (D0 hasta D7 en la
pantalla LCD), en uno de los puertos disponibles de un
microcontrolador PIC.
• La segunda configuración posible es a 4 bits de datos, lo cual
reduce a la mitad la cantidad de pines a ser utilizados en un
puerto de un microcontrolador PIC, pero ésta deberá ser definida
al inicio del programa para garantizar que la pantalla funcione
correctamente.
Nota Importante: PIC Basic asume por defecto que el conexionado entre un
módulo LCD alfanumérico y un microcontrolador, se ha realizado como se muestra
en el diagrama esquemático de la figura 6.6. En este caso no será necesario definir
estas conexiones en el programa; sin embargo, es conveniente saber que el
funcionamiento de un programa para el manejo de una pantalla LCD, no se verá
afectado si decidimos definir cada una de las conexiones como se muestran a
continuación:
DEFINE LCD_DREG PORTA ' Indica que el Bus de datos estará conectado
' en el Puerto A.
DEFINE LCD_BITS 4 ' El bus de datos de la LCD será de cuatro bits.
DEFINE LCD_DBIT 0 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTA ' Indica al uC que el pin “RS” estará en el Puerto A
DEFINE LCD_RSBIT 4 ' “RS” estará conectado en RA4
DEFINE LCD_EREG PORTB ' Indica al uC que el pin “E” estará en el Puerto B
DEFINE LCD_EBIT 3 ' “E” estará conectado en RB3
Compare estas definiciones con el diagrama esquemático de la figura 6.6, y
podrá notar que las conexiones entre la pantalla LCD y el microcontrolador
PIC coinciden exactamente con cada línea de programa de la nota anterior.
101
Figura 6.6.
Proyecto # 10
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x4 1
Resistencia de 1K Ohm 1
Potenciómetro de 5K Ohm 1
Fuente regulada de 5 Vdc 1
Tabla 6.1.
102
Aunque esta configuración es la que PicBasic asume por defecto, la misma
puede ser cambiada según convenga, pero siempre tomando en cuenta las
definiciones anteriormente mencionadas; en ellas se especifica la disposición
de los pines de la pantalla LCD con respecto a su conexión en los puertos del
microcontrolador.
LCDout
Sintaxis: LCDout comando, dato
La instrucción “Lcdout” envía datos específicos a una pantalla LCD
Alfanumérica para que puedan ser mostrados en la misma.
La instrucción “Lcdout” va acompañada de un comando de control el cual
opera según la tabla 6.2:
Tabla 6.2.
Estos comandos son indispensables para especificar en la pantalla LCD la
acción que deseamos tomar. Para el caso específico de la primera línea en
una pantalla LCD, bastará solo con escribir la instrucción “Lcdout”, seguida
del mensaje o variable que se desea mostrar.
Comando Acción
$FE, 1 Limpia la pantalla
$FE, 2 Retorna al inicio de la primera línea
$FE, $0C Apaga el Cursor
$FE, $0E Cursor bajo (Underline "_") activo
$FE, $0F Cursor intermitente activo
$FE, $10 Mueve el cursor un espacio a la izquierda
$FE, $14 Mueve el cursor un espacio a la derecha
$FE, $C0 Mueve el cursor al inicio de la segunda línea
$FE, $90 Mueve el cursor al inicio de la tercera línea
$FE, $D0 Mueve el cursor al inicio de la cuarta línea
103
En la figura 6.7 se muestran las direcciones de cada caracter en las líneas 2,
3 y 4:
Pantalla LCD 16x4
Línea 1 - - - - - - - - - - - - - - - -
Línea 2 $C0 $C1 $C2 $C3 $C4 $C5 $C6 $C7 $C8 $C9 $CA $CB $CC $CD $CE $CF
Línea 3 $90 $91 $92 $93 $94 $95 $96 $97 $98 $99 $9A $9B $9C $9D $9E $9F
Línea 4 $D0 $D1 $D2 $D3 $D4 $D5 $D6 $D7 $D8 $D9 $DA $DB $DC $DD $DE $DF
Figura 6.7.
Entonces, para escribir un mensaje en cada línea de una pantalla LCD,
tenemos que:
Lcdout "Mensaje Linea 1"
Lcdout $fe,$C0, "Mensaje Linea 2"
Lcdout $fe,$90, "Mensaje Linea 3"
Lcdout $fe,$D0, "Mensaje Linea 4"
También es posible iniciar un mensaje en otra posición en las líneas 2, 3 y 4,
cambiando la dirección en el comando de control de la instrucción.
6.4.- Proyecto #10. En el siguiente programa se puede ver que no ha sido
utilizado ningún tipo de definición de parámetros de conexión para los pines
de control entre la pantalla y el microcontrolador, por lo cual se asume que el
conexionado entre ambos dispositivos deberá ser igual al planteado en el
diagrama de la figura 6.6.
Realice el montaje y haga modificaciones al programa mostrado a
continuación, con el fin de comprobar la tabla 6.2.
' Programa en PIC Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Pause 500
LCDOut $fe, 1 ' Limpia la pantalla
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "* Pantalla LCD *"
104
LCDOut $fe,$C0, "* Alfanumerica *"
LCDOut $fe,$90, "* 1234567890 *"
LCDOut $fe,$D0, "* AaBbCcDdEeFf *"
Inicio:
GoTo Inicio ' Salta a la etiqueta inicio
End
Al conectar el circuito de la figura 6.6 y el programa cargado en el
microcontrolador, podremos ver como se despliega en la pantalla LCD de
cuatro líneas, cada frase preestablecida en el programa, como se muestra en
las figuras 6.8 y 6.9.
Figura 6.8. Figura 6.9.
105
6.5.- Proyecto #11. En el diagrama de la figura 6.10 se puede observar que la
conexión entre el modulo LCD y el microcontrolador ha cambiado con
respecto al proyecto #10, con el fin de utilizar en el programa la definición de
conexiones anteriormente mencionada.
Para este ejemplo se ha realizado un programa que muestra el valor cargado
en una variable a la cual hemos denominado “Dato”, y la cual podrá ser
incrementada al accionar el pulsador “P1” conectado en RB0; el valor de esta
variable también podrá decrecer al accionar el pulsador “P2” conectado en
RB1.
Los puertos han sido configurados de la siguiente manera:
• Puerto B: se configura como entrada ya que en los pines RB0 y RB1
estarán conectados los pulsadores P1 y P2.
• Puerto D: se configura como salida ya que éste será utilizado para el
control de la pantalla LCD.
La variable “Dato” ha sido inicializada con un valor cargado igual a 25. Para
aumentar o disminuir este valor, simplemente se pregunta si en RB0 o en RB1
hay un cambio de estado lógico. Adicionalmente se establecen dos
condiciones que se deben cumplir para que la variable pueda aumentar su
valor o disminuir:
• La primera condición al pulsar P1 para el incremento es: solo podrá ser
incrementado el valor cargado en la variable “Dato”, si ésta es menor
(“<”) a cincuenta (50).
• La segunda condición al pulsar P2 para disminuir el valor cargado en la
variable es: solo se podrá disminuir el valor cargado en la variable
“Dato” si ésta es mayor (“>”) a cero (0).
106
Para mostrar el valor decimal cargado en la variable “Dato” a través de la
pantalla LCD, se debe utilizar la directiva “Dec” o el símbolo “#” antes de la
variable, como se muestra a continuación:
Lcdout $fe,$C0,"Dato: ",Dec Dato ' Escribe el mensaje en la línea 2
' seguido del valor cargado en la
' variable "Dato" en Decimal.
ó,
Lcdout $fe,$C0,"Dato: ",#Dato
Figura 6.10.
107
Proyecto # 11 - 12
Componente Cantidad
PIC16F877A 1
Cristal de 8 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x2 1
Resistencia de 10K Ohm 2
Potenciómetro de 5K Ohm 1
Pulsador Normalmente Abierto 2
Fuente regulada de 5 Vdc 1
Tabla 6.3.
' Programa en Pic Basic Pro:
'****************************************
'* Nombre : Proyecto11.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Define Osc 8 ' Define el Oscilador para un Cristal
' de 8 Mhz.
TRISB = $FF ' Configura el puerto B como entrada.
TRISD = $00 ' Configura el puerto D como salida.
Dato Var Byte ' Declaración de la Variable "Dato" tipo Byte.
Dato = 25 ' Inicializa la Variable Dato = 25.
Lcdout $fe, 1 ' Limpia la pantalla
Inicio:
108
Lcdout $fe,2 ' Inicio de la primera línea.
Lcdout "P1 Suma P2 Resta" ' Escribe mensaje en la primera línea.
Lcdout $fe,$C0,"Dato: ",Dec Dato," " ' Escribe el mensaje en la 2da línea
' seguido del valor cargado en la
' variable "Dato" en Decimal.
' La siguiente instrucción pregunta si hay un "1" en RB0 y si la variable
' "Dato" es menor a 50. Si se cumplen estas dos condiciones, hace un salto
' con retorno a la subrutina "Suma".
If PORTB.0 = 1 And Dato < 50 Then Call Suma
' La siguiente instrucción pregunta si hay un "1" en RB1 y si la variable
' "Dato" es mayor a 0. Si se cumplen estas dos condiciones, hace un salto
' con retorno a la subrutina "Resta".
If PORTB.1 = 1 And Dato > 0 Then Call Resta
GoTo Inicio ' Salta a la etiqueta "Inicio".
Suma:
Dato = Dato + 1 ' Incrementa en una unidad la variable "Dato".
Pause 350 ' Realiza una pausa de 350 milisegundos para evitar
' que el incremento de la variable sea muy acelerado
' mientras el pulsador "P1" esté presionado.
Return ' Retorna una línea después del llamado "Call Suma".
Resta:
Dato = Dato - 1 ' Decrementa en una unidad la variable "Dato".
Pause 350 ' Realiza una pausa de 350 milisegundos para evitar
' que el decremento de la variable sea muy acelerado
' mientras el pulsador "P2" esté presionado.
Return ' Retorna una línea después del llamado "Call Resta".
End
Note que en la línea de programa encargada de imprimir el mensaje “Dato: “,
además del valor cargado en la variable, hay un espacio en blanco entre
comillas (“ “) para imprimir en la pantalla:
Lcdout $fe,$C0,"Dato: ",Dec Dato," "
Analice la razón por la cual ha sido considerado este espacio en blanco.
109
6.6.- Proyecto #12. En este proyecto nos hemos basado en el diagrama de la
figura 6.10 para efectuar la programación del microcontrolador.
La idea principal en este ejemplo, será mostrar un menú inicial en la pantalla
LCD, como se muestra a continuación:
"P1: Ver Mensaje1"
"P2: Ver Mensaje2"
Figura 6.11.
• Al accionar el pulsador “P1”, se deberá mostrar el siguiente sub-menú
(figura 6.12), el cual deberá permanecer visible durante 5 segundos
para luego retornar al menú inicial:
" Menu #1 "
"Mensaje #1 aqui!"
Figura 6.12.
• Al accionar el pulsador “P2”, se deberá mostrar el siguiente sub-menú
(figura 6.13), el cual también deberá permanecer visible durante 5
segundos para luego retornar al menú inicial:
" Menu #2 "
"Mensaje #2 aqui!"
Figura 6.13.
Lea detenidamente los comentarios de cada línea del programa. Observe que
en esta oportunidad hemos utilizado un alias para cada una de las entradas
utilizadas en el puerto B (RB0 se llamará P1, y RB1 se llamará P2).
' Programa en Pic Basic Pro:
'****************************************
'* Nombre : Proyecto12.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
110
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Symbol P1 = PORTB.0 ' Alias para RB0
Symbol P2 = PORTB.1 ' Alias para RB1
Define Osc 8 ' Define el Oscilador para un Cristal
' de 8 Mhz.
TRISB = $FF ' Configura el puerto B como entrada.
TrisD = $00 ' Configura el puerto D como salida.
LCDOut $fe, 1 ' Limpia la pantalla
Inicio:
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "P1: Ver Mensaje1"
LCDOut $fe,$C0, "P2: Ver Mensaje2"
If P1 = 1 Then Call Mensaje1 ' Pregunta si RB0 = 1
If P2 = 1 Then Call Mensaje2 ' Pregunta si RB1 = 1
GoTo Inicio
Mensaje1:
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut " Menu #1 "
LCDOut $fe,$C0, "Mensaje #1 aqui!"
Pause 5000 ' Pausa de 5 segundos.
Return ' Retorna una línea después del llamado "Call"
Mensaje2:
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut " Menu #2 "
LCDOut $fe,$C0, "Mensaje #2 aqui!"
Pause 5000 ' Pausa de 5 segundos.
Return ' Retorna una línea después del llamado "Call"
End
111
6.7.- Proyecto #13. En el siguiente ejemplo explicamos la forma de visualizar
en la pantalla LCD un valor decimal y sus equivalentes en hexadecimal,
binario y el código ASCII correspondiente, de un dato almacenado en una
variable tipo Byte.
Para lograr este objetivo, hemos declarado en el programa la variable “Dato”,
en la cual cargaremos un valor igual a 64, como ejemplo inicial.
Ya es conocido por un ejemplo anterior a éste, que si deseamos mostrar el
contenido de la variable en decimal, debemos anteponer la directiva “Dec” o el
símbolo “#” a ésta, como se puede ver a continuación:
LCDOut "Decimal: ", Dec Dato
LCDOut "Decimal: ", #Dato
El equivalente en Hexadecimal para este valor (64) es “40”, y el equivalente
en binario para este mismo valor es “1000000”. Entonces, para mostrar estos
valores en la pantalla LCD en su formato correspondiente, debemos utilizar
las siguientes directivas:
Hexadecimal: LCDOut "Hexadecimal: ",Hex Dato
Binario: LCDOut "Binario: ",Bin Dato
El código ASCII equivalente a este valor (“64”), corresponde al símbolo “@”, y
se muestra de la siguiente forma:
LCDOut "Código ASCII: ", Dato
Realice el montaje de la figura 6.14, y analice el programa que se muestra a
continuación:
112
Figura 6.14.
Proyecto # 13 - 14
Componente Cantidad
PIC16F877A 1
Cristal de 8 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x2 1
Potenciómetro de 5K Ohm 1
Fuente regulada de 5 Vdc 1
Tabla 6.4.
113
' Programa en Pic Basic Pro:
'****************************************
'* Nombre : Proyecto13.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Define Osc 8 ' Define el Oscilador para un Cristal
' de 8 Mhz.
TrisD = $00 ' Configura el puerto D como salida.
Dato Var Byte
Dato = 64 ' Carga la variable "Dato" con el Valor 64.
LCDOut $fe, 1 ' Limpia la pantalla.
Inicio:
LCDOuT $fe, 2 ' Posiciona el cursor en el inicio.
LCDOut "Decimal: ",Dec Dato," "
LCDOut $fe,$C0, "Hexadecimal: ",HEX Dato," "
Pause 4000 ' Hace una pausa de 4 segundos.
LCDOuT $fe, 2 ' Posiciona el cursor en el inicio.
LCDOut "Binario:",BIN Dato
LCDOut $fe,$C0, "Codigo ASCII: ", Dato," "
Pause 4000 ' Hace una pausa de 4 segundos.
GoTo Inicio ' Salta a la etiqueta "Inicio".
End
114
6.8.- Proyecto #14: Analice el programa propuesto a continuación, el cual
está basado en el diagrama esquemático de la figura 6.14. En este caso se
desea mostrar en la pantalla LCD los valores entre 33 y 125 en decimal,
además de sus equivalentes en hexadecimal y código ASCII correspondiente.
' Programa en Pic Basic Pro:
'****************************************
'* Nombre : Proyecto14.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Define Osc 8 ' Define el Oscilador para un Cristal
' de 8 Mhz.
TrisD = $00 ' Configura el puerto D como salida.
I Var Byte ' Declaración de la variable "I" topo Byte.
LCDOut $fe, 1 ' Limpia la pantalla.
Inicio:
' A continuación se carga la variable "I" con un valor inicial igual a
' 33, el cual se irá incrementando hasta llegar a 125. Por cada incremento
' se muestran los valores equivalentes en hexadecimal y su respectivo
' código ASCII en la pantalla LCD.
For I = 33 To 125
Lcdout $fe,2
Lcdout "Dec:",#I," Hex:",HEX I," "
Lcdout $fe,$C0,"ASCII: ", I," "
Pause 1000 ' Realiza una pausa de 1 segundo.
Next I
Fin:
GoTo Fin ' Bucle infinito.
End
115
6.9.- Proyecto #15: Con la ayuda de la instrucción “Count”, estaremos
realizando un contador de pulsos, el cual se compone básicamente de un
PIC16F877A y una pantalla LCD 2x16. El tren de pulsos cuadrados de
frecuencia variable, será generado desde un microcontrolador PIC16F84A
utilizando la instrucción “Pulsout”, y el cual deberá ser programado para que
sea posible aumentar o disminuir la frecuencia a través de dos pulsadores
conectados a él, P1 para aumentar la frecuencia y P2 para disminuir la
frecuencia, como se muestra en el diagrama de la figura 6.15.
Figura 6.15.
116
Proyecto # 15 - 16
Componente Cantidad
PIC16F877A 1
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x4 1
Resistencia de 10K Ohm 2
Potenciómetro de 5K Ohm 1
Pulsador Normalmente Abierto 2
Fuente regulada de 5 Vdc 1
Tabla 6.5.
En el circuito de la figura 6.15 se puede observar un microcontrolador
PIC16F877A, en el cual cargaremos el programa encargado de realizar el
conteo de pulsos enviados desde un microcontrolador PIC16F84A, el cual
también dispone de su propia programación para poder generar un tren de
pulsos variables.
El tren de pulsos de frecuencia variable desde los pulsadores P1 y P2, sale
desde el pin RB1 del PIC16F84A hacia el pin RB1 del PIC16F877A, el cual a
su vez realiza constantemente el conteo de pulsos, durante un tiempo
definido, que en este caso ha sido de 1000 milisegundos. Seguidamente el
resultado del conteo de pulsos en este período de tiempo es almacenado en
una variable la cual hemos denominado “Pulsos”, para luego ser mostrado en
la pantalla LCD.
Veamos a continuación la sintaxis de la nueva instrucción y seguidamente los
programas propuestos para este ejemplo.
117
Count
Sintaxis: Count pin, duración, variable
Con esta instrucción se puede medir la frecuencia de una señal simple,
contando el número de pulsos durante un tiempo determinado, definido en el
campo “duración” de la instrucción. Se pueden medir frecuencias de hasta 25
khz con un oscilador de 4 MHz. Para un oscilador de 20 MHz la frecuencia
máxima a ser medida será de 125 khz.
Pin: especifica el pin del puerto en el cual se introducirán los pulsos. Este pin
es designado como entrada automáticamente por la instrucción Count.
Duración: es el tiempo en milisegundos, durante el cual se realizará el conteo
de pulsos sobre el pin especificado.
Variable: es una variable definida por el programador en la cual se grabará el
resultado del conteo.
Programa para el contador de pulsos (PIC16F877A):
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Pulsos Var Word ' declaración de la variable "Pulsos" tipo Word
Lcdout $fe, 1 ' Limpia la pantalla
Inicio:
Count PORTB.1, 1000, Pulsos ' Cuenta los pulsos introducidos a través
' del pin RB1, durante 1000 milisegundos y el
' resultado del conteo es almacenado en la
118
' variable "Pulsos".
Lcdout $fe,2 ' Inicio de la primera línea.
Lcdout "Frecuencia " ' Escribe mensaje en la primera línea.
LcdOut $FE,$C0,"Medida = ",#Pulsos," Hz " ' Escribe dato en pantalla.
GoTo Inicio ' Salta a la etiqueta "Inicio"
End
Análisis del programa:
• Para empezar, se han definido los pines de control y bus de datos de la
pantalla LCD, al igual que la frecuencia del oscilador externo.
• Seguidamente se define la variable “Pulsos”, en la cual se cargará el
resultado del conteo de los pulsos introducidos a través del pin RB1.
• Se limpia la pantalla LCD.
• La instrucción “Count”, cuenta los pulsos introducidos por el pin RB1, y
el resultado es almacenado en la variable “Pulsos”.
• Por último se muestra el valor cargado en la variable “Pulsos”, en la
pantalla LCD y se retorna a la etiqueta “Inicio”.
Programa para el generador de pulsos (PIC16F84A):
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISB = %11111101 ' Configuración del puerto B
Base Var Word ' Declaración de la variable "Base" tipo Word
Espera VAR Word
PORTB.1 = 0 ' Inicializa la Salida RB0
Base = 100 ' Inicializa la variable Base = 100
Espera = 1
Inicio:
If PORTB.0 = 1 Then Call Suma ' Si RB0 = 1 llama a la subrutina "Suma"
119
If PORTB.2 = 1 Then Call Resta ' Si RB2 = 1 llama a la subrutina "Resta"
PulsOut PORTB.1,Base ' Genera un pulso de duración definida por la variable
' "Base".
pause Espera ' Pausa de "Base/100" milisegundos
GoTo Inicio ' Salta a inicio
Suma:
Pause 300 ' Pausa de 300 milisegundos
Base = Base + 100 ' Incrementa la variable "Base"
If Base = 10100 Then Base = 10000 ' Establece un límite máximo al valor cargado
' en la variable "Base".
Espera = Base / 100 ' Divide el valor cargado en la variable
' "Base" entre 100 y lo carga en la variable
' "Espera", para que la pausa que se genera
' después de cada pulso sea igual al tiempo
' del pulso.
Return ' Retorna una línea después del llamado "Call"
Resta:
Pause 300 ' Pausa de 300 milisegundos
Base = Base - 100 ' decrementa la variable "Base"
If Base = 0 Then Base = 100 ' Establece un límite máximo al valor cargado
' en la variable "Base".
Espera = Base / 100 ' Divide el valor cargado en la variable
' "Base" entre 100 y lo carga en la variable
' "Espera", para que la pausa que se genera
' después de cada pulso sea igual al tiempo
' del pulso.
Return ' Retorna una línea después del llamado "Call"
End
Análisis del programa:
• En el programa se puede observar que se han dado los pasos
necesarios en lo que respecta a la definición del tipo de oscilador y la
configuración del puerto que estamos utilizando en el diseño
propuesto.
• Seguidamente, ha sido declarada la variable “Base” y la variable
“Espera”, las cuales serán necesarias para almacenar la base de
tiempo de los pulsos generados por la instrucción Pulsout, además de
la pausa generada entre cada pulso.
120
• Inicializamos la variable “Base” con un valor igual a 100 y la variable
“Espera” con un valor igual a 1.
• A partir de la etiqueta “Inicio”, el primer paso de la subrutina ha sido
preguntar si los pulsadores P1 y P2 han sido activados. Si el pulsador
P1 es activado, el programa hace un salto con retorno a la subrutina
“Suma”, incrementando el valor de la variable “Base” en 100 unidades.
Si el pulsador P2 es activado, el programa hace un salto con retorno a
la subrutina “Resta”, haciendo decrecer en 100 unidades el valor
cargado en la variable “Base”. En estas dos subrutinas (Suma y Resta),
se establecen límites para la variable “Base”, de manera tal que si la
suma llega a ser igual a 10100, la variable “Base” mantiene su valor
igual a 10000. En el caso específico de la resta, si el valor de la
variable “Base” llega a ser igual a 0, entonces la variable mantiene
siempre su valor igual a 100. Seguidamente se carga la variable
“Espera”, tanto en la subrutina “Suma” como en la subrutina “Resta”,
valor que será utilizado para realizar la pausa entre pulsos.
• La instrucción Pulsout, genera un pulso en el pin RB1, con una
duración definida por el valor cargado en la variable “Base”. Por
ejemplo, si Base = 100, entonces el pulso generado será de 100
decenas de microsegundos, es decir, 1 milisegundo. Recuerde que la
instrucción Pulsout tiene una resolución de 10 microsegundos para un
oscilador de 4 Mhz.
• Seguidamente el programa realiza una pausa la cual depende también
del valor cargado en la variable “Espera”. Entonces, observe que si la
variable Base = 100, la pausa generada es de 1 milisegundo, debido a
que se está dividiendo el valor cargado en la variable “Base” entre 100
y el resultado es cargado en la variable “Espera”.
• Por último, el programa hace un salto a la etiqueta “Inicio” para
empezar el proceso.
121
El tren de pulsos generado por el microcontrolador PIC16F84A en el pin RB1,
se puede observar en la siguiente figura:
Figura 6.16.
Observe que la frecuencia de la señal generada cuando alimentamos el
circuito es de 480 Hz, debido a que el valor cargado en la variable “Base” es
igual a 100, y el valor cargado en la variable “Espera” es igual a 1.
Compare el valor de la frecuencia medido en el osciloscopio, con el valor
obtenido por la instrucción “Count”, en el programa cargado en el
microcontrolador PIC16F877A. En este caso, el valor mostrado en la pantalla
LCD, debe ser igual a 480 pulsos por segundo.
Realice las pruebas necesarias con la ayuda de un osciloscopio, para
visualizar la señal generada cada vez que aumenta o disminuye el valor de la
variable “Base”, a través de los pulsadores P1 y P2 respectivamente.
Compare el valor de la frecuencia medido en el osciloscopio, con el valor
obtenido en el conteo de pulsos por cada segundo transcurrido a través de la
instrucción “Count”.
122
6.10.- Proyecto #16: El siguiente proyecto está basado en el montaje de la
figura 6.15. En esta oportunidad estudiaremos el funcionamiento de la
instrucción “Pulsin”, con la cual mediremos la duración de los pulsos
generados por el microcontrolador PIC16F84A, programado en el proyecto
#15.
PULSIN
Sintaxis: PULSIN pin, nivel, variable
La instrucción PULSIN mide la duración de un pulso alto o bajo con una
resolución de 10 microsegundos para un oscilador de 4 Mhz, o una resolución
de 2 microsegundos para un oscilador de 20 Mhz, y el valor obtenido es
almacenado en una variable definida de 8 bits (byte) o 16 bits (Word).
Pin: especifica el pin del puerto en el cual se introducirá el pulso a ser medido.
Nivel: define si la medición se hace en nivel alto o bajo. (1 = alto, 0 = bajo).
Variable: es una variable de 8 bits (variable tipo byte) o 16 bits (variable tipo
word) definida por el programador en la cual se grabará el resultado de la
lectura.
Analice el siguiente programa:
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Define OSC 4 ' Define el oscilador en 4 Mhz
LECTURA VAR Word ' Definición de variable de 16 bits
Pause 200 ' Pausa de 200 milisegundos
LCDOut $fe, 1 ' Limpia la pantalla
123
Inicio:
LECTURA = 0 ' Inicializa la variable "Lectura".
PulsIn PORTB.1,1,LECTURA ' Mide la duración de un pulso.
LCDOut $fe, 2 ' Posiciona el cursor en el inicio.
LCDOut "Lectura: ",#LECTURA," " ' Muestra mensaje y dato por pantalla.
Lcdout $fe,$C0,"decenas de uS. " ' Muestra el mensaje de la segunda línea.
Pause 1000 ' Pausa de 1 segundo
GoTo Inicio ' Salta a inicio
End
Al compilar y grabar el programa en el microcontrolador PIC16F877A del
diagrama de la figura 6.15, podremos observar en la pantalla LCD el resultado
de la lectura generada por la instrucción “Pulsin”, la cual mide el tiempo de
cada pulso que ingresa a través del pin RB1, en decenas de microsegundos.
Entonces, su generamos un pulso cuya duración es igual a 1 milisegundo, el
valor cargado en la variable “Lectura” será igual o aproximado a 100.
124
6.11.- Proyecto #17: Realice el montaje para el circuito la figura 6.17, con el
cual estudiaremos la instrucción “POT” a través de un ejemplo de
programación, con el cual se pretende tomar lectura de un elemento resistivo,
el cual en este caso será un potenciómetro de 10Kohm.
Figura 6.17.
125
Proyecto # 17
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x2 1
Potenciómetro de 5K Ohm 1
Potenciómetro de 10K Ohm 1
Capacitor cerámico de 0,1 uF 1
Fuente regulada de 5 Vdc 1
Tabla 6.6.
POT
Sintaxis: POT pin, escala, variable
La instrucción “POT” lee un potenciómetro, foto celda, termistor, o cualquier
otro dispositivo capaz de variar su valor resistivo. Básicamente esta
instrucción calcula el tiempo de descarga del condensador C1 el cual varía
según el valor resistivo presente en la resistencia variable.
Pin: especifica el pin del puerto en el cual se va a conectar el potenciómetro.
Escala: Es una variable o constante que aumenta o disminuye el rango de
lectura en un porcentaje determinado. Esta escala es utilizada para ajustar el
rango de salida en la lectura del dispositivo, y es afectada directamente por
las constantes RC. El valor de la escala será correcto cuando el valor cargado
en la variable se aproxime a cero, cuando la resistencia medida sea mínima; y
también cuando el valor de la variable se aproxime a 255, cuando la
resistencia medida sea máxima.
126
Variable: es una variable en la cual se almacena el resultado obtenido de la
lectura del potenciómetro o componente resistivo.
Analice el siguiente programa, y experimente sobre el valor de C1, y el valor
de la escala en la instrucción POT, hasta lograr el rango más aceptable para
una resistencia variable (P1) de 10K.
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Define OSC 4 ' Define el oscilador en 4 Mhz
ESCALA VAR Byte
DATO Var Byte
Pause 200 ' Pausa de 200 milisegundos
ESCALA = 127 ' Asigna valor a la escala
LCDOut $fe, 1 ' Limpia la pantalla
Inicio:
Pot PORTB.0,ESCALA,DATO ' Toma lectura del Potenciómetro
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Lectura: ",#DATO," " ' Muestra dato por pantalla
GoTo inicio ' Salto a inicio
End
127
6.12.- Memoria CGRAM en la Pantalla LCD.
La pantalla LCD posee una memoria llamada CGRAM (Character Generator
RAM), destinada para que el usuario pueda almacenar hasta un máximo de 8
caracteres o figuras personalizadas como lo demostraremos a continuación.
Cada carácter es representado como un bloque constituido normalmente por
5 columnas y 8 filas, cada una de 8 bits (1 byte)*, es decir, cada carácter se
compone de ocho bytes.
C5 C4 C3 C2 C1 C5 C4 C3 C2 C1 C5 C4 C3 C2 C1 C5 C4 C3 C2 C1 C5 C4 C3 C2 C1
Fila 1
Fila 2
Fila 3
Fila 4 .............
Fila 5
Fila 6
Fila 7
Fila 8
Figura 6.18.
* Nota: Los 3 bits más significativos de cada byte (3 bits más significativos de
cada fila), son tomados como ceros.
En cada posición de la CGRAM se almacenan los 8 bytes que forman un
caracter. Las direcciones correspondientes a cada posición son:
Posición en
la CGRAM Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7
Posición 0 $40 $41 $42 $43 $44 $45 $46 $47
Posición 1 $48 $49 $4A $4B $4C $4D $4E $4F
Posición 2 $50 $51 $52 $53 $54 $55 $56 $57
Posición 3 $58 $59 $5A $5B $5C $5D $5E $5F
Posición 4 $60 $61 $62 $63 $64 $65 $66 $67
Posición 5 $68 $69 $6A $6B $6C $6D $6E $6F
Posición 6 $70 $71 $72 $73 $74 $75 $76 $77
Posición 7 $78 $79 $7A $7B $7C $7D $7E $7F
Tabla 6.7.
128
Veamos el siguiente ejemplo en el cual almacenaremos el símbolo de un
parlante en la posición 0 de la CGRAM.
Dato Dato Bytes en la
HEX Símbolo Binario CGRAM
$02 00000010 $40
$06 00000110 $41
$1A 00011010 $42
$1A 00011010 $43
$1A 00011010 $44
$06 00000110 $45
$02 00000010 $46
$00 00000000 $47
Tabla 6.8.
Note que cada cuadro representa un bit el cual corresponde a un “1” o un “0”
según sea el caso o la figura que deseamos realizar, donde “1” es encendido
y “0” es apagado.
La instrucción para desplegar este símbolo en la pantalla sería la siguiente:
LCDOUT $fe,$40,$02,$06,$1A,$1A,$1A,$06,$02,$00
Observe que hemos especificado la dirección inicial de la posición cero
después de la sentencia de comando $fe, seguido de los datos
correspondientes al caracter.
Una vez almacenado los datos correspondientes a la figura en la posición
cero de la memoria CGRAM, podemos desplegar el símbolo en la pantalla
LCD.
Esto se hace especificando la posición de la CGRAM que se desea mostrar
después del comando de control, como se muestra a continuación:
LCDOUT $FE,1, 0 ' Limpia la pantalla y luego muestra el símbolo
' almacenado en la posición 0 de la CGRAM
129
En este caso la figura aparece en la primera línea de la pantalla LCD.
Para mostrar esta misma figura en una posición diferente de la pantalla,
simplemente nos basamos en la tabla de comandos de la instrucción “Lcdout”
(Tabla 6.2) y en la figura 6.7, en la cual podremos encontrar la dirección de la
posición de visualización deseada en la pantalla LCD.
Por ejemplo;
• Para visualizar la figura cargada en la posición cero de la CGRAM en la
línea 2, posición $C0 de la pantalla LCD, la sintaxis sería la siguiente:
LcdOut $fe,$C0, 0
• Para visualizar una figura cargada en la posición cuatro de la CGRAM
en la línea 2, posición $C7 de la pantalla LCD, la sintaxis sería la
siguiente:
LcdOut $fe,$C7, 4
El programa para visualizar entonces la figura ya creada anteriormente en la
línea 1 de la pantalla LCD sería el siguiente:
' Programa en PIC Basic Pro
Pause 500 ' Pausa de 500 milisegundos
LCDOut $fe, 1 ' Limpia la pantalla
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
' Cargamos el caracter en la posición cero:
LCDOut $fe,$40,$02,$06,$1A,$1A,$1A,$06,$02,$00
' Muestra el caracter en la pantalla:
LCDOut $fe,1, 0
Inicio:
GoTo Inicio ' Salta a la etiqueta “Inicio” (Lazo infinito).
End
130
6.13.- Proyecto #18. A continuación realizaremos la simulación de un control
digital de volumen, basados en el diagrama de la figura 6.19. El pulsador “P1”
será el encargado de aumentar el nivel de volumen, mientras que el pulsador
“P2” será el encargado de disminuir el nivel.
Figura 6.19.
Proyecto # 18
Componente Cantidad
PIC16F877A 1
Cristal de 8 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x2 1
Resistencia de 10K Ohm 2
Potenciómetro de 5K Ohm 1
Pulsador Normalmente Abierto 2
Fuente regulada de 5 Vdc 1
Tabla 6.9.
131
Las pantallas que veremos representadas en este ejemplo son las mostradas
en las figuras 6.20, 6.21, 6.22 y 6.23. Se puede observar en ellas la
representación de un pequeño parlante y cuatro rectángulos, encargados de
indicar el nivel de volumen.
Figura 6.20.
Figura 6.21.
Figura 6.22.
Figura 6.23.
132
El primer paso en la elaboración de este ejercicio, es crear las figuras que
deseamos mostrar en la pantalla LCD basados en la explicación dada
anteriormente:
Figura 1:
Dato Dato Bytes en la
HEX Símbolo Binario CGRAM
$02 00000010 $40
$06 00000110 $41
$1A 00011010 $42
$1A 00011010 $43
$1A 00011010 $44
$06 00000110 $45
$02 00000010 $46
$00 00000000 $47
Palabra 0: $02, $06, $1A, $1A, $1A, $06, $02, $00
Figura 2:
Dato Dato Bytes en la
HEX Símbolo Binario CGRAM
$00 00000000 $48
$00 00000000 $49
$00 00000000 $4A
$00 00000000 $4B
$00 00000000 $4C
$00 00000000 $4D
$1F 00011111 $4E
$1F 00011111 $4F
Palabra 1: $00, $00, $00, $00, $00, $00, $1F, $1F
133
Figura 3:
Dato Dato Bytes en la
HEX Símbolo Binario CGRAM
$00 00000000 $50
$00 00000000 $51
$00 00000000 $52
$00 00000000 $53
$1F 00011111 $54
$1F 00011111 $55
$1F 00011111 $56
$1F 00011111 $57
Palabra 2: $00, $00, $00, $00, $1F, $1F, $1F, $1F
Figura 4:
Dato Dato Bytes en la
HEX Símbolo Binario CGRAM
$00 00000000 $58
$00 00000000 $59
$1F 00011111 $5A
$1F 00011111 $5B
$1F 00011111 $5C
$1F 00011111 $5D
$1F 00011111 $5E
$1F 00011111 $5F
Palabra 3: $00, $00, $1F, $1F, $1F, $1F, $1F, $1F
134
Figura 5:
Dato Dato Bytes en la
HEX Símbolo Binario CGRAM
$1F 00011111 $60
$1F 00011111 $61
$1F 00011111 $62
$1F 00011111 $63
$1F 00011111 $64
$1F 00011111 $65
$1F 00011111 $66
$1F 00011111 $67
Palabra 4: $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F
A continuación analice el siguiente programa, leyendo detenidamente los
comentarios:
' Programa en PIC Basic Pro
'****************************************
'* Nombre : Proyecto18.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
Define Osc 8 ' Define el Oscilador para un Cristal
' de 8 Mhz.
135
Symbol P1 = PORTB.0 ' Alias para RB0.
Symbol P2 = PORTB.1 ' Alias para RB1.
Volumen Var Byte ' Declaración de la variable "Volumen" tipo Byte.
Volumen = 1 ' Inicializa la variable “Volumen” con el valor "1".
' A continuación se cargan las cinco figuras creadas a partir de la
' posición cero de la memoria CGRAM:
LCDOut $fe, $40, $02, $06, $1A, $1A, $1A, $06, $02, $00 'Figura 1.
LCDOut $fe, $48, $00, $00, $00, $00, $00, $00, $1F, $1F 'Figura 2.
LCDOut $fe, $50, $00, $00, $00, $00, $1F, $1F, $1F, $1F 'Figura 3.
LCDOut $fe, $58, $00, $00, $1F, $1F, $1F, $1F, $1F, $1F 'Figura 4.
LCDOut $fe, $60, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F 'Figura 5.
LCDOut $fe, 1 ' Limpia la pantalla
LCDOut " Volumen: " ' Escribe "Volumen:" en la línea 1 de la pantalla.
Inicio:
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut $fe,$C5, 0 ' Muestra la Figura almacenada en la Posición 0
' de la CGRAM.
LCDOut $fe,$C6, 1 ' Muestra la Figura almacenada en la Posición 1
' de la CGRAM.
' A continuación se verifica si alguno de los pulsadores ha sido activado.
' Si P1 es activado y la variable "Volumen" es menor a cinco, llama a la
' subrutina "SubeVol".
' Si P2 es activado y la variable "Volumen" es mayor a cero, llama a la
' subrutina "BajaVol".
If P1 = 1 And Volumen < 5 Then Call SubeVol
If P2 = 1 And Volumen > 0 Then Call BajaVol
GoTo Inicio ' Salta a la etiqueta "Inicio".
SubeVol:
Volumen = Volumen + 1 ' Suma 1 al contenido de la variable "Volumen".
If Volumen = 2 Then Call Nivel1
If Volumen = 3 Then Call Nivel2
If Volumen = 4 Then Call Nivel3
Return
Nivel1:
LCDOut $fe,$C7, 2 ' Muestra la Figura almacenada en la Posición dos (2)
' de la CGRAM.
Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P1.
Return
136
Nivel2:
LCDOut $fe,$C8, 3 ' Muestra la Figura almacenada en la Posición tres (3)
' de la CGRAM.
Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P1.
Return
Nivel3:
LCDOut $fe,$C9, 4 ' Muestra la Figura almacenada en la Posición cuatro (4)
' de la CGRAM.
Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P1.
Return
BajaVol:
Volumen = Volumen - 1 ' Resta 1 al contenido de la variable "Volumen".
If Volumen = 3 Then Call Borra1
If Volumen = 2 Then Call Borra2
If Volumen = 1 Then Call Borra3
Return
Borra1:
LCDOut $fe,$C9," " ' Borra la figura colocando un espacio en blanco en la
' posición $C9 de la pantalla LCD.
Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P2.
Return
Borra2:
LCDOut $fe,$C8," " ' Borra la figura colocando un espacio en blanco en la
' posición $C8 de la pantalla LCD.
Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P2.
Return
Borra3:
LCDOut $fe,$C7," " ' Borra la figura colocando un espacio en blanco en la
' posición $C7 de la pantalla LCD.
Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P2.
Return
End
137
6.14.- Proyecto #19. Realice el siguiente ejercicio en el cual se podrá
visualizar un pequeño caballo que corre a lo largo de la pantalla LCD, como
se muestra en las figuras 6.25 y 6.26. El programa ha sido diseñado en base
al diagrama esquemático de la figura 6.24:
Figura 6.24.
Proyecto # 19
Componente Cantidad
PIC16F877A 1
Cristal de 8 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x4 1
Potenciómetro de 5K Ohm 1
Fuente regulada de 5 Vdc 1
Tabla 6.10.
138
A continuación podrá ver una secuencia numerada de cada una de las
pantallas que debe generar el programa propuesto:
Figura 6.25.
139
Figura 6.26.
140
Un paso fundamental es hacer el diseño de cada figura en una matriz
cuadriculada de 8 filas por 5 columnas, como se muestra en la figura 6.27.
Figura 6.27.
Rellenando los cuadros adecuados podemos llegar a realizar una gran
cantidad de figuras, las cuales podrán ser almacenadas en la CGRAM de una
pantalla LCD o incluso en la memoria de datos del microcontrolador, para
luego ser consultadas y almacenadas en la CGRAM.
Una vez hecho el diseño de la figura, procedemos a sacar los datos
correspondientes a cada posición en la CGRAM.
141
Los datos a ser almacenados en las ocho posiciones de la CGRAM son los
siguientes:
Figura 1:
Dato Dato Bytes en la
HEX Figura A Binario CGRAM
$00 00000000 $40
$00 00000000 $41
$10 00010000 $42
$0F 00001111 $43
$0F 00001111 $44
$0D 00001101 $45
$18 00011000 $46
$10 00010000 $47
Palabra 0: $00,$00,$10,$0F,$0F,$0D,$18,$10
Figura 2:
Dato Dato Bytes en la
HEX Figura B Binario CGRAM
$04 00000100 $48
$0E 00001110 $49
$1F 00011111 $4A
$1C 00011100 $4B
$1C 00011100 $4C
$1C 00011100 $4D
$06 00000110 $4E
$05 00000101 $4F
Palabra 1: $04,$0E,$1F,$1C,$1C,$1C,$06,$05
142
Figura 3:
Dato Dato Bytes en la
HEX Figura C Binario CGRAM
$00 00000000 $50
$00 00000000 $51
$10 00010000 $52
$0F 00001111 $53
$0F 00001111 $54
$0D 00001101 $55
$04 00000100 $56
$06 00000110 $57
Palabra 2: $00,$00,$10,$0F,$0F,$0D,$04,$06
Figura 4:
Dato Dato Bytes en la
HEX Figura D Binario CGRAM
$04 00000100 $58
$0E 00001110 $59
$1F 00011111 $5A
$1C 00011100 $5B
$1C 00011100 $5C
$1C 00011100 $5D
$08 00001000 $5E
$18 00011000 $5F
Palabra 3: $04,$0E,$1F,$1C,$1C,$1C,$08,$18
143
Figura 5:
Dato Dato Bytes en la
HEX Figura E Binario CGRAM
$04 00000100 $60
$0E 00001110 $61
$1F 00011111 $62
$07 00000111 $63
$07 00000111 $64
$07 00000111 $65
$02 00000010 $66
$03 00000011 $67
Palabra 4: $04,$0E,$1F,$07,$07,$07,$02,$03
Figura 6:
Dato Dato Bytes en la
HEX Figura F Binario CGRAM
$00 00000000 $68
$00 00000000 $69
$01 00000001 $6A
$1E 00011110 $6B
$1E 00011110 $6C
$16 00010110 $6D
$04 00000100 $6E
$0C 00001100 $6F
Palabra 5: $00,$00,$01,$1E,$1E,$16,$04,$0C
144
Figura 7:
Dato Dato Bytes en la
HEX Figura G Binario CGRAM
$04 00000100 $70
$0E 00001110 $71
$1F 00011111 $72
$07 00000111 $73
$07 00000111 $74
$07 00000111 $75
$0C 00001100 $76
$14 00010100 $77
Palabra 6: $04,$0E,$1F,$07,$07,$07,$0C,$14
Figura 8:
Dato Dato Bytes en la
HEX Figura H Binario CGRAM
$00 00000000 $78
$00 00000000 $79
$01 00000001 $7A
$1E 00011110 $7B
$1E 00011110 $7C
$16 00010110 $7D
$03 00000011 $7E
$01 00000001 $7F
Palabra 7: $00,$00,$01,$1E,$1E,$16,$03,$01
145
En esta oportunidad pondremos a correr nuestro caballo en la segunda línea
de la pantalla, y lo ubicaremos de la siguiente manera:
La primera mitad de nuestro caballo estará en la dirección $C0 y la otra mitad
estará en la dirección $C1, nos referimos respectivamente a las figuras “A” y
“B” de nuestro diseño.
Para ver el efecto que deseamos, hacemos una pausa de 300 milisegundos,
borramos la pantalla y mostramos las figuras “C” y “D” en las posiciones $C2
y $C3 respectivamente de la pantalla LCD; luego hacemos otra pausa de 300
milisegundos y comenzamos el proceso, solo que esta vez será partiendo
desde la dirección $C4.
Cuando la figura “D” llegue a la dirección $CF, estaremos listos para repetir
todo el proceso de forma inversa con las figuras “E”, “F”, “G” y “H”.
Pantalla LCD 16x4
Línea 1 $80 $81 $82 $83 $84 $85 $86 $87 $88 $89 $8A $8B $8C $8D $8E $8F
Línea 2 $C0 $C1 $C2 $C3 $C4 $C5 $C6 $C7 $C8 $C9 $CA $CB $CC $CD $CE $CF
Línea 3 $90 $91 $92 $93 $94 $95 $96 $97 $98 $99 $9A $9B $9C $9D $9E $9F
Línea 4 $D0 $D1 $D2 $D3 $D4 $D5 $D6 $D7 $D8 $D9 $DA $DB $DC $DD $DE $DF
Figura 6.28.
En la figura 6.28 se pueden observar las direcciones en una pantalla LCD de
16 columnas y 4 filas. Esta tabla de direcciones resulta muy útil al momento
de establecer la ubicación de cada figura en cualquiera de las líneas de la
pantalla LCD.
146
Veamos el programa que hace posible esta representación:
' Programa en PIC Basic Pro
'****************************************
'* Nombre : Proyecto19.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el
' bus de datos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3
' Programa en PIC Basic Pro
Define Osc 8 ' Define el Oscilador para un Cristal
' de 8 Mhz.
' Declaración de Variables
POS1 var Byte
POS2 var Byte
POS3 var Byte
POS4 var Byte
' Inicializamos las Variables correspondientes a la posición de la figura
' en la pantalla LCD
POS1 = $C0 ' Ver figura 6.13
POS2 = $C1 '
POS3 = $C2 '
POS4 = $C3 '
Pause 500 ' Tiempo de inicialización de la Pantalla LCD
' Cargamos las 8 figuras en la CGRAM:
LCDOUT $FE,$40,$00,$00,$10,$0F,$0F,$0D,$18,$10 ' Palabra 0 de la CGRAM
LCDOUT $FE,$48,$04,$0E,$1F,$1C,$1C,$1C,$06,$05 ' Palabra 1 de la CGRAM
LCDOUT $FE,$50,$00,$00,$10,$0F,$0F,$0D,$04,$06 ' Palabra 2 de la CGRAM
LCDOUT $FE,$58,$04,$0E,$1F,$1C,$1C,$1C,$08,$18 ' Palabra 3 de la CGRAM
LCDOUT $FE,$60,$04,$0E,$1F,$07,$07,$07,$02,$03 ' Palabra 4 de la CGRAM
LCDOUT $FE,$68,$00,$00,$01,$1E,$1E,$16,$04,$0C ' Palabra 5 de la CGRAM
LCDOUT $FE,$70,$04,$0E,$1F,$07,$07,$07,$0C,$14 ' Palabra 6 de la CGRAM
LCDOUT $FE,$78,$00,$00,$01,$1E,$1E,$16,$03,$01 ' Palabra 7 de la CGRAM
inicio:
147
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS1, 0 ' Muestra Palabra 0 en la LCD
LCDOUT $FE,POS2, 1 ' Muestra Palabra 1 en la LCD
Pause 300
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS3, 2 ' Muestra Palabra 2 en la LCD
LCDOUT $FE,POS4, 3 ' Muestra Palabra 3 en la LCD
Pause 300
' Aumentamos la posición de cada símbolo en la pantalla para dar el efecto
' de movimiento:
POS1 = POS1 + 3
POS2 = POS2 + 3
POS3 = POS3 + 3
POS4 = POS4 + 3
If POS4 > $CF Then RETRO ' Pregunta si llega al tope derecho de la LCD
' si POS4 = $CF salta a la etiqueta "RETRO"
GoTo inicio ' Salta a la etiqueta "inicio"
' Antes de retroceder nos aseguramos de que las figuras E,F,G y H tengan una
' posición inicial en la pantalla LCD:
RETRO:
POS1 = $CF
POS2 = $CE
POS3 = $CD
POS4 = $CC
RETROCEDE:
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS1, 7 ' Muestra Palabra 7 en la LCD
LCDOUT $FE,POS2, 6 ' Muestra Palabra 6 en la LCD
Pause 300
LCDOUT $fe, 1 ' Limpia la pantalla LCD
LCDOUT $FE,POS3, 5 ' Muestra Palabra 5 en la LCD
LCDOUT $FE,POS4, 4 ' Muestra Palabra 4 en la LCD
Pause 300
' Disminuimos la posición de cada símbolo en la pantalla para dar el efecto
' de movimiento en sentido contrario:
POS1 = POS1 - 3
POS2 = POS2 - 3
POS3 = POS3 - 3
POS4 = POS4 - 3
If POS4 < $C0 Then REINICIA ' Pregunta si llega al tope Izquierdo de la LCD
GoTo RETROCEDE
' Nos aseguramos de que las figuras A,B,C y D tengan una posición inicial en la
' pantalla LCD:
148
REINICIA:
POS1 = $C0
POS2 = $C1
POS3 = $C2
POS4 = $C3
GoTo inicio ' Se repite el proceso saltando a la etiqueta "inicio"
End
149
Teclado Matricial Capitulo VII
7.1.- Teclado Matricial: Para introducir datos de forma manual en un
microcontrolador, nada mejor que un teclado matricial para este fin. Los
teclados matriciales más comunes son de 3 columnas por 4 filas, y de 4
columnas por 4 filas, como los mostrados en la figura 7.1:
Figura 7.1.
Figura 7.2.
150
El principio de funcionamiento de un teclado matricial es muy sencillo.
Básicamente cuando pulsamos un botón en el teclado, estamos uniendo una
fila con una columna.
Por ejemplo, al presionar la tecla “1”, estaremos conectando la columna 1 con
la fila 1; si pulsamos la tecla “4”, estaremos conectando nuevamente la
columna 1, esta ves con la fila 2; si pulsamos la tecla “9”, entonces estaremos
conectando la columna 3 con la fila 3.
Existen diversas formas de conectar e interpretar el funcionamiento de un
teclado matricial. En el diagrama de la figura 7.3 se puede apreciar un teclado
matricial 3x4 conectado a los pines del puerto B, los cuales se han distribuido
y configurado de la siguiente manera:
Puerto B TrisB Teclado 3x4
RB0 0 (Salida) Columna 1
RB1 0 (Salida) Columna 2
RB2 0 (Salida) Columna 3
RB3 1 (Entrada) Fila 1
RB4 1 (Entrada) Fila 2
RB5 1 (Entrada) Fila 3
RB6 1 (Entrada) Fila 4
RB7 1 (Entrada) Sin Conexión
Tabla 7.1.
Observe en el diagrama esquemático que los pines RB3, RB4, RB5 y RB6
tienen una resistencia “Pull-up”, lo cual significa que si leemos cualquiera de
estas entradas, asumiendo que ninguna tecla ha sido presionada, entonces
siempre habrá un uno lógico presente en cada una de ellas.
151
Figura 7.3.
Entonces para saber si una tecla ha sido presionada, podemos aplicar el
siguiente análisis:
1. Enviamos un cero “0” por la columna 1, y enviamos un “1” por las
columnas 2 y 3.
PORTB.0 = 0 ' Columna 1 = 0
PORTB.1 = 1 ' Columna 2 = 1
PORTB.2 = 1 ' Columna 3 = 1
2. Leemos las filas 1, 2, 3 y 4 para verificar si alguna de ellas cambió su
estado a cero “0”. Si esto sucede, quiere decir que una de las teclas en
la columna 1 ha sido presionada, entonces:
Si PORTB.3 = 0 La tecla "1" fue presionada.
Si PORTB.4 = 0 La tecla "4" fue presionada.
Si PORTB.5 = 0 La tecla "7" fue presionada.
Si PORTB.6 = 0 La tecla "*" fue presionada.
152
3. Enviamos un cero “0” por la columna 2, y enviamos un “1” por las
columnas 1 y 3.
PORTB.0 = 1 ' Columna 1 = 1
PORTB.1 = 0 ' Columna 2 = 0
PORTB.2 = 1 ' Columna 3 = 1
4. Leemos las filas 1, 2, 3 y 4 para verificar si alguna de ellas cambió su
estado a cero “0”. Si esto sucede, en este caso quiere decir que una de
las teclas en la columna 2 ha sido presionada, entonces:
Si PORTB.3 = 0 La tecla "2" fue presionada.
Si PORTB.4 = 0 La tecla "5" fue presionada.
Si PORTB.5 = 0 La tecla "8" fue presionada.
Si PORTB.6 = 0 La tecla "0" fue presionada.
5. Enviamos un cero “0” por la columna 3, y enviamos un “1” por las
columnas 1 y 2.
PORTB.0 = 1 ' Columna 1 = 1
PORTB.1 = 1 ' Columna 2 = 1
PORTB.2 = 0 ' Columna 3 = 0
6. Leemos nuevamente las filas 1, 2, 3 y 4 para verificar si alguna de ellas
cambió su estado a cero “0”. Si esto sucede, entonces quiere decir que
una de las teclas en la columna 3 ha sido presionada.
Si PORTB.3 = 0 La tecla "3" fue presionada.
Si PORTB.4 = 0 La tecla "6" fue presionada.
Si PORTB.5 = 0 La tecla "9" fue presionada.
Si PORTB.6 = 0 La tecla "#" fue presionada.
A continuación veremos el algoritmo capaz de leer el teclado matricial
conectado al puerto B, y el cual a su vez genera el digito correspondiente a la
tecla presionada en un display de 7 segmentos conectado al puerto D.
153
Observe que el display de 7 segmentos es de ánodo común, lo cual significa
que para encender un segmento será necesario enviar un cero “0” a través
del pin que corresponda a éste, en el puerto D.
' Programa en PIC Basic Pro
Define Osc 8 ' Define el Oscilador para un Cristal
' de 8 Mhz.
TRISB = %01111000 ' Configura los pines del puerto B.
TRISD = %00000000 ' Configura los pines del puerto D.
Inicio:
Call Teclado ' Llama a la rutina barrido del teclado matricial.
Pause 300 ' Hace una pausa de 300 ms.
GoTo Inicio ' Salta a la etiqueta “Inicio”.
Teclado:
PORTB.0 = 0 ' Columna 1 = 0
PORTB.1 = 1 ' Columna 2 = 1
PORTB.2 = 1 ' Columna 3 = 1
If PORTB.3 = 0 Then PORTD = %11111001 ' tecla "1"
If PORTB.4 = 0 Then PORTD = %10011001 ' tecla "4"
If PORTB.5 = 0 Then PORTD = %11111000 ' tecla "7"
If PORTB.6 = 0 Then PORTD = %10011100 ' tecla "*"
PORTB.0 = 1 ' Columna 1 = 1
PORTB.1 = 0 ' Columna 2 = 0
PORTB.2 = 1 ' Columna 3 = 1
If PORTB.3 = 0 Then PORTD = %10100100 ' tecla "2"
If PORTB.4 = 0 Then PORTD = %10010010 ' tecla "5"
If PORTB.5 = 0 Then PORTD = %10000000 ' tecla "8"
If PORTB.6 = 0 Then PORTD = %11000000 ' tecla "0"
PORTB.0 = 1 ' Columna 1 = 1
PORTB.1 = 1 ' Columna 2 = 1
PORTB.2 = 0 ' Columna 3 = 0
If PORTB.3 = 0 Then PORTD = %10110000 ' tecla "3"
If PORTB.4 = 0 Then PORTD = %10000010 ' tecla "6"
If PORTB.5 = 0 Then PORTD = %10011000 ' tecla "9"
If PORTB.6 = 0 Then PORTD = %10100011 ' tecla "#"
Return
End
154
7.2.- Proyecto #20. En el siguiente proyecto utilizaremos una pantalla LCD
16x2, y un teclado matricial 3x4, conectados según el diagrama esquemático
de la figura 7.4. El objetivo de este proyecto será visualizar el valor o símbolo
correspondiente a cada una de las teclas.
Figura 7.4.
Proyecto # 20 - 21 - 22 - 23
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x2 1
Resistencia de 1K Ohm 4
Potenciómetro de 5K Ohm 1
Teclado Matricial 3x4 1
Fuente regulada de 5 Vdc 1
Tabla 7.2.
155
Utilizaremos la técnica de lectura de teclado mostrada anteriormente para la
programación de este proyecto.
Realice un análisis detallado del siguiente programa, y compare el algoritmo
de lectura del teclado matricial con el algoritmo comentado anteriormente.
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISA = %00000000 ' Configuración del puerto A
TRISB = %00000000 ' Configuración del puerto B
TRISD = %01111000 ' Configuración del puerto D
VAR1 VAR Byte ' Declaramos la Variable VAR1
var1 = 0 ' Inicializamos la variable VAR1
Pause 200 ' Pausa de 200 milisegundos
Lcdout $fe, 1 ' Limpia la pantalla
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "* Pantalla LCD *"
Lcdout $fe,$C0, "* Teclado Mat. *"
PAUSE 3000 ' Pausa de 3 segundos
Inicio:
Call Teclado
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Tecla Pulsada: "
Lcdout $fe,$C0, "--> ",#var1," "
GoTo Inicio
Teclado:
PORTD.0 = 0 ' Columna 1 = 0
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then VAR1 = 1 ' tecla "1"
If PORTD.4 = 0 Then VAR1 = 4 ' tecla "4"
If PORTD.5 = 0 Then VAR1 = 7 ' tecla "7"
If PORTD.6 = 0 Then VAR1 = 10 ' tecla "*"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 0 ' Columna 2 = 0
PORTD.2 = 1 ' Columna 3 = 1
156
If PORTD.3 = 0 Then VAR1 = 2 ' tecla "2"
If PORTD.4 = 0 Then VAR1 = 5 ' tecla "5"
If PORTD.5 = 0 Then VAR1 = 8 ' tecla "8"
If PORTD.6 = 0 Then VAR1 = 11 ' tecla "0"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 0 ' Columna 3 = 0
If PORTD.3 = 0 Then VAR1 = 3 ' tecla "3"
If PORTD.4 = 0 Then VAR1 = 6 ' tecla "6"
If PORTD.5 = 0 Then VAR1 = 9 ' tecla "9"
If PORTD.6 = 0 Then VAR1 = 12 ' tecla "#"
Return ' Retorna una línea después del llamado "Call"
End
157
Memoria de Datos Capitulo VIII
8.1.- La Memoria de Datos: La memoria EEPROM de datos resulta muy
importante cuando necesitamos almacenar información que no queremos que
se pierda al desconectar la energía de nuestros proyectos. La capacidad de
esta memoria varía según el modelo de microcontrolador que escojamos, y no
todos cuentan con esta característica.
Por ejemplo, el PIC16F84 cuenta con una memoria de datos de 64 bytes y el
PIC16F877 cuenta con una memoria de datos de 256 bytes. Esta información
puede ser verificada directamente en la hoja de características técnicas de
cada microcontrolador. Sin embargo, haremos un mapa de memoria de datos
para estos dos microcontroladores PIC:
0000: 00 01 02 03 04 05 06 07
0008: 08 09 0A 0B 0C 0D 0E 0F
0010: 10 11 12 13 14 15 16 17
0018: 18 19 1A 1B 1C 1D 1E 1F
0020: 20 21 22 23 24 25 26 27
0028: 28 29 2A 2B 2C 2D 2E 2F
0030: 30 21 32 33 34 35 36 37
0038: 38 39 3A 3B 3C 3D 3E 3F
Memoria de Datos PIC16F84
Tabla 8.1.
Podemos ver claramente en la tabla de memoria de datos, que tenemos 64
bytes que podemos utilizar para almacenar información, a partir de la posición
00 hasta la posición 3F.
158
En un microcontrolador PIC16F877 la capacidad de almacenamiento aumenta
considerablemente y lo podemos ver en el siguiente mapa:
0000: 00 01 02 03 04 05 06 07
0008: 08 09 0A 0B 0C 0D 0E 0F
0010: 10 11 12 13 14 15 16 17
0018: 18 19 1A 1B 1C 1D 1E 1F
0020: 20 21 22 23 24 25 26 27
0028: 28 29 2A 2B 2C 2D 2E 2F
0030: 30 21 32 33 34 35 36 37
0038: 38 39 3A 3B 3C 3D 3E 3F
0040: 40 41 42 43 44 45 46 47
0048: 48 49 4A 4B 4C 4D 4E 4F
0050: 50 51 52 53 54 55 56 57
0058: 58 59 5A 5B 5C 5D 5E 5F
0060: 60 61 62 63 64 65 66 67
0068: 68 69 6A 6B 6C 6D 6E 6F
0070: 70 71 72 73 74 75 76 77
0078: 78 79 7A 7B 7C 7D 7E 7F
0080: 80 81 82 83 84 85 86 87
0088: 88 89 8A 8B 8C 8D 8E 8F
0090: 90 91 92 93 94 95 96 97
0098: 98 99 9A 9B 9C 9D 9E 9F
00A0: A0 A1 A2 A3 A4 A5 A6 A7
00A8: A8 A9 AA AB AC AD AE AF
00B0: B0 B1 B2 B3 B4 B5 B6 B7
00B8: B8 B9 BA BB BC BD BE BF
00C0: C0 C1 C2 C3 C4 C5 C6 C7
00C8: C8 C9 CA CB CC CD CE CF
00D0: D0 D1 D2 D3 D4 D5 D6 D7
00D8: D8 D9 DA DB DC DD DE DF
00E0: E0 E1 E2 E3 E4 E5 E6 E7
00E8: E8 E9 EA EB EC ED EE EF
00F0: F0 F1 F2 F3 F4 F5 F6 F7
00F8: F8 F9 FA FB FC FD FE FF
Memoria de Datos PIC16F877
Tabla 8.2.
Guardar y leer datos resulta muy sencillo al trabajar en PicBasic. Este
compilador tiene instrucciones muy específicas las cuales estudiaremos a
continuación.
Si deseamos grabar algunos datos, será necesario saber la posición en la
cual estarán almacenados para luego poder ser consultados. La instrucción
159
en PicBasic para grabar datos en la memoria de datos EEPROM es “Write” y
la estructura de la sentencia es la siguiente:
WRITE dirección, dato
WRITE
Sintaxis: WRITE dirección, variable
La instrucción WRITE almacena datos en la memoria EEPROM de un
microcontrolador en una dirección específica.
Ejemplo:
Write $00,1 ' graba el dato o valor “1” en la dirección $00
Write $21,155 ' graba el dato o valor “155” en la dirección $21
Write $A0,VAR1 ' graba el dato almacenado en la variable VAR1,
' en la dirección $A0
Si deseamos leer alguno de los datos almacenados, la instrucción en PicBasic
para este fin es “Read”, y la estructura de la sentencia es la siguiente:
Read dirección, variable
READ
Sintaxis: READ dirección, variable
La instrucción READ permite leer datos desde la memoria EEPROM de datos
de un microcontrolador almacenándolos en una variable previamente definida.
160
Ejemplo:
Read $00, VAR1 ' lee el dato de la dirección especificada y lo guarda
' en la variable VAR1
Read $21, VAR2 ' lee el dato de la dirección especificada y lo guarda
' en la variable VAR2
Read $A0, VAR3 ' lee el dato de la dirección especificada y lo guarda
' en la variable VAR3
A continuación realizaremos una serie de ejercicios, en los cuales deberán ser
aplicados los todos conocimientos adquiridos en los capítulos anteriores.
La idea principal en cada proyecto será familiarizarse con el uso de la
memoria de datos, almacenando en ella información que deberá poder ser
consultada aunque el circuito sea reiniciado o apagado.
Como se puede observar en la figura 8.1, se requiere el uso de un teclado
matricial 3x4 para el ingreso de datos y una pantalla LCD, con la cual se
podrá visualizar toda la información a ser consultada.
Figura 8.1.
161
8.2.- Proyecto #21. En este proyecto vamos a almacenar datos en la
memoria EEPROM, para luego ser consultados y mostrados uno por uno en
la pantalla LCD.
Basados en el diagrama esquemático de la figura 8.1, empezamos el
programa asegurando que los puertos A, B y D están configurados de
acuerdo a los dispositivos conectados a él:
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
' Configuración de Puertos:
TRISA = %00000000
TRISB = %00000000
TRISD = %01111000
VAR1 VAR Byte ' Declaramos la variable “VAR1”
Seguidamente generamos una pausa de 200 milisegundos y damos un
mensaje de entrada el cual deberá permanecer durante 3 segundos:
Pause 200 ' Pausa de 200 milisegundos
Lcdout $fe, 1 ' Limpia la pantalla
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Memoria de Datos"
Lcdout $fe,$C0, "****************"
Pause 3000 ' Pausa de 3 segundos
Para almacenar un dato es necesario especificar una dirección en la memoria
de datos. En este ejemplo, veamos a almacenar el valor “1” en la posición de
memoria $00; “2” en la posición de memoria $01 y “3” en la posición de
memoria $02:
Write $00,1 ' Escribe el valor “1” en la posición “$00”
Write $01,2 ' Escribe el valor “2” en la posición “$01”
Write $02,3 ' Escribe el valor “3” en la posición “$02”
162
La siguiente subrutina lee el valor almacenado en la dirección $00 y lo
muestra en la pantalla LCD, espera tres segundos y lee el segundo valor
almacenado en la posición $01, lo muestra en la pantalla LCD y nuevamente
hace una pausa de tres segundos. Por último se lee el valor almacenado en la
posición $02 y lo muestra en la pantalla LCD durante tres segundos, para
luego volver a empezar el proceso de lectura.
Inicio:
Read $00,VAR1
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Dirección 00: "
Lcdout $fe,$C0, "Dato: ",#VAR1," "
Pause 3000
Read $01,VAR1
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Dirección 01: "
Lcdout $fe,$C0, "Dato: ",#VAR1," "
Pause 3000
Read $02,VAR1
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Dirección 02: "
Lcdout $fe,$C0, "Dato: ",#VAR1," "
Pause 3000
GoTo inicio
End
Para comprobar que estos datos están en la memoria de datos EEPROM del
microcontrolador, también es posible utilizar el programador P16Pro para este
fin, desde el cual podemos extraer el contenido completo de la memoria de
datos sin problemas, debido a que el software del programador cuenta con
una pequeña ventana llamada “Data Memory”, en la cual se pueden ver los
datos almacenados como se muestra en la figura 8.2:
163
Figura 8.2.
8.3.- Proyecto #22. En el ejemplo presentado a continuación se desea
almacenar una serie de datos a partir de una dirección específica en la
memoria de programa. Se puede experimentar cambiando las direcciones y
datos a ser almacenados. Veamos el siguiente programa, el cual está basado
en el diagrama de la figura 8.1:
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
' Configuración de Puertos:
TRISA = %00000000
TRISB = %00000000
TRISD = %01111000
I VAR Byte ' Declaramos la Variable I
VAR1 var Byte ' Declaramos la Variable VAR1
DIRECCION var Byte ' Declaramos la Variable DIRECCION
DATO var Byte ' Declaramos la Variable DATO
Pause 200 ' Pausa de 200 milisegundos
Lcdout $fe, 1 ' Limpia la pantalla
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Memoria de Datos"
Lcdout $fe,$C0, "****************"
Pause 3000 ' Pausa de 3 segundos
DIRECCION = $00 ' Asignamos una dirección inicial
DATO = 1 ' Primer dato que será almacenado
164
' Almacenaremos a continuación 20 datos en 20 direcciones
' consecutivas; los datos a almacenar serán: 1,3,5,7,9,11,13
' 15,17,19,21,23,25,27,29,31,33,35,37 y 39.
For I = 1 To 20 ' ejecuta la subrutina 20 veces
Write DIRECCION,DATO ' escribe el dato en la dirección especificada
DIRECCION = DIRECCION + 1 ' aumenta en una unidad la posición de la Mem.
DATO = DATO + 2 ' aumenta en dos unidades el valor del dato a almacenar.
Next I
Inicio:
DIRECCION = $00
For I = 1 To 20 ' ejecuta la subrutina 20 veces
Read DIRECCION,VAR1 ' lee el dato y lo almacena en VAR1
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Dirección ",#DIRECCION,": " ' muestra la dirección
Lcdout $fe,$C0, "Dato: ",#var1," " ' muestra el dato
DIRECCION = DIRECCION + 1 ' aumenta en uno la posición de la memoria
Pause 2000 ' Pausa de 2 segundos para poder visualizar la información
Next I
GoTo Inicio ' inicia el proceso de lectura de la memoria de datos
End
Si apagamos el circuito y leemos la memoria de datos, podremos observar los
valores almacenados en el siguiente mapa de la memoria:
Figura 8.3.
Se puede ver en la figura 8.3 que están almacenados 20 valores (el
equivalente de cada valor o dato en hexadecimal).
165
8.4.- Proyecto #23. En el siguiente ejemplo vamos a utilizar la rutina para el
control de un teclado matricial, ya que con ella podremos insertar valores que
serán almacenados en la memoria de datos. Analice el siguiente programa, el
cual ha sido desarrollado en base al diagrama de la figura 8.1.
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
' Configuración de Puertos:
TRISA = %00000000
TRISB = %00000000
TRISD = %01111000
I VAR Byte ' Declaramos la Variable I
VAR1 VAR Byte ' Declaramos la Variable VAR1
DIRECCION VAR Byte ' Declaramos la Variable DIRECCION
DATO VAR Byte ' Declaramos la Variable DATO
Pause 200 ' Pausa de 200 milisegundos
Lcdout $fe, 1 ' Limpia la pantalla
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Memoria de Datos"
Lcdout $fe,$C0, "****************"
Pause 3000 ' Pausa de 3 segundos
DIRECCION = $00 ' Asignamos una dirección inicial
Inicio:
Lcdout $fe, 1 ' Limpia la pantalla
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout "Direccion: ",#DIRECCION," "
Lcdout $fe,$C0, "Dato?: "
espera1:
Call Teclado
If VAR1 = 0 Then espera1 ' Si ninguna tecla fue pulsada salta a “espera1”
If VAR1 = 10 Then espera1 ' Si pulsamos la tecla asterisco salta a “espera1”
If VAR1 = 11 Then VAR1 = 0 ' Si pulsamos la tecla “0”, entonces VAR1 = 0
If VAR1 = 12 Then espera1 ' Si pulsamos la tecla numeral salta a “espera1”
Lcdout $fe,$C0, "Dato?: ",#VAR1," "
Write DIRECCION,VAR1 ' Escribe el valor en la memoria de datos
DIRECCION = DIRECCION + 1 ' Aumentamos la posición en una unidad
Pause 1000 ' Espera 1 segundo para simular un tiempo de grabación
166
Lcdout $fe,$C0, "Dato Almacenado"
Pause 1000 ' Espera 1 segundo para visualizar el mensaje
If DIRECCION = $0F Then Aviso ' Revisa si llegamos al límite asignado por
' el programador en la memoria de datos
GoTo inicio
Aviso:
Lcdout $fe, 1 ' Limpia la pantalla
Lcdout $fe, 2 ' Posiciona el cursor en el inicio
Lcdout " Memoria llena! "
Lcdout $fe,$C0, "****************"
Parada:
GoTo Parada
Teclado:
VAR1 = 0
PORTD.0 = 0 ' Columna 1 = 0
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then VAR1 = 1 ' tecla "1"
If PORTD.4 = 0 Then VAR1 = 4 ' tecla "4"
If PORTD.5 = 0 Then VAR1 = 7 ' tecla "7"
If PORTD.6 = 0 Then VAR1 = 10 ' tecla "*"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 0 ' Columna 2 = 0
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then VAR1 = 2 ' tecla "2"
If PORTD.4 = 0 Then VAR1 = 5 ' tecla "5"
If PORTD.5 = 0 Then VAR1 = 8 ' tecla "8"
If PORTD.6 = 0 Then VAR1 = 11 ' tecla "0"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 0 ' Columna 3 = 0
If PORTD.3 = 0 Then VAR1 = 3 ' tecla "3"
If PORTD.4 = 0 Then VAR1 = 6 ' tecla "6"
If PORTD.5 = 0 Then VAR1 = 9 ' tecla "9"
If PORTD.6 = 0 Then VAR1 = 12 ' tecla "#"
Return ' Retorna una línea después del llamado "Call"
End
167
Una vez compilado y puesto a prueba el programa, los valores podrán ser
introducidos a la memoria de datos a través del teclado matricial, y el límite de
datos a ser grabados será de 16 registros, ya que hemos fijado como límite la
dirección “$0F” en la memoria de datos, para luego mostrar un mensaje en la
pantalla LCD que nos indicará que hemos llenado cada uno de los 16
registros disponibles.
Recuerde que un microcontrolador PIC16F877 tiene una capacidad de
memoria de datos de 256 bytes, por lo tanto el límite que hemos fijado en el
programa anterior puede ser llevado a su capacidad máxima de ser
necesario.
168
8.5.- Proyecto #24: En el siguiente ejemplo hemos desarrollado un sistema
de control de acceso, en el cual el usuario deberá introducir una contraseña
previamente almacenada en la memoria de datos. Si la contraseña es
correcta, se genera un mensaje de confirmación y sonido (“Beep”). Si la
contraseña es incorrecta, se genera un mensaje de error y un sonido
intermitente (“Beep, Beep, Beep”).
El dispositivo encargado de generar el sonido (Buzzer), se encuentra
conectado al pin RC0.
Figura 8.4.
169
Proyecto # 24
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x2 1
Resistencia de 1K Ohm 4
Potenciómetro de 5K Ohm 1
Teclado Matricial 3x4 1
Transistor 2N3904 1
Buzzer 5 Vdc 1
Fuente regulada de 5 Vdc 1
Tabla 8.3.
Antes de empezar a programar, es importante tomar en cuenta cuales serán
las posiciones en la memoria de datos para guardar la contraseña.
Para un sistema de acceso donde la contraseña será de seis dígitos, y donde
cada dígito deberá ser almacenado en una posición específica,
convenientemente podemos tomar las posiciones en el mapa de la memoria
de datos a partir de la dirección “$10” por ejemplo, hasta la dirección “$15”,
como se puede apreciar en la siguiente tabla:
170
0000: 00 01 02 03 04 05 06 07
0008: 08 09 0A 0B 0C 0D 0E 0F
0010: 10 11 12 13 14 15 16 17
0018: 18 19 1A 1B 1C 1D 1E 1F
0020: 20 21 22 23 24 25 26 27
0028: 28 29 2A 2B 2C 2D 2E 2F
0030: 30 21 32 33 34 35 36 37
0038: 38 39 3A 3B 3C 3D 3E 3F
0040: 40 41 42 43 44 45 46 47
0048: 48 49 4A 4B 4C 4D 4E 4F
0050: 50 51 52 53 54 55 56 57
0058: 58 59 5A 5B 5C 5D 5E 5F
0060: 60 61 62 63 64 65 66 67
0068: 68 69 6A 6B 6C 6D 6E 6F
0070: 70 71 72 73 74 75 76 77
0078: 78 79 7A 7B 7C 7D 7E 7F
0080: 80 81 82 83 84 85 86 87
0088: 88 89 8A 8B 8C 8D 8E 8F
0090: 90 91 92 93 94 95 96 97
0098: 98 99 9A 9B 9C 9D 9E 9F
00A0: A0 A1 A2 A3 A4 A5 A6 A7
00A8: A8 A9 AA AB AC AD AE AF
00B0: B0 B1 B2 B3 B4 B5 B6 B7
00B8: B8 B9 BA BB BC BD BE BF
00C0: C0 C1 C2 C3 C4 C5 C6 C7
00C8: C8 C9 CA CB CC CD CE CF
00D0: D0 D1 D2 D3 D4 D5 D6 D7
00D8: D8 D9 DA DB DC DD DE DF
00E0: E0 E1 E2 E3 E4 E5 E6 E7
00E8: E8 E9 EA EB EC ED EE EF
00F0: F0 F1 F2 F3 F4 F5 F6 F7
00F8: F8 F9 FA FB FC FD FE FF
Memoria de Datos PIC16F877
Tabla 8.4.
Ahora analice detenidamente el siguiente programa tomando en cuenta cada
comentario. Notará que la clave que hemos establecido en el programa es
una serie de dígitos consecutivos “123456””.
También podrá notar que seguimos utilizando la misma rutina para el control
del teclado matricial.
171
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
' Configuración de Puertos:
TRISA = %00000000
TRISB = %00000000
TRISD = %01111000
' Declaramos las variables:
X VAR Byte
VAR1 VAR Byte
DIGITO VAR Byte[7]
CLV VAR Byte[7]
' Guardamos cada digito de la clave en las posiciones elegidas previamente:
Write 10, 1 ' Primer dígito de la clave
Write 11, 2 ' Segundo dígito de la clave
Write 12, 3 ' Tercer dígito de la clave
Write 13, 4 ' Cuarto dígito de la clave
Write 14, 5 ' Quinto dígito de la clave
Write 15, 6 ' Sexto dígito de la clave
' Iniciamos el sistema con una bienvenida:
Inicio:
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Cont. de Acceso"
LCDOut $fe,$C0, "** Bienvenido **"
Pause 2000 ' Hacemos una pausa de 2 segundos
Call Beep ' Generamos un sonido
Clave:
X = 0 ' inicializamos la variable X = 0
Read 10, CLV[1] ' leemos el primer dígito y lo guardamos en CLV[1]
Read 11, CLV[2] ' leemos el segundo dígito y lo guardamos en CLV[2]
Read 12, CLV[3] ' leemos el tercer dígito y lo guardamos en CLV[3]
Read 13, CLV[4] ' leemos el cuarto dígito y lo guardamos en CLV[4]
Read 14, CLV[5] ' leemos el quinto dígito y lo guardamos en CLV[5]
Read 15, CLV[6] ' leemos el sexto dígito y lo guardamos en CLV[6]
LCDOut $fe, 1 ' Limpia la LCD
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Introduzca su "
LCDOut $fe,$C0, "Clave de Acceso:"
Call Beep ' Generamos un sonido
172
Consulta:
Call Teclado ' Consultamos el teclado
If VAR1 = 0 Then consulta ' Si no hay una tecla pulsada vuelve a consultar
' Si VAR1 es diferente de cero, significa que pulsamos una tecla, por lo
' tanto generamos un sonido y continuamos…
Call Beep ' Generamos un sonido
' Seguidamente lo que hacemos es almacenar
' en seis variables definidas
' por el programador los dígitos introducidos
' desde el teclado matricial
' para luego ser comparados con los valores
' almacenados en la memoria de datos.
X = X + 1
DIGITO[X] = VAR1 ' El valor de la tecla pulsada lo
' guardamos en la variable correspondiente
If X = 6 Then comprobar ' Si X = 6 estamos guardando en DIGITO[6]
' el último valor introducido desde el
' teclado matricial
GoTo consulta ' Si X es diferente de 6 continuamos
' esperando el siguiente valor a ser
' ingresado desde el teclado
' A partir de la siguiente etiqueta empezamos la comprobación,
' y el formato es:
'
' Si DIGITO[X] es igual a CLV[X] el digito es correcto,
' y salta a la etiqueta “paseX”,
' si es diferente salta a la subrutina “error”; veamos…
Comprobar:
If DIGITO[1] = CLV[1] Then pase1:GoTo error
pase1:
If DIGITO[2] = CLV[2] Then pase2:GoTo error
pase2:
If DIGITO[3] = CLV[3] Then pase3:GoTo error
pase3:
If DIGITO[4] = CLV[4] Then pase4:GoTo error
pase4:
If DIGITO[5] = CLV[5] Then pase5:GoTo error
pase5:
If DIGITO[6] = CLV[6] Then correcto:GoTo error
' Si los seis dígitos han sido correctos
' se ejecuta la subrutina correspondiente.
173
Correcto:
Pause 500
LCDOut $fe, 1 ' Limpia la LCD
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut " * * * * * * "
LCDOut $fe,$C0, "Clave Correcta!"
Call beep ' Generamos un sonido
Pause 3000 ' Pausa para visualizar el mensaje
GoTo inicio
Error:
Pause 500
LCDOut $fe, 1 ' Limpia la LCD
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut " * * * * * * "
LCDOut $fe,$C0, " ERROR! "
Call beep ' Generamos un sonido
Call beep ' Generamos un sonido
Call beep ' Generamos un sonido
Pause 1500 ' Pausa para visualizar el mensaje
GoTo clave ' Salta a “clave” para nueva oportunidad
' La siguiente subrutina genera un “Beep” en el Buzzer
' conectado en RC0.
Beep:
High portc.0 ' Estado Lógico Alto para RC0
Pause 100 ' Pausa de 100 milisegundos
Low portc.0 ' Estado Lógico Bajo para RC0
Pause 100 ' Pausa de 100 milisegundos
Return ' Retorna una línea después del llamado "Call"
Teclado:
VAR1 = 0
PORTD.0 = 0 ' Columna 1 = 0
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then VAR1 = 1 ' tecla "1"
If PORTD.4 = 0 Then VAR1 = 4 ' tecla "4"
If PORTD.5 = 0 Then VAR1 = 7 ' tecla "7"
If PORTD.6 = 0 Then VAR1 = 10 ' tecla "*"
174
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 0 ' Columna 2 = 0
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then VAR1 = 2 ' tecla "2"
If PORTD.4 = 0 Then VAR1 = 5 ' tecla "5"
If PORTD.5 = 0 Then VAR1 = 8 ' tecla "8"
If PORTD.6 = 0 Then VAR1 = 11 ' tecla "0"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 0 ' Columna 3 = 0
If PORTD.3 = 0 Then VAR1 = 3 ' tecla "3"
If PORTD.4 = 0 Then VAR1 = 6 ' tecla "6"
If PORTD.5 = 0 Then VAR1 = 9 ' tecla "9"
If PORTD.6 = 0 Then VAR1 = 12 ' tecla "#"
Return ' Retorna una línea después del llamado "Call"
End
175
Interrupciones Capitulo IX
9.1.- ¿Qué son las Interrupciones?
Las interrupciones son cambios de trayectorias del flujo de un programa
causadas por agentes externos de mayor prioridad. Cuando esto ocurre, el
microcontrolador detiene el programa en curso, almacena la dirección en la
cual se ha detenido y salta a un vector de interrupción previamente definido
en el programa.
9.2.- Fuentes de Interrupciones:
A continuación mencionaremos cuatro posibles fuentes de interrupción en un
microcontrolador PIC16F84:
1. Activación de interrupción por el pin RB0/INT.
2. Desbordamiento del temporizador TMR0.
3. Cambio de estado de uno de los pines más significativos del puerto B
(RB4-RB7).
4. Finalización de la escritura en la EEPROM de datos.
Estas posibles fuentes de interrupción pueden aumentar en
microcontroladores mas avanzados.
9.3.- Registro INTCON:
Para aprender a controlar una de estas fuentes de interrupción, debemos
estudiar el registro de control de interrupciones “INTCON”, con el cual
podremos habilitar el inspector de interrupciones, seleccionar el tipo de
interrupción y consultar las banderas de interrupciones.
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
GIE EEIE TOIE INTE RBIE TOIF INTF RBIF
Figura 9.1.
176
GIE:
1 = habilita todas las interrupciones.
0 = deshabilita las interrupciones.
EEIE:
1 = habilita la interrupción por escritura de la EEPROM.
0 = deshabilita la interrupción por escritura de la EEPROM.
TOIE:
1 = habilita la interrupción por temporizador TMR0.
0 = deshabilita la interrupción por temporizador TMR0.
INTE:
1 = habilita la interrupción por RB0/INT.
0 = deshabilita la interrupción por RB0/INT.
RBIE:
1 = habilita la interrupción por puerto B (RB4-RB7).
0 = deshabilita la interrupción por puerto B.
TOIF: (Bandera de interrupción por desborde del TMR0)
1 = cuando TMR0 pasa de FFh a 00h.
Este bit debe ponerse a cero por software.
INTF: (Bandera de interrupción por RB0/INT)
1 = cuando ocurre una interrupción en RB0/INT.
Este bit debe ponerse a cero por software.
RBIF: (Bandera de interrupción por puerto B)
1 = cuando las entradas RB7 a RB4 cambian de estado.
Este bit debe ponerse a cero por software.
177
9.4.- Activación de interrupción a través del pin RB0/INT:
Para activar esta interrupción, lo primero que debemos tomar en cuenta es la
configuración del bit 4 (INTE) del registro INTCON, el cual deberá estar en “1”.
Otro paso importante antes de empezar a ejecutar la rutina principal de un
programa, será definir el vector de interrupción y habilitar el inspector de
interrupciones.
Estos pasos se pueden ver claramente en el programa propuesto para el
proyecto que presentamos a continuación.
9.5.- Proyecto #25. En el siguiente circuito hemos conectado un diodo LED
en el pin RA0, el cual deberá destellar a una frecuencia de 1 Hz. La
interrupción ocurre cuando activamos P1, lo cual produce un salto hacia el
vector de interrupción, en el cual habrá una rutina encargada de hacer
destellar un LED conectado en el pin RA1.
Figura 9.2.
178
Proyecto # 25
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
LED 2
Resistencia de 220 Ohm 2
Resistencia de 10K Ohm 1
Pulsador Normalmente Abierto 1
Fuente regulada de 5 Vdc 1
Tabla 9.1.
Figura 9.3.
Lea detenidamente los comentarios en cada línea y analice el funcionamiento
del programa y del registro INTCON:
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
179
TRISA = %00000000 ' Configura el Puerto A como salida
TRISB = %00000000 ' Configura el Puerto B como salida
I VAR Byte
Symbol LED1 = PORTA.0
Symbol LED2 = PORTA.1
Symbol INTEDG = OPTION_REG.6 ' Bit 6 del registro “Option”
' El bit 6 (INTEDG) del registro Option define si la interrupción será
' activada por flanco positivo o negativo.
On Interrupt GoTo Interrup ' Define el vector de interrupción.
INTCON = %10010000 ' Activa el inspector de interrupciones y
' habilita la interrupción RB0/INT.
PORTA = $00 ' Inicializa el puerto A.
LED1 = 0 ' Apaga el Led1
LED2 = 0 ' Apaga el Led2
INTEDG = 0 ' Cero (0) para activación de RB0/INT en flanco descendente
' Uno (1) para activación de RB0/INT en flanco ascendente
Inicio:
LED1 = 1 ' Enciende el Led1
Pause 1000 ' Pausa de 1000 ms (1 segundo)
LED1 = 0 ' Apaga el Led1
Pause 1000 ' Pausa de 1000 ms (1 segundo)
GoTo Inicio ' Salta a la etiqueta inicio
' Rutina de interrupción:
Interrup:
Disable ' Detiene al inspector de interrupciones mientras
' ejecuta las siguientes líneas:
For I = 1 To 6
LED2 = 1 ' Enciende el Led2
Pause 200 ' Pausa de 200 ms
LED2 = 0 ' Apaga el Led1
Pause 200 ' Pausa de 200 ms
Next I
INTCON = %10010000 ' Habilita las interrupciones (GIE=1)
' Habilita la interrupción RB0/INT (INTE=1)
' Inicializa la interrupción (INTF=0)
Enable ' Habilita el inspector de interrupciones.
Resume ' GIE = 1 y retorna al punto donde había quedado
' antes de la interrupción.
End
180
9.6.- Interrupción TMR0:
El registro TMR0 es un contador ascendente de ocho bits, el cual también
puede ser configurado como temporizador. Este registro produce una
interrupción cuando su conteo pasa de 255 ($FF) a 0 ($00). Cuando esto
ocurre, la bandera de interrupción TOIF en el registro INTCON se activa, es
decir, TOIF = 1.
La Figura 9.4 representa el funcionamiento del registro TMR0:
Figura 9.4.
181
El Bit “TOSE” del registro OPTION, elige el tipo de flanco activo cuando el
contador TMR0 es incrementado a través del pin RA4/TOCKI, es decir,
determina si el incremento se hará con el flanco de bajada o con el flanco de
subida de la señal aplicada.
“TOCKI” es una señal generada por un circuito externo aplicada al pin
RA4/TOCKI. A través de esta entrada es posible contar el número de pulsos
que lleguen a ella, y producir una interrupción por desborde cuando el
contador pasa de 255 ($FF) a 0 ($00). Se utiliza cuando deseamos que el
registro TMR0 se comporte como contador, y esto es posible configurando el
Bit “TOCS” del registro OPTION (TOCS = 1).
“FOSC/4” es una señal de reloj interna que genera pulsos que tienen una
frecuencia conocida y la cual depende del oscilador principal. FOSC/4 se
utiliza cuando queremos que el registro TMR0 se comporte como
temporizador, y esto se logra configurando el Bit “TOCS” del registro OPTION
(TOCS = 0).
“PRESCALER” el un divisor programable de frecuencia el cual se configura
seleccionando los bits PS2, PS1 y PS0 (bits menos significativos del Registro
OPTION). Para programar el PRESCALER, contamos con una tabla que
define los valores del Divisor (ver tabla 9.2).
“PSA” asigna el divisor de frecuencias y también puede ser programado a
través del bit 3 del registro OPTION.
9.7.- Registro OPTION:
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
RBPO# INTEDG TOCS TOSE PSA PS2 PS1 PS0
Figura 9.5.
RBP0#:
1 = resistencias Pull-Up del puerto B activadas.
0 = resistencias Pull-Up del puerto B desactivadas.
182
INTEDG: (Flanco activo de interrupción externa)
1 = activación de la interrupción con flanco ascendente
0 = activación de la interrupción con flanco descendente
TOCS:
1 = señal de reloj introducida a través de RA4/TOCKI
0 = señal de reloj interno FOSC/4
TOSE:
1 = incrementa TMR0 con flanco descendente de RA4/TOCKI
0 = incrementa TMR0 con flanco ascendente de RA4/TOCKI
PSA:
1 = asigna el divisor de frecuencia a WDT
0 = asigna el divisor de frecuencia a TMR0
PS2,PS1,PS0:
PS2 PS1 PS0
Divisor de
TMR0
Divisor de
WDT
0 0 0 1:2 1:1
0 0 1 1:4 1:2
0 1 0 1:8 1:4
0 1 1 1:16 1:8
1 0 0 1:32 1:16
1 0 1 1:64 1:32
1 1 0 1:128 1:64
1 1 1 1:256 1:128
Tabla 9.2.
183
9.8.- Proyecto #26. Para dar un ejemplo de aplicación del Registro TMR0
como temporizador, crearemos un programa que haga destellar un Led con
una frecuencia de 1 Hz. Este proceso se debe cumplir de la siguiente manera:
1. Encender el Led.
2. Esperar un segundo (1000 milisegundos).
3. Apagar el Led.
4. Esperar un segundo (1000 milisegundos).
5. Repetir todo el proceso.
En este punto resulta importante saber cuanto es la temporización máxima
que se puede lograr con TMR0. Para esto, será necesario aplicar una fórmula
sencilla:
Temporización TMR0 = 4 / Fosc x (256 - Valor a cargar en TMR0) x Prescaler
Fosc: Depende del Oscilador que usemos, y en este ejemplo utilizamos un
cristal de 4 Mhz, por lo tanto Fosc = 4000000.
Valor a cargar en TMR0: es el valor desde el cual se inicia el conteo para
generar el desborde. En este caso cargaremos cero, para garantizar que
cuente los 256 ciclos completos.
Prescaler: según la tabla 9.2, el valor máximo para el divisor del TMR0 es
256.
Entonces;
Temporización TMR0 = (4 / 4000000) x (256 - 0) x (256)
Temporización TMR0 = 0,065536 Segundos 65,536 milisegundos
Obviamente este tiempo no es suficiente para generar el retardo deseado de
1000 milisegundos, por lo cual proponemos entonces calcular el valor a
cargar en el registro TMR0, para un tiempo de desborde de 50 milisegundos,
el cual repetiremos 20 veces, dando como resultado un retardo de 1000
milisegundos, es decir, 1 segundo.
184
Entonces, aplicando la formula tenemos:
Temporización TMR0 = (4 / Fosc) x (256 – Valor a cargar en TMR0) x Prescaler
50 ms= (4 / 4000000) x (256 – Valor a cargar en TMR0) x 256
Despejando la incógnita tenemos que:
Valor a cargar en TMR0 = 256 – (50ms / (256 x 0,000001))
Valor a cargar en TMR0 = 256 – 195
Valor a cargar en TMR0 = 61
El valor a cargar en el registro TMR0 para que se produzca un desborde cada
50 milisegundos es 61.
Realice el montaje correspondiente al diagrama esquemático de la figura 9.6 y
analice detenidamente el programa que se muestra a continuación:
Figura 9.6.
185
Proyecto # 26
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
LED 1
Resistencia de 220 Ohm 1
Fuente regulada de 5 Vdc 1
Tabla 9.3.
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
I var Byte ' Declaración de la variable “I” tipo Byte.
On Interrupt GoTo retardo ' Define el vector de Interrupción
Symbol TOIF = INTCON.2 ' Alias para el bit 2 del registro INTCON.
Symbol GIE = INTCON.7 ' Alias para el bit 7 del registro INTCON.
Symbol LED = PORTA.0 ' Alias para el pin RA0
OPTION_REG = %0000111 ' Configuración del Registro OPTION
INTCON = %10100000 ' Configuración del Registro INTCON
Disable
Inicio:
High LED ' Enciende el Led
Call Retardo ' Llama a la rutina de retardo
Low LED ' Apaga el Led
Call Retardo ' Llama a la rutina de retardo
GoTo Inicio ' Salta a la etiqueta “inicio”.
Retardo:
For I = 1 To 20 ' Repetimos la interrupción 20 veces para
' obtener un retardo de 1 segundo.
Call Retardo1
Next I
Return
Retardo1: ' Retardo de 50 ms
' TMR0 se desborda cada 50 ms. Para calcular este valor
' Utilizamos la formula:
' Tiempo = 4 x Periodo x Valor a cargar en TMR0 x Valor del Divisor
' El cálculo del dato a cargar en TMR0 es:
186
' TMR0 = 256 - (0.050/0.000256) = 60,68 = 61
TMR0 = 61 ' Cargamos el dato en TMR0
Espera:
If TOIF = 1 Then Reseteo ' pregunta si TOIF es igual a 1, es decir,
' pregunta si TMR0 se desbordo.
GoTo Espera ' Salta a la etiqueta “Espera”.
Reseteo:
TOIF = 0 ' Inicializa la bandera TOIF
Return
Resume
End
9.9.- Interrupción por cambio de estado de uno de los pines más
significativos del puerto B (RB4-RB7):
Activar la interrupción por cambio de estado en los pines RB4, RB5, RB6 y
RB7 es muy sencillo, y lo podemos hacer a través del registro INTCON,
donde contamos con un bit llamado RBIE, que activa o desactiva este tipo de
interrupción, es decir, podemos configurar este registro de la siguiente
manera:
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
GIE EEIE TOIE INTE RBIE TOIF INTF RBIF
Figura 9.7.
INTCON = %10001000
GIE = 1, con este bit en estado lógico “1”, habilitamos las interrupciones.
RBIE = 1, con este bit en estado lógico “1”, habilitamos las interrupciones por
cambio de estado en el puerto B.
187
Es importante tomar en cuenta el registro de configuración del puerto B
(TrisB), en el cual debemos configurar los bits más significativos como
entrada.
TRISB = %1111XXXX, donde las X representan cualquier estado I/O debido a
que estos pines no serán utilizados.
9.10.- Proyecto #27. Para verificar el funcionamiento de estas interrupciones,
realice el circuito de la figura 9.8. En esta oportunidad el LED conectado en el
pin RA0 destella a una frecuencia de 1 Hz. Cuando se produce una
interrupción en cualquiera de los pines RB4, RB5 RB6 y RB7, el LED
conectado en el pin RA1 destella seis veces a una frecuencia de 1 Hz.
Figura 9.8.
188
Proyecto # 27
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
LED 2
Resistencia de 220 Ohm 2
Resistencia de 10K Ohm 4
Pulsador Normalmente Abierto 4
Fuente regulada de 5 Vdc 1
Tabla 9.4.
En este circuito las entradas RB4, RB5, RB6 y RB7 están normalmente en “0”;
para producir una interrupción bastará con activar cualquiera de los
pulsadores, para poner un “1” en la entrada correspondiente.
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISA = %00000000 ' Configura el puerto A como salida.
TRISB = %11110000 ' Configura los 4 bits más significativos como
' entrada.
I VAR Byte ' Declaración de la variable "I" tipo Byte
Symbol LED1 = PORTA.0 ' Alias para el pin RA0
Symbol LED2 = PORTA.1 ' Alias para el pin RA1
On Interrupt GoTo Interrup ' Define el vector de interrupción
INTCON = %10001000 ' habilita la interrupción RB4-RB7
Inicio:
LED1 = 1 ' Enciende el Led 1
Pause 1000 ' Pausa de 1 segundo
LED1 = 0 ' Apaga el Led 1
Pause 1000 ' Pausa de 1 segundo
GoTo Inicio ' Salta a la etiqueta "Inicio"
189
Interrup:
Disable
For I = 1 To 6
LED2 = 1 ' Enciende el Led 2
Pause 1000 ' Pausa de 1 segundo
LED2 = 0 ' Apaga el Led 2
Pause 1000 ' Pausa de 1 segundo
Next I
INTCON = %10001000 ' habilita las interrupciones (GIE=1)
' habilita la interrupción RB4-RB7 (RBIE=1)
' Inicializa la interrupción (RBIF=0)
Resume
Enable
End
190
Memoria Serial I2C Capitulo X
10.1.- ¿Qué es el bus I2C?
Se puede definir al Bus I2C como un puente de comunicaciones a dos hilos
entre los circuitos integrados de un sistema, desarrollado por la empresa
Philips y el cual se ha convertido en un estándar mundial para el control de
dispositivos como memorias EEPROM, sensores de temperatura,
convertidores A/D y D/A, entre otros dispositivos.
La tasa de transferencia de datos llega a niveles que van desde los 100 Khz
para un oscilador de 4 Mhz, hasta 400 khz para un oscilador de 20 Mhz. Si
deseamos utilizar una taza de transferencia inferior a 100 Khz la siguiente
directiva deberá ser definida al inicio del programa:
DEFINE I2C_SLOW 1
También es importante mencionar que el bus I2C tiene una capacidad de
conexión máxima de carga de 400 pF, que se traduce en aproximadamente
25 dispositivos entre memorias, sensores, convertidores A/D, etc. En el bus
I2C es necesario que al menos exista un chip maestro, que en nuestro caso
será un microcontrolador. A él podrán conectarse varios dispositivos I2C
esclavos a través del bus, donde cada uno de ellos se puede comunicar con
el dispositivo maestro, transmitiendo información de un lado a otro. En el bus
I2C también puede haber más de un chip maestro, todos con las mismas
prioridades.
Cada dispositivo I2C cuenta con una única dirección de 7 bits, de tal manera
que el microcontrolador podrá saber exactamente a cual de ellos transferir
información y a cual de ellos solicitar información en cualquier momento. Los
cuatro bits más significativos de esta dirección regularmente siempre estarán
fijos y su estado depende del tipo de dispositivo a ser conectado. Por ejemplo,
para una memoria EEPROM serial, los cuatro bits mas significativos en la
dirección siempre será 1010.
191
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
1 0 1 0 A2 A1 A0 R/W
Figura 10.1.
Los Bits 1, 2 y 3 son programables a través de los pines A0, A1 y A2 (ver
figura 10.2), con ellos seleccionamos la dirección de cada memoria EEPROM
conectada al Bus:
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
1 0 1 0 A2 A1 A0 R/W
Figura 10.2.
Figura 10.3.
El bit 0 es una bandera que indica el estado actual de la memoria, “lectura” o
“escritura”.
El Pin WP (Write Protection) debemos conectarlo a tierra (Gnd) si deseamos
escribir datos en la memoria.
El Pin SDA (Serial Data) es bi-direccional y es utilizado para transferir
direcciones y datos a un dispositivo I2C.
El Pin SCL (Serial Clock) se utiliza para sincronizar la transferencia de datos y
los dispositivos conectados al bus I2C.
Las instrucciones de programa en PicBasic para el control del bus I2C son
“I2Cread” e “I2CWrite”, con las cuales realizaremos los siguientes proyectos, y
192
en los cuales podremos almacenar datos y extraer datos de una memoria
serial 24LC256.
10.2.- Proyecto #28. En el siguiente ejemplo hemos empleado como
dispositivo maestro un microcontrolador PIC16F877, el cual tiene conectado
una memoria EEPROM 24LC256, además de una pantalla LCD para
visualizar los datos al momento de realizar la lectura de la memoria (figura
10.4).
Figura 10.4.
193
Proyecto # 28 - 29
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 22 pF 2
Pantalla LCD 16x2 1
Resistencia de 4,7K Ohm 2
Potenciómetro de 5K Ohm 1
Memoria EEPROM 24LC256 1
Fuente regulada de 5 Vdc 1
Tabla 10.1.
I2CWRITE
Sintaxis:
I2CWrite SDA, SCL, Control, Dirección, [dato], {etiqueta de salto opcional}
La instrucción I2CWrite enviará el dato de control y la dirección en la cual se
almacenará el dato cargado en la variable previamente cargada.
La primera actividad consiste en escribir un dato en una dirección específica
de la memoria de datos EEPROM conectada al bus I2C.
Analice el siguiente programa:
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Symbol SDA = PORTB.0 ' Alias para RB0
Symbol SCL = PORTB.1 ' Alias para RB1
194
Direc VAR Word ' Declaración de variable "Direc"
Control VAR Byte ' Declaración de variable "Control"
Dato VAR Byte ' Declaración de variable "Dato"
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
Control = $A0 ' Dato de Control
Direc = $10 ' Dirección en la memoria externa
Dato = $23 ' Dato a ser cargado en la dirección
' especificada ($23 = 35 Decimal)
I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria
Pause 10 ' Pausa de 10 milisegundos
LCDOUT $fe, 2, "Dato Grabado" ' Muestra mensaje por la LCD
Loop: GoTo Loop
End
A partir de la etiqueta “Inicio”, asignamos valores a las variables declaradas.
El dato de control, el cual contiene la dirección de la memoria 24LC256 es
“$A0”; la dirección en la cual vamos a almacenar un dato en este ejemplo será
“$10”; y por último el dato a ser almacenado será “$23”.
Si se pregunta porqué el dato de control es $A0, podrá obtener la respuesta
verificando la conexión de la memoria en el circuito de la figura 10.4. Observe
que los pines A2, A1 y A0, los hemos conectado a tierra.
Recuerde que estos tres pines definen la dirección del dispositivo; entonces,
debemos tomar en cuenta que para una memoria serial, los cuatro bits más
significativos están configurados como “1010xxxx”; los tres bits A2, A1 y A0
están conectados a tierra en este proyecto; y el bit R/W debe estar en “0” para
poder escribir un dato en la memoria (ver figura 10.5).
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 (A2) Bit 2 (A1) Bit 1 (A0) Bit 0 (R/W)
1 0 1 0 0 0 0 0
A 0
Figura 10.5.
195
Para enviar el dato a la memoria en la dirección especificada, utilizamos la
instrucción I2CWrite de la siguiente manera:
I2Cwrite PORTB.0, PORTB.1, $A0, $10, [$23]
Note que en el programa utilizamos los alias y las variables:
I2Cwrite SDA, SCL, Control, Direc, [dato]
Seguidamente se requiere de una pausa de 10 milisegundos, para asegurar el
tiempo necesario para la grabación del dato en la memoria. Una vez finalizada
la pausa, procedemos a mostrar un mensaje en la pantalla LCD, indicando
que el dato ya ha sido grabado.
I2CREAD
Sintaxis:
I2Cread SDA, SCL, Control, Dirección, [dato], {etiqueta de salto opcional}
La instrucción I2Cread enviará el dato de control y la dirección específica a un
dispositivo conectado a un bus I2C y almacenará el dato obtenido en una
variable definida. Al utilizar la etiqueta opcional, el programa saltará si no se
recibe ninguna respuesta del dispositivo consultado.
Para verificar que este dato en realidad está grabado en la memoria, y en la
dirección correcta, veamos el siguiente programa:
Define Osc 4 ' Define el Oscilador para un Cristal de 4 Mhz.
Symbol SDA = PORTB.0 ' Alias para RB0
Symbol SCL = PORTB.1 ' Alias para RB1
A1 Var Byte ' Declaración de variable "A1"
Direc var Word ' Declaración de variable "Direc"
Control Var Byte ' Declaración de variable "Control"
Pause 200 ' Pause de 200 milisegundos
196
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
Direc = $10 ' Dirección en la memoria externa
Control = $A0 ' Dato de Control
I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de Memoria
LCDOUT $fe, 2,"Dato: ",#A1 ' Muestra el dato leido
Ciclo: GoTo Ciclo
End
10.3.- Proyecto #29: El siguiente programa almacena datos a partir de la
dirección cero ($00) de la memoria EEPROM conectada al bus I2C. Se
almacenan números que se incrementan de dos en dos, donde el dato inicial
es igual a 1. Este proyecto está basado en el diagrama de la figura 10.4.
Analice el siguiente programa:
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Symbol SDA = PORTB.0 ' Alias para RB0
Symbol SCL = PORTB.1 ' Alias para RB1
I VAR Byte ' Declaración de variable "I"
A1 VAR Byte ' Declaración de variable "A1"
Direc VAR Word ' Declaración de variable "Direc"
Control VAR Byte ' Declaración de variable "Control"
Dato VAR Byte ' Declaración de variable "Dato"
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Direc = $00 ' Dirección en la memoria externa
Control = $A0 ' Dato de Control
Dato = 1 ' Dato inicial a ser grabado
Escribir:
For I = 0 To 50 ' Repetición
I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria
Pause 10 ' Pausa de 10 milisegundos
If I = 50 Then leer ' Condicional
Direc = Direc + 1 ' Suma 1 a la variable "Direc"
Dato = Dato + 2 ' Suma 2 a la variable "Dato"
Next I
197
Leer:
LCDOUT $fe, 2,"Datos Grabados" ' Muestra mensaje por la LCD
Pause 2000 ' Pausa de 2 segundos
LCDOut $fe, 2,"Inicia Lectura" ' Muestra mensaje por la LCD
Pause 2000 ' Pausa de 2 segundos
Direc = $00 ' Inicializa la dirección en la memoria externa
For I = 0 To 50 ' Repetición
I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de memoria
LCDOUT $fe, 2,"Dato ",#I,": ",#A1," " ' Muestra el dato leido
Pause 1000 ' Pausa de 1 segundo
If I = 50 Then final ' Condicional
Direc = Direc + 1 ' Suma 1 a la variable "Direc"
Next I
Final:
GoTo Final ' Salta a la etiqueta "final"
End
En caso de requerir mayor capacidad de memoria de datos para nuestros
proyectos, podemos utilizar memorias como la 24LC512 o varias de menor o
igual capacidad conectadas al bus I2C como se observa en la figura 10.6.
Por supuesto, es importante resaltar que cuando se tiene mas de una
memoria conectada al bus, se debe considerar el conexionado de los Pines 1,
2 y 3 (A0, A1 y A2 respectivamente). En el programa también debemos tomar
en cuenta que para leer cada una de estas memorias, tenemos que
especificar la dirección del “dispositivo”.
198
10.4.- Proyecto #30: Veamos el siguiente programa en el cual se almacenan
datos en dos memorias conectadas al bus I2C, para luego ser extraídos y
verificados.
Figura 10.6.
Proyecto # 30
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 22 pF 2
Pantalla LCD 16x2 1
Resistencia de 4,7K Ohm 2
Potenciómetro de 5K Ohm 1
Memoria EEPROM 24LC256 2
Fuente regulada de 5 Vdc 1
Tabla 10.2.
199
Analice el siguente programa, prestando atención a los comentarios de cada
línea:
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Symbol SDA = PORTB.0 ' Alias para RB0
Symbol SCL = PORTB.1 ' Alias para RB1
I VAR Byte ' Declaración de variable "I"
A1 VAR Byte ' Declaración de variable "A1"
Direc VAR Word ' Declaración de variable "Direc"
Control VAR Byte ' Declaración de variable "Control"
Dato VAR Byte ' Declaración de variable "Dato"
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
memoria1:
' Escribimos en la memoria 1 (Pin A0 = 0; Pin A1 = 0; Pin A2 = 0)
' xxxxAAAx
' xxxx210x
Control = %10100000 ' Dato de Control
Direc = $00 ' Dirección en la memoria externa
Dato = 1 ' Dato inicial a ser grabado
For I = 0 To 20 ' Repetición
I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria
Pause 10 ' Pausa de 10 milisegundos
If I = 20 Then confirma1 ' Condicional
Direc = Direc + 1 ' Suma 1 a la variable "Direc"
Dato = Dato + 2 ' Suma 2 a la variable "Dato"
Next I
confirma1:
LCDOUT $fe, 2,"Datos Grabados" ' Muestra mensaje por la LCD
LCDOut $fe,$C0,"Memoria 1 "
Pause 2000 ' Pausa de 2 segundos
' Escribimos en la memoria 2 (Pin A0 = 1; Pin A1 = 0; Pin A2 = 0)
memoria2:
' xxxxAAAx
' xxxx210x
Control = %10100010 ' Dato de Control
200
Direc = $00 ' Dirección en la memoria externa
Dato = 150 ' Dato inicial a ser grabado
For I = 0 To 20 ' Repetición
I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria
Pause 10 ' Pausa de 10 milisegundos
If I = 20 Then confirma2 ' Condicional
Direc = Direc + 1 ' Suma 1 a la variable "Direc"
Dato = Dato + 5 ' Suma 2 a la variable "Dato"
Next I
confirma2:
LCDOUT $fe, 2,"Datos Grabados" ' Muestra mensaje por la LCD
LCDOut $fe,$C0,"Memoria 2 "
Pause 2000
' Iniciamos la lectura en la memoria 1:
lectura1:
LCDOut $fe, 2,"Inicia Lectura" ' Muestra mensaje por la LCD
LCDOut $fe,$C0,"Memoria 1 "
Pause 2000 ' Pausa de 2 segundos
' xxxxAAAx
' xxxx210x
Control = %10100000 ' Dato de Control
Direc = $00 ' Dirección en la memoria externa
For I = 0 To 20 ' Repetición
I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de memoria
LCDOUT $fe, 2,"Dato ",#I,": ",#A1," " ' Muestra el dato leido
Pause 1000 ' Pausa de 1 segundo
If I = 20 Then lectura2 ' Condicional
Direc = Direc + 1 ' Suma 1 a la variable "Direc"
Next I
lectura2:
LCDOut $fe, 2,"Inicia Lectura" ' Muestra mensaje por la LCD
LCDOut $fe,$C0,"Memoria 2 "
Pause 2000 ' Pausa de 2 segundos
' xxxxAAAx
' xxxx210x
Control = %10100010 ' Dato de Control
Direc = $00 ' Dirección en la memoria externa
For I = 0 To 20 ' Repetición
I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de memoria
201
LCDOUT $fe, 2,"Dato ",#I,": ",#A1," " ' Muestra el dato leido
Pause 1000 ' Pausa de 1 segundo
If I = 20 Then final ' Condicional
Direc = Direc + 1 ' Suma 1 a la variable "Direc"
Next I
final:
GoTo final ' Salta a la etiqueta "final"
End
202
Conversor A/D en el PIC16F877 Capitulo XI
11.1.- Conversor A/D.
Los microcontroladores de las familias PIC16F87x y PIC18Fxxx de los cuales
estaremos hablando a continuación, poseen un convertidor Analógico-Digital
que convierte una señal analógica en un número de 8 o 10 bits, según sea la
configuración elegida por el diseñador.
En los microcontroladores PIC de 28 pines como el PIC16F870,
encontraremos que solo poseen 5 entradas para la conversión A/D, y en el
caso particular de los microcontroladores de 40 pines como el PIC16F877 o el
PIC18F442 por ejemplo, se puede observar que poseen 8 canales para
conversión A/D, identificadas por las siglas AN(n), las cuales se encuentran
distribuidas entre el puerto A y el puerto E, como se muestra en el diagrama
de pines de la figura 11.1:
Figura 11.1.
203
En el microcontrolador PIC16F877, cada canal de conversión A/D está
conectado a un pin ubicado en el puerto “A” y en el puerto “E”. Por ejemplo, el
canal AN0 corresponde al pin # 2 del microcontrolador, o expresado de otra
manera, al pin RA0 del puerto A. El canal AN1 corresponde al pin # 3; el canal
AN2 corresponde al pin # 4 y así sucesivamente; entonces se puede ver
claramente que el puerto A cuenta con cinco de los ocho canales del
conversor A/D, y los otros tres canales están ubicados en los pines
correspondientes al puerto E del microcontrolador.
Un punto importante a considerar al momento de utilizar el convertidor A/D,
será decidir si la conversión se hará configurando el conversor a 8 o 10 bits,
con lo cual a su vez estaremos definiendo la resolución en el proceso de
conversión.
Esto significa que si elegimos la conversión de una señal analógica a solo 8
bits (28
= 256), los valores digitales resultantes de la conversión estarán
comprendidos entre 0 y 255 (en binario es de 00000000 hasta 11111111),
como se puede observar en la tabla 11.1:
Decimal BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1
2 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 1 1
4 0 0 0 0 0 1 0 0
250 1 1 1 1 1 0 1 0
251 1 1 1 1 1 0 1 1
252 1 1 1 1 1 1 0 0
253 1 1 1 1 1 1 0 1
254 1 1 1 1 1 1 1 0
255 1 1 1 1 1 1 1 1
………….
………….
REGISTRO BAJO (ADRESL)
Tabla 11.1.
204
Cuando la conversión se hace a 10 bits, la resolución aumenta
considerablemente en relación a la de 8 bits, ya que tenemos 210
= 1024
datos de conversión, como se puede observar en la tabla 11.2:
Decimal BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 1
2 0 0 0 0 0 0 0 0 1 0
3 0 0 0 0 0 0 0 0 1 1
4 0 0 0 0 0 0 0 1 0 0
1018 1 1 1 1 1 1 1 0 1 0
1019 1 1 1 1 1 1 1 0 1 1
1020 1 1 1 1 1 1 1 1 0 0
1021 1 1 1 1 1 1 1 1 0 1
1022 1 1 1 1 1 1 1 1 1 0
1023 1 1 1 1 1 1 1 1 1 1
………….
………….
REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH)
………….
Tabla 11.2.
Para comprender aún mejor este punto, veamos el siguiente ejemplo:
Si configuramos el conversor A/D a 8 bits e introducimos una señal cuya
amplitud varía entre 0 y 5 voltios, y donde el voltaje de referencia del
conversor es 5 voltios, entonces la resolución que obtendremos en la
conversión sería la siguiente:
Resolución = n
Vi
2
max
Resolución = 8
2
5V
205
Resolución =
256
5V
Resolución = 0.0196 ≈ 0.02 V
Esto significa que la resolución a 8 bits para el ejemplo planteado es de 20
mV por cada paso que da el conversor A/D entre 0 y 255.
Si configuramos el conversor A/D a 10 bits, entonces tenemos que 210
= 1024,
y por lo tanto obtenemos una resolución mayor, lo cual podemos demostrar
realizando los cálculos correspondientes:
Resolución = n
Vi
2
max
Resolución = 10
2
5V
Resolución =
1024
5V
Resolución = 0.00488 ≈ 0.0049 V
Entonces la resolución a 10 Bits es de 4.9 mV por cada paso que da el
conversor A/D entre 0 y 1023.
206
Veamos el diagrama de bloques del conversor A/D (figura 11.2):
Figura 11.2.
Resulta interesante saber que se puede obtener más resolución en términos
de voltios por paso, si utilizamos un voltaje de referencia menor al de la
alimentación del microcontrolador a través de los pines “Ref+” o “Ref-“ según
sea el caso.
Por ejemplo, si aplicamos un voltaje de referencia positivo igual a 2.5 voltios
en el pin RA3/AN3/Ref+ del puerto A, el cual ha sido previamente configurado
para esto, entonces:
Resolución = n
Vi
2
max
207
Resolución = 10
2
5.2 V
Resolución =
1024
5.2 V
Resolución = 0.00244 ≈ 0.0025 V
La resolución del conversor A/D sería de 2.5 mV por cada paso entre 0 y
1023. Hay una serie de pasos que debemos tomar en cuenta para llevar a
cabo una conversión A/D, basados en el diagrama de bloques de la figura
11.2:
Lo primero, será configurar los canales de entrada que utilizaremos para
introducir la señal analógica al conversor A/D y los canales para voltajes de
referencia, en el caso de ser necesario. Esto se hace seleccionando la
combinación correspondiente en los bits PCFG3, PCFG2 PCFG1 y PCFG0
del registro de control ADCON1 (figura 11.3).
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
ADFM ------ ------ ------ PCFG3 PCFG2 PCFG1 PCFG0
Figura 11.3.
En este punto es muy conveniente detenerse a analizar la tabla 11.3, que
define cuales pines del puerto A y E serán entradas al conversor A/D, según
la combinación elegida.
208
PCFG3 PCFG2 PCFG1 PCFG0 AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 Vref+ Vref-
0 0 0 0 A A A A A A A A Vdd Vss
0 0 0 1 A A A A Vref+ A A A RA3 Vss
0 0 1 0 D D D A A A A A Vdd Vss
0 0 1 1 D D D A Vref+ A A A RA3 Vss
0 1 0 0 D D D D A D A A Vdd Vss
0 1 0 1 D D D D Vref+ D A A RA3 Vss
0 1 1 x D D D D D D D D Vdd Vss
1 0 0 0 A A A A Vref+ Vref- A A RA3 RA2
1 0 0 1 D D A A A A A A Vdd Vss
1 0 1 0 D D A A Vref+ A A A RA3 Vss
1 0 1 1 D D A A Vref+ Vref- A A RA3 RA2
1 1 0 0 D D D A Vref+ Vref- A A RA3 RA2
1 1 0 1 D D D D Vref+ Vref- A A RA3 RA2
1 1 1 0 D D D D D D D A Vdd Vss
1 1 1 1 D D D D Vref+ Vref- D A RA3 RA2
Tabla 11.3.
El segundo paso será activar el canal en el cual se encuentra presente la
señal analógica para que pase a la etapa de muestreo. La selección de las
entradas analógicas se realiza configurando los bits CHS2 (bit 5), CHS1 (bit 4)
y CHS0 (bit 3) del registro ADCON0 (figura 11.4):
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE ------ ADON
Figura 11.4.
CHS2 CHS1 CHS0 Canal/Pin
0 0 0 = Canal 0 (AN0)/RA0
0 0 1 = Canal 1 (AN1)/RA1
0 1 0 = Canal 2 (AN2)/RA2
0 1 1 = Canal 3 (AN3)/RA3
1 0 0 = Canal 4 (AN4)/RA5
1 0 1 = Canal 5 (AN5)/RE0
1 1 0 = Canal 6 (AN6)/RE1
1 1 1 = Canal 7 (AN7)/RE2
Tabla 11.4.
209
También es posible seleccionar el canal que deseamos utilizar, con la
instrucción de programa ADCin, en la cual sólo se especifica cual será el
canal de entrada de la señal a ser convertida y la variable en la cual se
almacenará el resultado de la conversión.
Por ejemplo: ADCin 0, temperatura
Significa que el resultado de la conversión de una señal presente en la
entrada “AN0” será almacenado en la variable “temperatura”, la cual ha sido
previamente definida en el programa.
Aunque la instrucción ADCin se encarga de controlar el registro ADCON0
ahorrando algunas líneas de programa, consideramos conveniente hacer una
revisión de los registros de control del conversor A/D.
11.2.- El registro ADCON0:
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE ------ ADON
Figura 11.5.
Bit 7 y Bit 6: Selección del reloj del conversor A/D.
ADCS1 ADCS0
0 0 = Fosc/2
0 1 = Fosc/8
1 0 = Fosc/32
1 1 = FRC
Conversión del Reloj
Tabla 11.5.
210
Bit 5, Bit 4 y Bit 3: Selección del canal de entrada.
CHS2 CHS1 CHS0 Canal/Pin
0 0 0 = Canal 0 (AN0)/RA0
0 0 1 = Canal 1 (AN1)/RA1
0 1 0 = Canal 2 (AN2)/RA2
0 1 1 = Canal 3 (AN3)/RA3
1 0 0 = Canal 4 (AN4)/RA5
1 0 1 = Canal 5 (AN5)/RE0
1 1 0 = Canal 6 (AN6)/RE1
1 1 1 = Canal 7 (AN7)/RE2
Tabla 11.6.
Bit 2: Estado de la conversión.
GO/DONE: Solo funciona si ADON = 1
1 = Conversión A/D en progreso.
0 = Conversión A/D detenida.
Bit 1: Este bit no está implementado.
Bit 0: Enciende el conversor A/D.
1 = conversor A/D encendido.
0 = conversor A/D apagado.
11.3.- El registro ADCON1:
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
ADFM ------ ------ ------ PCFG3 PCFG2 PCFG1 PCFG0
Figura 11.6.
Bit 7: Justificación del resultado de la conversión a 10 bits a la derecha o
izquierda.
211
1 = Justifica a la derecha.
0 = Justifica a la Izquierda.
Bit 6 al Bit 4: No están implementados.
Bit3, Bit 2, Bit 1 y Bit 0: Configuración
PCFG3 PCFG2 PCFG1 PCFG0 AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 Vref+ Vref-
0 0 0 0 A A A A A A A A Vdd Vss
0 0 0 1 A A A A Vref+ A A A RA3 Vss
0 0 1 0 D D D A A A A A Vdd Vss
0 0 1 1 D D D A Vref+ A A A RA3 Vss
0 1 0 0 D D D D A D A A Vdd Vss
0 1 0 1 D D D D Vref+ D A A RA3 Vss
0 1 1 x D D D D D D D D Vdd Vss
1 0 0 0 A A A A Vref+ Vref- A A RA3 RA2
1 0 0 1 D D A A A A A A Vdd Vss
1 0 1 0 D D A A Vref+ A A A RA3 Vss
1 0 1 1 D D A A Vref+ Vref- A A RA3 RA2
1 1 0 0 D D D A Vref+ Vref- A A RA3 RA2
1 1 0 1 D D D D Vref+ Vref- A A RA3 RA2
1 1 1 0 D D D D D D D A Vdd Vss
1 1 1 1 D D D D Vref+ Vref- D A RA3 RA2
Tabla 11.7.
A = Entrada Analógica
D = I/O Digital
Para definir en un programa si la conversión A/D se hará a 8 bits o a 10 bits,
se deben utilizar las siguientes directivas:
Conversión a 8 Bits:
Define ADC_BITS 8
212
Esta directiva define que el resultado de la conversión A/D de una señal,
aplicada a cualquiera de los canales, será de 8 bits. Este resultado será
almacenado en un registro definido por el fabricante denominado ADRESL.
BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
REGISTRO BAJO (ADRESL)
Figura 11.7.
Conversión a 10 Bits:
Define ADC_BITS 10
Cuando realizamos la conversión A/D a 10 bits, el resultado de la conversión
se almacena en dos registros, ADRESH y ADRESL, los cuales unidos forman
un solo registro de 16 bits, solo que en la parte alta de éste, los 6 bits mas
significativos (Bit 2 al Bit 7 de ADRESH, figura 11.8) no son tomados en
cuent, es decir, son considerados como “0”. Esto da como resultado que el
valor máximo a ser almacenado en él será: 0000001111111111, es decir,
1023.
BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
0 0 0 0 0 0
REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH)
Figura 11.8.
En la conversión a 10 bits también es muy importante considerar el bit 7
(ADFM) del registro de control ADCON1, ya que este bit mantiene el resultado
de la conversión de 10 bits justificado, ya sea a la derecha si ADFM = 1, como
lo demuestra la figura 11.9, o a la izquierda si ADFM = 0 como lo demuestra la
figura 11.10:
213
BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
0 0 0 0 0 0
REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH)
Figura 11.9.
BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0
0 0 0 0 0 0
REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH)
Figura 11.10.
Cuando justificamos el resultado de la conversión A/D a la izquierda, el bit
menos significativo de éste es el bit 6 del registro ADRESL, y el bit más
significativo es el bit 7 del registro ADRESH.
Nota: En el proceso de conversión A/D, resulta importante considerar un
tiempo mínimo requerido en la etapa de muestreo, necesario para cargar el
condensador de mantenimiento “C-Hold” (ver figura 11.2). El tiempo de
muestreo se define a través de la siguiente directiva:
Define ADC_SAMPLEUS {tiempo}
Ejemplo:
Define ADC_SAMPLEUS 50
214
11.4.- Proyecto #31: A continuación presentamos un ejemplo de conversión
A/D a 8 bits, el cual consta básicamente de un microcontrolador PIC16F877,
un oscilador externo de 10 Mhz, una pantalla LCD para visualizar los
resultados, y un potenciómetro de 5Kohm para introducir un voltaje variable
en un canal de entrada al conversor A/D.
Figura 11.11.
215
Proyecto # 31
Componente Cantidad
PIC16F877A 1
Cristal de 10 Mhz 1
Capacitor cerámico de 22 pF 2
Pantalla LCD 16x2 1
Resistencia de 220 Ohm 2
Potenciómetro de 5K Ohm 2
Fuente regulada de 5 Vdc 1
Tabla 11.8.
ADCin
Sintaxis: ADCin canal, Variable
Esta instrucción solo es válida para microcontroladores que tienen convertidor
A/D, por ejemplo, el PIC16F877, el PIC18F442, el PIC18F452, el PIC18F458
entre otros.
Realice el montaje del circuito propuesto en la figura 11.11, y analice cada
línea de programa leyendo detenidamente los comentarios.
DEFINE OSC 10 ' Define el Oscilador a 10 Mhz
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto (0 o 4) en caso
' de utilizar los cuatro Bits mas significativos de la LCD
DEFINE LCD_RSREG PORTB ' Indica al uC que el pin "RS" estará en el Puerto B
DEFINE LCD_RSBIT 1 ' "RS" estará conectado en RB1
DEFINE LCD_EREG PORTB ' Indica al uC que el pin "E" estará en el Puerto B
DEFINE LCD_EBIT 0 ' "E" estará conectado en RB0
DEFINE LCD_LINES 2 ' Define el número de líneas de la pantalla
216
DEFINE ADC_BITS 8 ' Define la conversión A/D a 8 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
A VAR Byte ' Declaración de una variable tipo Byte (8 bits)
ADCON1 = %00000000 ' Configura el registro ADCON1
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOUT "C-AD a 8 Bit: " ' Muestra mensaje en la línea 1
LCDOUT $fe,$C0," ",Dec A," " ' Muestra dato en la línea 2
PAUSE 100 ' Pausa de 100 milisegundos
GoTo Inicio ' Salta a inicio
End
En este ejemplo, podemos observar como varía el resultado cargado en la
variable “A” al modificar el valor del potenciómetro conectado al canal AN0 del
conversor A/D (figura 11.11). Recordemos que la variable “A”, definida al
inicio del programa, es del tipo Byte (8 Bits), suficiente para una conversión
A/D de 8 Bits.
Además es importante observar que hemos seleccionado una configuración
en el registro ADCON1, para que todos los canales estén activos y
disponibles para una posible solicitud de conversión, y también para que el
voltaje de referencia sea el mismo de la fuente de alimentación del circuito.
Otro detalle importante es que el resultado de la conversión A/D se muestra
en la pantalla LCD en decimal, debido a que se antepone a la variable “A” la
directiva “Dec”.
El resultado de la conversión también lo podemos ver en binario anteponiendo
la directiva “Bin”, o en hexadecimal, anteponiendo la directiva “Hex”.
Si deseamos obtener una mayor resolución en la conversión A/D, podemos
hacer unos cambios en la configuración del conversor, sin necesidad de
modificar el circuito de la figura 11.11.
217
Esto significa que podemos configurar el conversor A/D a 10 Bits, lo cual nos
lleva a considerar los siguientes cambios:
1. Debemos definir ADC_BITS = 10.
2. La variable en la cual será almacenado el resultado, debe ser del tipo
Word (16 Bits), ya que una vez que se desborde el registro ADRESL,
se requerirá disponer de más bits, debido a que el resultado para una
conversión de 10 bits varía entre 0 y 1023.
3. Debemos recordar justificar el resultado de la conversión A/D a la
derecha, configurando el bit 7 del registro ADCON1, es decir, ADFM =
1.
4. El mensaje mostrado en la primera línea de la pantalla LCD deberá ser:
“C-AD a 10 Bit:”.
Analice el siguiente programa en el cual se pueden observar los cambios
antes mencionados:
DEFINE OSC 10 ' Define Oscilador a 10 Mhz
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto (0 o 4) en caso
' de utilizar los cuatro Bits mas significativos de la LCD
DEFINE LCD_RSREG PORTB ' Indica al uC que el pin "RS" estará en el Puerto B
DEFINE LCD_RSBIT 1 ' "RS" estará conectado en RB1
DEFINE LCD_EREG PORTB ' Indica al uC que el pin "E" estará en el Puerto B
DEFINE LCD_EBIT 0 ' "E" estará conectado en RB0
DEFINE LCD_LINES 2 ' Define el número de líneas de la pantalla
Define ADC_BITS 10 ' Define la conversión A/D a 10 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
A VAR Word ' Declaración de una variable tipo word (16 bits)
ADCON1 = %10000000 ' Configura el registro ADCON1
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
218
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOUT "C-AD a 10 Bit: " ' Muestra mensaje en la línea 1
LCDOUT $fe,$C0," ",Dec A," " ' Muestra dato en la línea 2
PAUSE 100 ' Pausa de 100 milisegundos
GoTo Inicio ' Salta a inicio
End
Al modificar el valor del potenciómetro conectado al canal AN0, podemos
observar cómo varía el resultado de la conversión en la pantalla LCD entre 0 y
1023.
Mueva el potenciómetro hasta obtener un resultado cercano a 512 en la
pantalla LCD, y mida con un multímetro el voltaje aplicado en el canal AN0, el
cual deberá ser aproximadamente 2,5 voltios, ya que el voltaje de referencia
según la configuración elegida en el registro de control ADCON1 es el mismo
voltaje que alimenta al circuito, es decir, 5 voltios.
219
Comunicación Serial
Transmisión y Recepción de Datos Capitulo XII
12.1.- Comunicación Serial.
En este capítulo nos dedicaremos a estudiar la comunicación serial asíncrona,
la cual resulta muy útil cuando necesitamos transmitir o recibir datos entre
circuitos gobernados por microcontroladores PIC, o inclusive cuando
deseamos establecer una comunicación entre nuestros circuitos y nuestro PC.
Las instrucciones en PicBasic para la comunicación serial, se rigen bajo el
protocolo de comunicación RS-232, el cual es una norma o estándar mundial
que define los parámetros en la comunicación serial. Este protocolo define
además estándares como la velocidad de transmisión en baudios (300, 1200,
2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200 y 128000
bps), niveles de voltaje, distancia entre dispositivos, entre otros.
Cuando se trata de comunicación serial entre un microcontrolador y un PC, es
importante tomar en cuenta que los niveles de voltaje entre ambos
dispositivos deben ser acoplados, ya que en un puerto serial de un PC, los
niveles de voltaje están comprendidos entre +12V y -12V, y en un
microcontrolador los niveles de voltaje están comprendidos entre 0V y 5V.
Estas y otras características han sido detalladas a lo largo del capítulo a
través de algunas recomendaciones y ejemplos.
A continuación estudiaremos las instrucciones SerIn y SerOut con las cuales
haremos posible la comunicación serial asíncrona entre diversos dispositivos.
Estas dos instrucciones son capaces de emular una comunicación RS-232 en
cualquier microcontrolador que no posea en su hardware USART (Universal
Synchronous / Asynchronous Receiver / Transmitter).
12.2.- Instrucción SerIn: La instrucción SerIn se encarga de recibir uno o
mas valores a través de un pin específico, usando el formato asíncrono
estándar 8N1 que significa 8 bits de datos, sin revisión de paridad y 1 bit de
parada (stop). SerIn trabaja por defecto con un oscilador de 4 Mhz, y para
220
tener una transferencia de datos segura con otros osciladores de mayor valor,
será necesario utilizar la directiva “Define Osc” al inicio del programa.
Ejemplo: Define Osc 20 (para un oscilador de 20 Mhz).
Sintaxis: SERIN pin, modo,{tiempo, etiqueta}, variable
Pin: en este campo definiremos cual será el pin de entrada entre los puertos
disponibles del microcontrolador. Ejemplo: PortB.1
Modo: define la velocidad de transmisión en baudios.
Valor Numérico Modo Tasa de Bps
0 T2400 2400
1 T1200 1200
2 T9600 9600
3 T300 300
4 N2400 2400
5 N1200 1200
6 N9600 9600
7 N300 300
Tabla 12.1.
Ejemplo:
Serin PortC.1, 0, variable Velocidad de transmisión: 2400 bps
Serin PortA.1, 1, variable Velocidad de transmisión: 1200 bps
Serin PortE.0, 2, variable Velocidad de transmisión: 9600 bps
Serin PortC.4, 3, variable Velocidad de transmisión: 300 bps
El campo “Modo” también puede ser definido como se muestra en la columna
2 de la tabla 12.1, incluyendo la librería MODEDEFS.BAS en el inicio del
programa (Include "modedefs.bas"), o utilizando directamente la
instrucción “SYMBOL” como se muestra a continuación:
221
Symbol T2400 = 0 ' Dato verdadero (Driven True)
Symbol T1200 = 1 ' Dato verdadero (Driven True)
Symbol T9600 = 2 ' Dato verdadero (Driven True)
Symbol T300 = 3 ' Dato verdadero (Driven True)
Symbol N2400 = 4 ' Dato invertido (Driven inverted)
Symbol N1200 = 5 ' Dato invertido (Driven inverted)
Symbol N9600 = 6 ' Dato invertido (Driven inverted)
Symbol N300 = 7 ' Dato invertido (Driven inverted)
Tiempo: este campo es opcional al igual que el campo “etiqueta”, y su objetivo
es establecer un tiempo en milisegundos definido por el programador, el cual
una vez vencido, hará que se realice un salto a la “etiqueta”, también definida
por el programador. Ejemplo:
Serin PortA.3, 2, 10, inicio, variable
Este ejemplo se interpreta de la siguiente forma: el microcontrolador recibe los
datos por el pin RA3 a 9600 bps en formato de dato verdadero; si no se
reciben datos durante 10 milisegundos, salta a la etiqueta “inicio”; si recibe
datos lo almacena en la variable y continúa con el programa.
Variable: En este campo se especifica la variable en la cual se desea sean
almacenados los datos recibidos. Ejemplo:
Serin PortC.7, 4, dato
12.3.- Proyecto #32: En este proyecto vamos a transmitir datos desde un PC
hacia un microcontrolador PIC16F877, utilizando un circuito integrado
MAX232 entre ambos dispositivos y donde los datos enviados desde el PC
serán visualizados en una pantalla LCD.
Para enviar datos desde el PC hacia el microcontrolador, explicaremos como
realizar un pequeño proyecto en Visual Basic, en el cual haremos un teclado
matricial 3x4, que enviará un dato por cada tecla presionada a través del
puerto serial COM1.
Para ello será necesario construir el circuito de la figura 12.1. Es importante
tomar en cuenta en la construcción de este circuito, la polaridad de los
222
condensadores de 1 uF, ya que una polaridad invertida afectará
negativamente el funcionamiento del MAX232 (Observe la polaridad de cada
condensador en la figura 12.2).
Entre los pines 15 (Gnd) y 16 (Vcc) del MAX232 se debe conectar un
condensador de 1 uF como se muestra en la figura 12.2, ya que la ausencia
de este componente también afectará el funcionamiento del circuito
produciendo errores en la recepción de datos.
Figura 12.1.
223
Proyecto # 32
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 22 pF 2
Pantalla LCD 16x2 1
Resistencia de 220 Ohm 1
Capacitor Electrolítico de uF 5
Conector DB-9M 1
IC MAX232 1
Fuente regulada de 5 Vdc 1
Tabla 12.2.
Figura 12.2.
224
' Programa en Pic Basic Pro
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Symbol T9600 = 2 ' Dato verdadero (Driven True)
dato var Byte ' Define la variable “dato” como Byte
pause 500 ' Pausa de 500 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
inicio:
SerIn PORTC.7, T9600, dato ' espera datos durante 1 ms
LCDOUT $fe, 2,"Dato: "
LCDOut $fe,$C0,#dato," "
GoTo inicio ' Salta a inicio
End
Como velocidad de transmisión, hemos elegido utilizar 9600 bps, por lo cual
debemos definir este valor en nuestro programa.
Las señales con las que actúa el puerto del PC son digitales y la tensión con
la cual trabaja es +12V y -12V; adicionalmente resulta importante saber que la
lógica es invertida, es decir:
+12 V Lógica = “0”
-12 V Lógica = “1”
De ahí la importancia de saber cual será el formato que debemos utilizar a la
hora de definir los parámetros para la comunicación (dato verdadero, o dato
invertido).
En este caso y como se puede observar en la segunda línea de programa
(Symbol T9600 = 2), esteremos utilizando el formato “driven true”, debido a que
el MAX232 tiene en sus salidas un inversor para los datos provenientes del
puerto serial del PC hacia el microcontrolador y vice versa.
225
Programa en Visual Basic 6.0:
Para crear un nuevo proyecto en Visual Basic, hacemos clic en el menú
Archivo Nuevo Proyecto y seleccionamos la opción “EXE estándar” (figura
12.3).
Figura 12.3.
Figura 12.4.
226
Figura 12.5.
Una vez creado un nuevo proyecto, será importante activar el componente
para manejar la comunicación serial “Microsoft Comm Control 6.0”. Esto se
realiza haciendo clic en el menú Proyectos Componentes Controles.
Figura 12.6.
227
Al hacer clic en el botón “Aceptar” veremos que en la barra de herramientas
aparece un nuevo icono representado por un teléfono.
Figura 12.7.
Inserte en el formulario el icono “MsComm” como se muestra en la figura
12.8, y configure los siguientes parámetros en la ventana de propiedades:
CommPort: 1 (ver figura 12.9)
Settings: 9600,n,8,1 (ver figura 12.10)
Figura 12.8.
228
Figura 12.9. Figura 12.10.
Seguidamente haga doble clic sobre el formulario para visualizar la ventana
de código en la cual introduciremos las siguientes líneas de programa, las
cuales se encargarán de abrir el puerto serial del PC (Figura 12.11).
Figura 12.11.
229
Utilice el icono “CommandButton” en la barra de herramientas para agregar
botones en el formulario:
Figura 12.12.
Para cambiar el nombre del botón, busque la celda “Caption” en la ventana de
propiedades del mismo (ver figura 12.13):
Figura 12.13.
230
Este procedimiento se repite hasta lograr obtener un formulario con 12
botones debidamente identificados como se observa en la figura 12.14:
Figura 12.14.
El siguiente paso es designar a cada botón la instrucción que se encargará de
enviar un dato específico a través del puerto serial del PC. Haga doble clic en
el primer botón del formulario y agregue la siguiente línea de comando (ver
figura 12.15):
MSComm1.Output = Chr$(1)
Figura 12.15.
231
Se repite el paso anterior para el resto de los botones:
Botón #2: MSComm1.Output = Chr$(2)
Botón #3: MSComm1.Output = Chr$(3)
Botón #4: MSComm1.Output = Chr$(4)
Botón #5: MSComm1.Output = Chr$(5)
Botón #6: MSComm1.Output = Chr$(6)
Botón #7: MSComm1.Output = Chr$(7)
Botón #8: MSComm1.Output = Chr$(8)
Botón #9: MSComm1.Output = Chr$(9)
Botón #10: MSComm1.Output = Chr$(10)
Botón #11: MSComm1.Output = Chr$(11)
Botón #12: MSComm1.Output = Chr$(12)
Por último, haga clic en el botón “Iniciar” (ver figura 12.16), para hacer
funcionar el teclado 3x4 desde el cual se enviarán datos hacia el
microcontrolador.
Al hacer clic en cualquiera de los botones del teclado, estará enviando al
microcontrolador el dato correspondiente el cual podrá ser observado en la
pantalla LCD de su circuito.
232
Figura 12.16.
Por último, generamos el archivo ejecutable desde el menú Archivo Generar
“Nombre del archivo.exe”
233
12.4.- Instrucción SerOut: La instrucción SerOut en PicBasic se encarga de
enviar uno o mas valores a través de un pin específico, usando el formato
asíncrono estándar 8N1, que significa 8 bits de datos, sin revisión de paridad
y 1 bit de parada (stop).
Sintaxis: SEROUT pin, modo, [variable]
Pin: en este campo definiremos cual será el pin de salida entre los puertos
disponibles del microcontrolador. Ejemplo: PortB.5
Modo: define la velocidad de transmisión en baudios y emplea la misma tabla
de la instrucción Serin (Tabla 12.1).
Variable: En este campo se especifica la variable que contiene los datos que
serán enviados a través de pin especificado. Ejemplo:
SerOut PORTC.6, T9600, [variable]
12.5.- Proyecto #33: Comenzaremos por realizar el circuito de la figura 12.17,
el cual será conectado al PC a través del puerto serial COM1, y a través del
HyperTerminal de Windows veremos como son transmitidos los datos desde
el microcontrolador hasta el PC.
Veamos el siguiente programa en PBP:
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Symbol T9600 = 2 ' Dato verdadero (Driven True)
I VAR Byte ' Define la variable “I” como Byte
inicio:
For I = 0 To 9 ' Repetición de 0 a 9
SerOut PORTC.6, T9600, [#I] ' Envía los datos a través del pin RC6
pause 1000 ' Pausa de 1 segundo
Next I
234
GoTo inicio ' Salta a inicio
End
Podemos ver en el programa anterior como es enviado el contenido de la
variable “I”, la cual incrementa su valor de cero a nueve, dato que sale en
formato serial asíncrono a través del Pin RC6 a 9600 bps.
Figura 12.17.
235
Proyecto # 33
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 22 pF 2
Capacitor Electrolítico de uF 5
Conector DB-9M 1
IC MAX232 1
Fuente regulada de 5 Vdc 1
Tabla 12.3.
En caso de no disponer de un MAX232 para el acople entre el
microcontrolador y el puerto serial del PC, también se pueden utilizar dos
resistencias limitadoras de corriente, como se muestra en el diagrama de la
figura 12.18.
Figura 12.18.
236
Deberá tomar en cuenta entonces, que los parámetros de comunicación
cambian, debido a que los datos ya no pasarán a través del inversor integrado
en el MAX232.
Esto significa que el programa a utilizar para el circuito de la figura 12.18 es el
siguiente:
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
Symbol N9600 = 6 ' Dato invertido (Driven inverted)
dato var Byte ' Define la variable “dato” como Byte
I var Byte ' Define la variable “I” como Byte
Inicio:
For I = 0 To 9 ' Repetición de 0 a 9
SerOut PORTC.6, N9600, [#I] ' envía los datos a través del pin RC6
Pause 1000 ' Pausa de 1 segundo
Next I
GoTo Inicio ' Salta a inicio
End
Para abrir el HyperTerminal de Windows, haga clic en el menú Inicio Todos
los Programas Accesorios Comunicaciones HyperTerminal. Escriba un
nombre para la conexión y haga clic en “Aceptar”.
237
Figura 12.19.
Normalmente el puerto disponible para la comunicación serial es el COM1.
Seleccione el puerto disponible en su PC para realizar la prueba de
transmisión y luego haga clic en el botón “Configurar” (figura 12.20).
238
Figura 12.20.
En la figura 12.21 se observan los campos en los cuales se pueden
establecer los parámetros para la comunicación serial, los cuales deben
coincidir con los parámetros seleccionados para la instrucción SerOut.
Figura 12.21.
239
También es conveniente tomar en cuenta en la configuración de la conexión,
el tipo de emulación (figura 12.22).
Figura 12.22.
Finalmente, al aceptar todos estos cambios en la ventana de configuración del
HyperTerminal de Windows, podremos ver la siguiente ventana (figura
12.23), en la cual se recibirán los datos enviados desde el microcontrolador.
Una vez conectada la alimentación del circuito, el microcontrolador empezará
a enviar los datos desde cero hasta nueve, con intervalos de tiempo de un
segundo.
240
Figura 12.23.
12.6.- Proyecto #34: En base a los conocimientos adquiridos hasta ahora,
realizaremos a continuación un circuito capaz de medir un voltaje variable
aplicado a una de las entradas del conversor A/D de un PIC16F877A, el cual
a su vez deberá enviar el resultado de la conversión en decimal a una pantalla
LCD, y enviar este mismo resultado a un PC, a través del puerto serial donde
los datos serán recibidos y “convertidos”, en una hoja de cálculo (Excel), para
posteriormente graficar el conjunto de datos de una muestra de diez lecturas
acumuladas.
Antes de iniciar con la programación, será importante considerar los
siguientes puntos:
• La conversión A/D será a 10 Bits, por lo cual debemos tener presente
realizar esta definición, es decir, Define ADC_BITS 10.
241
• La pantalla LCD estará conectada en el puerto “D”, por lo cual será
necesario definir los pines de la misma al inicio del programa.
Figura 12.24.
242
Proyecto # 34
Componente Cantidad
PIC16F877A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 33 pF 2
Pantalla LCD 16x2 1
Resistencia de 220 Ohm 1
Capacitor Electrolítico de uF 5
Conector DB-9M 1
IC MAX232 1
Potenciómetro de 5K Ohm 1
Fuente regulada de 5 Vdc 1
Tabla 12.4.
Programa en Pic Basic Pro:
'****************************************
'* Nombre : Proyecto34.pbp *
'* Autor : Nombre del Autor *
'* Copyright : Copyright (Año) *
'* Fecha : Fecha *
'* Versión : 1.0 *
'****************************************
DEFINE OSC 4 ' Define Oscilador a 4 Mhz
DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D
DEFINE LCD_BITS 4 ' El bus será de cuatro bits.
DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto (0 o 4) en caso
' de utilizar los cuatro Bits mas significativos de la LCD
DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto B
DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RB1
DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto B
DEFINE LCD_EBIT 3 ' "E" estará conectado en RB0
DEFINE LCD_LINES 2 ' Define el número de líneas de la pantalla
Symbol T9600 = 2 ' Dato verdadero (Driven True)
Define ADC_BITS 10 ' Define la conversión A/D a 10 Bits
DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS
A VAR Word ' Declaración de una variable tipo word (16 bits)
243
ADCON1 = %10000000 ' Configura el registro ADCON1
LCDOut $fe, 1 ' Limpia la LCD
inicio:
ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOUT "C-AD a 10 Bit: " ' Muestra mensaje en la línea 1
LCDOUT $fe,$C0,"Dato: ",Dec A," " ' Muestra dato en la línea 2
SerOut PORTC.6, T9600, [#A] ' envía los datos al PC
pause 500 ' Pausa de 500 milisegundos
GoTo inicio ' Salta a inicio
End
En el programa se puede observar cómo hemos definido el conexionado de la
pantalla LCD, así como también la configuración básica establecida para el
conversor A/D, el cual hará la conversión a 10 bits con el fin de obtener una
mayor resolución en el proceso de medición del voltaje aplicado al pin RA0.
Una vez iniciada la conversión, se puede observar que el resultado de la
misma es almacenada en la variable “A”, la cual hemos declarado como una
variable de 16 bits (word), debido a que el resultado de la conversión requiere
mas de ocho bits de datos. Este resultado puede ser mostrado fácilmente en
la pantalla LCD en decimal anteponiendo la directiva “Dec” a la variable en la
cual hemos almacenado el dato resultado de la conversión.
El siguiente paso en el programa consiste en enviar el dato obtenido al PC a
través del puerto serial, para luego hacer una pequeña pausa de 500
milisegundos y empezar nuevamente el proceso para una nueva lectura.
Un paso importante en este punto, una vez obtenido el resultado de la
conversión A/D en la pantalla LCD, será verificar la transferencia de datos
hacia el PC con la ayuda del HyperTerminal de Windows.
244
Para esto debemos conectar el cable serial entre el circuito y el PC, desde la
cual realizaremos una nueva conexión con el HyperTerminal, como se
muestra en figura 12.25:
Figura 12.25.
En este punto solo debemos dar un nombre a la conexión y configurar el
puerto con el cual estaremos trabajando como se muestra a continuación:
245
Figura 12.26.
Figura 12.27.
Es importante recordar que la configuración del puerto en el PC debe coincidir
con la configuración elegida para el microcontrolador PIC. Una vez
configurado el HyperTerminal de Windows, se podrán observar los datos en la
ventana, los cuales estarán llegando cada 500 milisegundos, tiempo definido
246
anteriormente en el programa que hemos cargado en el microcontrolador PIC
(figura 12.28).
Figura 12.28.
Después de verificar la correcta recepción de datos desde el HyperTerminal,
se debe asegurar de cerrar esta ventana (Figura 12.28) para garantizar la
disponibilidad del puerto serial.
La idea principal de esta práctica, será llevar estos datos a una hoja de Excel,
en la cual podamos realizar los cálculos para expresar estos valores en sus
equivalentes en voltios para luego tomar una muestra significativa y
graficarlos como se observa en la figura 12.29.
247
Figura 12.29.
El primer paso para configurar la hoja de Excel, será ubicar las herramientas
de Visual Basic y agregar a la hoja de cálculo el control “Microsoft
communications control, Version 6.0”. Para esto debemos seguir los
siguientes pasos:
248
1.- Al abrir la hoja de cálculo, podemos ver un menú de opciones en la parte
superior de la ventana denominado “Herramientas”. Haga clic en el menú
“Herramientas” y seleccione la opción “Personalizar”.
Figura 12.30.
Al seleccionar esta opción podrá observar que en la ventana “Personalizar”
hay tres fichas de configuración. Seleccione la ficha “Barra de herramientas”
como se muestra en la figura 12.31.
249
Figura 12.31.
En esta ficha encontrará una serie de opciones disponibles, de las cuales
deberá seleccionar “Visual Basic”. Haga clic en al botón “Cerrar” y verá que
aparece en la hoja de cálculo una caja de herramientas nueva llamada “Visual
Basic” (Figura 12.32), la cual podemos trasladar a la parte superior de la hoja
de cálculo, la cual contiene el resto de las herramientas típicas usadas en
Excel (Figura 12.33).
250
Figura 12.32.
251
Figura 12.33.
Haga clic en el botón “Cuadro de controles” (figura 12.33), y desplace la caja
de herramientas nuevamente a la parte superior de la hoja de cálculo junto
con el resto de herramientas comunes de Excel (Figura 12.34).
252
Figura 12.34.
En esta serie de botones, podemos encontrar uno denominado “Mas
controles” (ver Figura 12.35), el cual despliega una lista de opciones. Ubique
el siguiente control: “Microsoft communications control, Version 6.0”.
Al hacer doble clic en este control la lista de opciones desaparece y es en
este momento en el cual debemos agregar el mismo sobre la hoja de cálculo.
Para esto, debe mantener el botón izquierdo del mouse activado y arrastrar el
253
puntero hasta que aparezca un pequeño recuadro. Al soltar el botón izquierdo
el control aparece sobre la hoja. La figura de un Teléfono sobre un “MODEM”
lo identifica claramente, como se muestra en la figura 12.35.
Figura 12.35.
El siguiente paso será agregar un botón en el cual se configura el código
necesario para la apertura del puerto serial en el PC (Figura 12.36).
254
Figura 12.36.
Al hacer doble clic sobre el nuevo botón, estamos entrando al editor de Visual
Basic, en el cual podemos agregar las siguientes líneas de programa, las
cuales permitirán abrir el puerto al hacer clic sobre el botón que hemos
agregado para tal fin:
Private Sub CommandButton1_Click()
'abre el puerto de comunicación
If Hoja1.MSComm1.PortOpen = False Then
Hoja1.MSComm1.PortOpen = True
End If
End Sub
Observe la figura 12.37, en la cual se puede ver el campo “Caption”,
correspondiente a la etiqueta del botón de comando que estamos
configurando, la cual podemos personalizar con un nombre adecuado como
“Abrir Puerto” o “Abrir Comm1”.
255
Figura 12.37.
En figura 12.37 también podemos apreciar las líneas de programación
agregadas al botón de comando, y el icono que nos permitirá regresar a la
hoja de cálculo para continuar con la programación.
Al regresar a la hoja de cálculo podremos notar el cambio en la etiqueta del
botón de comando, como se muestra en la figura 12.38:
256
Figura 12.38.
Ahora solo nos queda configurar el evento OnComm, relativo a la recepción
de datos, haciendo doble clic sobre el control de comunicaciones (figura
12.39):
Figura 12.39.
257
Veremos a continuación la ventana del editor de Visual Basic (Figura 12.40):
Figura 12.40.
Recordemos que para almacenar datos en una variable, es importante
considerar la declaración de la misma antes de ejecutar cualquier otra línea
de programa que así la requiera. Es por esto que para este ejemplo, el primer
258
paso en la configuración del control de comunicaciones ha sido la declaración
de dos variables, las cuales hemos denominado “Apuntador” y “datainput”.
La variable “Apuntador” será declarada como “Byte” y la variable “datainput”
será declarada como “String”.
Analice el uso de la variable “Apuntador” en el código del evento OnComm, el
cual detallamos unas líneas más adelante. Esta variable se usa básicamente
como acumulador y determina la posición en un rango predeterminado de las
filas en la hoja de cálculo. Esto se debe a que estamos interesados en
mantener una muestra de los diez últimos valores capturados en el puerto
para poder realizar una gráfica de líneas suavizadas, la cual se estará
actualizando cada 500 milisegundos.
Para almacenar un dato presente en el puerto serial (Comm1), utilizamos el
comando “MSComm1.Input”, entonces, para almacenar un dato en la variable
“datainput”, debemos realizar el siguiente arreglo:
datainput = MSComm1.Input
Luego para llevar el dato almacenado en la variable a una celda en la hoja de
cálculo, podemos utilizar el siguiente comando:
Hoja1.Cells(Fila, Columna)
Un punto importante a considerar es que la variable “datainput” por estar
declarada como “String”, almacenará una serie de datos consecutivos uno
tras otro. Podemos extraer un dato de la cadena de caracteres almacenada
en la variable “datainput” de la siguiente manera:
Hoja1.Cells(Fila, Columna) = Mid(Variable, Bit de inicio, longitud)
Ejemplo:
Si datainput = 643645650681701718745776
Para extraer los tres primeros caracteres y llevarlos por ejemplo a la celda
(40,2) debemos hacer el siguiente arreglo:
259
Hoja1.Cells(40, 2) = Mid(datainput, 1, 3)
Para mantener este dato y capturar uno mas actualizado, simplemente
debemos hacer un arreglo para desplazar el contenido de la celda (40,2) a la
celda (39,2). Cuando llegue el próximo dato actualizado, el contenido de esta
celda deberá pasar a la celda (38,2) y así sucesivamente. Al repetir el
desplazamiento de celdas diez veces, podremos tomar estos valores y
graficarlos en la hoja de cálculo.
Veamos a continuación el código para el evento OnComm:
Private Sub MSComm1_OnComm()
'Declara variable
Dim Apuntador As Byte
Dim datainput As String
datainput = MSComm1.Input
For Apuntador = 30 To 40
Hoja1.Cells(Apuntador, 2) = Hoja1.Cells(Apuntador + 1, 2)
Next
Hoja1.Cells(40, 2) = Mid(datainput, 1, 4)
End Sub
260
Figura 12.41.
Analice cuidadosamente el contenido del código en el evento OnComm.
Verifique la rutina encargada de apilar los datos entre las celdas (40,1) y (30,
1). Por último, analice la extracción de datos de la cadena de caracteres
almacenada en la variable “datainput”.
Completados todos estos pasos, lo siguiente será volver a la hoja de cálculo y
salir del modo de diseño, haciendo clic en el icono señalado en la siguiente
figura:
261
Figura 12.42.
Cuando se sale del modo de diseño, el control de comunicaciones
desaparece de la hoja de cálculo. Ahora, haciendo clic en el botón “Abrir
Comm1” y activando el circuito, podremos ver que aparecen los datos de la
conversión A/D del microcontrolador en la pantalla LCD y en la hoja de
cálculo, específicamente en las celdas B40, B39, B38, B37, B36, B35, B34,
B33, B32, B31 y B30.
En la figura 12.43 se pueden ver unos datos de prueba almacenados en las
celdas anteriormente mencionadas. Estos datos pueden ser identificados
poniendo un nombre o encabezado en la celda B29, por ejemplo, podemos
escribir la palabra “Lecturas: “.
En la columna C de la hoja de cálculo, haremos la conversión de datos para
expresar los valores obtenidos en Voltios. Para esto aplicaremos la siguiente
formula en las celdas C40, C39, C38, C37, C36, C35, C34, C33, C32, C31 y
C30:
• =(B40*5)/1024 para la celda C40
• =(B39*5)/1024 para la celda C39
• =(B38*5)/1024 para la celda C38
• =(B37*5)/1024 para la celda C37
262
• =(B36*5)/1024 para la celda C36
• =(B35*5)/1024 para la celda C35
• =(B34*5)/1024 para la celda C34
• =(B33*5)/1024 para la celda C33
• =(B32*5)/1024 para la celda C32
• =(B31*5)/1024 para la celda C31
• =(B30*5)/1024 para la celda C30
Figura 12.43.
263
Figura 12.44.
Observe en la figura 12.44, la formula para la celda C40. Observe también
que hemos ocultado una serie de filas de la hoja de cálculo, las cuales hemos
reservado para agregar un gráfico de líneas suavizadas.
Para graficar esta serie de datos, seleccionamos las diez celdas (desde la
celda C30 hasta la celda C40) y hacemos clic en el icono “Asistente para
Gráficos” (Figura 12.45), donde aparecerá una ventana en la cual podremos
elegir el tipo de gráfico que deseamos utilizar. Seleccione la ficha “Tipos
personalizados” y haga clic en la opción “Líneas suavizadas” de la lista
(Figura 12.46).
264
Figura 12.45.
Figura 12.46.
265
En la siguiente ventana podemos ver el rango de datos que será graficado
(Figura 12.47):
Figura 12.47.
Si se desea personalizar aún mas el gráfico, se puede hacer en la ficha
“Serie”, en cual es posible editar el recuadro que contiene la leyenda. En la
siguiente ventana encontraremos una serie de fichas con una gran variedad
de opciones que nos permitirán añadir detalles como el título del gráfico,
identificar los ejes, agregar líneas de división, y algunos otros detalles útiles
para mejorar la apariencia del gráfico. (figura 12.48).
266
Figura 12.48.
Seguidamente, podemos seleccionar si el gráfico será colocado en una hoja
nueva, o en la hoja de cálculo en la cual hemos estado trabajando (figura
12.49):
Figura 12.49.
Finalmente podremos ver en la hoja de Excel los datos enviados desde el
microcontrolador, los cuales a su vez serán graficados constantemente, como
se puede observar en la figura 12.50.
267
Figura 12.50.
268
Servomotores Capitulo XIII
13.1.- ¿Qué es un Servomotor?
Un servomotor es un dispositivo electromecánico capaz de rotar su eje a una
posición específica a lo largo de su recorrido, inyectando un tren de pulsos
controlados, a un circuito de control que posee dentro de su caja o chasis.
Esta señal se introduce a través de un cable de control que se distingue entre
los tres cables que posee y que según la marca del servomotor puede ser de
color blanco o amarillo. Los cables de alimentación se distinguen por sus
colores rojo (Positivo) y negro (Negativo).
Un servomotor estándar tiene dimensiones muy apropiadas para realizar
proyectos de robótica, y aunque se pueden encontrar en diferentes tamaños,
es importante resaltar que la fuerza de un servo en su eje no es directamente
proporcional al tamaño del mismo. Esto significa que su fuerza depende en
gran sentido de su diseño interior, es decir, de la mecánica y material que
componen sus engranajes.
Veamos a continuación algunas características técnicas importantes en un
servomotor estándar:
Control: Control por ancho de pulso.
Pulso: 3-5 Voltios Pico a Pico.
Voltaje de operación: 4.8 a 6.0 Voltios.
269
Torque (4.8V): 3.0 kg/cm (42 oz/in)
Torque (6.0V): 4.5 kg/cm (48.60 oz/in)
Rango de Temperatura Operacional: -20 a +60 ºC.
Velocidad (4.8V): 0.19sec/60 grados.
Velocidad (6.0V): 0.15sec/60 grados.
Corriente (4.8V): 7.4mA activo y 160mA al aplicar fuerza.
Corriente (6.0V): 7.7mA activo y 180mA al aplicar fuerza.
Figura 13.1.
Para controlar la posición del eje de un servomotor, hace falta enviar un tren
de pulsos, donde el ancho de cada pulso determina el punto en el cual el eje
mantiene su posición, siempre y cuando esté presente el tren de pulsos. El
recorrido será en la mayoría de los modelos de 180º y los tiempos
correspondientes al pulso en la señal para las posiciones principales (0º, 90º y
270
180º) se especifican en la tabla 13.1. (Estos tiempos pueden variar de
acuerdo al modelo y marca del servomotor).
Tabla 13.1.
Entonces, si deseamos llevar el eje a 0º, se deben introducir al servo pulsos
de 0.6 milisegundos (T1) aproximadamente, cada 20 milisegundos, como se
muestra en la figura 13.3. T2 corresponde por consiguiente al tiempo que
debemos esperar para enviar un nuevo pulso, el cual mantiene actualizada la
posición de eje. El tiempo T2 puede estar dentro del rango 10 ms ≤ T2 ≤ 40
ms.
Figura 13.3.
271
A medida que aumentamos gradualmente el tiempo T1, el eje del servomotor
se irá moviendo en sentido horario. Cuando T1 = 1.5 ms podremos ver que el
eje forma un ángulo de 90º con respecto al punto de inicio (0º). En la figura
13.4 se puede observar la señal correspondiente a esta posición (90º), donde
T2 se mantiene en 20 milisegundos.
Figura 13.4.
La señal correspondiente a la posición máxima (180º) en un servomotor
estándar, tendría entonces valores para T1 = 2.6 ms y T2 = 20 ms. (figura
13.5).
Figura 13.5.
272
13.2.- Proyecto #35: Se puede crear un programa en PicBasic que cumpla
con estas características, en el cual variando solo una variable, podemos
modificar el ángulo de giro de un servomotor. Veamos el siguiente ejemplo:
Figura 13.6.
Proyecto # 35
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 22 pF 2
Servomotor 1
Fuente regulada de 5 Vdc 1
Tabla 13.2.
273
PAUSEUS
Sintaxis: PAUSEUS periodo
La instrucción Pause realiza un pausa en el programa por un periodo definido
en microsegundos. Esta instrucción no pone al microcontrolador en modo de
bajo consumo de energía.
Programa en Pic Basic Pro:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
PULSO VAR Word ' Define la variable "Pulso" (16 Bits)
PULSO = 1550 ' Inicializamos la variable "Pulso"
Inicio:
High PORTB.0 ' RB0 = 1
PauseUs PULSO ' Pausa en microsegundos
Low PORTB.0 ' RB0 = 0
Pause 20 ' Pausa de 20 milisegundos
GoTo Inicio ' Salto a inicio
End
Al compilar, grabar y ejecutar el programa anterior en el microcontrolador,
podremos ver en un osciloscopio el tren de pulsos presente en el pin RB0
como se muestra en la figura 13.7.
274
Figura 13.7.
Volt/Div: 2V
Time/Div: 5ms
Período: 21,55 ms
T1: 1,55 ms (Ancho de pulso positivo).
T2: 20 ms
Vpp: 5,44 Voltios.
Ciclo de trabajo: 8,16%
Tiempo de subida: 160,0 us
Tiempo de bajada: 160,0 us
Al aplicar el tren de pulsos al servomotor, su eje rotará hasta una posición en
el punto medio de su recorrido total.
Si analizamos el programa, podremos observar que la instrucción “PauseUs”
realiza una parada durante un tiempo definido por la variable “Pulso”, cuyo
valor es de 1550, es decir, se está generando una pausa de 1550
microsegundos, o lo que es igual, 1,55 milisegundos.
Seguidamente hacemos una pausa de 20 milisegundos antes de enviar
nuevamente el pulso al Pin RB0.
275
Entonces, si deseáramos modificar el ángulo de giro, podemos cambiar el
valor de la variable “Pulso”, siempre y cuando el valor esté dentro del rango
de tiempo permitido (0,65 ms ≤ T1 ≤ 2.6 ms), es decir, 650 ≤ PauseUs ≤ 2600.
Una forma aún más práctica para generar el tren de pulsos de la figura 13.7,
sería haciendo uso de la instrucción “PulsOut”, como se muestra a
continuación:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
Inicio:
PulsOut PORTB.0,65 ' Genera pulsos de 650 microsegundos de
' duración.
Low PORTB.0 ' RB0 = 0
Pause 20 ' Pausa de 20 milisegundos.
GoTo Inicio ' Salto a inicio.
End
276
13.3.- Proyecto #36: Para hacer un poco más interesante la práctica, en la
cual el objetivo ha sido controlar el ángulo de giro de un servomotor,
proponemos incorporar al circuito dos pulsadores para aumentar y disminuir el
ángulo y una pantalla LCD para visualizar el valor en microsegundos de cada
pulso enviado al servomotor (Figura 13.8).
Figura 13.8.
277
Proyecto # 36
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 22 pF 2
Pantalla LCD 16x2 1
Resistencia de 10K Ohm 3
Potenciómetro de 5K Ohm 1
Servomotor 1
Pulsador Normalmente Abierto 2
Fuente regulada de 5 Vdc 1
Tabla 13.3.
Programa en PBP:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
TRISB = %11110110 ' Configuración del puerto B
PULSO VAR Word ' Define la variable "Pulso" (16 Bits)
PULSO = 1550 ' Inicializamos la variable "Pulso"
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
High PORTB.0 ' RB0 = 1
PauseUs PULSO ' Pausa en microsegundos
Low PORTB.0 ' RB0 = 0
Pause 15 ' Pausa de 15 milisegundos
' Considerando que las siguientes instrucciones consumen
' 1 ms cada una y la instrucción de salto consume 2 ms, la
' pausa anterior será de 15 ms para lograr un tiempo entre
' cada pulso de 20 ms.
If PORTB.1 = 1 And PULSO < 2600 Then Call SUMA
' Si RB1 = 1 significa que se ha activado el pulsador
' conectado a él. La condición se cumple sólo si el pulsador
' está activado y la variable "Pulso" es menor a 2600.
If PORTB.2 = 1 And PULSO > 650 Then Call RESTA
' Si RB2 = 1 significa que se ha activado el pulsador
278
' conectado a él. La condición se cumple sólo si el pulsador
' está activado y la variable "Pulso" es mayor a 650.
LCDOUT $fe, 2,"PULSO: ",#PULSO," uS "
' Muestra el dato cargado en la variable "Pulso"
GoTo Inicio ' Salto a inicio
SUMA:
PULSO = PULSO + 100 ' Suma 100 a la variable "Pulso"
Pause 40 ' Pausa de 40 milisegundos
Return ' Retorno
RESTA:
PULSO = PULSO - 100 ' Resta 100 a la variable "Pulso"
Pause 40 ' Pausa de 40 milisegundos
Return ' Retorno
' Si se aumenta o disminuye la pausa en las subrutinas
' suma y resta, se logra un efecto de aumento o disminución
' de la velocidad variación del ángulo.
End
Si empleamos la instrucción “PulsOut”:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
TRISB = %11110110 ' Configuración del puerto B
PULSO VAR Word ' Define la variable "Pulso" (16 Bits)
PULSO = 155 ' Inicializamos la variable "Pulso"
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
PulsOut PORTB.0, PULSO ' Genera un pulso en RB0
Low PORTB.0 ' RB0 = 0
Pause 15 ' Pausa de 15 milisegundos
' Considerando que las siguientes instrucciones consumen
' 1 ms cada una y la instrucción de salto consume 2 ms, la
' pausa anterior será de 15 ms para lograr un tiempo entre
' cada pulso de 20 ms.
If PORTB.1 = 1 And PULSO < 260 Then Call SUMA
' Si RB1 = 1 significa que se ha activado el pulsador
' conectado a él. La condición se cumple sólo si el pulsador
279
' está activado y la variable "Pulso" es menor a 260.
If PORTB.2 = 1 And PULSO > 65 Then Call RESTA
' Si RB2 = 1 significa que se ha activado el pulsador
' conectado a él. La condición se cumple sólo si el pulsador
' está activado y la variable "Pulso" es mayor a 65.
LCDOUT $fe, 2,"PULSO: ",#PULSO,"0 uS "
' Muestra el dato cargado en la variable "Pulso"
GoTo Inicio ' Salto a inicio
SUMA:
PULSO = PULSO + 10 ' Suma 10 a la variable "Pulso"
Pause 40 ' Pausa de 40 milisegundos
Return ' Retorno
RESTA:
PULSO = PULSO - 10 ' Resta 10 a la variable "Pulso"
Pause 40 ' Pausa de 40 milisegundos
Return ' Retorno
' Si se aumenta o disminuye la pausa en las subrutinas
' suma y resta, se logra un efecto de aumento o disminución
' de la velocidad variación del ángulo.
End
280
13.4.- Proyecto #37: En la siguiente actividad se desea controlar un
servomotor y visualizar el tiempo de cada pulso en una pantalla LCD,
conectados a un microcontrolador principal. Desde un microcontrolador
secundario se enviará el dato correspondiente al ángulo del eje, estableciendo
una comunicación serial con el microcontrolador principal, de tal manera que
cuando se requiera aumentar o disminuir el ángulo, sean utilizados dos
pulsadores conectados en cualquiera de los puertos disponibles del
microcontrolador secundario.
El circuito propuesto se muestra en la figura 13.9.
Figura 13.9.
281
Proyecto # 37
Componente Cantidad
PIC16F84A 2
Cristal de 4 Mhz 2
Capacitor cerámico de 22 pF 4
Pantalla LCD 16x2 1
Resistencia de 10K Ohm 3
Potenciómetro de 5K Ohm 1
Pulsador Normalmente Abierto 2
Fuente regulada de 5 Vdc 1
Tabla 13.4.
Programa para el microcontrolador principal U1:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
Symbol T9600 = 2 ' Dato verdadero (Driven True)
PULSO VAR Word ' Define la variable "Pulso" (16 Bits)
PULSO = 155 ' Inicializa variable "Pulso"
pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
SerIn PORTB.7, T9600, 16, Sigue, PULSO ' Espera dato
' durante 16 ms
Sigue:
LCDOUT $fe, 2,"PULSO: ",#PULSO,"0 uS " ' Muestra dato.
PulsOut PORTB.1, PULSO ' Genera pulso en RB1
GoTo Inicio ' Salto a inicio
End
282
Programa para el microcontrolador secundario U2:
DEFINE OSC 4
Symbol T9600 = 2 ' Dato verdadero (Driven True)
PULSO VAR Word ' Define la variable "Pulso" (16 Bits)
PULSO = 155 ' Inicializa variable "Pulso"
inicio:
If PORTA.0 = 1 And PULSO < 250 Then Call suma
' Si RA0 = 1 significa que se ha activado el pulsador
' conectado a él. La condición se cumple sólo si el pulsador
' está activado y la variable "Pulso" es menor a 250.
If PORTA.1 = 1 And PULSO > 60 Then Call resta
' Si RA1 = 1 significa que se ha activado el pulsador
' conectado a él. La condición se cumple sólo si el pulsador
' está activado y la variable "Pulso" es mayor a 60.
GoTo inicio ' Salto a inicio
suma:
PULSO = PULSO + 10 ' Suma 10 a la variable "Pulso"
SerOut PORTA.2, T9600, [PULSO] ' Envía dato serial por RA2
PAUSE 40 ' Pausa de 40 milisegundos
Return ' Retorno
resta:
PULSO = PULSO - 10 ' Resta 10 a la variable "Pulso"
SerOut PORTA.2, T9600, [PULSO] ' Envía dato serial por RA2
PAUSE 40 ' Pausa de 40 milisegundos
Return ' Retorno
End
283
13.5.- Proyecto #38: En la siguiente actividad se controlará un servomotor
desde el puerto serial de un PC, desde donde enviaremos el dato a ser
cargado en la instrucción “PulsOut” en el código de programa del
microcontrolador, y el cual definirá el ancho de pulso a ser introducido en el
servomotor cada 20 milisegundos. El circuito consta de un microcontrolador
PIC16F84A con oscilador de 4 Mhz y un servomotor, donde la línea de control
estará conectada al Pin RB1. Para la comunicación entre el PC y el circuito,
emplearemos un circuito integrado MAX-232 (Figura 13.10).
Figura 13.10.
284
Proyecto # 38
Componente Cantidad
PIC16F84A 1
Cristal de 4 Mhz 1
Capacitor cerámico de 22 pF 2
IC MAX232 1
Capacitor electrolítico de 0,1 uF 5
Potenciómetro de 5K Ohm 1
Conector DB-9M 1
Fuente regulada de 5 Vdc 1
Tabla 13.5.
Programa en Pic Basic Pro:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
Symbol T9600 = 2 ' Dato verdadero (Driven True)
PULSO VAR Word ' Define la variable "Pulso" (16 Bits)
PORTB.1 = 0 ' Inicializa RB1
inicio:
SerIn PORTB.7, T9600, 18, sigue, PULSO ' Espera dato
' durante 18 ms
sigue:
PulsOut PORTB.1, PULSO ' Genera pulso en RB1
GoTo inicio ' Salto a inicio
End
285
Para la comunicación serial, se ha definido el modo de dato verdadero a 9600
bps (T9600). A partir de la etiqueta “inicio”, el primer paso será esperar un
dato serial durante 18 milisegundos antes de saltar a la etiqueta “sigue”, para
generar el pulso correspondiente y donde su duración se calcula en decenas
de microsegundos. Seguidamente se genera un salto a la etiqueta “inicio”
para repetir el proceso.
La interfaz gráfica para el control del servomotor la hemos realizado en Visual
Basic (Figura 13.11), desde la cual podremos seleccionar el tiempo de
duración de los pulsos enviados al servomotor.
Además hemos agregado tres botones con valores fijos para las tres
posiciones principales (0º, 90º y 180º). Veamos a continuación el desarrollo de
la interfaz gráfica paso a paso:
Figura 13.11.
286
Paso 1: creamos un nuevo proyecto “EXE estándar” (Figura 13.12):
Figura 13.12.
Paso 2: Identificamos el formulario en las propiedades del mismo, ingresando
un nombre que identifique nuestra aplicación:
Figura 13.13.
287
Figura 13.14.
Paso 3: activamos el componente para manejar la comunicación serial
“Microsoft Comm Control 6.0”. Esto se realiza haciendo clic en el menú
Proyectos Componentes Controles. Seguidamente se inserta el icono
“MsComm” como se muestra en la figura 13.15, y se configuran los
parámetros de conexión en la ventana de propiedades (Figuras 13.16 y
13.17):
Figura 13.15.
288
Figura 13.16. Figura 13.17.
Paso 4: cerramos la ventana de código e incluimos los botones, el campo de
texto y la imagen en el formulario (Figura 13.18). Recuerde identificar cada
botón en la ventana de propiedades (Figura 13.19):
Figura 13.18. Figura 13.19.
289
Figura 13.20.
Paso 5: se asigna un nombre a cada botón en la ventana de propiedades
(Figura 13.21):
290
Figura 13.21.
Paso 6: se hace doble clic sobre el formulario para agregar el siguiente
código, con el cual habilitaremos el puerto serial del PC, y asignaremos una
función específica a cada botón (Figura 13.20):
Dim Servo As Byte ' Declaración de Variable "Servo"
' tipo byte
______________________________________________________________________________
Private Sub Form_Load() ' Rutina para abrir el puerto serial
MSComm1.PortOpen = True
If MSComm1.PortOpen = False Then
MSComm1.PortOpen = True
End If
Servo = 155 ' Inicializamos la variable "Servo"
MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1
Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto
End Sub
______________________________________________________________________________
291
Private Sub Boton1_Click() ' Boton 0º
Servo = 70 ' Carga el valor para 0º
Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto
MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1
End Sub
______________________________________________________________________________
Private Sub Boton2_Click() ' Boton 90º
Servo = 155 ' Carga el valor para 90º
Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto
MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1
End Sub
______________________________________________________________________________
Private Sub Boton3_Click() ' Boton 90º
Servo = 250 ' Carga el valor para 180º
Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto
MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1
End Sub
______________________________________________________________________________
Private Sub Boton4_Click() ' Boton <--
If Servo > 70 Then ' Restará solo si Servo es > 70
Servo = Servo - 5 ' Resta 5 a la variable "Servo"
Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto
End If
End Sub
______________________________________________________________________________
Private Sub Boton5_Click() ' Boton -->
If Servo < 250 Then ' Sumará solo si Servo es < 250
Servo = Servo + 5 ' Suma 5 a la variable "Servo"
Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto
End If
End Sub
______________________________________________________________________________
Private Sub Boton6_Click() ' Boton "Enviar Dato"
MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1
End Sub
292
Nota Importante:
Recuerde que el dato a ser cargado en la instrucción “PulsOut” del programa
de control del PIC16F84A, se mide en decenas de microsegundos para un
oscilador de 4 Mhz, por ejemplo:
PulsOut PORTB.1, 100
Esto significa que el tiempo del pulso generado será de 100 decenas de
microsegundos:
10 microsegundos x 100 = 1000 microsegundos ó 1 milisegundo.
Por lo tanto, los datos que enviamos al microcontrolador a través del puerto
serial desde la aplicación que hemos creado en Visual Basic, deben ser
considerados como la cantidad de decenas de microsegundos que deseamos
que dure cada pulso enviado al servomotor.
Esta es la razón por la cual hemos multiplicado por diez el dato a ser
mostrado en la caja de texto, especificando además la unidad de tiempo
correspondiente, que en este caso se expresa con la palabra
“Microsegundos”.
Paso 7: generamos el archivo ejecutable desde el menú Archivo Generar
“Nombre del archivo.exe”.
293
Módulos RF para comunicaciones Capítulo XIV
14.1.- Proyectos con Módulos RF.
A continuación realizaremos algunos proyectos donde la base de éstos serán
los módulos inalámbricos RF de la empresa Linx Technologies Inc.
(http://www.linxtechnologies.com), los cuales ofrecen una gran variedad de
modelos en diferentes rangos de frecuencias y donde la característica más
resaltante radica en que no requieren componentes externos a excepción de
la antena (figura 14.1). Su interfaz serial nos permite realizar una
comunicación directa o sin modificaciones en el protocolo RS-232, haciendo
muy sencillo el trabajo de comunicar dos circuitos que se encuentran a
distancias considerablemente largas en sus versiones de módulos LR (Long
Range), para distancias que pueden llegar a exceder los 900 metros en su
frecuencia estándar de 418 Mhz. También se pueden adquirir para trabajar en
frecuencias de 315 Mhz o 433 Mhz.
Figura 14.1.
El voltaje de alimentación no debe exceder los 3.3 Vdc, por lo cual se debe
considerar el uso de una regulador de voltaje para el transmisor y receptor,
considerando que el voltaje estándar en nuestros circuitos ha sido de 5 Vdc.
294
Transmisor: TXM-418-LR-S
Figura 14.2.
Receptor: RXM-418-LR-S
Figura 14.3.
El pin 4 (LADJ/VCC) en el transmisor puede ser utilizado para el ajuste en la
potencia del transmisor, variando el valor de una resistencia o potenciómetro,
y la relación resistencia versus potencia se puede ver en la figura 14.4:
295
Figura 14.4.
El pin PDN (Power Down) se encuentra disponible en el transmisor y receptor
y puede ser utilizado para poner el dispositivo en bajo consumo de energía
(menor a 5nA). Si se desea utilizar la opción de bajo consumo de energía se
requiere de una resistencia Pull-up de 10Kohm a Vcc o de menor valor en el
pin PDN. Cuando PDN = 0, entonces el transmisor o receptor entran en
reposo.
Todas estas consideraciones pueden ser ampliadas en la hoja de datos de
cada dispositivo suministradas por el fabricante.
A continuación realizaremos una serie de proyectos en los cuales
implementaremos la comunicación serial inalámbrica, y los cuales resultan
muy interesantes como base para nuevos proyectos.
296
14.2.- Proyecto #39: En el siguiente proyecto se requiere la construcción de
dos circuitos, figura 14.5 y figura 14.6. En el transmisor hemos empleado un
microcontrolador PIC16F877 debido a que en los siguientes proyectos iremos
incorporando más dispositivos externos a demás de la pantalla LCD. El
circuito receptor estará controlado por un PIC16F84 al cual le hemos
conectado una pantalla LCD para visualizar los datos recibidos.
Circuito Transmisor:
Figura 14.5.
297
Circuito Receptor:
Figura 14.6.
298
Proyecto # 39
Componente Cantidad
PIC16F877A 1
PIC16F84A 1
Cristal de 4 Mhz 2
Capacitor cerámico de 22 pF 4
TXM-418-LR-S con antena 1
RXM-418-LR-S con antena 1
Pantalla LCD 16x2 2
Potenciómetro de 5K Ohm 2
Resistencia de 390 Ohm 2
Resistencia de 750 Ohm 1
Resistencia de 10K Ohm 1
Fuente regulada de 3.3 Vdc / 5 Vdc 2
Tabla 14.1.
La primera actividad consiste en enviar una secuencia de dígitos (0 al 9) hacia
el receptor, los cuales deben poder ser visualizados en la pantalla LCD del
mismo. Esto significa que cuando transmitimos el primer dígito al receptor,
éste será mostrado en la pantalla LCD del circuito transmisor y receptor y
ambos deberán ser iguales para confirmar que la transmisión de datos ha sido
exitosa.
Programa para el circuito transmisor:
Symbol T9600 = 2 ' Dato verdadero (Driven True)
I VAR Byte ' Define la variable "I" como Byte
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
inicio:
299
For I = 0 To 9 ' Repetición de 0 a 9
SerOut PORTB.0, T9600, [I] ' Envía los datos por RB0
LCDOut $fe, 2,"Dato: ",#I ' Muestra dato por la LCD
Pause 1000 ' Pausa de 1 segundo
Next I
GoTo inicio ' Salta a inicio y reinicia el conteo
End
Programa para el circuito receptor:
Symbol T9600 = 2 ' Dato verdadero (Driven True)
dato var Byte ' Define la variable "dato" como Byte
pause 500 ' Pausa de 500 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
inicio:
SerIn PORTB.7, T9600, dato ' espera datos durante 1 ms
LCDOUT $fe, 2,"Dato: ",#dato," "
GoTo inicio ' Salta a inicio
End
Como podemos observar en los diagramas de los circuitos, los módulos TXM-
418-LR-S y RXM-418-LR-S conforman el medio a través del cual viajan los
datos, sustituyendo al cable, cuyas limitaciones son de apenas unos pocos
metros cuando se requiere de comunicación serial RS-232.
300
14.3.- Proyecto #40: Incorporando un teclado matricial al proyecto anterior,
podemos enviar datos asignados a cada tecla.
Circuito transmisor:
Figura 14.7.
301
Circuito Receptor:
Figura 14.8.
302
Proyecto # 40
Componente Cantidad
PIC16F877A 1
PIC16F84A 1
Cristal de 4 Mhz 2
Capacitor cerámico de 22 pF 4
Pantalla LCD 16x2 2
TXM-418-LR-S con antena 1
RXM-418-LR-S con antena 1
Resistencia de 1K Ohm 4
Resistencia de 390 Ohm 2
Resistencia de 750 Ohm 1
Resistencia de 10K Ohm 1
Potenciómetro de 5K Ohm 2
Teclado Matricial 3x4 1
Fuente regulada de 3.3 Vdc / 5 Vdc 2
Tabla 14.2.
Programa para el circuito transmisor con teclado matricial:
Symbol T9600 = 2 ' Dato verdadero (Driven True)
TRISD = %01111000 ' Configuración de Puerto D
TECLA VAR Byte ' Declaración de variable "Tecla"
pause 500 ' Pausa de 500 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
inicio:
Call teclado ' Llama a rutina de barrido de teclas
PAUSE 100 ' Pausa de 1050 milisegundos
SerOut PORTB.0, T9600, [TECLA] ' Envía dato por RB0
LCDOUT $fe, 2,"Dato: ",#TECLA ' Muestra dato por la LCD
303
GoTo inicio ' Salto a inicio
teclado:
PORTD.0 = 0 ' Columna 1 = 0
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then TECLA = 1 ' tecla "1"
If PORTD.4 = 0 Then TECLA = 4 ' tecla "4"
If PORTD.5 = 0 Then TECLA = 7 ' tecla "7"
If PORTD.6 = 0 Then TECLA = 10 ' tecla "*"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 0 ' Columna 2 = 0
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then TECLA = 2 ' tecla "2"
If PORTD.4 = 0 Then TECLA = 5 ' tecla "5"
If PORTD.5 = 0 Then TECLA = 8 ' tecla "8"
If PORTD.6 = 0 Then TECLA = 11 ' tecla "0"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 0 ' Columna 3 = 0
If PORTD.3 = 0 Then TECLA = 3 ' tecla "3"
If PORTD.4 = 0 Then TECLA = 6 ' tecla "6"
If PORTD.5 = 0 Then TECLA = 9 ' tecla "9"
If PORTD.6 = 0 Then TECLA = 12 ' tecla "#"
Return
End
Se puede apreciar en la rutina de barrido del teclado que hemos asignado un
valor específico en cada condición, es decir, si presionamos la tecla #1, el
valor asignado a la variable “TECLA” será igual a uno. Si presionamos la tecla
#2, entonces la variable “TECLA” será igual a dos, y así sucesivamente hasta
la última tecla.
304
Cada vez que presionamos una tecla, el dato correspondiente a la misma es
cargado y enviado al receptor el cual a su vez almacena este dato en una
variable, e inmediatamente lo muestra en la pantalla LCD. Esta acción se
puede apreciar en el código de programa que se muestra a continuación.
Programa para el circuito receptor:
Symbol T9600 = 2 ' Dato verdadero (Driven True)
dato VAR Byte ' Define la variable "dato" como Byte
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
inicio:
SerIn PORTB.7, T9600, dato ' Espera de datos
LCDOUT $fe, 2,"Dato: ",#dato," "
GoTo inicio ' Salta a inicio
End
A partir de la etiqueta “inicio” se espera la llegada de los datos enviados
desde el circuito transmisor. En este punto la instrucción “SerIn” mantiene al
microcontrolador en espera, de tal manera que cuando llega un dato, éste se
almacena en la variable correspondiente “dato” y seguidamente salta a la
siguiente línea, que en este caso corresponde a la instrucción LCDout la cual
se encargará de mostrar el dato en la pantalla.
Es importante resaltar que cuando el circuito transmisor es apagado, el
módulo receptor (RXM-418-LR-S) pierde sincronía y puede entregar datos
errados o aleatorios al microcontrolador. Esto es un problema que puede ser
corregido con unas pocas líneas de programación como lo demostraremos en
el siguiente proyecto.
305
14.4.- Proyecto #41: En este proyecto se plantea realizar un sistema de
control a distancia que maneje ocho salidas de potencia en el circuito
receptor, de tal manera que pueda ser encendida o apagada cualquiera de
ellas al presionar el botón correspondiente en el teclado del circuito
transmisor. Esto significa que al pulsar la tecla “1”, el estado de la salida
correspondiente a esta tecla en el circuito receptor debe cambiar. Si la salida
se encuentra en estado lógico cero, la misma debe cambiar a estado lógico
uno y viceversa. Lo mismo debe aplicar para el resto de las salidas de
potencia del circuito receptor.
Para el circuito transmisor podemos emplear el mismo diagrama de la
actividad anterior.
Circuito transmisor:
Figura 14.9.
306
Diagrama del circuito receptor:
Figura 14.10.
307
Programa para el circuito transmisor con teclado matricial:
Symbol T9600 = 2 ' Dato verdadero (Driven True)
TRISD = %01111000 ' Configuración de Puerto D
TECLA VAR Byte ' Declaración de variable "Tecla"
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
inicio:
Call teclado ' Llama a rutina de barrido de teclas.
If tecla = 0 Then inicio ' Si TECLA = 0 ninguna tecla fue
' presionada y salta de nuevo a
' la etiqueta inicio.
SerOut PORTB.0, T9600, [%10011001] ' Envía código de confirmación.
PAUSE 200
SerOut PORTB.0, T9600, [TECLA] ' Envía dato por RB0
PAUSE 300 ' Pausa de 300 milisegundos
LCDOUT $fe, 2,"Dato: ",#TECLA," " ' Muestra dato por la LCD
GoTo inicio ' Salto a inicio
teclado:
tecla = 0
PORTD.0 = 0 ' Columna 1 = 0
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then TECLA = 1 ' tecla "1"
If PORTD.4 = 0 Then TECLA = 4 ' tecla "4"
If PORTD.5 = 0 Then TECLA = 7 ' tecla "7"
If PORTD.6 = 0 Then TECLA = 10 ' tecla "*"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 0 ' Columna 2 = 0
PORTD.2 = 1 ' Columna 3 = 1
If PORTD.3 = 0 Then TECLA = 2 ' tecla "2"
If PORTD.4 = 0 Then TECLA = 5 ' tecla "5"
If PORTD.5 = 0 Then TECLA = 8 ' tecla "8"
308
If PORTD.6 = 0 Then TECLA = 11 ' tecla "0"
PORTD.0 = 1 ' Columna 1 = 1
PORTD.1 = 1 ' Columna 2 = 1
PORTD.2 = 0 ' Columna 3 = 0
If PORTD.3 = 0 Then TECLA = 3 ' tecla "3"
If PORTD.4 = 0 Then TECLA = 6 ' tecla "6"
If PORTD.5 = 0 Then TECLA = 9 ' tecla "9"
If PORTD.6 = 0 Then TECLA = 12 ' tecla "#"
Return
End
En el programa del circuito transmisor se pueden observar algunas mejoras. A
partir de la etiqueta “inicio” se puede observar que no se envían datos al
receptor a menos que se presione una tecla.
Si una tecla es presionada, entonces enviamos un código elegido al azar al
receptor (Ej. 10011001), para indicar que el siguiente dato corresponde al de
la tecla presionada. De esta manera evitaremos observar datos errados en la
pantalla LCD del circuito receptor, ya que su programa ha sido diseñado para
que solo cambie el estado lógico de las salidas de potencia, solo si recibe el
código correcto enviado desde el circuito transmisor.
Programa para el circuito receptor:
TRISD = %00000000
Symbol T9600 = 2 ' Dato verdadero (Driven True)
dato VAR Byte ' Define la variable "dato" como Byte
salida VAR Byte
Pause 500 ' Pausa de 500 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
PORTD = 0 ' Inicializamos el puerto D
inicio:
SerIn PORTB.7, T9600, dato ' Espera datos.
If DATO = %10011001 Then sigue ' Salta a la etiqueta "sigue"
309
' si se recibe el código correcto
' que hemos elegido (10011001)
GoTo inicio ' Salto a inicio.
sigue:
SerIn PORTB.7, T9600, dato ' espera datos durante 1 ms
If dato = 1 Then Toggle PORTD.0 ' Invierte el Bit en RD0
If dato = 2 Then Toggle PORTD.1 ' Invierte el Bit en RD1
If dato = 3 Then Toggle PORTD.2 ' Invierte el Bit en RD2
If dato = 4 Then Toggle PORTD.3 ' Invierte el Bit en RD3
If dato = 5 Then Toggle PORTD.4 ' Invierte el Bit en RD4
If dato = 6 Then Toggle PORTD.5 ' Invierte el Bit en RD5
If dato = 7 Then Toggle PORTD.6 ' Invierte el Bit en RD6
If dato = 8 Then Toggle PORTD.7 ' Invierte el Bit en RD7
LCDOUT $fe, 2,"Salida #: ",#dato," " ' Muestra dato en LCD
GoTo inicio ' Salta a inicio
End
310
Instrucciones de programa de PicBasic Capítulo XV
@
Sintaxis:
@ instrucción en lenguaje ensamblador
Esta instrucción es utilizada para insertar dentro del código PicBasic, líneas
de programa en lenguaje ensamblador. En este caso, cada línea en lenguaje
ensamblador debe llevar el símbolo @ al inicio.
Ejemplo:
Led Var Byte ' Declaración de Variable Led
TRISB = $00 ' Configura el puerto B como salida
Led = $00 ' Inicializamos la variable Led
Inicio:
@bsf _Led,0 ' pone en 1 el bit 0 de la variable Led
Pause 1000 ' Pausa de 1 segundo
PORTB = Led ' Saca dato por el puerto B
Pause 1000 ' Pausa de 1 segundo
@bcf _Led,0 ' pone en 0 el bit 0 de la variable Led
PORTB = Led ' Saca dato por el puerto B
GoTo Inicio ' Salto a inicio
End
Nota Importante: para acceder a una variable declarada en PicBasic, desde
el lenguaje ensamblador se debe anteponer el símbolo “_” (Guión bajo), ya
que de lo contrario no será posible el acceso a ésta. En el ejemplo, se puede
ver que para acceder a la variable “Led” desde el lenguaje ensamblador, se
antepuso el guión bajo a la variable, quedando “_Led”.
311
ADCin
Sintaxis:
ADCin canal, Variable
Lee una entrada del conversor A/D y el resultado es almacenado en una
variable.
Esta instrucción solo es válida para microcontroladores que tienen convertidor
A/D, por ejemplo, el PIC16F877, el PIC18F442, el PIC18F452, el PIC18F458
entre otros.
Asm… EndAsm
Sintaxis:
Asm
*
*
Instrucciones en lenguaje ensamblador
*
*
EndAsm
Esta instrucción permite insertar un conjunto de instrucciones en lenguaje
ensamblador y al igual que en la instrucción “@”, también aplica el uso del
símbolo “_” (Guión Bajo), el cual debe anteceder a las variables que se
deseen utilizar.
312
Branch
Sintaxis:
Branch Variable,[Etiqueta1, Etiqueta2,…EtiquetaN]
La instrucción Branch hace un salto a una etiqueta dependiendo del valor de
la variable, es decir, si la variable es igual a 0, el salto se hace a la etiqueta 1;
si la variable es igual a 1, el salto se hace a la etiqueta 2; si la variable es
igual a 2, el salto se hace a la etiqueta 3, y así sucesivamente.
Ejemplo:
I var Byte ' Declaración de Variable I
TRISB = $00 ' Configura el puerto B como salida
PORTB = $00 ' Inicializa el puerto B
I = 0 ' Inicializa la variable I
inicio:
Branch I,[Led1,Led2,Led3]
Led1:
PORTB = %00000001 ' enciende el led en RB0
pause 1000 ' pause de 1 segundo
PORTB = %00000000 ' apaga el led
I = I + 1 ' suma 1 a la variable I
GoTo inicio ' salta a inicio
Led2:
PORTB = %00000010 ' enciende el led en RB1
pause 1000 ' pause de 1 segundo
PORTB = %00000000 ' apaga el Led
I = I + 1 ' suma 1 a la variable I
GoTo inicio ' salta a inicio
Led3:
PORTB = %00000100 ' enciende el led en RB2
pause 1000 ' pause de 1 segundo
PORTB = %00000000 ' apaga el Led
I = 0 ' Inicializa la variable I
GoTo inicio ' salta a inicio
End
313
Button
Sintaxis: Button pin, estado, retardo, rango, variable, acción, etiqueta
La instrucción “Button” elimina los rebotes de un “pulsador” o “switch”, y
genera auto-repetición.
Pin: especifica el pin del puerto en el cual será conectado el pulsador.
Estado: indica cual es estado lógico que debe ocurrir cuando el pulsador es
presionado (0 o 1). Si es 0, el pulsador deberá ser activo-bajo y si es 1, el
pulsador deberá ser activo-alto (Ver figura 15.1).
Activo-Alto
S1
Pulsador
Al Pin
R1
10 Kohm
+5V
R1
10 Kohm S1
Pulsador
Al Pin
+5V
Activo-Bajo
Figura 15.1.
Retardo: es una variable o constante (0 – 255) que especifica cuantos ciclos
deben pasar antes de efectuar la auto-repetición. Este campo tiene dos
funciones especiales: si el campo retardo es igual 0, no permite anti-rebote y
no permite auto-repetición. Si el campo retardo es igual a 255, permite el anti-
rebote pero no permite la auto-repetición.
Rango: es una variable o constante (0 – 255) que especifica el número de
ciclos entre auto-repeticiones.
314
Variable: es una variable auxiliar tipo Byte, definida también al inicio del
programa para uso exclusivo de la instrucción Button, por lo cual no deberá
ser utilizada con otro fin en el programa. Siempre debe ser inicializada antes
del comando Button.
Acción: indica el estado del botón cuando éste no es presionado.
Etiqueta: la instrucción realiza un salto a la etiqueta definida en este campo
cuando el pulsador no ha sido presionado.
Ejemplo:
TRISB = %11111101 ' Configuración del puerto B
A0 Var Byte ' declaración de la variable A0
Lcdout $fe,1
A0 = 0 ' inicializa la variable A0
inicio:
Button PORTB.0,1,2,2,A0,0,NoPres
PulsOut PORTB.1,150
NoPres:
Pause 10
GoTo inicio ' Salta a inicio
End
315
Call
Sintaxis:
Call etiqueta
La instrucción “Call”, llama a una subrutina la cual está identificada con una
etiqueta, y una vez culminada la subrutina la cual contiene al final la
instrucción “Return”, vuelve a la siguiente línea después del llamado.
Ejemplo:
inicio:
Call Teclado
If A0 = 1 Then led1
.
.
.
Teclado:
.
.
.
.
Return
End
Clear
Sintaxis:
Clear
La instrucción “Clear” inicializa todos los registros de la RAM a cero, es decir,
todas las variables simultáneamente pasarán a ser cero.
316
ClearWDT
Sintaxis:
ClearWDT
La instrucción “ClearWDT” inicializa el Perro Guardián (Watchdog Timer).
Count
Sintaxis:
Count pin, duración, variable
La instrucción “Count” puede medir la frecuencia de una señal simple
determinando el número de pulsos por segundo. Se pueden medir frecuencias
de hasta 25 khz con un oscilador de 4 MHz. Para un oscilador de 20 MHz la
frecuencia máxima a ser medida será de 125 khz.
Pin: especifica el pin del puerto en el cual se introducirán los impulsos. Este
pin es designado como entrada automáticamente por la instrucción Count.
Duración: es el tiempo durante el cual se realizará el conteo de impulsos
sobre el pin especificado.
Variable: es una variable definida por el programador en la cual se grabará el
resultado del conteo.
317
Data
Sintaxis:
Data {@Dirección inicial}, constante1, constante2,…constanteN
La instrucción “Data” solo puede ser utilizada para las familias de
microcontroladores que incorporan memoria EEPROM en su arquitectura.
Para los microcontroladores que no cuentan con esta memoria, existe la
posibilidad de agregar una memoria EEPROM externa a través del protocolo
de comunicación I2C.
Básicamente esta instrucción guarda varias constantes a partir de una
dirección que especificamos en el campo correspondiente.
Ejemplo:
Data @10,1,3,5,7,9
En este ejemplo, la instrucción Data almacenará los valores 1, 3, 5, 7 y 9 en
las direcciones de memoria 10, 11, 12, 13 y 14 respectivamente.
DTMFout
Sintaxis:
DTMFout pin, {On-ms, Off-ms}, [tono, tono,...tono]
La instrucción DTMFout genera tonos DTMF en secuencia y a través de un
puerto cualquiera del microcontrolador.
Pin: especifica el pin del puerto en el cual se emitirán los tonos DTMF.
On-ms: es una variable, constante o expresión que especifica la duración de
cada tono en milisegundos. En caso de no utilizar este parámetro, el tiempo
por defecto de cada tono es de 200 ms.
318
Off-ms: es una variable o constante que especifica el tiempo en milisegundos
del silencio que hay entre cada tono. En caso de no utilizar este parámetro, el
tiempo por defecto será de 50 ms.
Tono: puede ser una variable o constante (entre 0 – 15), que especifica el
tono que debe ser generado.
Dígito en la
Instrucción
DTMFout
Dígito en un
Teclado
Telefónico
Frecuencias
Bajas
Frecuencias
Altas
1 1 697 HZ 1209 HZ
2 2 697 HZ 1336 HZ
3 3 697 HZ 1477 HZ
4 4 770 HZ 1209 HZ
5 5 770 HZ 1336 HZ
6 6 770 HZ 1477 HZ
7 7 852 HZ 1209 HZ
8 8 852 HZ 1336 HZ
9 9 852 HZ 1477 HZ
10 0 941 HZ 1209 HZ
11 * 941 HZ 1336 HZ
12 # 941 HZ 1477 HZ
13 A 697 HZ 1633 HZ
14 B 770 HZ 1633 HZ
15 C 852 HZ 1633 HZ
0 D 941 HZ 1633 HZ
Tabla 15.1.
319
Figura 15.2.
Ejemplo:
DTMFout PortC.0, [0,1,2,3,4,5,6,7,8,9]
Conectando el pin de salida (RC0) adecuadamente a una línea telefónica,
estaremos marcando sin problemas un número telefónico. En algunos casos
es recomendable utilizar los tiempos On-ms y Off-ms para realizar un
marcado más exacto.
Ejemplo:
DTMFout PortC.0,400,150, [6,4,3,8,7,1,0]
320
Los tonos tendrán una duración de 400 milisegundos cada uno y un tiempo en
silencio entre ellos de 150 milisegundos.
En cuanto al oscilador se recomienda usar del tipo HS (desde 10 Mhz o
superior) para obtener mejores resultados en la generación de tonos DTMF,
así como también se recomienda utilizar un circuito de acople entre el
microcontrolador y el dispositivo externo al cual enviaremos los tonos.
C2
0.1 uF
Parlante
R1
1K
Al Pin
C2
10 uF
GND
R2
1K
C1
10 uF
GNDGND
Al Pin Al amplif icador de Audio
C1
0.1 uF
Figura 15.3.
321
EEPROM
Sintaxis:
EEPROM dirección,[constante1, constante2,….constanteN]
La instrucción “EEPROM” es capaz de almacenar datos en la memoria de
datos de un microcontrolador siempre y cuando éste cuente con esta
característica y a partir de la dirección indicada, almacena constantes
específicas en las posiciones consecutivas a la inicial.
Es importante resaltar que los datos solo son almacenados al momento de
grabar el microcontrolador en nuestro programador para microcontroladores
PIC, por lo tanto, para realizar lecturas o grabaciones de nuevos datos
durante la ejecución de un programa se debe recurrir a las instrucciones Read
y Write.
END
Sintaxis:
End
La instrucción “END” detiene la ejecución de un programa y pone el
microcontrolador en bajo consumo de energía.
FREQOUT
Sintaxis:
FreqOut pin, On-ms, Frecuencia1, Frecuencia2
La instrucción “FreqOut” genera una o dos señales de frecuencia entre 0 y
32767 Hz previamente definidas, durante un período de tiempo también
definido.
322
Pin: especifica el pin del puerto en el cual se va a generar la señal.
On-ms: Es una variable o constante que determina el tiempo de duración de
la señal.
Frecuencia1: puede ser una variable o constante (entre 0 – 32767) que
especifica la frecuencia del primer tono.
Frecuencia2: puede ser una variable o constante (entre 0 – 32767) que
especifica la frecuencia del segundo tono, el cual sale mezclado con la
frecuencia 1.
En cuanto al oscilador también se recomienda usar del tipo HS (20 Mhz) para
obtener mejores resultados en la generación de tonos, así como también se
recomienda utilizar un circuito de acople entre el microcontrolador y el
dispositivo externo al cual enviaremos los tonos (ver figura 15.3).
Ejemplo:
FreqOut PortC.2, 1000, 2000
Genera un tono de 2000Hz durante 1 segundo.
FreqOut PortC.2, 1000, 1500, 3500
Genera dos tonos a la vez durante 1 segundo, uno de 1500Hz y otro de
3500Hz.
323
FOR… NEXT
Sintaxis:
For variable = inicio to final {step {-} incremento}
*
*
Instrucciones…
*
*
Next {variable}
La instrucción “For…Next” se encarga de hacer repeticiones de instrucciones
que permanecen dentro del lazo For… Next.
El parámetro Step afecta el incremento según el valor asignado después de
esta palabra. Si este parámetro es omitido, el incremento es en una unidad.
Ejemplo:
Z Var Byte ' Declaración de la Variable Z
Inicio:
For Z = 0 To 10
PORTD.0 = 1 ' Pone en 1 el pin RD0
Pause 1000 ' Pausa de 1 segundo
PORTD.0 = 0 ' Pone en 0 el pin RD0
Pause 1000 ' Pausa de 1 segundo
Next Z
End
324
Gosub
Sintaxis:
Gosub etiqueta
La instrucción “Gosub” ejecuta subrutinas dentro de un programa principal
donde la ubicación de las mismas estará definida por la etiqueta
correspondiente. Una vez ejecutada la subrutina y encontrada la instrucción
Return, la ejecución del programa continúa en la línea siguiente a la
instrucción Gosub.
GOTO
Sintaxis:
GOTO etiqueta
La instrucción “Goto” continúa la ejecución de un programa a partir de la
etiqueta especificada. Esta instrucción no tiene retorno.
HIGH
Sintaxis:
HIGH pin
La instrucción “High” pone en uno lógico el pin especificado, el cual configura
automáticamente como salida.
Ejemplo:
Inicio:
HIGH PORTA.0 ' Pone en 1 el pin RA0
325
GoTo inicio
End
I2CREAD
Sintaxis:
I2Cread SDA, SCL, Control, Dirección, [dato], {etiqueta de salto opcional}
La instrucción “I2Cread” enviará el dato de control y la dirección específica a
un dispositivo conectado a un bus I2C y almacenará el dato obtenido en una
variable definida. Al utilizar la etiqueta opcional, el programa saltará si no se
recibe ninguna respuesta del dispositivo consultado.
Ejemplo:
SDA VAR PORTB.0
SCL VAR PORTB.1
A1 VAR Byte
Direc VAR Word
Control VAR Byte
Pause 500 ' Pause de 500 milisegundos
LCDOut $fe, 1 ' Limpia la LCD
inicio:
Direc = $10 ' Dirección en la memoria externa
Control = $A0 ' Dato de Control
I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de
' memoria
LCDOUT $fe, 2,"Dato: ",#A1 ' Muestra el dato leído
ciclo: GoTo ciclo
End
326
I2CWRITE
Sintaxis:
I2CWrite SDA, SCL, Control, Dirección, [dato], {etiqueta de salto opcional}
La instrucción “I2CWrite” enviará el dato de control y la dirección en la cual se
almacenará el dato cargado en la variable previamente cargada.
Ejemplo:
SDA VAR PORTB.0
SCL VAR PORTB.1
Direc var Word
Control Var Byte
inicio:
Direc = $10 ' Dirección en la memoria externa
Control = $A0 ' Dato de Control
I2Cwrite SDA, SCL, Control, Direc, [$21] ' Escribe la
' memoria
pause 10 ' Pausa de 10 milisegundos
Loop: GoTo Loop
End
IF – THEM – ELSE
Sintaxis:
If expresión 1 {AND / OR expresión 2} Then etiqueta
Con la instrucción “If – Them” podemos seleccionar uno, dos o mas posibles
comportamientos de programa, tomando decisiones en una estructura de
programación sencilla y la cual será considerada casi en la totalidad de los
programas.
327
Ejemplo 1: Si pulsamos un botón conectado al pin RA0 se cumple la condición
y salta a la etiqueta “Espera”.
inicio:
Input PORTA.0 ' Designa el PIN RA0 como entrada
If PORTA.0 = 1 Then Espera ' Si RA0 = 1 salta a la etiqueta
GoTo inicio ' Salta a "inicio" si RA0 = 0
Espera:
GoTo Espera
End
Ejemplo 2:
inicio:
Input PORTA.0 ' Designa el PIN RA0 como entrada
If PORTA.0 = 1 Then ' Si RA0 = 1 ...
GoTo Espera ' salta a la etiqueta "Espera"
Else ' de lo contrario...
GoTo inicio ' salta a la etiqueta "inicio"
EndIf ' Fin de la instrucción IF-Them-Else
Espera:
GoTo Espera
End
Solo se utiliza “EndIf” cuando deseamos tener más de una condición o toma
de decisión.
328
Ejemplo 3:
A VAR Byte
inicio:
Input PORTA.0 ' Designa el PIN RA0 como entrada
If PORTA.0 = 1 Then
A = A + 1
If A = 10 Then Espera ' Si A = 10 salta a la etiqueta “Espera”
EndIf
GoTo inicio ' Salta a "inicio"
Espera:
GoTo Espera
End
INPUT
Sintaxis:
INPUT PIN
Designa un pin específico como entrada.
Ejemplo:
inicio:
Input PORTA.0 ' Designa el PIN RA0 como entrada
Espera:
GoTo Espera
End
329
LCDIN
Sintaxis:
LCDin dirección, [variable1, variable2,…]
La instrucción “LCDin” carga el dato almacenado en una dirección de la
memoria RAM de la LCD en una variable previamente definida.
Ejemplo:
A VAR Byte
inicio:
LCDIn $10,[A] ' Lee el dato en la dirección de memoria $10
' y lo carga en la variable "A".
Espera:
GoTo Espera
End
330
LCDout
Sintaxis:
LCDout comando, dato
La instrucción “Lcdout” envía datos específicos a una pantalla LCD
Alfanumérica para que puedan ser mostrados en la misma.
Tabla 15.2.
Ejemplo:
Pause 200
LCDOut $fe, 1 ' Limpia la pantalla
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "* Pantalla LCD *" ' escribe
LCDOut $fe,$C0, "* Alfanumerica *"
LCDOut $fe,$90, "* 1234567890 *"
LCDOut $fe,$D0, "* AaBbCcDdEeFf *"
Inicio:
GoTo Inicio
End
Comando Acción
$FE, 1 Limpia la pantalla
$FE, 2 Retorna al inicio de la primera línea
$FE, $0C Apaga el Cursor
$FE, $0E Cursor bajo (Underline "_") activo
$FE, $0F Cursor intermitente activo
$FE, $10 Mueve el cursor un espacio a la izquierda
$FE, $14 Mueve el cursor un espacio a la derecha
$FE, $C0 Mueve el cursor al inicio de la segunda línea
$FE, $90 Mueve el cursor al inicio de la tercera línea
$FE, $D0 Mueve el cursor al inicio de la cuarta línea
331
LOW
Sintaxis:
LOW pin
La instrucción “LOW” coloca en cero lógico un pin específico.
Ejemplo:
inicio:
Low PORTA.0 ' configura RA0 = 0
espera:
GoTo espera
End
NAP
Sintaxis:
NAP periodo
La instrucción “NAP” pone el microcontrolador en modo de bajo consumo de
energía por periodos de tiempo definidos en la siguiente tabla:
332
Periodo Retardo (ms)
0 18
1 36
2 72
3 144
4 288
5 576
6 1152
7 2304
Tabla 15.3.
Ejemplo:
inicio:
NAP 6 ' Bajo consumo de energía durante 1152 milisegundos
espera:
GoTo espera
End
OUTPUT
Sintaxis:
OUTPUT pin
La instrucción “OUTPUT” configura un pin específico como salida.
Ejemplo:
inicio:
OUTPUT PORTA.0 ' configura RA0 como salida
espera:
GoTo espera
End
333
PAUSE
Sintaxis:
PAUSE periodo
La instrucción “Pause” realiza una pausa en el programa por un periodo
definido en milisegundos. Esta instrucción no pone al microcontrolador en
modo de bajo consumo de energía.
Ejemplo:
inicio:
High PORTA.0 ' RA0 = 1
Pause 1000 ' Pausa de 1 segundo
Low PORTA.0 ' RA0 = 0
Pause 1500 ' Pausa de 1.5 segundos
GoTo inicio ' Salta a la etiqueta "inicio"
End
PAUSEUS
Sintaxis:
PAUSEUS periodo
La instrucción “PauseUs” realiza una pausa en el programa por un periodo
definido en microsegundos. Esta instrucción no pone al microcontrolador en
modo de bajo consumo de energía.
Ejemplo:
334
inicio:
High PORTA.0 ' RA0 = 1
PauseUs 200 ' Pausa de 200 microsegundos
Low PORTA.0 ' RA0 = 0
PauseUs 1500 ' Pausa de 1.5 milisegundos
GoTo inicio ' Salta a la etiqueta "inicio"
End
POT
Sintaxis:
POT pin, escala, variable
La instrucción “POT” lee un potenciómetro, foto celda, termistor, o cualquier
otro dispositivo capaz de variar su valor resistivo. Básicamente esta
instrucción calcula el tiempo de descarga del condensador C1 el cual varía
según el valor resistivo presente en la resistencia variable.
Pin: especifica el pin del puerto en el cual se va a conectar el potenciómetro.
Escala: Es una variable o constante que aumenta o disminuye el rango de
lectura en un porcentaje determinado. Esta escala es utilizada para ajustar el
rango de salida en la lectura del dispositivo, y es afectada directamente por
las constantes RC. El valor de la escala será correcto cuando el valor cargado
en la variable se aproxime a cero, cuando la resistencia medida sea mínima; y
también cuando el valor de la variable se aproxime a 255, cuando la
resistencia medida sea máxima.
Variable: es una variable en la cual se almacena el resultado obtenido de la
lectura del potenciómetro o componente resistivo.
335
PULSIN
Sintaxis:
PULSIN pin, nivel, variable
La instrucción “PULSIN” mide la duración de un pulso alto o bajo con una
resolución de 10 microsegundos para un oscilador de 4 Mhz y el valor
obtenido es almacenado en una variable definida de 8 bits (variable tipo byte)
o 16 bits (variable tipo Word).
Pin: especifica el pin del puerto en el cual se introducirán los pulsos.
Nivel: define si la medición se hace en nivel alto o bajo. (1 = alto, 0 = bajo).
Variable: es una variable de 8 bits (variable tipo byte) o 16 bits (variable tipo
word) definida por el programador en la cual se grabará el resultado de la
lectura.
Ejemplo:
Define OSC 4 ' Define el oscilador en 4 Mhz
LECTURA VAR Word ' Definición de variable de 16 bits
Pause 200 ' Pausa de 200 milisegundos
LCDOut $fe, 1 ' Limpia la pantalla
Inicio:
LECTURA = 0 ' Inicializa la variable
PulsIn PORTB.0,1,LECTURA
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Lect. en ms:",#LECTURA," " ' Muestra mensaje y
' dato por pantalla
Pause 1000 ' Pausa de 1 segundo
GoTo Inicio ' Salta a inicio
End
336
PULSOUT
Sintaxis:
PULSOUT pin, nivel, variable
La instrucción “PULSOUT” genera pulsos con una duración definida en
decenas de microsegundos. (Tiene una resolución de 10 microsegundos
para un oscilador de 4 Mhz).
Ejemplo:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
Inicio:
PulsOut PORTB.0,100 ' Genera un pulso de 1 milisegundo de
' duración o 100 decenas de uS.
Pause 1 ' Pausa de 1 milisegundo.
GoTo Inicio ' Salto a inicio
End
PWM
Sintaxis:
PWM pin, nivel, ciclo
La instrucción “PWM” envía pulsos PWM (Pulse Width Modulation) a un pin
específico.
Pin: especifica el pin del puerto en el cual se genera PWM.
Nivel: es una variable o constante que determina la duración del pulso en su
nivel alto, es decir, partiendo de nivel = 1 si se incrementa este valor, el ancho
de pulso positivo se incrementa hasta nivel = 254 donde el ciclo de trabajo es
337
aproximadamente 100%. Cuando nivel = 0 la salida se mantiene en cero
lógico; cuando nivel = 255 la salida se mantiene en uno lógico.
Ciclo: es una variable o constante en el cual se define el número de ciclos en
un pin específico.
Ejemplo:
DEFINE OSC 4 ' Define el oscilador en 4 Mhz
Inicio:
PWM PORTB.0,127,100 ' Señal PWM
GoTo Inicio ' Salto a inicio
End
RANDOM
Sintaxis:
RANDOM variable
La instrucción RANDOM almacena números aleatorios en una variable de 16
Bits (Word).
Ejemplo:
A0 VAR Word ' Declaración de variable "A0" Word (16 Bits)
Pause 200 ' Pausa de 200 milisegundos
LCDOut $fe, 1 ' Limpia la pantalla
Inicio:
Random A0 ' Almacena un número aleatorio en A0
338
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "RANDOM: ",#A0," " ' Muestra mensaje y
' dato por pantalla
Pause 1500 ' Pausa de 1.5 segundos
GoTo Inicio ' Salto a inicio
End
READ
Sintaxis:
READ dirección, variable
La instrucción “READ” permite leer datos desde la memoria EEPROM de
datos de un microcontrolador almacenándolos en una variable previamente
definida.
Ejemplo:
' Declaración de Variables:
I VAR Byte
DIRECCION VAR Byte
DATO VAR Byte
WRITE 1, 3 ' Escribe en la memoria de datos
WRITE 2, 5 ' Escribe en la memoria de datos
WRITE 3, 7 ' Escribe en la memoria de datos
WRITE 4, 9 ' Escribe en la memoria de datos
WRITE 5, 11 ' Escribe en la memoria de datos
DIRECCION = 1 ' Dirección inicial de lectura
Pause 200 ' Pausa de 200 milisegundos
LCDOut $fe, 1 ' Limpia la pantalla
Inicio:
For I = 1 To 5 ' Repite la lectura cinco veces
339
Read DIRECCION,DATO ' Lee la dirección especificada y la
' guarda en la variable "Dato".
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Direccion: ",#DIRECCION," " ' Muestra dirección
LCDOut $fe,$C0, "Dato: ",#DATO," " ' Muestra el dato leído
DIRECCION = DIRECCION + 1 ' Suma uno (1) a la variable
Pause 1500 ' Pausa de 1.5 segundos
Next I
End
RETURN
Sintaxis:
RETURN
Retorno de una subrutina desde donde se ha generado un salto del tipo Call o
Gosub.
Ejemplo:
inicio:
Call Teclado
If A0 = 1 Then led1
.
.
.
Teclado:
.
.
.
.
Return
End
340
REVERSE
Sintaxis:
REVERSE pin
La instrucción “REVERSE” cambia el estado de un pin I/O, es decir, si el pin
es entrada, éste pasa a ser salida. Si un pin es “salida”, éste pasa a ser
entrada.
Ejemplo:
TRISB = %00000000 ' Configura los pines del puerto B como
' salida.
Inicio:
High PORTB.5 ' RB5 = 1
Pause 1000 ' Pausa de 1 segundo
Low PORTB.5 ' RB5 = 0
Reverse PORTB.5 ' RB5 ahora es entrada
End
SELECT CASE
Sintaxis:
SELECT CASE variable
La instrucción “SELECT CASE” es un condicional que permite seleccionar
entre un número determinado de subrutinas.
Ejemplo:
' Declaración de Variables
I VAR Byte
Z VAR Byte
Pause 200 ' Pausa de 200 milisegundos
LCDOut $fe, 1 ' Limpia la pantalla
341
Z = 0 ' Inicializa la variable Z
Inicio:
Z = Z + 1 ' Incrementa la variable Z
If Z = 4 Then Final ' Si Z = 4 salta a la etiqueta "Final"
Select Case Z ' Condicional Select Case para la
' variable Z.
Case 1
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Select Case 1" ' Muestra mensaje por la LCD
Pause 1500 ' Pausa de 1.5 segundos
GoTo Inicio ' Salto a inicio
Case 2
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Select Case 2" ' Muestra mensaje por la LCD
Pause 1500 ' Pausa de 1.5 segundos
GoTo Inicio ' Salto a inicio
Case 3
LCDOut $fe, 2 ' Posiciona el cursor en el inicio
LCDOut "Select Case 3" ' Muestra mensaje por la LCD
Pause 1500 ' Pausa de 1.5 segundos
GoTo Inicio ' Salto a inicio
End Select
Final:
GoTo Final
End
342
SERIN
Sintaxis:
SERIN pin, modo,{tiempo, etiqueta}, variable
La instrucción “SerIn” se encarga de recibir uno o mas valores a través de un
pin específico usando el formato asíncrono estándar 8N1 que significa 8 bits
de datos, sin revisión de paridad y 1 bit de parada (stop). SerIn trabaja por
defecto con un oscilador de 4 Mhz y para tener una transferencia de datos
segura con otros osciladores de mayor valor, será necesario utilizar la
directiva “Define Osc” al inicio del programa.
Pin: en este campo definiremos cual será el pin de entrada entre los puertos
disponibles del microcontrolador. Ejemplo: PortB.1
Modo: define la velocidad de transmisión en baudios.
Tiempo: este campo es opcional al igual que el campo “etiqueta” y su objetivo
es establecer un tiempo en milisegundos definido por el programador, el cual
una vez vencido, hará que se realice un salto a la “etiqueta” también definida
por el programador.
Variable: en este campo se especifica la variable en la cual se desea sean
almacenados los datos recibidos.
Ejemplo:
Symbol T9600 = 2 ' Dato verdadero (Driven True)
dato var Byte ' Define la variable “dato” como Byte
Pause 500 ' Pausa de 500 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
SerIn PORTC.7, T9600, dato ' espera datos durante 1 ms
343
LCDOUT $fe, 2,"Dato: "
LCDOut $fe,$C0,#dato," "
GoTo Inicio ' Salta a inicio
End
SEROUT
Sintaxis:
SEROUT pin, modo, [variable]
La instrucción “SerOut” se encarga de enviar uno o mas valores a través de
un pin específico usando el formato asíncrono estándar 8N1 que significa 8
bits de datos, sin revisión de paridad y 1 bit de parada (stop).
Pin: en este campo definiremos cual será el pin de salida entre los puertos
disponibles del microcontrolador.
Modo: define la velocidad de transmisión en baudios y emplea la misma tabla
de la instrucción SerIn.
Variable: en este campo se especifica la variable que contiene los datos que
serán enviados a través de pin especificado.
Ejemplo:
Symbol T9600 = 2 ' Dato verdadero (Driven True)
I VAR Byte ' Define la variable “I” como Byte
Inicio:
For I = 0 To 9 ' Repetición de 0 a 9
SerOut PORTC.6, T9600, [#I] ' “#” envía los datos en ASCII
Pause 1000 ' Pausa de 1 segundo
Next I
344
GoTo Inicio ' Salta a inicio
End
SLEEP
Sintaxis:
SLEEP período
La instrucción “SLEEP” lleva a un estado de bajo consumo de energía a un
microcontrolador por un período de tiempo definido en segundos.
Ejemplo:
Inicio:
Sleep 10 ' Bajo consumo de energía durante 10 segundos
Espera:
GoTo Espera ' Salta a la etiqueta "Espera"
End
SWAP
Sintaxis:
SWAP variable, variable
La instrucción “SWAP” intercambia el contenido de dos variables.
Ejemplo:
A1 VAR Byte ' Define la variable "A1" como Byte
B1 VAR Byte ' Define la variable "B1" como Byte
345
A1 = 10
B1 = 15
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
Swap A1,B1 ' Intercambia datos entre variables
LCDOUT $fe, 2,"A1: ",#A1 ' Muestra variable A1 por la LCD
LCDOut $fe,$C0,"B1: ",#B1 ' Muestra variable B1 por la LCD
Espera:
GoTo Espera ' Salta a la etiqueta "Espera"
End
TOGGLE
Sintaxis:
TOGGLE pin
La instrucción “TOGGLE” invierte el estado lógico de un pin específico, es
decir, si un pin se encuentra en estado lógico cero (0), éste pasa a ser uno
lógico (1) y viceversa.
Ejemplo:
High PORTA.0 ' Pone en uno (1) RA0
Inicio:
Toggle PORTA.0 ' invierte el estado lógico de RA0
Pause 1000 ' Pausa de 1 segundo
346
GoTo Inicio ' Salto a inicio
End
WHILE-WEND
Sintaxis:
WHILE condición
...instrucciones...
WEND
La instrucción “WHILE – WEND” mantiene la ejecución de las instrucciones
involucradas, es decir, entre While y Wend, hasta que se cumpla la condición
establecida.
Ejemplo:
A VAR Byte ' Declaración de variable "A"
A = 0 ' Inicializa la variable "A"
Pause 200 ' Pausa de 200 milisegundos para la LCD
LCDOut $fe, 1 ' Limpia la LCD
Inicio:
While A < 5 ' Condicional While - Wend
High PORTB.0 ' RB0 = 1
Pause 1000 ' Pausa de 1 segundo
Low PORTB.0 ' RB0 = 0
PAUSE 1000 ' Pausa de 1 segundo
A = A + 1 ' incrementa en uno (1) la variable "A"
Wend
347
LCDOUT $fe, 2, "While - Wend" ' Muestra mensaje
LCDOut $fe,$C0,"ha terminado!" ' Muestra mensaje
Espera:
GoTo Espera ' Salta a la etiqueta "espera"
End
WRITE
Sintaxis:
WRITE dirección, variable
La instrucción “WRITE” almacena datos en la memoria EEPROM de un
microcontrolador en una dirección específica.
Ejemplo:
Inicio:
WRITE 1, $03 ' Escribe en la dirección 1 o $01 el dato $03
WRITE 2, $A1 ' Escribe en la dirección 2 o $02 el dato $A1
WRITE 3, 7 ' Escribe en la dirección 3 o $03 el dato $07
WRITE 9, 13 ' Escribe en la dirección 9 o $09 el dato $0D
WRITE 5, $F0 ' Escribe en la dirección 15 o $0F el dato $0F
espera:
GoTo espera
End
348
Apéndice A
Programador de Microcontroladores PIC
Existe una gran diversidad de programadores para microcontroladores PIC los
cuales puede adquirir en tiendas de electrónica OnLine o en su proveedor
local de componentes electrónicos. Sin embargo, consideramos una
excelente experiencia llevar a cabo la construcción de su propio programador
por lo cual le proponemos uno de los más populares y prácticos, capaz de
programar una gran variedad de modelos de microcontroladores PIC, de muy
bajo costo y fácil construcción. Recomendamos P16Pro, programador de
microcontroladores desarrollado por Bojan Dobaj de Slovenia, cuyo sitio oficial
en la red es http://www.picallw.com.
Figura A.1.
349
Software:
Descargue el software en su última versión en el sitio Web
http://www.picallw.com, en la sección denominada “Download”. Una vez
descargado el archivo, se precede a descomprimir el mismo para luego iniciar
la instalación del software haciendo doble clic sobre el archivo ejecutable que
ha resultado disponible, denominado “Setup.exe”
A continuación se muestran las pantallas que se generan en el proceso de
instalación del software:
• La figura A.2 muestra el inicio del proceso de instalación del
software.
Figura A.2.
• El instalador le mostrara un mensaje de bienvenida en el cual
deberá seleccionar la opción “NEXT” para continuar con la
instalación (Figura A.3).
350
Figura A.3.
• Luego deberá indicar la ruta de instalación del software en el
disco duro. La ruta propuesta por defecto es C:Picall (Figura
A.4).
Figura A.4.
• En la siguiente pantalla, el programa instalador le sugiere un
nombre para el icono o acceso al programa en la barra de inicio
de Windows (Figura A.5).
351
Figura A.5.
• Al hacer clic en el botón “Install” (Figura A.6), empieza la
instalación de archivos para finalmente completar el proceso
haciendo clic en el botón “Finish” (Figura A.7).
Figura A.6.
352
Figura A.7.
Configuración del Software Picall/P16Pro PIC:
Para dar inicio al software Picall/P16Pro, haga clic en el menú “Inicio” de
Windows Picall Picall v0.16. Inmediatamente se despliega la ventana de
la figura A.9.
Figura A.8.
353
Figura A.9.
Antes de comenzar a programar cualquier microcontrolador, se deberán
seleccionar ciertos parámetros importantes en el software. Estos parámetros
son los que mencionamos a continuación.
354
Tipo de programador:
El programador se identifica en el software como “P16PRO” y usted deberá
seleccionarlo en el campo correspondiente como se muestra en la Figura
A.10.
Figura A.10.
355
Modelo del microcontrolador:
En el siguiente paso se deberá seleccionar el modelo de microcontrolador que
desea programar.
Figura A.11.
Otro punto importante a verificar será el puerto seleccionado, el cual deberá
estar en LPT Port = Auto. Esta opción se encuentra en el menú “Settings”.
356
Figura A.12.
El software también cuenta con ayuda visual para saber la posición exacta del
microcontrolador en la base del programador, como se muestra en la figura
A.13. Notará que al cambiar el modelo de microcontrolador a ser programado,
la figura cambia indicando la posición adecuada para evitar daños
irreversibles en el dispositivo.
357
Figura A.13.
358
Apéndice B Tabla ASCII
ASCII Control Characters
Decimal Hex ASCII Function Key
0 0 NUL (null) Ctrl-@
1 1 SOH (start of heading) Ctrl-A
2 2 STX (start of text) Ctrl-B
3 3 ETX (end of text) Ctrl-C
4 4 EOT (end of transmission) Ctrl-D
5 5 ENQ (enquiry) Ctrl-E
6 6 ACK (acknowledge) Ctrl-F
7 7 BEL (bell) Ctrl-G
8 8 BS (backspace) Ctrl-H
9 9 HT (horizontal tab) Ctrl-I
10 A LF (line feed) Ctrl-J
11 B VT (vertical tab) Ctrl-K
12 C FF (form feed) Ctrl-L
13 D CR (carriage return) Ctrl-M
14 E SO (shift out) Ctrl-N
15 F SI (shift in) Ctrl-O
16 10 DLE (data link escape) Ctrl-P
17 11 DC1 (device control 1) Ctrl-Q
18 12 DC2 (device control 2) Ctrl-R
19 13 DC3 (device control 3) Ctrl-S
20 14 DC4 (device control 4) Ctrl-T
21 15 NAK (negative acknowledge) Ctrl-U
22 16 SYN (synchronous idle) Ctrl-V
23 17 ETB (end of trans. block) Ctrl-W
24 18 CAN (cancel) Ctrl-X
25 19 EM (end of medium) Ctrl-Y
26 1A SUB (substitute) Ctrl-Z
27 1B ESC (escape) Ctrl-[
28 1C FS (file separator) Ctrl-
29 1D GS (group separator) Ctrl-]
30 1E RS (record separator) Ctrl-^
31 1F US (unit separator) Ctrl-_
Tabla B.1.
Fuente: http://www.melabs.com/resources/pbpmanual/
359
Caracteres ASCII Standard
Decimal Hex Display / Key
32 20 Space
33 21 !
34 22 "
35 23 #
36 24 $
37 25 %
38 26 &
39 27 '
40 28 (
41 29 )
42 2A *
43 2B +
44 2C ,
45 2D -
46 2E .
47 2F /
48 30 0
49 31 1
50 32 2
51 33 3
52 34 4
53 35 5
54 36 6
55 37 7
56 38 8
57 39 9
58 3A :
59 3B ;
60 3C <
61 3D =
62 3E >
63 3F ?
Decimal Hex Display / Key
64 40 @
65 41 A
66 42 B
67 43 C
68 44 D
69 45 E
70 46 F
71 47 G
72 48 H
73 49 I
74 4A J
75 4B K
76 4C L
77 4D M
78 4E N
79 4F O
80 50 P
81 51 Q
82 52 R
83 53 S
84 54 T
85 55 U
86 56 V
87 57 W
88 58 X
89 59 Y
90 5A Z
91 5B [
92 5C 
93 5D ]
94 5E ^
95 5F _
Decimal Hex Display / Key
96 60 `
97 61 a
98 62 b
99 63 c
100 64 d
101 65 e
102 66 f
103 67 g
104 68 h
105 69 i
106 6A j
107 6B k
108 6C l
109 6D m
110 6E n
111 6F o
112 70 p
113 71 q
114 72 r
115 73 s
116 74 t
117 75 u
118 76 v
119 77 w
120 78 x
121 79 y
122 7A z
123 7B {
124 7C |
125 7D }
126 7E ~
127 7F DEL
Tabla B.2.
Fuente: http://www.melabs.com/resources/pbpmanual/
360
Apéndice C Software y Practicas en Formato Digital
361
Se pueden obtener los archivos digitales de cada uno de los proyectos
planteados en esta obra (archivo fuente en pbp de cada proyecto y
archivo compilado .hex), ingresando al sitio Web:
http://www.conexionelectronica.com
362
Bibliografía
INTERNET:
Microchip Technology Inc., http://www.microchip.com
microEngineering Labs, Inc., http://www.melabs.com
Mecanique, http://www.mecanique.co.uk
Picallw, http://www.picallw.com
Wikipedia, http://es.wikipedia.org
Linx Technologies, http://www.linxtechnologies.com
Empresas:
microEngineering Labs, Inc.
Box 60039
Colorado Springs CO 80960
Tel. (719) 520-5323
Fax. (719) 520-1867
http://www.melabs.com
Microchip Technology Inc.
2355 W. Chandler Blvd.
Chandler AZ 85224-6199
Tel. (602) 786-7200
Fax. (602) 899-9210
http://www.microchip.com
Mecanique
85 Marine Parade
SaltBurn by the Sea
TS12 1BZ
United Kingdom
Tel. +44 1287 622382
Fax. +44 8700 520279
http://www.mecanique.co.uk

LENGUAJE BASIC WILBER PINILLA

  • 1.
    BASIC PARABASIC PARABASICPARABASIC PARA MICROCONTROLADORES PICMICROCONTROLADORES PICMICROCONTROLADORES PICMICROCONTROLADORES PIC Christian Bodington Esteva Ingeniero en Electrónica
  • 3.
    i CONTENIDO Prólogo. . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 Capítulo I. Herramientas de Diseño. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Capítulo II. MicroCode Studio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 Capitulo III. Microcontroladores PIC. 3.1.- ¿Que es un PIC? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21 3.2.- El Oscilador Externo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25 3.3.- El Circuito de Reset. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.4.- Consideraciones técnicas de diseño. . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.4.1.- Estado Lógico de un pin I/O. . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.4.2. Lectura de un estado lógico en un pin I/O. . . . . . . . . . . . . . . 33 3.4.3. El Opto-acoplador. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.4.4. Fuente de poder, 5Vdc / 3.3Vdc. . . . . . . . . . . . . . . . . . . . . . . 37 Capítulo IV. Estructura de un programa. Componentes y operadores en PicBasic. 4.1.- Estructura de un programa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 4.2.- Subrutinas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 4.3.- Componentes y operadores en PicBasic. . . . . . . . . . . . . . . . . . . . . . . .41
  • 4.
    ii 4.3.1.- Define. .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 4.3.2.- Variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .42 4.3.3.- Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.3.4.- Constantes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4.3.5.- Símbolos o Alias. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 4.3.6.- Operadores Aritméticos. . . . . . . . . . . . . . . . . . . . . . . . . . . . .45 4.3.7.- Operadores Binarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .45 4.3.8.- Operadores de Comparación. . . . . . . . . . . . . . . . . . . . . . . . 46 4.3.9.- Operadores Lógicos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Capitulo V. Primeros Programas con el PIC16F84. 5.1.- Proyecto #1. Implementación de las instrucciones de programa High, Low Goto y Pause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47 5.2.- Proyecto #2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 5.3.- Proyecto #3. Implementación de la instrucción If-Them-Else. . . . . . . .60 5.4.- Proyecto #4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 5.5.- Proyecto #5. Implementación de la instrucción For-Next. . . . . . . . . . . 65 5.6.- Proyecto #6. Implementación de la instrucción Frecout. . . . . . . . . . . . 68 5.7.- Proyecto #7. Implementación de la instrucción Button . . . . . . . . . . . . .76 5.7.1.- Proyecto #7.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 5.7.2.- Proyecto #7.2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 5.7.3.- Proyecto #7.3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
  • 5.
    iii 5.8.- Proyecto #8.Implementación de la instrucción Branch . . . . . . . . . . . . 91 5.9.- Proyecto #9. Implementación de la instrucción PWM . . . . . . . . . . . . . 94 Capitulo VI. Módulos LCD. 6.1.- Pantallas LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 6.2.- Identificación de los pines de una pantalla LCD . . . . . . . . . . . . . . . . . 98 6.3.- Conexión de una pantalla LCD en Pic Basic. . . . . . . . . . . . . . . . . . . . 99 6.4.- Proyecto #10. Implementación de la instrucción Lcdout . . . . . . . . . . 103 6.5.- Proyecto #11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 6.6.- Proyecto #12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109 6.7.- Proyecto #13. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .111 6.8.- Proyecto #14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .114 6.9.- Proyecto #15. Implementación de la instrucción Count. . . . . . . . . . . 115 6.10.- Proyecto #16. Implementación de la instrucción Pulsin. . . . . . . . . . 122 6.11.- Proyecto #17. Implementación de la instrucción Pot. . . . . . . . . . . . 124 6.12.- Memoria CGRAM en la Pantalla LCD. . . . . . . . . . . . . . . . . . . . . . . .127 6.13.- Proyecto #18. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130 6.14.- Proyecto #19. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137 Capitulo VII. Teclado Matricial. 7.1.- Teclado Matricial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149 7.2.- Proyecto #20. Aplicación de un teclado 3x4. . . . . . . . . . . . . . . . . . . .154
  • 6.
    iv Capitulo VIII. Memoriade Datos. 8.1.- Memoria de Datos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .157 8.2.- Proyecto #21. Implementación de la instrucción Read. . . . . . . . . . . .161 8.3.- Proyecto #22. Implementación de la instrucción Write. . . . . . . . . . . .163 8.4.- Proyecto #23. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .165 8.5.- Proyecto #24. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .168 Capitulo IX. Interrupciones. 9.1.- ¿Qué son las Interrupciones?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175 9.2.- Fuentes de Interrupciones. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175 9.3.- Registro INTCON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175 9.4.- Activación de interrupción a través del pin RB0/INT. . . . . . . . . . . . . . 177 9.5.- Proyecto #25. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 9.6.- Interrupción TMR0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .180 9.7.- Registro OPTION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181 9.8.- Proyecto #26. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 9.9.- Interrupción por cambio de estado de uno de los pines más significativos del puerto B (RB4-RB7). . . . . . . . . . . . . . . . . . . . . . . . . . . . .186 9.10.- Proyecto #27. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .187 Capitulo X. Memoria Serial I2C. 10.1.- ¿Qué es el bus I2C?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .190 10.2.- Proyecto #28. Implementación de las instrucciones I2Cwrite, I2Cread . . 192
  • 7.
    v 10.3.- Proyecto #29.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .196 10.4.- Proyecto #30. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198 Capitulo XI. Conversor A/D en el PIC16F877. 11.1.- Conversor A/D. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .202 11.2.- El registro ADCON0. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209 11.3.- El registro ADCON1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210 11.4.- Proyecto #31. Implementación de la instrucción ADCin. . . . . . . . . . 214 Capitulo XII. Comunicación Serial. Transmisión y Recepción de Datos. 12.1.- Comunicación Serial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 12.2.- Instrucción SerIn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 12.3.- Proyecto #32. Implementación de la instrucción SerIn. . . . . . . . . . . 221 12.4.- Instrucción SerOut. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233 12.5.- Proyecto #33. Implementación de la instrucción SerOut. . . . . . . . . .233 12.6.- Proyecto #34 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .240 Capitulo XIII. Servomotor. 13.1.- ¿Qué es un Servomotor?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .268 13.2.- Proyecto #35. Implementación de la instrucción PauseUs. . . . . . . . .272 13.3.- Proyecto #36. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .276 13.4.- Proyecto #37. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .280 13.5.- Proyecto #38. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .283
  • 8.
    vi Capitulo XIV. MódulosRF para comunicaciones. 14.1.- Módulos RF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .293 14.2.- Proyecto #39. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .296 14.3.- Proyecto #40. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .300 14.4.- Proyecto #41. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .305 Capitulo XV. Instrucciones de programa de PicBasic. @. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 ADCin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 Asm… EndAsm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .311 Branch. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .312 Button. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313 Call. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Clear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .315 ClearWDT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .316 Count . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 DTMFout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 EEPROM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .321 End. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 FreqOut. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .321 For… Next. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .323 Gosub. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324
  • 9.
    vii Goto. . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .324 High. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .324 I2Cread. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 I2Cwrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .326 IF-Then-Else. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Input. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .328 LCDin. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .329 LCDout. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .330 Low. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .331 NAP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 Output. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 Pause. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .333 PauseUs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .333 Pot. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 PulsIn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 PulsOut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 PWM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 Random . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .337 Read . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 Return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 Reverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .340 Select Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .340 SerIn. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .342
  • 10.
    viii SerOut . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .343 Sleep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .344 Swap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .344 Toggle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .345 While-Wend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 Write . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .347 Apéndice A . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .348 Apéndice B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .358 Apéndice C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .360 Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .362
  • 11.
    Prólogo Emprender el estudiode microcontroladores para el desarrollo de proyectos electrónicos que sean la base para nuevas ideas es el objetivo primordial de esta primera edición, en la cual nos hemos concentrado en dar al lector algunas herramientas fundamentales con las cuales esperamos abrir un campo de conocimiento en la electrónica de control, a través de un sin numero de posibilidades de diseño a partir de una serie de ejemplos prácticos desarrollados en lenguaje Basic para Microcontroladores PIC. De toda la gama de posibilidades entre las familias de microcontroladores PIC que ofrece Microchip Inc., hemos elegido para empezar el microcontrolador más popular de toda la serie, el PIC16F84, que será utilizado en este libro para estudiar algunas de sus características a través del desarrollo de actividades que en principio no requieren un nivel de conocimiento elevado y a través del cual daremos los pasos necesarios para adentrarnos en las gamas mas altas, de las que se ha seleccionado el microcontrolador PIC16F877 para la realización de proyectos electrónicos de nivel medio y avanzado, y en los que podremos manejar dispositivos periféricos que le dan un gran valor agregado a cada uno de nuestros proyectos y abren posibilidades de desarrollo muy interesantes al lector. Además, hemos considerado proporcionar la información adecuada referente a las herramientas de desarrollo más importantes en la actualidad, para programación en lenguaje Basic para microcontroladores PIC. En esta ocasión iniciamos con el estudio del compilador PicBasic Pro, de la empresa microEngineering Labs, Inc., la cual ofrece una de las herramientas mas populares en el área, debido a que cuenta con una gran variedad de instrucciones que hacen de la programación de microcontroladores una tarea fácil y muy productiva a la hora de desarrollar proyectos que involucren periféricos como pantallas LCD, teclados matriciales, sensores de temperatura, presión, gas, humedad, memorias de datos entre otros, y donde una de las características más relevantes es el considerable ahorro de tiempo, lo que se traduce en efectividad y menos líneas de programa, de tal
  • 12.
    2 manera que eldiseñador puede prestar mayor atención a los detalles, logrando así perfeccionar su desempeño en cualquiera de las funciones que desee programar. Otra de las herramientas que hemos decidido incorporar a la obra, es el programador de microcontroladores PIC P16Pro/PicAll, de la página oficial de PicallW, de Boban Dobaj, Diseñador. Este programador soporta una gran cantidad de modelos de las series 12, 16 y 18 de Microchip. Su construcción es sumamente sencilla y de muy bajo costo, además de una serie de ventajas entre las cuales podemos mencionar la alta velocidad de transferencia de datos hacia el dispositivo al momento de ser grabado. Cada capítulo contiene teoría sobre la cual se pretende estudiar el funcionamiento de los microcontroladores y periféricos conectados a él. Para ello hemos desarrollado una serie de prácticas en las que el lector deberá hacer montajes de circuitos en base a los diagramas esquemáticos siguiendo las instrucciones y leyendo detenidamente los comentarios de cada línea de programa. Esperamos con esto proporcionar al lector una base sólida de conocimientos para el desarrollo de proyectos electrónicos, proyectos de robótica y todo aquello que represente una innovación científica en este campo. Finalmente, el agradecimiento para todos nuestros colaboradores en la edición de esta publicación, quienes se han encargado de revisar cada detalle, proyectos e ideas plasmadas en cada capitulo. Ingeniero en Información, Maria del Carmen Lara T. Ingeniero en Electrónica, Jesús Frank Phorlakis. Técnico Superior en Electricidad, Raúl Mastropasqua.
  • 13.
    3 Herramientas de DiseñoCapitulo I En la elaboración de proyectos electrónicos con microcontroladores PIC, resulta muy importante considerar una serie de herramientas, las cuales vamos a describir a continuación: Software: para la programación en Lenguaje Basic, contamos con una gran variedad de posibilidades en el mercado, y entre las cuales hemos elegido para esta primera edición, el Ambiente Integrado de Desarrollo Microcode Studio (IDE) de microEngineering Labs, Inc., además del compilador Basic, PICBasic Compiler, o PICBasic Pro Compiler. Con estas dos herramientas estaremos realizando la programación en cada uno de los proyectos propuestos a partir del capítulo V. Figura 1.1. (Fuente: http://www.microengineeringlabs.com)
  • 14.
    4 • Programador deMicrocontroladores PIC: es una herramienta indispensable con la cual podemos grabar el código generado por el compilador PicBasic para poner en funcionamiento cada uno de los proyectos propuestos en cada capítulo. Existen en internet una gran cantidad de modelos de programadores para microcontroladores PIC, de muy bajo costo y fácil construcción. Consideramos una buena experiencia realizar el montaje de cualquiera de estos diseños, aunque en esta oportunidad nuestra recomendación es el programador P16Pro/Picallw. Los detalles para la construcción de este programador están contenidos en el apéndice A. Figura 1.2.
  • 15.
    5 • Placa deprototipos: proporciona al diseñador conexiones sin soldaduras, con lo cual se hace más práctico el desarrollo de los proyectos electrónicos propuestos a lo largo de cada capítulo. Figura 1.3. • Multímetro digital: este instrumento de medición será muy útil durante la elaboración de los circuitos propuetos en cada capítulo. Figura 1.4.
  • 16.
    6 • Fuente depoder regulada con salida de voltaje variable. En el capítulo III se propone la construcción de una fuente de poder regulada a 5 Vdc y 3.3 Vdc. Figura 1.5. • Herramientas de corte, extractor de circuitos integrados, cable rígido para conexiones en la placa de prototipos. Figura 1.6.
  • 17.
    7 • Osciloscopio: esteinstrumento se requiere para el desarrollo de algunas prácticas en las cuales se hace necesario medir las señales generadas desde el microcontrolador. Figura 1.7. • Componentes electrónicos: microcontroladores PIC en los modelos definidos en cada ejemplo práctico, resistencias, diodos, servomotores, condensadores, cristales y otros componentes de fácil adquisición. Cada proyecto cuenta con una tabla en la cual se decriben los componentes electrónicos que deberán ser utilizados en el cada montaje. Figura 1.7.
  • 18.
    8 Microcode Studio CapituloII Microcode Studio (IDE), es un Ambiente Integrado de Desarrollo de MECANIQUE, diseñado especialmente para microEngineering Labs, Inc., de libre adquisición a través de la página Web http://www.microengineeringlabs.com Figura 2.1. (Fuente: http://www.microengineeringlabs.com) Descargar este programa es muy sencillo y esto lo podemos hacer ingresando a la siguiente dirección: http://www.microengineeringlabs.com/resources/win_ide.htm En esta página se puede encontrar una sección destinada para la descarga del archivo instalador, como se observa en la figura 2.2:
  • 19.
    9 Figura 2.2. (Fuente: http://www.microengineeringlabs.com) Ademásde esta herramienta, es necesario adquirir el compilador PicBasic, (Figura 2.3). Se puede acceder directamente a la página de productos de microEngineering Labs a través de la dirección: http://www.melabs.com/products/index.htm Figura 2.3. (Fuente: http://www.microengineeringlabs.com) Es posible descargar una versión DEMO del compilador PIC Basic, con la cual se pueden compilar programas con un máximo de 31 líneas de código, a través de la dirección: http://www.melabs.com/pbpdemo.htm
  • 20.
    10 Figura 2.4. (Fuente: http://www.melabs.com) Paraempezar la descarga del archivo de instalación del compilador, solo hay que hacer clic en el link señalado en la figura 2.4, e indicar la ruta en la cual se desea que el archivo de instalación sea almacenado. Nota Importante: Es necesario adquirir una de las versiones completas del compilador Basic, para no tener límites en la cantidad de líneas del programa a compilar. En la figura 2.5 se puede observar el archivo descargado para la versión disponible del software Microcode Studio, y en la figura 2.6 se puede observar el archivo del compilador PicBasic Pro en su versión de prueba. Figura 2.5. Figura 2.6. Haga clic en el Link aquí señalado, para descargar la versión Demo de PicBasic. Pro
  • 21.
    11 El proceso deinstalación es muy sencillo. El primer paso será ejecutar el archivo mcsinstall.exe, el cual es el responsable de iniciar el proceso de instalación de Microcode Studio: Figura 2.7. Seguidamente Microcode Studio le da la bienvenida en la ventana que se muestra a continuación: Figura 2.8.
  • 22.
    12 Haga clic enel botón “Next” y podrá ver en la siguiente ventana el acuerdo de licencia para Microcode Studio: Figura 2.9. La ruta por defecto para la instalación de Microcode Studio es C:Archivos de programaMecaniqueMCS. Esta ruta puede ser cambiada haciendo clic en el botón “Browse”, a través del cual se podrá ubicar la nueva carpeta en la cual deberá ser instalado el software: Figura 2.10. Nombre de la carpeta en la cual se encontrará el archivo ejecutable de Microcode Studio.
  • 23.
    13 Pulse “Next” parainiciar la copia de archivos (figura 2.11), y finalmente espere que se complete la instalación (figura 2.12). Figura 2.11. Figura 2.12.
  • 24.
    14 Una vez instaladoMicrocode Studio, es importante tomar en cuenta que antes de iniciar este software, es necesario instalar el compilador Basic, el cual es indispensable para la generación del código que será cargado en el microcontrolador PIC. Instalación del compilador PicBasic Pro: Para dar inicio a la instalación del compilador Pic Basic, será necesario ejecutar el archivo denominado “pbpdemo.exe” para el caso de la versión de demostración. La figura 2.13 muestra la ventana de inicio del proceso de instalación, en la cual se da la bienvenida al usuario y le invita a cerrar cualquier otra aplicación que se encuentre en uso en ese momento. Figura 2.13. En la siguiente ventana se debe especificar la unidad de disco duro en la cual se instalará el compilador y el nombre de la carpeta que va a contener los archivos a ser instalados. El software de instalación del compilador establece por defecto la ruta indicada en la figura 2.14.
  • 25.
    15 Figura 2.14. Seguidamente sedebe especificar el nombre de la carpeta que va a contener los accesos directos a los archivos que ofrecen información adicional acerca del compilador PicBasic. Este paso puede ser omitido seleccionando la opción “Don’t create a Start Menu Folder”: Figura 2.15.
  • 26.
    16 Una vez seleccionadaslas rutas de instalación del compilador, se debe hacer clic en el botón “Install” (figura 2.16), para dar inicio a la copia de archivos. Figura 2.16. Figura 2.17.
  • 27.
    17 Figura 2.18. Finalmente sepuede ver en la ventana de la figura 2.18, un mensaje en el cual se confirma que el compilador PICBasic Pro ha sido instalado satisfactoriamente. Deshabilite la opción “Install Microcode Studio IDE” y seguidamente haga clic en el botón “Finish”. Nota: Puede descargar la documentación completa del compilador PicBasic a través de la dirección: http://www.melabs.com/support/index.htm
  • 28.
    18 Integración de MicrocodeStudio y Pic Basic Pro: Es importante integrar Microcode Studio con el compilador PicBasic Pro, indicando la ruta en la cual se encuentra instalado. Para esto debemos iniciar el software y seguir las siguientes instrucciones: 1. Desde el menú de Inicio de Windows ejecute “Microcode Studio”. Figura 2.19. 2. Haga clic en el menú “View” y seleccione la opción “Compile and Program Options”. Figura 2.20.
  • 29.
    19 3. En lapestaña “Compiler” haga clic en el botón “Find Automatically” para una ubicación automática del compilador, o si lo prefiere haga clic en “Find Manually” para ubicar el compilador manualmente. Figura 2.21. 4. En la pestaña “Programmer” se pide la ubicación del software del programador que estaremos utilizando para grabar los microcontroladores. Figura 2.22.
  • 30.
    20 Se debe ubicaren la lista el programador “PICALL Programmer”, haciendo clic en el botón denominado “Add New Programmer” (Figura 2.22), y seguidamente se debe seleccionar de la lista de opciones, como se puede observar en la figura 2.23: Figura 2.23. Por último, al hacer clic en el botón “Next”, el software realizará la búsqueda automática de la carpeta que contiene el archivo ejecutable del programador Picall, el cual ha debido ser instalado según el procedimiento descrito en el Apéndice A.
  • 31.
    21 Microcontroladores PIC CapituloIII 3.1. Que es un PIC? Los PIC son una familia de microcontroladores desarrollados y fabricados por la empresa Microchip Technologies Inc., los cuales cuentan con una tecnología tipo RISC (Reduced Instruction Set Computer) y poseen en su arquitectura interna características especiales que varían según el modelo de PIC que deseamos utilizar. Podríamos decir que estos dispositivos se asemejan a una computadora pero de tamaño muy reducido, ya que cuentan con casi los mismos recursos que éstas, es decir, poseen memoria de programa, memoria RAM, memoria de datos, puertos de entrada o salida, temporizadores y en algunos casos cuentan con recursos adicionales como convertidores A/D, comparadores, USART (Universal Synchronous/Asynchronous Receiver/Transmitter), comunicación serie I2C, entre otros. Con todas estas características es lógico pensar que este dispositivo pasa a ser el corazón del circuito a ser controlado. Esto significa que el microcontrolador es el encargado de dirigir todos los procesos de un circuito electrónico, en base a las instrucciones de programa o rutinas que definen funciones específicas de control, donde las mismas serán realizadas en lenguaje Basic para microcontroladores PIC. Es por esta razón que consideramos muy importante estudiar la arquitectura interna del microcontrolador que se desea programar y aunque esta tarea pueda parecer difícil, el Lenguaje Basic para microcontroladores PIC la hace sumamente sencilla. El diseño de programas para microcontroladores PIC va acompañado normalmente con un previo estudio del diseño del hardware que hará que nuestros proyectos se pongan en marcha. Es decir, resulta absolutamente necesario saber cual será la función específica de cada pin; por ejemplo, en el caso de los puertos I/O (IN/OUT) a ser utilizados en el microcontrolador, es importante definir sus funciones antes de empezar a programar, ya que éstos pueden ser configurados a conveniencia como entrada o como salida de datos de forma independiente. También podemos destinar un puerto completo
  • 32.
    22 del microcontrolador parael control de dispositivos periféricos como pantallas LCD, teclados, motores paso a paso, leds, servomotores entre otros. De ahí la importancia de establecer cual será la función de cada puerto del microcontrolador PIC elegido para nuestros proyectos. Otra decisión importante será elegir convenientemente el modelo de microcontrolador a ser utilizado, ya que hay una gran gama de modelos que pueden ser adaptados a necesidades específicas de diseño. Figura 3.1. Los microcontroladores PIC comúnmente más utilizados son los siguientes: • PIC12C508 y PIC12C509, tienen memoria de programa EPROM, oscilador interno, y son muy utilizados en diseños de pequeños circuitos. • PIC16F84A, tiene memoria de programa tipo FLASH, oscilador externo, 13 pines I/O entre otras características que estaremos estudiando a lo largo del contenido de esta obra. Este PIC ha resultado ser uno de los más populares de toda la serie. • PIC16F87X, incluyen un gran número de mejoras en comparación con el PIC16F84, debido principalmente a que cuentan con un numero de pines I/O superior a éste, además de otras características relevantes. Por ejemplo, con esta serie de microcontroladores contamos con una mayor capacidad en cuanto a memoria de programa y memoria de datos.
  • 33.
    23 • PIC18F4XX, estosmicrocontroladores resultan muy útiles cuando deseamos diseñar proyectos más avanzados. Cada uno de estos microcontroladores cuenta con una completa hoja de datos que puede ser descargada de la página oficial de Microchip: http://www.microchip.com Estas características influyen directamente al momento de decidir que modelo de microcontrolador PIC deseamos utilizar en nuestros proyectos, según sea el objetivo de diseño del circuito que deseamos realizar. El microcontrolador PIC16F84 es uno de los microcontroladores más populares y en algunos casos, el preferido por estudiantes para dar inicio al estudio de la programación de microcontroladores, seguido del PIC16F877 el cual posee más recursos importantes que estaremos estudiando a continuación. Antes de empezar a revisar todo lo referente a la programación de microcontroladores PIC, consideramos importante recordar algunas de las características de éstos dispositivos, para tener una base de conocimientos básicos para poder realizar un programa de control de un diseño completamente personalizado. Para empezar, veamos algunas características del microcontrolador PIC16F84: • Microcontrolador de 8 Bits. • Memoria de programa tipo Flash de 1024 palabras de 14 bits. • Memoria RAM de 68 bytes. • Memoria EEPROM de datos de 64 bytes. • Velocidad de operación de hasta 20 Mhz. • Cuatro fuentes de interrupción. • Posee 13 pines I/O (pines de entrada o salida).
  • 34.
    24 Diagrama de pinesdel PIC16F84: Figura 3.2. PIN Identificación Descripción del Pin 1 RA2 Pin de Entrada/Salida (I/O) del puerto A 2 RA3 Pin de Entrada/Salida (I/O) del puerto A 3 RA4/TOCKI Pin de Entrada/Salida (I/O) del puerto A 4 MCLR Reset y entrada de voltaje de programación. 5 Vss Pin de Alimentación a Tierra (GND) 6 RB0/INT Pin de Entrada/Salida (I/O) del puerto B 7 RB1 Pin de Entrada/Salida (I/O) del puerto B 8 RB2 Pin de Entrada/Salida (I/O) del puerto B 9 RB3 Pin de Entrada/Salida (I/O) del puerto B 10 RB4 Pin de Entrada/Salida (I/O) del puerto B 11 RB5 Pin de Entrada/Salida (I/O) del puerto B 12 RB6 Pin de Entrada/Salida (I/O) del puerto B 13 RB7 Pin de Entrada/Salida (I/O) del puerto B 14 Vdd Pin de Alimentación de 5Vdc 15 OCS2/CLKOUT Salida del oscilador a cristal. 16 OSC1/CLKIN Entrada del oscilador a cristal o fuente externa de reloj. 17 RA0 Pin de Entrada/Salida (I/O) del puerto A 18 RA1 Pin de Entrada/Salida (I/O) del puerto A Tabla 3.1
  • 35.
    25 El microcontrolador PIC16F84cuenta con dos puertos I/O, el puerto A, el cual consta de cinco pines I/O y el puerto B, el cual consta de ocho pines I/O como se puede observar en la figura 3.3: Figura 3.3. En total se cuenta con trece pines I/O, los cuales pueden ser programados como entrada o salida según convenga al momento de diseñar un circuito de control. Los pines correspondientes al oscilador (OSC1 y OSC2) y al reset (MCLR) deben ser siempre tomados en cuenta en el diseño de nuestros proyectos. Es por este motivo que damos inicio al estudio de algunos circuitos indispensables para el correcto funcionamiento del microcontrolador PIC. 3.2. El Oscilador Externo. Es un circuito indispensable para el funcionamiento del microcontrolador y el cual además, define la velocidad a la cual va a trabajar. Para hacer funcionar nuestro diseño podemos elegir entre las siguientes cuatro opciones: • Oscilador LP: Oscilador de bajo consumo (Low Power). • Oscilador XT: Cristal / Resonador.
  • 36.
    26 • Oscilador HS:Oscilador de alta velocidad (High Speed). • Oscilador RC: Resistencia / Condensador. En los modos de oscilador LP, XT y HS el cristal debe ser conectado a los pines 15 y 16, Osc2/CLKout y Osc1/CLKin respectivamente, como se muestra en la figura 3.4. Figura 3.4. Los valores de los condensadores cerámicos vienen dados según la tabla que se muestra a continuación: Modo Frecuencia Osc1/CLKin Osc2/CLKout LP 32 kHz 200 kHz 68 - 100 pF 15 - 33 pF 68 - 100 pF 15 - 33 pF XT 2 MHz 4 MHz 15 - 33 pF 15 - 33 pF 15 - 33 pF 15 - 33 pF HS 4 MHz 10 MHz 15 - 33 pF 15 - 33 pF 15 - 33 pF 15 - 33 pF Tabla 3.2
  • 37.
    27 Por ejemplo, paraun oscilador tipo XT, podemos utilizar un cristal de cuarzo como el de la figura 3.5. Figura 3.5. Al conectar el microcontrolador a la fuente de alimentación de 5 Vdc y medir la señal de salida del oscilador XT con un osciloscopio, en el pin 15 (Osc2/CLKout) del microcontrolador, podremos ver la onda generada bajo los siguientes parámetros de medición seleccionados en el equipo: • Voltios/Div: 200mV • Time/Div: 100ns Figura 3.6.
  • 38.
    28 La lectura dela frecuencia y período en este caso sería la siguiente: • Frecuencia: 3,972 Mhz • Período: 251,71 ns Cristal de cuarzo TTL: Este tipo de cristal consta de cuatro pines, de los cuales solo tres están implementados de la siguiente manera: Figura 3.7. Pin 1: NC (Este pin no se encuentra conectado internamente) Pin 7: GND Pin 8: Salida TTL Pin 14: +5Vdc En su salida se obtiene un tren de pulsos como se puede observar en la figura 3.8, bajo los siguientes parámetros de medición seleccionados en un osciloscopio: • Voltios/Div: 2V • Time/Div: 100ns
  • 39.
    29 Figura 3.8. La lecturade la frecuencia y período en este caso sería la siguiente: • Frecuencia: 3,999 Mhz • Período: 250,013 ns El oscilador externo en modo RC resulta ser el más sencillo de todos y por ende el más económico. Su configuración lo hace menos preciso debido a que existe una tolerancia de error en sus componentes, sin olvidar también que la temperatura puede afectar la operación de este tipo de oscilador. Los valores recomendados para este oscilador son los siguientes: • 5 Kohm ≤ R1 ≤ 100 Kohm • C1 > 20 pF
  • 40.
    30 Figura 3.9. 3.3. Circuitode Reset: El Pin denominado MCLR (Master Clear), siempre debe ser tomado en cuenta cuando se diseña un circuito con microcontroladores PIC. A través de este Pin se podrá reiniciar el dispositivo, si a éste se le aplica un nivel lógico bajo (0V), por lo tanto resulta importante destacar que para que un programa cargado en un microcontrolador se mantenga en ejecución, el Pin MCLR debe estar siempre en un nivel lógico alto (5V). Si deseamos tener control externo del reset de un microcontrolador PIC, debemos considerar el circuito de la figura 3.10:
  • 41.
    31 Figura 3.10. Este circuitopermite reiniciar el microcontrolador cada vez que el pulsador P1 es presionado. 3.4. Consideraciones técnicas de diseño: A continuación veremos algunos circuitos básicos que deben ser tomados en cuenta para el desarrollo de prácticas con microcontroladores PIC. Estos circuitos son muy útiles cuando deseamos visualizar el resultado de una acción programada en el microcontrolador. 3.4.1. Estado Lógico de un pin I/O: Una manera muy sencilla de ver el estado lógico de un pin configurado como salida en cualquiera de los puertos de microcontrolador es a través del uso de LEDs, como se observa en los circuitos de la figura 3.11.
  • 42.
    32 En el primercircuito, el LED se iluminará solo cuando el estado lógico del pin de salida del puerto sea igual a “1”, es decir, 5 voltios. En el segundo circuito, el LED se iluminará solo cuando el estado lógico de la salida del puerto sea igual a “0”, es decir, 0 voltios. Figura 3.11. Esto significa que si deseamos realizar un programa en Lenguaje Basic encargado de cambiar el estado lógico de un pin específico, en cualquiera de los puertos de un microcontrolador, una forma “básica” de visualizar este cambio es a través del uso de LEDs.
  • 43.
    33 3.4.2. Lectura deun estado lógico en un pin I/O: El microcontrolador también nos permite capturar datos o señales externas para luego ser procesadas y convertidas en respuestas que pueden definir una acción específica en nuestros circuitos de prueba. Un ejemplo común podría ser el uso de un pulsador para hacer destellar un led cada vez que éste sea presionado. Si deseamos introducir un nivel lógico bajo (0V), o alto (5V), a una de las entradas de un microcontrolador a través de un pulsador, podríamos considerar los circuitos de la figura 3.12, los cuales nos proporcionan dos formas diferentes de hacerlo: Figura 3.12.
  • 44.
    34 El primer circuitoen la figura 3.12 mantiene un nivel lógico alto (5V) mientras el pulsador permanece abierto. Al presionar el pulsador, el nivel lógico en el pin I/O del puerto pasa a ser bajo (0V). El segundo circuito de la figura 3.12 mantiene un nivel lógico bajo (0V) mientras el pulsador permanece abierto. Al presionar el pulsador, el nivel lógico en el pin I/O del puerto pasa a ser alto (5V). 3.4.3. El Opto-acoplador: El opto-acoplador es un componente muy útil cuando se requiere acoplar circuitos electrónicos digitales con etapas de manejo de potencia o con otros circuitos. Este componente en una de sus versiones, se compone básicamente de un diodo LED el cual se encarga de iluminar un fototransistor, para que éste conduzca corriente a través del colector. Figura 3.13.
  • 45.
    35 En la configuraciónde la figura 3.13, cuando en el pin I/O aplicamos un 1 lógico (5V), el LED del opto-acoplador enciende y el fototransistor conduce la corriente a tierra; por lo tanto, en la salida tendremos un 0 lógico (0V). Si apagamos el LED, el transistor no conduce, de tal manera que en la salida tendremos un 1 lógico (5V). En la configuración de la figura 3.14, cuando en el pin I/O aplicamos un 1 lógico (5V), el LED del opto-acoplador enciende y el fototransistor conduce para poner en la salida un 1 lógico (5V). Mientras haya un 0 lógico en la entrada, el fototransistor permanecerá abierto entre el emisor y colector, dando como resultado un 0 lógico (0V) en la salida. Figura 3.14. Una configuración muy común para el control de dispositivos de potencia como motores eléctricos, luces incandescentes, solenoides, etc., se puede ver en la figura 3.15, la cual se basa en cualquiera de los dos circuitos antes mencionados (figura 3.13 y figura 3.14), en la cual se ha incluido un relé a
  • 46.
    36 través del cualcirculará la corriente necesaria entre sus contactos, para hacer funcionar cualquiera de estos dispositivos de potencia. Figura 3.15.
  • 47.
    37 3.4.4. Fuente depoder, 5Vdc / 3.3Vdc: En caso de no disponer de una fuente de poder regulada, proponemos la construccion de un diseño sencillo que podemos implementar en todos los proyectos propuestos. En la figura 3.16 se puede observar el diseño de una fuente regulada con salidas de voltaje de +5 Vdc y +3.3 Vdc: Figura 3.16.
  • 48.
    38 Estructura de unprograma. Componentes y operadores en PicBasic. Capitulo IV 4.1.- Estructura de un programa: Para que nuestros programas tengan una apariencia ordenada y se facilite la comprensión del mismo ante otros programadores que deseen realizar mejoras a éste, es necesario establecer una estructura que nos permita identificar fácilmente cada una de las partes que lo componen. Figura 4.1. En la figura 4.1 se puede observar la estructura básica de un programa hecho en Microcode Studio, y en la cual hemos identificado las cuatro secciones que consideramos más importantes para lograr un programa bien estructurado. A B C D
  • 49.
    39 Sección A: Correspondeal encabezado del programa, en el cual se debe considerar información básica del mismo, como el nombre, la identificación de autor, Copyright, fecha de elaboración o fecha de los últimos cambios realizados, versión del programa que se está realizando, e incluso una breve descripción acerca del objetivo del programa y su aplicación en un determinado circuito electrónico. Es importante resaltar que cada línea del encabezado debe empezar con una comilla simple, en forma de comentario (ver “Sección D”). Sección B: Esta sección empieza en la columna cero del editor de texto de Microcode Studio, y en ella se pueden declarar las definiciones (concepto que estudiaremos mas adelante) y las etiquetas de cada una de las subrutinas que serán programadas. Las etiquetas identifican puntos específicos o subrutinas dentro de un programa. Son definidas por el programador y deben tener al final de cada una de ellas el símbolo de “dos puntos”, que definen el final de la misma. Sección C: Estará destinada para las instrucciones de programa y la misma está separada de la columna cero del editor de texto por una tabulación, es decir, cuando el cursor se encuentra en la columna cero, presionamos una vez la tecla “TAB”, y de esta manera establecemos un espacio mínimo, siempre igual o superior entre la sección B y C. Sección D: Esta destinada para realizar comentarios acerca de la función que estará cumpliendo una instrucción específica en nuestro programa. Cada comentario debe empezar siempre con una comilla simple como se muestra a continuación: ' Define el Oscilador para un Cristal ' de 4 Mhz. Cuando un comentario es demasiado extenso, podemos continuar el mismo en la siguiente línea, siempre que la frase comience con su respectiva comilla.
  • 50.
    40 Los comentarios ayudanal diseñador a identificar cada línea de programa o cada una de las funciones de cada subrutina, garantizando así una buena documentación en cada uno de los programas que realizamos. 4.2.- Subrutinas: Una subrutina se presenta como un algoritmo separado del algoritmo principal, y estará destinado a resolver una tarea específica. Las subrutinas pueden ser referidas cada vez que sea necesario, llamando a la etiqueta que corresponde a ésta, la cual debe ir siempre al inicio de la misma. Led1: For Z = 0 To 9 LED = Encendido Pause 1000 LED = Apagado Pause 1000 Next Z GoTo Inicio End Subrutina Etiqueta
  • 51.
    41 4.3.- Componentes yoperadores en PicBasic. PIC Basic cuenta con una serie de herramientas de programación entre las cuales podemos mencionar las etiquetas, variables, identificadores, constantes, comentarios, símbolos entre otras. Algunas de estas herramientas son de uso obligatorio a la hora de realizar un programa, y otras que no son de uso obligatorio, nos facilitarán el trabajo considerablemente. 4.3.1.- Define: La directiva “Define” resulta muy importante en la programación de microcontroladores con PicBasic, ya que establece una serie de parámetros que de no ser tomados en cuenta, causará que nuestros programas sencillamente no funcionen en la mayoría de los casos. Esta serie de parámetros están directamente relacionados con dispositivos externos al microcontrolador. Por ejemplo, si deseamos utilizar un oscilador de diferente frecuencia al valor establecido por defecto (4 Mhz), será conveniente entonces definir la velocidad del mismo utilizando la directiva: Define Osc {frecuencia} De igual forma deben ser considerados estos parámetros para el uso de dispositivos como pantallas LCD, donde se deberán definir los puertos de conexión para el bus de datos y bus de control. Así mismo ocurre para el caso de las comunicaciones seriales o I2C, donde los parámetros también deben ser definidos. Veamos a continuación la tabla de parámetros para el uso de la instrucción Define.
  • 52.
    42 Parámetro Descripción OSC {frecuencia}Frecuencia del Oscilador en Mhz LCD_DREG {puerto} Puerto de datos LCD LCD_DBIT {bit} Bit inicial del puerto de datos LCD_RSREG {puerto} Puerto para RS (Register Select) LCD_RSBIT {bit} Pin del Puerto para RS LCD_EREG {puerto} Puerto para E (Enable) LCD_EBIT {bit} Pin del Puerto para E LCD_RWREG {puerto} Puerto para RW (Read/Write) LCD_RWBIT {pin} Pin del puerto para RW LCD_LINES {líneas} Número de líneas de la LCD (1,2 o 4) I2C_SCLOUT 1 Interface de Reloj I2C Bipolar I2C_SLOW 1 Cuando en la transferencia es utilizado un oscilador mas lento que 8 Mhz. Tabla 4.1. 4.3.2.- Variables: En las variables podemos almacenar datos temporalmente, los cuales podrán ser consultados o modificados cada vez que sea necesario. Regularmente la definición de variables se hace al inicio del programa y para ello se utiliza la palabra VAR seguida por el tipo de variable según la tabla que mostramos a continuación: Nombre de la Variable VAR Tipo de Variable Descripción A1 Var Bit Toma los valores 0 y 1 unicamente Temp Var Byte Toma valores entre 0 y 255 (8 bits) dig1 Var Word Toma valores entre 0 y 65535 (16 bits) Tabla 4.2. El nombre de la variable es elegido por el programador y el tipo de variable se define según el tipo de dato que se desea almacenar temporalmente.
  • 53.
    43 4.3.3.- Arrays: Lasvariables Arrays tienen un determinado número de “elementos”, definido según el tamaño de la variable. Las variables Arrays tipo Bit, pueden almacenar 256 elementos; las variables Arrays tipo Byte pueden almacenar hasta 96 elementos y las variables Arrays tipo Word hasta 48 elementos, los cuales a su vez pueden ser accesados en cualquiera de los tres casos a través de un índice. Este índice se específica entre corchetes como se muestra en los siguientes ejemplos: Para declarar una variable Array utilizamos el siguiente formato: Dato Var Byte[7] El primer elemento de esta variable es Dato[0] y el último elemento es Dato[7], lo cual significa que hemos declarado una variable array de 8 elementos. En este caso podemos almacenar un byte en cada elemento, siempre especificando el índice. Ejemplo: Almacenar en cada elemento de la variable “Dato” los valores 200, 15, 56, 75, 80, 20, 33, 45. Dato[0] = 200 Dato[1] = 15 Dato[2] = 56 Dato[3] = 75 Dato[4] = 80 Dato[5] = 20 Dato[6] = 33 Dato[7] = 45 En algunos casos se debe verificar la hoja de datos del microcontrolador, ya que la cantidad de elementos que se pueden almacenar en variables arrays tipo Byte o Word puede variar según el modelo del mismo.
  • 54.
    44 4.3.4.- Constantes: Ayudana identificar un valor constante en nuestro programa, facilitando aún más la comprensión del mismo a la hora de verificar su funcionamiento. En la tabla 4.3 se puede observar la forma de declarar una constante. Nombre de la Constante CON Valor de la Constante Temp_Max CON 150 Temp_Min CON 55 Tabla 4.3. 4.3.5.- Símbolos o Alias: Proveen un nombre único y específico a elementos o variables dentro de nuestro programa. Para definir un símbolo, utilizamos la palabra “Symbol”, seguida del alias del elemento, el símbolo de igualdad “=”, y por último el elemento en cuestión: Symbol {alias} = {elemento} Por ejemplo, si deseamos controlar un motor DC a través de uno de los pines del puerto A de un microcontrolador, resultaría mucho mas sencillo referirse a este pin como “Motor”, en vez de referirse a él como “PortA.0”. Entonces, Symbol Motor = PORTA.0 Veamos otros ejemplos: Symbol Relay = PORTB.0 Symbol Sensor = PORTA.0 Symbol LED = PORTA.1 Symbol RC0 = PORTC.0
  • 55.
    45 4.3.6.- Operadores Aritméticos:Entre los operadores aritméticos más utilizados tenemos los que se muestran en la siguiente tabla: Operador Descripción Operador Descripción + Suma ABS Valor Absoluto - Resta SIN Seno del Angulo * Multiplicación COS Coseno del Angulo / División MIN Minimo de un número // Residuo MAX Máximo de un número << Desplaza a la Izquierda REV Invertir un Bit >> Desplaza a la Derecha DIG Valor de un digito para un número decimal = Asignación de Valores Tabla 4.4. 4.3.7.- Operadores Binarios: En la siguiente tabla veremos los operadores binarios proporcionados para el Lenguaje PicBasic: Operrador Descripción & AND Lógico | OR Lógico ^ XOR Lógico ˜ NOT Lógico &/ NAND Lógico |/ NOR Lógico ^/ NXOR Lógico Tabla 4.5. Con estos operadores resulta muy sencillo realizar operaciones binarias, como lo demuestra el siguiente ejemplo: Si aplicamos una AND lógica, donde deseamos filtrar los siete bits más significativos del valor almacenado en la siguiente variable: Var1 = %00101001 Entonces, Var1 = Var1 & %00000001
  • 56.
    46 El resultado deesta operación es Var1 = %00000001 4.3.8.- Operadores de Comparación: Los operadores de comparación normalmente son utilizados con la instrucción If…Them… para realizar comparaciones entre variables o datos extraídos de alguna operación aritmética. Operador Descripción = Igual <> Diferente < Menor que > Mayor que <= Menor o igual que >= Mayor o igual que Tabla 4.6. 4.3.9.- Operadores Lógicos: Los operadores lógicos son utilizados para establecer condiciones entre variables y son utilizados de la misma manera que los operadores de comparación. Operador Descripción AND AND Lógico OR OR Lógico XOR XOR Lógico NOT NOT Lógico NOT AND NAND Lógico NOT OR NOR Lógico NOT XOR NXOR Lógico Tabla 4.7. Ejemplo: If Var1 = 1 and Var2 = 3 And Var3 = 5 Then Goto inicio La condición saltará a la etiqueta “inicio” solo si se cumplen las tres condiciones.
  • 57.
    47 Primeros Programas conel PIC16F84 Capitulo V Para aprender a programar un microcontrolador resulta importante dar inicio al tema con ejemplos prácticos y sencillos, que nos ayuden a comprender el funcionamiento de la arquitectura del PIC y las instrucciones de programa que se están empleando. El primer paso entonces será realizar el montaje del circuito con base en los conocimientos adquiridos en las páginas anteriores. Se debe tomar en cuenta que aunque en los diagramas de los circuitos que se muestran a continuación, no están presentes los pines de alimentación “Vcc” y “Gnd”, éstos deben ser conectados debidamente a la fuente de alimentación de 5 Voltios. A medida que se van proponiendo ejemplos de aplicación práctica, estaremos estudiando la sintaxis de las instrucciones empleadas en cada proyecto para facilitar la comprensión general de éste, referente a la programación y diseño electrónico. 5.1.- Proyecto #1: A continuación realice el montaje de la figura 5.1, en base al cual realizaremos la programación necesaria para encender dos Leds conectados a los puertos del microcontrolador: Figura 5.1.
  • 58.
    48 Proyecto # 1 ComponentesCantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 LED 2 Resistencia de 220 Ohm 2 Fuente regulada de 5 Vdc 1 Tabla 5.1. • El Led 1 se encuentra conectado en el pin RA0 del puerto A, el cual deberá ser configurado como “Salida”. • El Led 2 se encuentra conectado en el pin RB0 del puerto B, el cual deberá ser configurado igualmente como “Salida”. Note que el ánodo del diodo LED se encuentra conectado al pin de salida del puerto, por lo tanto para que encienda el LED debemos hacer salir un 1 lógico por el pin correspondiente. Como los pines de los puertos pueden ser configurados como “entradas” o como “salidas”, es importante tomar en cuenta los registros de configuración de puertos, los cuales para el caso específico del PIC16F84 son dos: TrisA (registro de configuración I/O del puerto A), es un registro de 8 bits, de los cuales los tres más significativos no se encuentran implementados en este modelo de microcontrolador, ya que como se puede observar en el diagrama de pines del dispositivo (figura 3.2), el puerto A solo cuenta con 5 pines (RA0, RA1, RA2, RA3 y RA4).
  • 59.
    49 Un ejemplo deconfiguración de los pines I/O del puerto A es el siguiente: 1 1 1 1 0 RA4 RA3 RA2 RA1 RA0 Registro TrisA Figura 5.2. 1 = Entrada (Al configurar un bit del registro TrisA en “1”, éste se comporta como entrada). 0 = Salida (Al configurar un bit del registro TrisA en “0”, éste se comporta como salida). Al ver la figura 5.2, se puede observar que el pin RA0 ha sido configurado como salida y el resto de los pines como entrada. En PicBasic, este paso se realiza de la siguiente manera: TrisA = %11110 (“%” para expresar la configuración en Binario), ó: TrisA = $1E (“$” para expresar la configuración en Hexadecimal) TrisB, es un registro de 8 bits en el cual se configuran los pines del puerto B, ya sea como entrada o como salida, por ejemplo: 1 1 1 1 1 1 1 0 RB7 RB6 RB5 RA4 RA3 RA2 RA1 RA0 Registro TrisB Figura 5.3. 1 = Entrada (Al configurar un bit del registro TrisB en “1”, éste se comporta como entrada). 0 = Salida (Al configurar un bit del registro TrisB en “0”, éste se comporta como salida). Bit menos significativo Bit menos significativo “Recordemos entonces que como el Led 1 se encuentra conectado en el pin RA0, el bit correspondiente a este pin en el registro TrisA ha sido configurado como salida”.
  • 60.
    50 Para el casoparticular del puerto B, se puede observar que el pin RB0 ha sido configurado como salida y el resto de los pines como entrada. “Consideramos importante configurar los pines que no estarán en uso como entrada, ya que de esta forma podemos evitar daños en el hardware interno del microcontrolador al experimentar con éste en un tablero de pruebas.” La configuración en PicBasic para el registro TrisB, ajustada al ejemplo de la figura 5.3 sería entonces la siguiente: TrisB = %11111110 (si se desea hacer la notación en binario), ó: TrisB = $FE (si se desea hacer la notación en hexadecimal) Antes de verificar el programa propuesto para este ejemplo, veremos la sintaxis de las instrucciones utilizadas en él, para tener una idea clara de la función que cumple cada instrucción. Esta información puede ser complementada en el capítulo XV, en el cual encontrará la descripción de cada una de las instrucciones utilizadas en cada proyecto planteado en esta edición. Sintaxis de las Instrucciones empleadas en el programa: HIGH Sintaxis: HIGH pin La instrucción “High” pone en uno lógico un pin I/O específico.
  • 61.
    51 LOW Sintaxis: LOW pin Lainstrucción “LOW” coloca en cero lógico un pin I/O específico. GOTO Sintaxis: GOTO etiqueta La instrucción “Goto” continúa la ejecución de un programa a partir de la etiqueta especificada (Esta instrucción no tiene retorno). PAUSE Sintaxis: PAUSE periodo La instrucción “Pause” realiza una pausa en el programa por un periodo definido en milisegundos. Veamos el programa en PicBasic: '**************************************** '* Nombre : Proyecto1.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz.
  • 62.
    52 TRISA = %11110' Configuración el Puerto A TRISB = %11111110 ' Configuración el Puerto B PORTA = 0 ' Inicializa el puerto "A", es decir, ' se ponen todos los pines en cero. PORTB = 0 ' Inicializa el puerto "B". Inicio: ' Etiqueta de Inicio del programa High PORTA.0 ' Enciente el Led conectado en el pin RA0 Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 ' Seg. Low PORTA.0 ' Apaga el Led conectado en el pin RA0 Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 ' Seg. High PORTB.0 ' Enciente el Led conectado en el pin RB0 Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 ' Seg. Low PORTB.0 ' Apaga el Led conectado en el pin RB0 Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 ' Seg. GoTo Inicio ' Salta a la etiqueta "Inicio" y se repite el ' proceso. End La instrucción “High” se encarga de poner un nivel lógico alto en el pin especificado seguidamente. En este caso, primero se escribe el puerto y seguido de un punto, se especifica el número del pin en el puerto que deseamos utilizar. La instrucción “Low” es responsable en este caso de poner el pin especificado en un nivel lógico bajo. Al igual que en la instrucción “High”, se debe especificar el puerto y el pin del puerto a ser utilizado. La instrucción “GoTo” realiza un salto hacia una etiqueta específica; en este caso el programa salta a la etiqueta “Inicio” para empezar de nuevo todo el proceso.
  • 63.
    53 Al escribir elprograma en el editor de texto de Microcode Studio, se debe grabar el mismo con el nombre de su preferencia para que éste pueda ser compilado y al mismo tiempo pueda ser enviado al microcontrolador. Observe que para este programa, hemos designado el nombre “Proyecto1.pbp” (figura 5.4). Figura 5.4. Antes de compilar el programa, se debe asegurar de seleccionar el modelo apropiado de microcontrolador PIC, como se observa en la figura 5.5. Luego se compila el programa y se verifica que éste no tenga errores.
  • 64.
    54 Figura 5.5. Seguidamente, sedebe proceder a cargar el programa compilado en el microcontrolador con la ayuda del programador de microcontroladores Pic. Al hacer clic en el icono “Compilar y Grabar en el PIC” (ver figura 5.5), el compilador habrá generado un archivo de nombre “Ejemplo1.hex” y seguidamente se abrirá el software “Picall/P16Pro”, como se observa en la figura 5.6: Figura 5.6. En este momento el microcontrolador deberá estar montado en la base del programador en la posición indicada por la figura 5.6. Compilar Compilar y Grabar en el PIC Modelo del uC.
  • 65.
    55 Antes de programarel microcontrolador, también resulta conveniente verificar los fusibles de programación, accediendo al botón “Config”, el cual puede ser visualizado en la figura 5.6. En esta sección se debe configurar el tipo de oscilador utilizado en nuestro circuito, así como otras opciones disponibles que comentaremos a continuación (ver figura 5.7). Figura 5.7. En la figura 5.7 se pueden observar tres secciones llamadas “Oscillator”, “Hardware” y “Protection”: • En la sección “Oscillator”, debemos seleccionar el tipo de oscilador utilizado en nuestro circuito electrónico, el cual en este caso es del tipo XT, debido a que el cristal que hemos elegido es de 4 Mhz. • En la sección “Hardware” es posible activar el temporizador “Perro Guardián”, el cual se encarga de reiniciar el microcontrolador en caso de fallas o bloqueos en el programa. Para utilizar el “Watchdog” es necesario diseñar el programa bajo ciertos parámetros, de forma que podamos reiniciar el temporizador “Watchdog” antes de que éste se desborde y provoque un “Reset” en el sistema. Si nuestro programa llegara a fallar, el temporizador Watchdog completaría su conteo y se desbordaría, provocando un “Reset” del sistema.
  • 66.
    56 • En lasección “Hardware” también disponemos de la opción “Power Up Timer”, la cual una vez activada en el microcontrolador, hará que éste no pueda iniciar el programa hasta tanto el voltaje aplicado al circuito sea estable y seguro (ver figura 5.8). 0 1 2 3 4 5 6 1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 Tiempo Voltios Figura 5.8. • En la sección “Protection”, tenemos la posibilidad de proteger el código de programa almacenado en la memoria del microcontrolador. Finalmente hacemos clic en el botón “Program” (ver figura 5.6), para descargar el programa “Proyecto1.hex” en el microcontrolador; inmediatamente se podrá ver el proceso de grabación y verificación de datos, para luego culminar con el montaje del microcontrolador en el circuito de prueba. Estos pasos se deben aplicar en cada uno de los proyectos aquí planteados, o cada vez que se desee realizar una modificación a un programa para obtener siempre mejores resultados sobre el objetivo propuesto en cada actividad.
  • 67.
    57 5.2.- Proyecto #2:En este ejemplo conectaremos un Led en cada pin del puerto B, el cual a su vez deberá ser configurado como salida para garantizar el correcto funcionamiento del mismo. En la figura 5.9 podemos observar en detalle la conexión del circuito eléctrico que deberá ser montado. Figura 5.9. Proyecto # 2 Componente Cantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor de 33 pF 2 LED 8 Resistencia de 220 Ohm 8 Fuente regulada de 5 Vdc 1 Tabla 5.2.
  • 68.
    58 En el proyecto#1 se pudo observar como es posible encender un led conectado a un pin del puerto A o B en un PIC16F84A, utilizando las instrucciones High y Low. También existen otras formas de poner un “1” o un “0” lógico en un pin configurado como salida; esto se puede lograr de varias maneras: PORTA.0 = 1 ' RA0 = 1 -> (es igual a High PortA.0) PORTA.0 = 0 ' RA0 = 0 -> (es igual a Low PortA.0) Cuando deseamos poner varios pines de un mismo puerto en “1”, podemos utilizar las siguientes opciones: PORTB = %10101010 ' RB7 = 1, RB5 = 1, RB3 = 1, RB1 = 1 ' RB6 = 0, RB4 = 0, RB2 = 0, RB0 = 0 Este mismo ejemplo de configuración en hexadecimal: PORTB = $AA ' RB7 = 1, RB5 = 1, RB3 = 1, RB1 = 1 ' RB6 = 0, RB4 = 0, RB2 = 0, RB0 = 0 Recordemos que el símbolo “%” expresa la notación en binario, por lo cual se deben expresar los ocho bits a ser cargados en el registro “PortB”. Otra forma de expresar este ejemplo sería colocando la notación en hexadecimal con el símbolo “$”, seguido del valor calculado. Basados en esta información podemos lograr encender y apagar varios leds simultáneamente conectados a uno de los puertos del microcontrolador como lo muestra el montaje de la figura 5.9. Veamos el siguiente programa: '**************************************** '* Nombre : Proyecto2.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '****************************************
  • 69.
    59 Define Osc 4' Define el Oscilador para un Cristal ' de 4 Mhz. TRISB = %00000000 ' Configura el Puerto B como Salida PORTB = %00000000 ' Inicializa el puerto "B". Inicio: ' Etiqueta de Inicio del programa PORTB = %01010101 ' Enciente las salidas RB0, RB2, RB4 y RB6, al ' mismo tiempo apaga RB1, RB3, RB5 y RB7. Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 Seg. PORTB = %10101010 ' Enciente las salidas RB1, RB3, RB5 y RB7, al ' mismo tiempo apaga RB0, RB2, RB4 y RB6. Pause 1000 ' Hace una pausa de 1000 milisegundos = 1 Seg. GoTo Inicio ' Salta a la etiqueta "Inicio" y se repite el ' proceso. End Este programa enciende primero las salidas pares del puerto B y apaga las salidas impares, genera una pausa de 1 segundo (1000 ms) y seguidamente hace el proceso inverso en las salidas, es decir, enciende las salidas impares y apaga las salidas pares para generar nuevamente otra pausa de 1 segundo y así repetir el proceso completo al generar un salto a la etiqueta “Inicio”.
  • 70.
    60 5.3.- Proyecto #3:Los pines en los puertos de un microcontrolador pueden ser configurados también como entradas, como se detalla en el contenido del proyecto #1, donde se explica claramente que al poner un “1” en un bit de un registro de configuración de puerto, ya sea TRISA o TRISB, para el caso del PIC16F84A, éste se comportará como entrada. Realice el montaje de la figura 5.10 y analice el programa que se muestra a continuación. Figura 5.10. Proyecto # 3 Componente Cantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 LED 1 Resistencia de 220 Ohm 1 Resistencia de 10K Ohm 1 Pulsador Normalmente Abierto 1 Fuente regulada de 5 Vdc 1 Tabla 5.3.
  • 71.
    61 IF – THEM– ELSE Sintaxis: If expresión 1 {AND / OR expresión 2} Then etiqueta Con la instrucción If – Them podemos tomar decisiones a lo largo de un programa, basadas en condiciones específicas definidas por el programador. El siguiente programa hace destellar un LED conectado en RB0, solo cuado el pulsador es activado: '**************************************** '* Nombre : Proyecto3.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. TRISA = %11111 ' configura el Puerto A como Entrada TRISB = %00000000 ' Configura el Puerto B como Salida PORTB = $00 ' Inicializa el puerto B Inicio: If PORTA.0 = 1 Then PORTB.0 = 1 ' Pregunta si RA0 = 1, si se cumple ' la condición entonces enciende el Led. Pause 1000 ' Hace una pausa de 1 segundo (1000 ms) Low PORTB.0 ' Apaga el Led Pause 1000 ' Hace una pausa de 1 segundo (1000 ms) GoTo inicio ' Salta a la etiqueta "Inicio" End Para verificar si el pulsador está activado, se pregunta si RA0 = 1. Esto es posible gracias a la instrucción “IF” la cual genera un resultado siempre que la condición planteada se cumpla, y para lo cual debemos utilizar necesariamente su complemento “Then” seguido de la acción a ser tomada.
  • 72.
    62 En este casosi el pulsador ha sido activado, entonces RA0 = 1, es decir, se cumple la condición y por lo tanto RB0 = 1, es decir, el LED enciende. 5.4.- Proyecto #4: En este ejemplo empleamos un microcontrolador PIC16F877A, con el cual nos hemos planteado la lectura de ocho pulsadores conectados al puerto B, de tal manera que al activar uno de ellos podemos mostrar un dígito decimal en un Display de siete segmentos. Figura 5.11.
  • 73.
    63 Proyecto # 4 ComponenteCantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Resistencia de 220 Ohm 8 Resistencia de 10K Ohm 8 Pulsador Normalmente Abierto 8 Display de 7 Segmentos - Cátodo común 1 Fuente regulada de 5 Vdc 1 Tabla 5.4. En el diagrama esquemático de la figura 5.11 se pueden observar ocho pulsadores normalmente abiertos, los cuales una vez activados generan un estado lógico alto en el puerto seleccionado (puerto “B”), el cual ha sido configurado como entrada. El display de 7 segmentos de cátodo común, se encuentra conectado al puerto “D”, donde el bit menos significativo RB0 corresponde al segmento “a” del display, RB1 corresponde al segmento “b”, RB2 corresponde al segmento “c”, RB3 corresponde al segmento “d”, RB4 corresponde al segmento “e”, RB5 corresponde al segmento “f” y RB6 corresponde al segmento “g”. El siguiente programa es una forma básica de tomar una lectura de cada pulsador conectado al puerto “B” y generar un resultado en el puerto de salida al cual hemos conectado un display de 7 segmentos: '**************************************** '* Nombre : Proyecto4.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '****************************************
  • 74.
    64 Define Osc 4' Define el Oscilador para un Cristal ' de 4 Mhz. TRISB = $FF ' Configura el Puerto B como Entrada TrisD = $00 ' Configura el Puerto D como Salida Inicio: ' A continuación se verifica cada pin del puerto B, ' si hay un 1 lógico en alguna de las entradas el ' puerto D se actualiza con el dato correspondiente ' para generar en el Display un dígito decimal. ' gfedcba ' ||||||| If PORTB.0 = 1 Then PortD = %00111111 ' Enciende los segmentos correspondientes ' al dígito “cero” en el display. If PORTB.1 = 1 Then PortD = %00000110 ' Enciende los segmentos correspondientes ' al dígito “uno” en el display. If PORTB.2 = 1 Then PortD = %01011011 ' Enciende los segmentos correspondientes ' al dígito “dos” en el display. If PORTB.3 = 1 Then PortD = %01001111 ' Enciende los segmentos correspondientes ' al dígito “tres” en el display. If PORTB.4 = 1 Then PortD = %01100110 ' Enciende los segmentos correspondientes ' al dígito “cuatro” en el display. If PORTB.5 = 1 Then PortD = %01101101 ' Enciende los segmentos correspondientes ' al dígito “cinco” en el display. If PORTB.6 = 1 Then PortD = %01111101 ' Enciende los segmentos correspondientes ' al dígito “seis” en el display. If PORTB.7 = 1 Then PortD = %00000111 ' Enciende los segmentos correspondientes ' al dígito “siete” en el display. GoTo Inicio ' Salta a la etiqueta "Inicio" End
  • 75.
    65 5.5.- Proyecto #5:En el ejemplo a continuación se realiza un conteo ascendente desde cero hasta nueve en un display de 7 segmentos conectado al puerto “D” de un PIC16F877A. Figura 5.12. Proyecto # 5 Componente Cantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Resistencia de 220 Ohm 8 Display de 7 Segmentos - Cátodo común 1 Fuente regulada de 5 Vdc 1 Tabla 5.5.
  • 76.
    66 FOR… NEXT Sintaxis: Forvariable = inicio to final {step {-} incremento} * * Instrucciones… * * Next { variable} La instrucción For…Next se encarga de hacer repeticiones de instrucciones que permanecen dentro del lazo For… Next. El parámetro Step afecta el incremento según el valor asignado después de esta palabra. Si este parámetro es omitido, el incremento es en una unidad. Analice el siguiente programa: '**************************************** '* Nombre : Proyecto5.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. I Var Byte ' Declaración de la Variable "I" tipo Byte ' Constantes para definir cada dígito decimal en el Display: ' gfedcba ' ||||||| Cero CON %00111111 Uno CON %00000110 Dos CON %01011011 Tres CON %01001111 Cuatro CON %01100110 Cinco CON %01101101 Seis CON %01111101 Siete CON %00000111
  • 77.
    67 Ocho CON %01111111 NueveCON %01100111 ' Configuración del Puerto de Salida: TrisD = $00 ' Configura el Puerto D como Salida Inicio: For I = 0 To 9 ' Repetición de Instrucciones dentro del Lazo ' For - Next Call Digito ' Salto con Retorno hacia la etiqueta "Digito" Pause 1000 ' Pausa de 1 segundo (1000 ms) Next I GoTo Inicio ' Salta a la etiqueta "Inicio" Digito: ' Verificación del dígito a ser mostrado en el Display el cual ' se corresponde con el valor almacenado en la variable "I". If I = 0 Then PortD = cero If I = 1 Then PortD = Uno If I = 2 Then PortD = dos If I = 3 Then PortD = tres If I = 4 Then PortD = cuatro If I = 5 Then PortD = cinco If I = 6 Then PortD = seis If I = 7 Then PortD = siete If I = 8 Then PortD = ocho If I = 9 Then PortD = nueve Return ' Retorna una línea después del salto con retorno (Call) End Al iniciar el conteo en el display de 7 segmentos, se puede observar un conteo ascendente que da inicio en cero y se va incrementando en una unidad cada segundo hasta llegar a nueve. Si deseamos realizar el incremento en más de una unidad por vez, tan solo debemos incluir la directiva “Step”, seguido del incremento, es decir, si queremos realizar un incremento de dos unidades por vez, entonces el lazo For – Next se compone de la siguiente manera:
  • 78.
    68 For I =0 To 9 Step 2 ' Repetición de Instrucciones dentro del Lazo ' For – Next con incremento en dos unidades. Call Digito ' Salto con Retorno hacia la etiqueta "Digito" Pause 1000 ' Pausa de 1 segundo (1000 ms) Next I Esto significa que el conteo arranca en cero y cada segundo transcurrido se podrán ver los dígitos: “2”, “4”, “6” y “8”. Para realizar un conteo regresivo, el lazo For – Next se compone de la siguiente forma: For I = 9 To 0 Step -1 ' Repetición de Instrucciones dentro del Lazo ' For – Next. Call Digito ' Salto con Retorno hacia la etiqueta "Digito" Pause 1000 ' Pausa de 1 segundo (1000 ms) Next I En este caso en conteo inicia en nueve y decrece en una unidad hasta llegar a cero. 5.6.- Proyecto #6: PicBasic cuenta con una instrucción capaz de generar tonos DTMF (Dual Tone Multifrecuency - Multifrecuencia de doble tono), tonos que se utilizan en telefonía para marcar una serie de números y así poder establecer la comunicación entre dos o más personas. Una aplicación interesante para esta instrucción podría ser el discado de números telefónicos en sistemas de alarma cuando ha sido activado un dispositivo de supervisión, para luego generar un mensaje de voz que nos alerte de dicho evento. Realice el montaje de la figura 5.13 y analice el programa que se muestra a continuación, el cual genera tonos DTMF consecutivos de una serie de dígitos predefinidos. Es muy importante considerar que para generar los tonos adecuadamente el oscilador externo debe ser de 10 Mhz o superior.
  • 79.
    69 Figura 5.13. Proyecto #6 Componente Cantidad PIC16F84A 1 Cristal de 10 Mhz 1 Capacitor cerámico de 33 pF 2 Capcitor Electrolítico de 10 uF 2 Parlante de 8 Ohm 1 Fuente regulada de 5 Vdc 1 Tabla 5.6. En la tabla 5.7 se puede observar la frecuencia baja y la frecuencia alta de cada digito entre cero y quince, los cuales se corresponden a su vez con cada uno de los dígitos de un teclado telefónico, como se puede observar en la segunda columna de la misma tabla. Esto quiere decir que si generamos las frecuencias correspondientes al dígito “1” utilizando la instrucción “DTMFout”, obtendremos las mismas frecuencias baja y alta que se generan al pulsar el dígito “1” de cualquier teléfono de tonos DTMF. Si deseáramos generar desde el microcontrolador el tono DTMF
  • 80.
    70 correspondiente al dígito“0” de un teclado telefónico, entonces, según la tabla 5.7, el dígito a introducir en la instrucción “DTMFout” deberá ser el “10”. Dígito en la Instrucción DTMFout Dígito en un Teclado Telefónico Frecuencias Bajas Frecuencias Altas 1 1 697 HZ 1209 HZ 2 2 697 HZ 1336 HZ 3 3 697 HZ 1477 HZ 4 4 770 HZ 1209 HZ 5 5 770 HZ 1336 HZ 6 6 770 HZ 1477 HZ 7 7 852 HZ 1209 HZ 8 8 852 HZ 1336 HZ 9 9 852 HZ 1477 HZ 10 0 941 HZ 1209 HZ 11 * 941 HZ 1336 HZ 12 # 941 HZ 1477 HZ 13 A 697 HZ 1633 HZ 14 B 770 HZ 1633 HZ 15 C 852 HZ 1633 HZ 0 D 941 HZ 1633 HZ Tabla 5.7. Figura 5.14.
  • 81.
    71 Antes de empezara programar, vamos a verificar la sintaxis de la instrucción DTMFout: DTMFout Sintaxis: DTMFout pin, {On-ms, Off-ms}, [tono, tono,...tono] La instrucción DTMFout genera tonos DTMF en secuencia y a través de un puerto cualquiera del microcontrolador. Pin: especifica el pin del puerto en el cual se emitirán los tonos DTMF. On-ms: es una variable o constante que especifica la duración de cada tono en milisegundos. En caso de no utilizar este parámetro, el tiempo por defecto de cada tono es de 200 ms. Off-ms: es una variable o constante que especifica el tiempo en milisegundos del silencio que hay entre cada tono. En caso de no utilizar este parámetro, el tiempo en silencio entre cada tono por defecto será de 50 ms. Tono: puede ser una variable o constante entre 0 y 15, que especifica el tono que debe ser generado.
  • 82.
    72 Programa en PicBasic: '**************************************** '* Nombre : Proyecto6.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** Define Osc 10 ' Define el Oscilador en 10 Mhz. TRISA = $FE ' Configura el pin RA0 como Salida ' y el resto de los pines como entrada. Inicio: DTMFOut PORTA.0, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] Pause 2000 ' Genera una pausa de 2 segundos. DTMFOut PORTA.0, 400, 150, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] Pause 2000 ' Genera una pausa de 2 segundos. GoTo Inicio ' Salta a la etiqueta "Inicio". End
  • 83.
    73 Observe que enla primera instrucción “DTMFout”, después de la etiqueta “Inicio”, no se especifica la duración de cada tono y el tiempo en silencio entre cada tono. Esto significa que el microcontrolador genera cada tono con una duración de 200 milisegundos por defecto, y un tiempo en silencio entre cada tono de 50 milisegundos como se muestra en las figuras 5.15 y 5.16 respectivamente: Figura 5.15.
  • 84.
    74 Figura 5.16. La segundainstrucción “DTMFout”, después de la etiqueta “Inicio”, tiene definido un tiempo de duración para cada tono de 400 milisegundos (figura 5.17), y un tiempo de espera entre cada tono de 150 milisegundos (figura 5.18). Estos tiempos pueden ser ajustados a conveniencia cada vez que sea necesario.
  • 85.
  • 86.
    76 5.7.- Proyecto #7:En este proyecto estudiaremos la instrucción “Button”, la cual es utilizada para la eliminación de rebotes en pulsadores o para efectuar repeticiones en un botón, como sucede en el caso de los teclados de las computadoras, en las cuales si dejamos presionado un botón o tecla, la misma se repite indefinidamente a una frecuencia específica, la cual puede ser variada fácilmente como lo demostraremos a continuación. Antes de empezar, veamos la sintaxis de la instrucción Button: Button Sintaxis: Button pin, estado, retardo, rango, variable, acción, etiqueta La instrucción “Button” elimina los rebotes de un “pulsador” o “switch”, y genera auto-repetición. Pin: especifica el pin del puerto en el cual será conectado el pulsador. Estado: indica cual es estado lógico que debe ocurrir cuando el pulsador es presionado (0 o 1). Si es 0, el pulsador deberá ser activo-bajo y si es 1, el pulsador deberá ser activo-alto (Ver figura 5.19).
  • 87.
    77 Figura 5.19. Retardo: esuna variable o constante (0 – 255) que especifica cuantos ciclos deben pasar antes de efectuar la auto-repetición. Este campo tiene dos funciones especiales: si el campo retardo es igual 0, no permite anti-rebote y no permite auto-repetición. Si el campo retardo es igual a 255, permite el anti- rebote pero no permite la auto-repetición. Rango: es una variable o constante (0 – 255) que especifica el número de ciclos entre auto-repeticiones. Variable: es una variable auxiliar tipo Byte, definida también al inicio del programa para uso exclusivo de la instrucción Button, por lo cual no deberá ser utilizada con otro fin en el programa. Siempre debe ser inicializada antes del comando Button. Acción: indica el estado del botón cuando éste no es presionado.
  • 88.
    78 Etiqueta: la instrucciónrealiza un salto a la etiqueta definida en este campo cuando el pulsador no ha sido presionado. Adicionalmente utilizaremos la instrucción “Pulsout” en el ejemplo, para generar pulsos de tiempo definido. PULSout Sintaxis: PULSout pin, nivel, variable La instrucción “PULSout”, genera pulsos con una duración definida en decenas de microsegundos. (Tiene una resolución de 10 microsegundos para un oscilador de 4 Mhz, y una resolución de 2 microsegundos para un oscilador de 20 Mhz).
  • 89.
    79 Para este proyectohemos preparado tres ejemplos los cuales están basados en el circuito de la figura 5.20. Figura 5.20. Proyecto # 7 - 7.1 - 7.2 - 7.3 Componente Cantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Resistencia de 10K Ohm 1 Pulsador Normalmente Abierto 1 Fuente regulada de 5 Vdc 1 Tabla 5.8.
  • 90.
    80 Se puede observaren el diagrama esquemático, que mientras el pulsador permanece abierto, hay un cero lógico en el pin RB0, el cual debemos configurar como entrada en el programa. Cuando el pulsador sea presionado, el estado lógico en el pin RB0 será un uno lógico. La salida a través de la cual se van a generar los pulsos será el pin RB1, en el cual hemos conectado un osciloscopio para poder ver el resultado de las señales generadas a partir de las especificaciones dadas en cada ejemplo a continuación. 5.7.1.- Proyecto #7.1: Para el primer ejemplo, se pide generar un pulso de 1.5 milisegundos una vez presionado el botón. Luego, pasados 20 milisegundos con el botón presionado, debe empezar una auto-repetición de este pulso cada 10 milisegundos. Veamos el siguiente programa: Define Osc 4 TRISB = %11111101 ' Configuración del puerto B A Var Byte ' declaración de la variable A para la instrucción Button. A = 0 ' inicializa la variable A PORTB.1 = 0 ' Inicializa la Salida RB0 Inicio: Button PORTB.0,1,2,1,A,0,Tiempo PulsOut PORTB.1,150 ' Genera un pulso de 1.5ms o 150 decenas de ' microsegundos. Tiempo: Pause 10 ' Pausa de 10 milisegundos GoTo Inicio ' Salta a inicio End
  • 91.
    81 Ahora analicemos lasecuencia del programa: • Mientras el pulsador permanece abierto, la instrucción Button salta a la etiqueta especificada, la cual en este caso hemos denominado “Tiempo”. Seguidamente el programa completa el ciclo ejecutando las instrucciones que siguen, y finalmente retorna a la etiqueta inicio. • Si es presionado el pulsador, se genera el primer pulso a través de la instrucción “Pulsout PortB.1, 150” (figura 5.21), y el programa continúa su curso hasta completar el primer ciclo. En este punto la auto- repetición aún no comienza, ya que hemos especificado en la instrucción Button, que ésta debe comenzar al terminar el segundo ciclo: Button PORTB.0,1,2,1,A,0,Tiempo Figura 5.21.
  • 92.
    82 Al terminar elprimer ciclo de programa, han transcurrido los primeros 10 milisegundos. Con el segundo ciclo de programa ocurre nuevamente el salto a la etiqueta “Tiempo”, produciéndose una nueva pausa de 10 milisegundos, para un tiempo de espera antes de ejecutar la auto-repetición de 20 milisegundos. Figura 5.22. • Cumplidos los dos ciclos especificados en el campo “retardo” de la instrucción Button, la instrucción empieza la auto-repetición cada “un ciclo”, ya que así lo hemos especificado en el campo “rango” de la instrucción: Button PORTB.0,1,2,1,A,0,Tiempo
  • 93.
    83 En la figura5.22 se puede apreciar la lectura de la señal producida por el programa al activar el pulsador. Observe que el tiempo entre el primer pulso y la auto-repetición es de 20 milisegundos, y que el tiempo entre cada auto- repetición es de 10 milisegundos (figura 5.23). Figura 5.23.
  • 94.
    84 En la figura5.24 se puede observar la señal generada al activar el pulsador, en la cual se ve la auto-repetición del pulso de 1.5 milisegundos, la cual permanecerá hasta que el pulsador sea liberado. Figura 5.24.
  • 95.
    85 5.7.2.- Proyecto #7.2:Para el siguiente ejemplo se pretende generar el mismo pulso de 1.5 milisegundos indefinidamente cada 20 milisegundos, siempre y cuando el pulsador permanezca activado. Analice el siguiente programa: Define Osc 4 TRISB = %11111101 ' Configuración del puerto B A Var Byte ' declaración de la variable A A = 0 ' inicializa la variable A PORTB.1 = 0 ' Inicializa la Salida RB0 Inicio: Button PORTB.0,1,2,2,A,0,Tiempo PulsOut PORTB.1,150 ' Genera un pulso de 1.5ms o 150 decenas de ' microsegundos. Tiempo: Pause 10 ' Pausa de 10 milisegundos GoTo Inicio ' Salta a inicio End Observe en el programa que el único cambio para lograr el objetivo, ha sido aumentar en una unidad el campo “rango” de la instrucción Button, lo cual significa que se deben esperar dos ciclos de programa entre cada auto- repetición para producir el pulso de 1.5 milisegundos. Button PORTB.0,1,2,2,A,0,Tiempo La secuencia para este programa es la siguiente: • Mientras el pulsador permanece abierto, al igual que en el ejemplo anterior, la instrucción Button hace un salto a la etiqueta “Tiempo” por cada ciclo de programa. • Cuando activamos el pulsador, se genera el primer pulso de 1.5 milisegundos gracias a la instrucción Pulsout; luego se genera una
  • 96.
    86 pausa de 10milisegundos y finaliza el primer ciclo con un salto a la etiqueta “Inicio”. En el segundo ciclo, la instrucción Button verifica el conteo de los ciclos, el cual es controlado por la variable “A”, determinando que aún no se puede empezar la auto-repetición hasta tanto no haya culminado el segundo ciclo, de tal manera que ocurre nuevamente el salto a la etiqueta “Tiempo”, y se produce una nueva pausa de 10 milisegundos. • Culminados los dos ciclos definidos en el campo “retardo” de la instrucción Button para el anti-rebote, se produce el primer pulso de 1.5 milisegundos de la auto-repetición. • Ahora podemos ver en el osciloscopio (figura 5.25), la señal generada al activar el pulsador, y en la cual se produce un pulso de 1.5 milisegundos, cada 20 milisegundos. Figura 5.25.
  • 97.
    87 5.7.3.- Proyecto #7.3:En este ejemplo se debe generar un pulso de 2.5 milisegundos, con un tiempo para anti-rebotes en el pulsador de 30 milisegundos, y un tiempo entre cada auto-repetición de 10 milisegundos. Analice el siguiente programa: Define Osc 4 TRISB = %11111101 ' Configuración del puerto B A Var Byte ' declaración de la variable A A = 0 ' inicializa la variable A PORTB.1 = 0 ' Inicializa la Salida RB0 Inicio: Button PORTB.0,1,3,1,A,0,Tiempo PulsOut PORTB.1,250 ' Genera un pulso de 2.5ms o 250 decenas de ' microsegundos. Tiempo: Pause 10 ' Pausa de 10 milisegundos GoTo Inicio ' Salta a inicio End En este caso se puede observar que los parámetros en la instrucción Button han sido configurados para que el tiempo en anti-rebote dure tres ciclos de programa, y para la auto-repetición un ciclo de programa. Entonces, la secuencia de programa es la siguiente: • Al activar el botón, se genera un pulso de 2.5 milisegundos. • Debido a que el campo “retardo” en la instrucción Button es igual a tres, la instrucción ejecutará la auto-repetición después de cumplir con los tres ciclos de programa, pasando por la subrutina “Tiempo” en cada ciclo, lo cual da como resultado un retardo de 30 milisegundos. • Al culminar el tercer ciclo de programa, empieza la auto-repetición, generando un pulso de 2.5 milisegundos por cada ciclo de programa,
  • 98.
    88 es decir, aproximadamentecada 10 milisegundos. La auto-repetición se mantiene siempre y cuando el pulsador permanezca activo. En la figura 5.26 se puede observar la señal generada al activar el pulsador, al igual que la medición del tiempo en el pulso generado por la instrucción “Pulsout”, igual a 2.5 milisegundos. Figura 5.26.
  • 99.
    89 En la figura5.27, se puede apreciar el tiempo de espera generado por la instrucción “Button”, igual a 30 milisegundos, para evitar los rebotes en el pulsador. También se puede observar claramente, que una vez culminado este tiempo, se genera una auto-repetición del pulso, la cual se mantiene siempre que el pulsador se encuentre presionado. Figura 5.27.
  • 100.
    90 Observe en lafigura 5.28 la medición del tiempo entre cada auto-repetición. Figura 5.28.
  • 101.
    91 5.8.- Proyecto #8:En este proyecto estudiaremos la instrucción “Branch”, con un ejemplo sencillo basado en el circuito de la figura 5.29, en el cual se debe iluminar cada Led en forma consecutiva por cada segundo transcurrido. Figura 5.29. Proyecto # 8 Componente Cantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 LED 3 Resistencia de 220 Ohm 3 Fuente regulada de 5 Vdc 1 Tabla 5.9.
  • 102.
    92 Branch Sintaxis: Branch Variable,[Etiqueta1,Etiqueta2,…EtiquetaN] La instrucción Branch hace un salto a una etiqueta dependiendo del valor de la variable, es decir, si la variable es igual a 0, el salto se hace a la etiqueta 1; si la variable es igual a 1, el salto se hace a la etiqueta 2; si la variable es igual a 2, el salto se hace a la etiqueta 3, y así sucesivamente. Analice el siguiente programa: '**************************************** '* Nombre : Proyecto8.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** I var Byte ' Declaración de la variable “I” TRISB = $00 ' Configura el puerto B como salida PORTB = $00 ' Inicializa el puerto B I = 0 ' Inicializa la variable I Inicio: Branch I,[Led1,Led2,Led3] Led1: PORTB = %00000001 ' enciende el led en RB0 Pause 1000 ' pause de 1 segundo PORTB = %00000000 ' apaga el led I = I + 1 ' suma 1 a la variable I GoTo inicio ' salta a inicio Led2: PORTB = %00000010 ' enciende el led en RB1 Pause 1000 ' pause de 1 segundo PORTB = %00000000 ' apaga el Led I = I + 1 ' suma 1 a la variable I GoTo inicio ' salta a inicio
  • 103.
    93 Led3: PORTB = %00000100' enciende el led en RB2 Pause 1000 ' pause de 1 segundo PORTB = %00000000 ' apaga el Led I = 0 ' Inicializa la variable I GoTo Inicio ' salta a inicio End Observe en el programa que a partir de la etiqueta “Inicio”, la instrucción “Branch” hace un salto a la etiqueta especificada según el valor cargado en la variable “I”, que se corresponde con la posición de la etiqueta que hemos designado entre los corchetes. Entonces, si I = 0, la instrucción hace un salto a la etiqueta “Led1”; si I = 1, la instrucción hace un salto a la etiqueta “Led2”; si I = 2, entonces la instrucción hace un salto a la etiqueta “Led3”.
  • 104.
    94 5.9.- Proyecto #9:La instrucción “PWM”, puede ser usada para generar voltajes analógicos implementando el circuito conectado al pin RB0 de la figura 5.30. A continuación realizaremos un ejemplo de aplicación de la instrucción PWM para generar un voltaje determinado, aplicando una serie de cálculos sencillos. Figura 5.30. Proyecto # 9 Componente Cantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Resistencia de 10K Ohm 1 Capcitor Electrolítico de 10 uF 1 Fuente regulada de 5 Vdc 1 Tabla 5.10.
  • 105.
    95 PWM Sintaxis: PWM pin,nivel, ciclo La instrucción PWM envía pulsos PWM (Pulse Width Modulation) a un pin específico. Pin: especifica el pin del puerto en el cual se genera PWM. Nivel: es una variable o constante que determina la duración del pulso en su nivel alto, es decir, partiendo de nivel = 1, si se incrementa este valor, el ancho de pulso positivo se incrementa, hasta nivel = 254, donde el ciclo de trabajo es aproximadamente 100%. Cuando nivel = 0, la salida se mantiene en cero lógico; cuando nivel = 255, la salida se mantiene en uno lógico. Ciclo: es una variable o constante en el cual se define el número de ciclos en un pin específico. PWM es una abreviación de Pulse Width Modulation, o modulación por ancho de pulso, y es un método utilizado normalmente para el control de velocidad de motores eléctricos, o para regular voltajes en fuentes conmutadas entre otras aplicaciones. Este control se lleva a cabo modificando el ancho de pulso o ciclo de trabajo de la señal generada. En nuestro ejemplo, para generar un voltaje específico en una de las salidas de un microcontrolador a través de la instrucción PWM, podemos aplicar la siguiente fórmula: 255 nivelVfuente Vout ∗ = donde, Vout: voltaje de salida. Vfuente: voltaje de la fuente de alimentación del circuito. Nivel: constante entre 0 y 255.
  • 106.
    96 Por ejemplo, sideseamos obtener Vout = 3.5V, entonces, 1795,178 5 2555.3255 ≈= ∗ = ∗ = V V Vfuente Vout nivel El valor a ser cargado en el campo “nivel” de la instrucción es 179. Al medir el voltaje en la salida del circuito de la figura 5.30, podemos comprobar que éste se aproxima al valor deseado de 3.5 voltios. El programa a ser cargado en el microcontrolador es el siguiente: DEFINE OSC 4 ' Define el oscilador en 4 Mhz Inicio: PWM PORTB.0,179,100 ' Señal PWM GoTo Inicio ' Salto a inicio End
  • 107.
    97 Módulos LCD CapituloVI 6.1.- Pantallas LCD: Las pantallas LCD alfanuméricas, son las más utilizadas hoy en día en el desarrollo de proyectos o equipos electrónicos en los cuales se hace necesario visualizar mensajes de texto cortos, que proporcionen la información adecuada sobre un evento determinado. Las pantallas más comunes suelen ser de 1x16, de 2x16 y de 4x16 (Filas x Columnas). Todas estas configuraciones también se encuentran para 20 columnas y hasta para 40 columnas. Aunque en esta edición solo estudiaremos el uso de pantallas alfanuméricas, también resulta interesante mencionar que existen en el mercado pantallas gráficas (GLCD), como la que se observa en la figura 6.3, y donde se debe aplicar un método de control diferente al de las pantallas alfanuméricas. Figura 6.1. Pantalla LCD 2x16. Figura 6.2. Pantalla LCD 4x16. Figura 6.3. Pantalla GLCD (Graphic Liquid Crystal Display) de 128x64 pixel.
  • 108.
    98 6.2.- Identificación delos pines de una pantalla LCD: Veamos a continuación la descripción de cada uno de los pines de una pantalla LCD: Figura 6.4. Pinout de un módulo LCD con conexión a Vcc, Gnd y Control de contraste. Pin 1, 2 y 3: como se puede observar en la figura 6.4, en la mayoría de las pantallas LCD, el Pin No. 1 y 2 corresponden a la alimentación de la pantalla, GND y Vcc, donde el voltaje máximo comúnmente soportado es de 5 Vdc. El Pin No.3 corresponde al control de contraste de la pantalla. Pin 4: "RS" (trabaja paralelamente al Bus de datos del modulo LCD, Pines 7 al 14, es decir, cuando RS es cero, el dato presente en el bus corresponde a un registro de control o instrucción, pero cuando RS es uno, el dato presente en el bus corresponde a un registro de datos o caracter alfanumérico. Pin 5: "R/W" (Read/Write), este pin es utilizado para leer un dato desde la pantalla LCD o para escribir un dato en la pantalla LCD. Si R/W = 0, esta condición indica que podemos escribir un dato en la pantalla. Si R/W = 1, esta condición nos permite leer un dato desde la pantalla LCD. Pin 6: "E" (Enable), este es el pin de habilitación, es decir, si E = 0 el módulo LCD se encuentra inhabilitado para recibir datos, pero si E = 1, el módulo LCD se encuentra habilitado para trabajar, de tal manera que podemos escribir o leer desde el modulo LCD.
  • 109.
    99 Pin 7 al14:"Bus de Datos”, el Pin 7 hasta el Pin 14 representan 8 líneas que se utilizan para colocar el dato que representa una instrucción para el modulo LCD o un carácter alfanumérico. Pin 15-16: "BackLight", en muchos modelos de LCD, los pines 15 y 16 son respectivamente el “Ánodo” y el “Cátodo”, aunque se pueden encontrar en el mercado modelos de pantallas LCD donde esta condición es configurable desde la parte posterior del circuito impreso a través de “Jumpers”, o conexiones donde podemos invertir los Pines, de manera tal que el Pin 15 sea el “Cátodo” y el Pin 16 el “Ánodo”, como se muestra en la figura 6.5. Figura 6.5. 6.3.- Conexión de una pantalla LCD en Pic Basic: Una pantalla LCD puede ser conectada a un microcontrolador utilizando los ocho bits del bus de datos (D0 a D7) o solamente los cuatro bits mas significativos del bus de datos (D4 a D7). Al emplear los ocho bits, estos deberán estar conectados en un solo puerto y nunca en puertos diferentes. Si deseamos trabajar solo con los cuatro bits más significativos del bus, estos deberán ser conectados en los cuatro bits menos significativos de un puerto o en los cuatro bits más significativos del puerto seleccionado. Los pines E (Pin 6) y RS (Pin 4) pueden estar conectados en cualquier puerto del microcontrolador. Por último, el Pin R/W deberá estar conectado a tierra (GND) para indicar a la pantalla LCD que estaremos escribiendo, esto debido a que estaremos trabajando inicialmente solo con la instrucción “Lcdout”.
  • 110.
    100 Un dato interesanteresulta ser el hecho de que las pantallas LCD pueden ser controladas utilizando dos configuraciones distintas para el bus de datos: • La primera configuración es a 8 bits de datos, lo cual requiere que conectemos todos los pines del bus (D0 hasta D7 en la pantalla LCD), en uno de los puertos disponibles de un microcontrolador PIC. • La segunda configuración posible es a 4 bits de datos, lo cual reduce a la mitad la cantidad de pines a ser utilizados en un puerto de un microcontrolador PIC, pero ésta deberá ser definida al inicio del programa para garantizar que la pantalla funcione correctamente. Nota Importante: PIC Basic asume por defecto que el conexionado entre un módulo LCD alfanumérico y un microcontrolador, se ha realizado como se muestra en el diagrama esquemático de la figura 6.6. En este caso no será necesario definir estas conexiones en el programa; sin embargo, es conveniente saber que el funcionamiento de un programa para el manejo de una pantalla LCD, no se verá afectado si decidimos definir cada una de las conexiones como se muestran a continuación: DEFINE LCD_DREG PORTA ' Indica que el Bus de datos estará conectado ' en el Puerto A. DEFINE LCD_BITS 4 ' El bus de datos de la LCD será de cuatro bits. DEFINE LCD_DBIT 0 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTA ' Indica al uC que el pin “RS” estará en el Puerto A DEFINE LCD_RSBIT 4 ' “RS” estará conectado en RA4 DEFINE LCD_EREG PORTB ' Indica al uC que el pin “E” estará en el Puerto B DEFINE LCD_EBIT 3 ' “E” estará conectado en RB3 Compare estas definiciones con el diagrama esquemático de la figura 6.6, y podrá notar que las conexiones entre la pantalla LCD y el microcontrolador PIC coinciden exactamente con cada línea de programa de la nota anterior.
  • 111.
    101 Figura 6.6. Proyecto #10 Componente Cantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x4 1 Resistencia de 1K Ohm 1 Potenciómetro de 5K Ohm 1 Fuente regulada de 5 Vdc 1 Tabla 6.1.
  • 112.
    102 Aunque esta configuraciónes la que PicBasic asume por defecto, la misma puede ser cambiada según convenga, pero siempre tomando en cuenta las definiciones anteriormente mencionadas; en ellas se especifica la disposición de los pines de la pantalla LCD con respecto a su conexión en los puertos del microcontrolador. LCDout Sintaxis: LCDout comando, dato La instrucción “Lcdout” envía datos específicos a una pantalla LCD Alfanumérica para que puedan ser mostrados en la misma. La instrucción “Lcdout” va acompañada de un comando de control el cual opera según la tabla 6.2: Tabla 6.2. Estos comandos son indispensables para especificar en la pantalla LCD la acción que deseamos tomar. Para el caso específico de la primera línea en una pantalla LCD, bastará solo con escribir la instrucción “Lcdout”, seguida del mensaje o variable que se desea mostrar. Comando Acción $FE, 1 Limpia la pantalla $FE, 2 Retorna al inicio de la primera línea $FE, $0C Apaga el Cursor $FE, $0E Cursor bajo (Underline "_") activo $FE, $0F Cursor intermitente activo $FE, $10 Mueve el cursor un espacio a la izquierda $FE, $14 Mueve el cursor un espacio a la derecha $FE, $C0 Mueve el cursor al inicio de la segunda línea $FE, $90 Mueve el cursor al inicio de la tercera línea $FE, $D0 Mueve el cursor al inicio de la cuarta línea
  • 113.
    103 En la figura6.7 se muestran las direcciones de cada caracter en las líneas 2, 3 y 4: Pantalla LCD 16x4 Línea 1 - - - - - - - - - - - - - - - - Línea 2 $C0 $C1 $C2 $C3 $C4 $C5 $C6 $C7 $C8 $C9 $CA $CB $CC $CD $CE $CF Línea 3 $90 $91 $92 $93 $94 $95 $96 $97 $98 $99 $9A $9B $9C $9D $9E $9F Línea 4 $D0 $D1 $D2 $D3 $D4 $D5 $D6 $D7 $D8 $D9 $DA $DB $DC $DD $DE $DF Figura 6.7. Entonces, para escribir un mensaje en cada línea de una pantalla LCD, tenemos que: Lcdout "Mensaje Linea 1" Lcdout $fe,$C0, "Mensaje Linea 2" Lcdout $fe,$90, "Mensaje Linea 3" Lcdout $fe,$D0, "Mensaje Linea 4" También es posible iniciar un mensaje en otra posición en las líneas 2, 3 y 4, cambiando la dirección en el comando de control de la instrucción. 6.4.- Proyecto #10. En el siguiente programa se puede ver que no ha sido utilizado ningún tipo de definición de parámetros de conexión para los pines de control entre la pantalla y el microcontrolador, por lo cual se asume que el conexionado entre ambos dispositivos deberá ser igual al planteado en el diagrama de la figura 6.6. Realice el montaje y haga modificaciones al programa mostrado a continuación, con el fin de comprobar la tabla 6.2. ' Programa en PIC Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Pause 500 LCDOut $fe, 1 ' Limpia la pantalla LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "* Pantalla LCD *"
  • 114.
    104 LCDOut $fe,$C0, "*Alfanumerica *" LCDOut $fe,$90, "* 1234567890 *" LCDOut $fe,$D0, "* AaBbCcDdEeFf *" Inicio: GoTo Inicio ' Salta a la etiqueta inicio End Al conectar el circuito de la figura 6.6 y el programa cargado en el microcontrolador, podremos ver como se despliega en la pantalla LCD de cuatro líneas, cada frase preestablecida en el programa, como se muestra en las figuras 6.8 y 6.9. Figura 6.8. Figura 6.9.
  • 115.
    105 6.5.- Proyecto #11.En el diagrama de la figura 6.10 se puede observar que la conexión entre el modulo LCD y el microcontrolador ha cambiado con respecto al proyecto #10, con el fin de utilizar en el programa la definición de conexiones anteriormente mencionada. Para este ejemplo se ha realizado un programa que muestra el valor cargado en una variable a la cual hemos denominado “Dato”, y la cual podrá ser incrementada al accionar el pulsador “P1” conectado en RB0; el valor de esta variable también podrá decrecer al accionar el pulsador “P2” conectado en RB1. Los puertos han sido configurados de la siguiente manera: • Puerto B: se configura como entrada ya que en los pines RB0 y RB1 estarán conectados los pulsadores P1 y P2. • Puerto D: se configura como salida ya que éste será utilizado para el control de la pantalla LCD. La variable “Dato” ha sido inicializada con un valor cargado igual a 25. Para aumentar o disminuir este valor, simplemente se pregunta si en RB0 o en RB1 hay un cambio de estado lógico. Adicionalmente se establecen dos condiciones que se deben cumplir para que la variable pueda aumentar su valor o disminuir: • La primera condición al pulsar P1 para el incremento es: solo podrá ser incrementado el valor cargado en la variable “Dato”, si ésta es menor (“<”) a cincuenta (50). • La segunda condición al pulsar P2 para disminuir el valor cargado en la variable es: solo se podrá disminuir el valor cargado en la variable “Dato” si ésta es mayor (“>”) a cero (0).
  • 116.
    106 Para mostrar elvalor decimal cargado en la variable “Dato” a través de la pantalla LCD, se debe utilizar la directiva “Dec” o el símbolo “#” antes de la variable, como se muestra a continuación: Lcdout $fe,$C0,"Dato: ",Dec Dato ' Escribe el mensaje en la línea 2 ' seguido del valor cargado en la ' variable "Dato" en Decimal. ó, Lcdout $fe,$C0,"Dato: ",#Dato Figura 6.10.
  • 117.
    107 Proyecto # 11- 12 Componente Cantidad PIC16F877A 1 Cristal de 8 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x2 1 Resistencia de 10K Ohm 2 Potenciómetro de 5K Ohm 1 Pulsador Normalmente Abierto 2 Fuente regulada de 5 Vdc 1 Tabla 6.3. ' Programa en Pic Basic Pro: '**************************************** '* Nombre : Proyecto11.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Define Osc 8 ' Define el Oscilador para un Cristal ' de 8 Mhz. TRISB = $FF ' Configura el puerto B como entrada. TRISD = $00 ' Configura el puerto D como salida. Dato Var Byte ' Declaración de la Variable "Dato" tipo Byte. Dato = 25 ' Inicializa la Variable Dato = 25. Lcdout $fe, 1 ' Limpia la pantalla Inicio:
  • 118.
    108 Lcdout $fe,2 'Inicio de la primera línea. Lcdout "P1 Suma P2 Resta" ' Escribe mensaje en la primera línea. Lcdout $fe,$C0,"Dato: ",Dec Dato," " ' Escribe el mensaje en la 2da línea ' seguido del valor cargado en la ' variable "Dato" en Decimal. ' La siguiente instrucción pregunta si hay un "1" en RB0 y si la variable ' "Dato" es menor a 50. Si se cumplen estas dos condiciones, hace un salto ' con retorno a la subrutina "Suma". If PORTB.0 = 1 And Dato < 50 Then Call Suma ' La siguiente instrucción pregunta si hay un "1" en RB1 y si la variable ' "Dato" es mayor a 0. Si se cumplen estas dos condiciones, hace un salto ' con retorno a la subrutina "Resta". If PORTB.1 = 1 And Dato > 0 Then Call Resta GoTo Inicio ' Salta a la etiqueta "Inicio". Suma: Dato = Dato + 1 ' Incrementa en una unidad la variable "Dato". Pause 350 ' Realiza una pausa de 350 milisegundos para evitar ' que el incremento de la variable sea muy acelerado ' mientras el pulsador "P1" esté presionado. Return ' Retorna una línea después del llamado "Call Suma". Resta: Dato = Dato - 1 ' Decrementa en una unidad la variable "Dato". Pause 350 ' Realiza una pausa de 350 milisegundos para evitar ' que el decremento de la variable sea muy acelerado ' mientras el pulsador "P2" esté presionado. Return ' Retorna una línea después del llamado "Call Resta". End Note que en la línea de programa encargada de imprimir el mensaje “Dato: “, además del valor cargado en la variable, hay un espacio en blanco entre comillas (“ “) para imprimir en la pantalla: Lcdout $fe,$C0,"Dato: ",Dec Dato," " Analice la razón por la cual ha sido considerado este espacio en blanco.
  • 119.
    109 6.6.- Proyecto #12.En este proyecto nos hemos basado en el diagrama de la figura 6.10 para efectuar la programación del microcontrolador. La idea principal en este ejemplo, será mostrar un menú inicial en la pantalla LCD, como se muestra a continuación: "P1: Ver Mensaje1" "P2: Ver Mensaje2" Figura 6.11. • Al accionar el pulsador “P1”, se deberá mostrar el siguiente sub-menú (figura 6.12), el cual deberá permanecer visible durante 5 segundos para luego retornar al menú inicial: " Menu #1 " "Mensaje #1 aqui!" Figura 6.12. • Al accionar el pulsador “P2”, se deberá mostrar el siguiente sub-menú (figura 6.13), el cual también deberá permanecer visible durante 5 segundos para luego retornar al menú inicial: " Menu #2 " "Mensaje #2 aqui!" Figura 6.13. Lea detenidamente los comentarios de cada línea del programa. Observe que en esta oportunidad hemos utilizado un alias para cada una de las entradas utilizadas en el puerto B (RB0 se llamará P1, y RB1 se llamará P2). ' Programa en Pic Basic Pro: '**************************************** '* Nombre : Proyecto12.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '****************************************
  • 120.
    110 DEFINE LCD_DREG PORTD' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Symbol P1 = PORTB.0 ' Alias para RB0 Symbol P2 = PORTB.1 ' Alias para RB1 Define Osc 8 ' Define el Oscilador para un Cristal ' de 8 Mhz. TRISB = $FF ' Configura el puerto B como entrada. TrisD = $00 ' Configura el puerto D como salida. LCDOut $fe, 1 ' Limpia la pantalla Inicio: LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "P1: Ver Mensaje1" LCDOut $fe,$C0, "P2: Ver Mensaje2" If P1 = 1 Then Call Mensaje1 ' Pregunta si RB0 = 1 If P2 = 1 Then Call Mensaje2 ' Pregunta si RB1 = 1 GoTo Inicio Mensaje1: LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut " Menu #1 " LCDOut $fe,$C0, "Mensaje #1 aqui!" Pause 5000 ' Pausa de 5 segundos. Return ' Retorna una línea después del llamado "Call" Mensaje2: LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut " Menu #2 " LCDOut $fe,$C0, "Mensaje #2 aqui!" Pause 5000 ' Pausa de 5 segundos. Return ' Retorna una línea después del llamado "Call" End
  • 121.
    111 6.7.- Proyecto #13.En el siguiente ejemplo explicamos la forma de visualizar en la pantalla LCD un valor decimal y sus equivalentes en hexadecimal, binario y el código ASCII correspondiente, de un dato almacenado en una variable tipo Byte. Para lograr este objetivo, hemos declarado en el programa la variable “Dato”, en la cual cargaremos un valor igual a 64, como ejemplo inicial. Ya es conocido por un ejemplo anterior a éste, que si deseamos mostrar el contenido de la variable en decimal, debemos anteponer la directiva “Dec” o el símbolo “#” a ésta, como se puede ver a continuación: LCDOut "Decimal: ", Dec Dato LCDOut "Decimal: ", #Dato El equivalente en Hexadecimal para este valor (64) es “40”, y el equivalente en binario para este mismo valor es “1000000”. Entonces, para mostrar estos valores en la pantalla LCD en su formato correspondiente, debemos utilizar las siguientes directivas: Hexadecimal: LCDOut "Hexadecimal: ",Hex Dato Binario: LCDOut "Binario: ",Bin Dato El código ASCII equivalente a este valor (“64”), corresponde al símbolo “@”, y se muestra de la siguiente forma: LCDOut "Código ASCII: ", Dato Realice el montaje de la figura 6.14, y analice el programa que se muestra a continuación:
  • 122.
    112 Figura 6.14. Proyecto #13 - 14 Componente Cantidad PIC16F877A 1 Cristal de 8 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x2 1 Potenciómetro de 5K Ohm 1 Fuente regulada de 5 Vdc 1 Tabla 6.4.
  • 123.
    113 ' Programa enPic Basic Pro: '**************************************** '* Nombre : Proyecto13.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Define Osc 8 ' Define el Oscilador para un Cristal ' de 8 Mhz. TrisD = $00 ' Configura el puerto D como salida. Dato Var Byte Dato = 64 ' Carga la variable "Dato" con el Valor 64. LCDOut $fe, 1 ' Limpia la pantalla. Inicio: LCDOuT $fe, 2 ' Posiciona el cursor en el inicio. LCDOut "Decimal: ",Dec Dato," " LCDOut $fe,$C0, "Hexadecimal: ",HEX Dato," " Pause 4000 ' Hace una pausa de 4 segundos. LCDOuT $fe, 2 ' Posiciona el cursor en el inicio. LCDOut "Binario:",BIN Dato LCDOut $fe,$C0, "Codigo ASCII: ", Dato," " Pause 4000 ' Hace una pausa de 4 segundos. GoTo Inicio ' Salta a la etiqueta "Inicio". End
  • 124.
    114 6.8.- Proyecto #14:Analice el programa propuesto a continuación, el cual está basado en el diagrama esquemático de la figura 6.14. En este caso se desea mostrar en la pantalla LCD los valores entre 33 y 125 en decimal, además de sus equivalentes en hexadecimal y código ASCII correspondiente. ' Programa en Pic Basic Pro: '**************************************** '* Nombre : Proyecto14.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Define Osc 8 ' Define el Oscilador para un Cristal ' de 8 Mhz. TrisD = $00 ' Configura el puerto D como salida. I Var Byte ' Declaración de la variable "I" topo Byte. LCDOut $fe, 1 ' Limpia la pantalla. Inicio: ' A continuación se carga la variable "I" con un valor inicial igual a ' 33, el cual se irá incrementando hasta llegar a 125. Por cada incremento ' se muestran los valores equivalentes en hexadecimal y su respectivo ' código ASCII en la pantalla LCD. For I = 33 To 125 Lcdout $fe,2 Lcdout "Dec:",#I," Hex:",HEX I," " Lcdout $fe,$C0,"ASCII: ", I," " Pause 1000 ' Realiza una pausa de 1 segundo. Next I Fin: GoTo Fin ' Bucle infinito. End
  • 125.
    115 6.9.- Proyecto #15:Con la ayuda de la instrucción “Count”, estaremos realizando un contador de pulsos, el cual se compone básicamente de un PIC16F877A y una pantalla LCD 2x16. El tren de pulsos cuadrados de frecuencia variable, será generado desde un microcontrolador PIC16F84A utilizando la instrucción “Pulsout”, y el cual deberá ser programado para que sea posible aumentar o disminuir la frecuencia a través de dos pulsadores conectados a él, P1 para aumentar la frecuencia y P2 para disminuir la frecuencia, como se muestra en el diagrama de la figura 6.15. Figura 6.15.
  • 126.
    116 Proyecto # 15- 16 Componente Cantidad PIC16F877A 1 PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x4 1 Resistencia de 10K Ohm 2 Potenciómetro de 5K Ohm 1 Pulsador Normalmente Abierto 2 Fuente regulada de 5 Vdc 1 Tabla 6.5. En el circuito de la figura 6.15 se puede observar un microcontrolador PIC16F877A, en el cual cargaremos el programa encargado de realizar el conteo de pulsos enviados desde un microcontrolador PIC16F84A, el cual también dispone de su propia programación para poder generar un tren de pulsos variables. El tren de pulsos de frecuencia variable desde los pulsadores P1 y P2, sale desde el pin RB1 del PIC16F84A hacia el pin RB1 del PIC16F877A, el cual a su vez realiza constantemente el conteo de pulsos, durante un tiempo definido, que en este caso ha sido de 1000 milisegundos. Seguidamente el resultado del conteo de pulsos en este período de tiempo es almacenado en una variable la cual hemos denominado “Pulsos”, para luego ser mostrado en la pantalla LCD. Veamos a continuación la sintaxis de la nueva instrucción y seguidamente los programas propuestos para este ejemplo.
  • 127.
    117 Count Sintaxis: Count pin,duración, variable Con esta instrucción se puede medir la frecuencia de una señal simple, contando el número de pulsos durante un tiempo determinado, definido en el campo “duración” de la instrucción. Se pueden medir frecuencias de hasta 25 khz con un oscilador de 4 MHz. Para un oscilador de 20 MHz la frecuencia máxima a ser medida será de 125 khz. Pin: especifica el pin del puerto en el cual se introducirán los pulsos. Este pin es designado como entrada automáticamente por la instrucción Count. Duración: es el tiempo en milisegundos, durante el cual se realizará el conteo de pulsos sobre el pin especificado. Variable: es una variable definida por el programador en la cual se grabará el resultado del conteo. Programa para el contador de pulsos (PIC16F877A): DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Pulsos Var Word ' declaración de la variable "Pulsos" tipo Word Lcdout $fe, 1 ' Limpia la pantalla Inicio: Count PORTB.1, 1000, Pulsos ' Cuenta los pulsos introducidos a través ' del pin RB1, durante 1000 milisegundos y el ' resultado del conteo es almacenado en la
  • 128.
    118 ' variable "Pulsos". Lcdout$fe,2 ' Inicio de la primera línea. Lcdout "Frecuencia " ' Escribe mensaje en la primera línea. LcdOut $FE,$C0,"Medida = ",#Pulsos," Hz " ' Escribe dato en pantalla. GoTo Inicio ' Salta a la etiqueta "Inicio" End Análisis del programa: • Para empezar, se han definido los pines de control y bus de datos de la pantalla LCD, al igual que la frecuencia del oscilador externo. • Seguidamente se define la variable “Pulsos”, en la cual se cargará el resultado del conteo de los pulsos introducidos a través del pin RB1. • Se limpia la pantalla LCD. • La instrucción “Count”, cuenta los pulsos introducidos por el pin RB1, y el resultado es almacenado en la variable “Pulsos”. • Por último se muestra el valor cargado en la variable “Pulsos”, en la pantalla LCD y se retorna a la etiqueta “Inicio”. Programa para el generador de pulsos (PIC16F84A): Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. TRISB = %11111101 ' Configuración del puerto B Base Var Word ' Declaración de la variable "Base" tipo Word Espera VAR Word PORTB.1 = 0 ' Inicializa la Salida RB0 Base = 100 ' Inicializa la variable Base = 100 Espera = 1 Inicio: If PORTB.0 = 1 Then Call Suma ' Si RB0 = 1 llama a la subrutina "Suma"
  • 129.
    119 If PORTB.2 =1 Then Call Resta ' Si RB2 = 1 llama a la subrutina "Resta" PulsOut PORTB.1,Base ' Genera un pulso de duración definida por la variable ' "Base". pause Espera ' Pausa de "Base/100" milisegundos GoTo Inicio ' Salta a inicio Suma: Pause 300 ' Pausa de 300 milisegundos Base = Base + 100 ' Incrementa la variable "Base" If Base = 10100 Then Base = 10000 ' Establece un límite máximo al valor cargado ' en la variable "Base". Espera = Base / 100 ' Divide el valor cargado en la variable ' "Base" entre 100 y lo carga en la variable ' "Espera", para que la pausa que se genera ' después de cada pulso sea igual al tiempo ' del pulso. Return ' Retorna una línea después del llamado "Call" Resta: Pause 300 ' Pausa de 300 milisegundos Base = Base - 100 ' decrementa la variable "Base" If Base = 0 Then Base = 100 ' Establece un límite máximo al valor cargado ' en la variable "Base". Espera = Base / 100 ' Divide el valor cargado en la variable ' "Base" entre 100 y lo carga en la variable ' "Espera", para que la pausa que se genera ' después de cada pulso sea igual al tiempo ' del pulso. Return ' Retorna una línea después del llamado "Call" End Análisis del programa: • En el programa se puede observar que se han dado los pasos necesarios en lo que respecta a la definición del tipo de oscilador y la configuración del puerto que estamos utilizando en el diseño propuesto. • Seguidamente, ha sido declarada la variable “Base” y la variable “Espera”, las cuales serán necesarias para almacenar la base de tiempo de los pulsos generados por la instrucción Pulsout, además de la pausa generada entre cada pulso.
  • 130.
    120 • Inicializamos lavariable “Base” con un valor igual a 100 y la variable “Espera” con un valor igual a 1. • A partir de la etiqueta “Inicio”, el primer paso de la subrutina ha sido preguntar si los pulsadores P1 y P2 han sido activados. Si el pulsador P1 es activado, el programa hace un salto con retorno a la subrutina “Suma”, incrementando el valor de la variable “Base” en 100 unidades. Si el pulsador P2 es activado, el programa hace un salto con retorno a la subrutina “Resta”, haciendo decrecer en 100 unidades el valor cargado en la variable “Base”. En estas dos subrutinas (Suma y Resta), se establecen límites para la variable “Base”, de manera tal que si la suma llega a ser igual a 10100, la variable “Base” mantiene su valor igual a 10000. En el caso específico de la resta, si el valor de la variable “Base” llega a ser igual a 0, entonces la variable mantiene siempre su valor igual a 100. Seguidamente se carga la variable “Espera”, tanto en la subrutina “Suma” como en la subrutina “Resta”, valor que será utilizado para realizar la pausa entre pulsos. • La instrucción Pulsout, genera un pulso en el pin RB1, con una duración definida por el valor cargado en la variable “Base”. Por ejemplo, si Base = 100, entonces el pulso generado será de 100 decenas de microsegundos, es decir, 1 milisegundo. Recuerde que la instrucción Pulsout tiene una resolución de 10 microsegundos para un oscilador de 4 Mhz. • Seguidamente el programa realiza una pausa la cual depende también del valor cargado en la variable “Espera”. Entonces, observe que si la variable Base = 100, la pausa generada es de 1 milisegundo, debido a que se está dividiendo el valor cargado en la variable “Base” entre 100 y el resultado es cargado en la variable “Espera”. • Por último, el programa hace un salto a la etiqueta “Inicio” para empezar el proceso.
  • 131.
    121 El tren depulsos generado por el microcontrolador PIC16F84A en el pin RB1, se puede observar en la siguiente figura: Figura 6.16. Observe que la frecuencia de la señal generada cuando alimentamos el circuito es de 480 Hz, debido a que el valor cargado en la variable “Base” es igual a 100, y el valor cargado en la variable “Espera” es igual a 1. Compare el valor de la frecuencia medido en el osciloscopio, con el valor obtenido por la instrucción “Count”, en el programa cargado en el microcontrolador PIC16F877A. En este caso, el valor mostrado en la pantalla LCD, debe ser igual a 480 pulsos por segundo. Realice las pruebas necesarias con la ayuda de un osciloscopio, para visualizar la señal generada cada vez que aumenta o disminuye el valor de la variable “Base”, a través de los pulsadores P1 y P2 respectivamente. Compare el valor de la frecuencia medido en el osciloscopio, con el valor obtenido en el conteo de pulsos por cada segundo transcurrido a través de la instrucción “Count”.
  • 132.
    122 6.10.- Proyecto #16:El siguiente proyecto está basado en el montaje de la figura 6.15. En esta oportunidad estudiaremos el funcionamiento de la instrucción “Pulsin”, con la cual mediremos la duración de los pulsos generados por el microcontrolador PIC16F84A, programado en el proyecto #15. PULSIN Sintaxis: PULSIN pin, nivel, variable La instrucción PULSIN mide la duración de un pulso alto o bajo con una resolución de 10 microsegundos para un oscilador de 4 Mhz, o una resolución de 2 microsegundos para un oscilador de 20 Mhz, y el valor obtenido es almacenado en una variable definida de 8 bits (byte) o 16 bits (Word). Pin: especifica el pin del puerto en el cual se introducirá el pulso a ser medido. Nivel: define si la medición se hace en nivel alto o bajo. (1 = alto, 0 = bajo). Variable: es una variable de 8 bits (variable tipo byte) o 16 bits (variable tipo word) definida por el programador en la cual se grabará el resultado de la lectura. Analice el siguiente programa: DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Define OSC 4 ' Define el oscilador en 4 Mhz LECTURA VAR Word ' Definición de variable de 16 bits Pause 200 ' Pausa de 200 milisegundos LCDOut $fe, 1 ' Limpia la pantalla
  • 133.
    123 Inicio: LECTURA = 0' Inicializa la variable "Lectura". PulsIn PORTB.1,1,LECTURA ' Mide la duración de un pulso. LCDOut $fe, 2 ' Posiciona el cursor en el inicio. LCDOut "Lectura: ",#LECTURA," " ' Muestra mensaje y dato por pantalla. Lcdout $fe,$C0,"decenas de uS. " ' Muestra el mensaje de la segunda línea. Pause 1000 ' Pausa de 1 segundo GoTo Inicio ' Salta a inicio End Al compilar y grabar el programa en el microcontrolador PIC16F877A del diagrama de la figura 6.15, podremos observar en la pantalla LCD el resultado de la lectura generada por la instrucción “Pulsin”, la cual mide el tiempo de cada pulso que ingresa a través del pin RB1, en decenas de microsegundos. Entonces, su generamos un pulso cuya duración es igual a 1 milisegundo, el valor cargado en la variable “Lectura” será igual o aproximado a 100.
  • 134.
    124 6.11.- Proyecto #17:Realice el montaje para el circuito la figura 6.17, con el cual estudiaremos la instrucción “POT” a través de un ejemplo de programación, con el cual se pretende tomar lectura de un elemento resistivo, el cual en este caso será un potenciómetro de 10Kohm. Figura 6.17.
  • 135.
    125 Proyecto # 17 ComponenteCantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x2 1 Potenciómetro de 5K Ohm 1 Potenciómetro de 10K Ohm 1 Capacitor cerámico de 0,1 uF 1 Fuente regulada de 5 Vdc 1 Tabla 6.6. POT Sintaxis: POT pin, escala, variable La instrucción “POT” lee un potenciómetro, foto celda, termistor, o cualquier otro dispositivo capaz de variar su valor resistivo. Básicamente esta instrucción calcula el tiempo de descarga del condensador C1 el cual varía según el valor resistivo presente en la resistencia variable. Pin: especifica el pin del puerto en el cual se va a conectar el potenciómetro. Escala: Es una variable o constante que aumenta o disminuye el rango de lectura en un porcentaje determinado. Esta escala es utilizada para ajustar el rango de salida en la lectura del dispositivo, y es afectada directamente por las constantes RC. El valor de la escala será correcto cuando el valor cargado en la variable se aproxime a cero, cuando la resistencia medida sea mínima; y también cuando el valor de la variable se aproxime a 255, cuando la resistencia medida sea máxima.
  • 136.
    126 Variable: es unavariable en la cual se almacena el resultado obtenido de la lectura del potenciómetro o componente resistivo. Analice el siguiente programa, y experimente sobre el valor de C1, y el valor de la escala en la instrucción POT, hasta lograr el rango más aceptable para una resistencia variable (P1) de 10K. DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Define OSC 4 ' Define el oscilador en 4 Mhz ESCALA VAR Byte DATO Var Byte Pause 200 ' Pausa de 200 milisegundos ESCALA = 127 ' Asigna valor a la escala LCDOut $fe, 1 ' Limpia la pantalla Inicio: Pot PORTB.0,ESCALA,DATO ' Toma lectura del Potenciómetro LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Lectura: ",#DATO," " ' Muestra dato por pantalla GoTo inicio ' Salto a inicio End
  • 137.
    127 6.12.- Memoria CGRAMen la Pantalla LCD. La pantalla LCD posee una memoria llamada CGRAM (Character Generator RAM), destinada para que el usuario pueda almacenar hasta un máximo de 8 caracteres o figuras personalizadas como lo demostraremos a continuación. Cada carácter es representado como un bloque constituido normalmente por 5 columnas y 8 filas, cada una de 8 bits (1 byte)*, es decir, cada carácter se compone de ocho bytes. C5 C4 C3 C2 C1 C5 C4 C3 C2 C1 C5 C4 C3 C2 C1 C5 C4 C3 C2 C1 C5 C4 C3 C2 C1 Fila 1 Fila 2 Fila 3 Fila 4 ............. Fila 5 Fila 6 Fila 7 Fila 8 Figura 6.18. * Nota: Los 3 bits más significativos de cada byte (3 bits más significativos de cada fila), son tomados como ceros. En cada posición de la CGRAM se almacenan los 8 bytes que forman un caracter. Las direcciones correspondientes a cada posición son: Posición en la CGRAM Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7 Posición 0 $40 $41 $42 $43 $44 $45 $46 $47 Posición 1 $48 $49 $4A $4B $4C $4D $4E $4F Posición 2 $50 $51 $52 $53 $54 $55 $56 $57 Posición 3 $58 $59 $5A $5B $5C $5D $5E $5F Posición 4 $60 $61 $62 $63 $64 $65 $66 $67 Posición 5 $68 $69 $6A $6B $6C $6D $6E $6F Posición 6 $70 $71 $72 $73 $74 $75 $76 $77 Posición 7 $78 $79 $7A $7B $7C $7D $7E $7F Tabla 6.7.
  • 138.
    128 Veamos el siguienteejemplo en el cual almacenaremos el símbolo de un parlante en la posición 0 de la CGRAM. Dato Dato Bytes en la HEX Símbolo Binario CGRAM $02 00000010 $40 $06 00000110 $41 $1A 00011010 $42 $1A 00011010 $43 $1A 00011010 $44 $06 00000110 $45 $02 00000010 $46 $00 00000000 $47 Tabla 6.8. Note que cada cuadro representa un bit el cual corresponde a un “1” o un “0” según sea el caso o la figura que deseamos realizar, donde “1” es encendido y “0” es apagado. La instrucción para desplegar este símbolo en la pantalla sería la siguiente: LCDOUT $fe,$40,$02,$06,$1A,$1A,$1A,$06,$02,$00 Observe que hemos especificado la dirección inicial de la posición cero después de la sentencia de comando $fe, seguido de los datos correspondientes al caracter. Una vez almacenado los datos correspondientes a la figura en la posición cero de la memoria CGRAM, podemos desplegar el símbolo en la pantalla LCD. Esto se hace especificando la posición de la CGRAM que se desea mostrar después del comando de control, como se muestra a continuación: LCDOUT $FE,1, 0 ' Limpia la pantalla y luego muestra el símbolo ' almacenado en la posición 0 de la CGRAM
  • 139.
    129 En este casola figura aparece en la primera línea de la pantalla LCD. Para mostrar esta misma figura en una posición diferente de la pantalla, simplemente nos basamos en la tabla de comandos de la instrucción “Lcdout” (Tabla 6.2) y en la figura 6.7, en la cual podremos encontrar la dirección de la posición de visualización deseada en la pantalla LCD. Por ejemplo; • Para visualizar la figura cargada en la posición cero de la CGRAM en la línea 2, posición $C0 de la pantalla LCD, la sintaxis sería la siguiente: LcdOut $fe,$C0, 0 • Para visualizar una figura cargada en la posición cuatro de la CGRAM en la línea 2, posición $C7 de la pantalla LCD, la sintaxis sería la siguiente: LcdOut $fe,$C7, 4 El programa para visualizar entonces la figura ya creada anteriormente en la línea 1 de la pantalla LCD sería el siguiente: ' Programa en PIC Basic Pro Pause 500 ' Pausa de 500 milisegundos LCDOut $fe, 1 ' Limpia la pantalla LCDOut $fe, 2 ' Posiciona el cursor en el inicio ' Cargamos el caracter en la posición cero: LCDOut $fe,$40,$02,$06,$1A,$1A,$1A,$06,$02,$00 ' Muestra el caracter en la pantalla: LCDOut $fe,1, 0 Inicio: GoTo Inicio ' Salta a la etiqueta “Inicio” (Lazo infinito). End
  • 140.
    130 6.13.- Proyecto #18.A continuación realizaremos la simulación de un control digital de volumen, basados en el diagrama de la figura 6.19. El pulsador “P1” será el encargado de aumentar el nivel de volumen, mientras que el pulsador “P2” será el encargado de disminuir el nivel. Figura 6.19. Proyecto # 18 Componente Cantidad PIC16F877A 1 Cristal de 8 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x2 1 Resistencia de 10K Ohm 2 Potenciómetro de 5K Ohm 1 Pulsador Normalmente Abierto 2 Fuente regulada de 5 Vdc 1 Tabla 6.9.
  • 141.
    131 Las pantallas queveremos representadas en este ejemplo son las mostradas en las figuras 6.20, 6.21, 6.22 y 6.23. Se puede observar en ellas la representación de un pequeño parlante y cuatro rectángulos, encargados de indicar el nivel de volumen. Figura 6.20. Figura 6.21. Figura 6.22. Figura 6.23.
  • 142.
    132 El primer pasoen la elaboración de este ejercicio, es crear las figuras que deseamos mostrar en la pantalla LCD basados en la explicación dada anteriormente: Figura 1: Dato Dato Bytes en la HEX Símbolo Binario CGRAM $02 00000010 $40 $06 00000110 $41 $1A 00011010 $42 $1A 00011010 $43 $1A 00011010 $44 $06 00000110 $45 $02 00000010 $46 $00 00000000 $47 Palabra 0: $02, $06, $1A, $1A, $1A, $06, $02, $00 Figura 2: Dato Dato Bytes en la HEX Símbolo Binario CGRAM $00 00000000 $48 $00 00000000 $49 $00 00000000 $4A $00 00000000 $4B $00 00000000 $4C $00 00000000 $4D $1F 00011111 $4E $1F 00011111 $4F Palabra 1: $00, $00, $00, $00, $00, $00, $1F, $1F
  • 143.
    133 Figura 3: Dato DatoBytes en la HEX Símbolo Binario CGRAM $00 00000000 $50 $00 00000000 $51 $00 00000000 $52 $00 00000000 $53 $1F 00011111 $54 $1F 00011111 $55 $1F 00011111 $56 $1F 00011111 $57 Palabra 2: $00, $00, $00, $00, $1F, $1F, $1F, $1F Figura 4: Dato Dato Bytes en la HEX Símbolo Binario CGRAM $00 00000000 $58 $00 00000000 $59 $1F 00011111 $5A $1F 00011111 $5B $1F 00011111 $5C $1F 00011111 $5D $1F 00011111 $5E $1F 00011111 $5F Palabra 3: $00, $00, $1F, $1F, $1F, $1F, $1F, $1F
  • 144.
    134 Figura 5: Dato DatoBytes en la HEX Símbolo Binario CGRAM $1F 00011111 $60 $1F 00011111 $61 $1F 00011111 $62 $1F 00011111 $63 $1F 00011111 $64 $1F 00011111 $65 $1F 00011111 $66 $1F 00011111 $67 Palabra 4: $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F A continuación analice el siguiente programa, leyendo detenidamente los comentarios: ' Programa en PIC Basic Pro '**************************************** '* Nombre : Proyecto18.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 Define Osc 8 ' Define el Oscilador para un Cristal ' de 8 Mhz.
  • 145.
    135 Symbol P1 =PORTB.0 ' Alias para RB0. Symbol P2 = PORTB.1 ' Alias para RB1. Volumen Var Byte ' Declaración de la variable "Volumen" tipo Byte. Volumen = 1 ' Inicializa la variable “Volumen” con el valor "1". ' A continuación se cargan las cinco figuras creadas a partir de la ' posición cero de la memoria CGRAM: LCDOut $fe, $40, $02, $06, $1A, $1A, $1A, $06, $02, $00 'Figura 1. LCDOut $fe, $48, $00, $00, $00, $00, $00, $00, $1F, $1F 'Figura 2. LCDOut $fe, $50, $00, $00, $00, $00, $1F, $1F, $1F, $1F 'Figura 3. LCDOut $fe, $58, $00, $00, $1F, $1F, $1F, $1F, $1F, $1F 'Figura 4. LCDOut $fe, $60, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F 'Figura 5. LCDOut $fe, 1 ' Limpia la pantalla LCDOut " Volumen: " ' Escribe "Volumen:" en la línea 1 de la pantalla. Inicio: LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut $fe,$C5, 0 ' Muestra la Figura almacenada en la Posición 0 ' de la CGRAM. LCDOut $fe,$C6, 1 ' Muestra la Figura almacenada en la Posición 1 ' de la CGRAM. ' A continuación se verifica si alguno de los pulsadores ha sido activado. ' Si P1 es activado y la variable "Volumen" es menor a cinco, llama a la ' subrutina "SubeVol". ' Si P2 es activado y la variable "Volumen" es mayor a cero, llama a la ' subrutina "BajaVol". If P1 = 1 And Volumen < 5 Then Call SubeVol If P2 = 1 And Volumen > 0 Then Call BajaVol GoTo Inicio ' Salta a la etiqueta "Inicio". SubeVol: Volumen = Volumen + 1 ' Suma 1 al contenido de la variable "Volumen". If Volumen = 2 Then Call Nivel1 If Volumen = 3 Then Call Nivel2 If Volumen = 4 Then Call Nivel3 Return Nivel1: LCDOut $fe,$C7, 2 ' Muestra la Figura almacenada en la Posición dos (2) ' de la CGRAM. Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P1. Return
  • 146.
    136 Nivel2: LCDOut $fe,$C8, 3' Muestra la Figura almacenada en la Posición tres (3) ' de la CGRAM. Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P1. Return Nivel3: LCDOut $fe,$C9, 4 ' Muestra la Figura almacenada en la Posición cuatro (4) ' de la CGRAM. Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P1. Return BajaVol: Volumen = Volumen - 1 ' Resta 1 al contenido de la variable "Volumen". If Volumen = 3 Then Call Borra1 If Volumen = 2 Then Call Borra2 If Volumen = 1 Then Call Borra3 Return Borra1: LCDOut $fe,$C9," " ' Borra la figura colocando un espacio en blanco en la ' posición $C9 de la pantalla LCD. Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P2. Return Borra2: LCDOut $fe,$C8," " ' Borra la figura colocando un espacio en blanco en la ' posición $C8 de la pantalla LCD. Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P2. Return Borra3: LCDOut $fe,$C7," " ' Borra la figura colocando un espacio en blanco en la ' posición $C7 de la pantalla LCD. Pause 350 ' Pausa de 350 milisegundos, mientras se suelta P2. Return End
  • 147.
    137 6.14.- Proyecto #19.Realice el siguiente ejercicio en el cual se podrá visualizar un pequeño caballo que corre a lo largo de la pantalla LCD, como se muestra en las figuras 6.25 y 6.26. El programa ha sido diseñado en base al diagrama esquemático de la figura 6.24: Figura 6.24. Proyecto # 19 Componente Cantidad PIC16F877A 1 Cristal de 8 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x4 1 Potenciómetro de 5K Ohm 1 Fuente regulada de 5 Vdc 1 Tabla 6.10.
  • 148.
    138 A continuación podráver una secuencia numerada de cada una de las pantallas que debe generar el programa propuesto: Figura 6.25.
  • 149.
  • 150.
    140 Un paso fundamentales hacer el diseño de cada figura en una matriz cuadriculada de 8 filas por 5 columnas, como se muestra en la figura 6.27. Figura 6.27. Rellenando los cuadros adecuados podemos llegar a realizar una gran cantidad de figuras, las cuales podrán ser almacenadas en la CGRAM de una pantalla LCD o incluso en la memoria de datos del microcontrolador, para luego ser consultadas y almacenadas en la CGRAM. Una vez hecho el diseño de la figura, procedemos a sacar los datos correspondientes a cada posición en la CGRAM.
  • 151.
    141 Los datos aser almacenados en las ocho posiciones de la CGRAM son los siguientes: Figura 1: Dato Dato Bytes en la HEX Figura A Binario CGRAM $00 00000000 $40 $00 00000000 $41 $10 00010000 $42 $0F 00001111 $43 $0F 00001111 $44 $0D 00001101 $45 $18 00011000 $46 $10 00010000 $47 Palabra 0: $00,$00,$10,$0F,$0F,$0D,$18,$10 Figura 2: Dato Dato Bytes en la HEX Figura B Binario CGRAM $04 00000100 $48 $0E 00001110 $49 $1F 00011111 $4A $1C 00011100 $4B $1C 00011100 $4C $1C 00011100 $4D $06 00000110 $4E $05 00000101 $4F Palabra 1: $04,$0E,$1F,$1C,$1C,$1C,$06,$05
  • 152.
    142 Figura 3: Dato DatoBytes en la HEX Figura C Binario CGRAM $00 00000000 $50 $00 00000000 $51 $10 00010000 $52 $0F 00001111 $53 $0F 00001111 $54 $0D 00001101 $55 $04 00000100 $56 $06 00000110 $57 Palabra 2: $00,$00,$10,$0F,$0F,$0D,$04,$06 Figura 4: Dato Dato Bytes en la HEX Figura D Binario CGRAM $04 00000100 $58 $0E 00001110 $59 $1F 00011111 $5A $1C 00011100 $5B $1C 00011100 $5C $1C 00011100 $5D $08 00001000 $5E $18 00011000 $5F Palabra 3: $04,$0E,$1F,$1C,$1C,$1C,$08,$18
  • 153.
    143 Figura 5: Dato DatoBytes en la HEX Figura E Binario CGRAM $04 00000100 $60 $0E 00001110 $61 $1F 00011111 $62 $07 00000111 $63 $07 00000111 $64 $07 00000111 $65 $02 00000010 $66 $03 00000011 $67 Palabra 4: $04,$0E,$1F,$07,$07,$07,$02,$03 Figura 6: Dato Dato Bytes en la HEX Figura F Binario CGRAM $00 00000000 $68 $00 00000000 $69 $01 00000001 $6A $1E 00011110 $6B $1E 00011110 $6C $16 00010110 $6D $04 00000100 $6E $0C 00001100 $6F Palabra 5: $00,$00,$01,$1E,$1E,$16,$04,$0C
  • 154.
    144 Figura 7: Dato DatoBytes en la HEX Figura G Binario CGRAM $04 00000100 $70 $0E 00001110 $71 $1F 00011111 $72 $07 00000111 $73 $07 00000111 $74 $07 00000111 $75 $0C 00001100 $76 $14 00010100 $77 Palabra 6: $04,$0E,$1F,$07,$07,$07,$0C,$14 Figura 8: Dato Dato Bytes en la HEX Figura H Binario CGRAM $00 00000000 $78 $00 00000000 $79 $01 00000001 $7A $1E 00011110 $7B $1E 00011110 $7C $16 00010110 $7D $03 00000011 $7E $01 00000001 $7F Palabra 7: $00,$00,$01,$1E,$1E,$16,$03,$01
  • 155.
    145 En esta oportunidadpondremos a correr nuestro caballo en la segunda línea de la pantalla, y lo ubicaremos de la siguiente manera: La primera mitad de nuestro caballo estará en la dirección $C0 y la otra mitad estará en la dirección $C1, nos referimos respectivamente a las figuras “A” y “B” de nuestro diseño. Para ver el efecto que deseamos, hacemos una pausa de 300 milisegundos, borramos la pantalla y mostramos las figuras “C” y “D” en las posiciones $C2 y $C3 respectivamente de la pantalla LCD; luego hacemos otra pausa de 300 milisegundos y comenzamos el proceso, solo que esta vez será partiendo desde la dirección $C4. Cuando la figura “D” llegue a la dirección $CF, estaremos listos para repetir todo el proceso de forma inversa con las figuras “E”, “F”, “G” y “H”. Pantalla LCD 16x4 Línea 1 $80 $81 $82 $83 $84 $85 $86 $87 $88 $89 $8A $8B $8C $8D $8E $8F Línea 2 $C0 $C1 $C2 $C3 $C4 $C5 $C6 $C7 $C8 $C9 $CA $CB $CC $CD $CE $CF Línea 3 $90 $91 $92 $93 $94 $95 $96 $97 $98 $99 $9A $9B $9C $9D $9E $9F Línea 4 $D0 $D1 $D2 $D3 $D4 $D5 $D6 $D7 $D8 $D9 $DA $DB $DC $DD $DE $DF Figura 6.28. En la figura 6.28 se pueden observar las direcciones en una pantalla LCD de 16 columnas y 4 filas. Esta tabla de direcciones resulta muy útil al momento de establecer la ubicación de cada figura en cualquiera de las líneas de la pantalla LCD.
  • 156.
    146 Veamos el programaque hace posible esta representación: ' Programa en PIC Basic Pro '**************************************** '* Nombre : Proyecto19.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto en el uC para el ' bus de datos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto D DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RD2 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto D DEFINE LCD_EBIT 3 ' "E" estará conectado en RD3 ' Programa en PIC Basic Pro Define Osc 8 ' Define el Oscilador para un Cristal ' de 8 Mhz. ' Declaración de Variables POS1 var Byte POS2 var Byte POS3 var Byte POS4 var Byte ' Inicializamos las Variables correspondientes a la posición de la figura ' en la pantalla LCD POS1 = $C0 ' Ver figura 6.13 POS2 = $C1 ' POS3 = $C2 ' POS4 = $C3 ' Pause 500 ' Tiempo de inicialización de la Pantalla LCD ' Cargamos las 8 figuras en la CGRAM: LCDOUT $FE,$40,$00,$00,$10,$0F,$0F,$0D,$18,$10 ' Palabra 0 de la CGRAM LCDOUT $FE,$48,$04,$0E,$1F,$1C,$1C,$1C,$06,$05 ' Palabra 1 de la CGRAM LCDOUT $FE,$50,$00,$00,$10,$0F,$0F,$0D,$04,$06 ' Palabra 2 de la CGRAM LCDOUT $FE,$58,$04,$0E,$1F,$1C,$1C,$1C,$08,$18 ' Palabra 3 de la CGRAM LCDOUT $FE,$60,$04,$0E,$1F,$07,$07,$07,$02,$03 ' Palabra 4 de la CGRAM LCDOUT $FE,$68,$00,$00,$01,$1E,$1E,$16,$04,$0C ' Palabra 5 de la CGRAM LCDOUT $FE,$70,$04,$0E,$1F,$07,$07,$07,$0C,$14 ' Palabra 6 de la CGRAM LCDOUT $FE,$78,$00,$00,$01,$1E,$1E,$16,$03,$01 ' Palabra 7 de la CGRAM inicio:
  • 157.
    147 LCDOUT $fe, 1' Limpia la pantalla LCD LCDOUT $FE,POS1, 0 ' Muestra Palabra 0 en la LCD LCDOUT $FE,POS2, 1 ' Muestra Palabra 1 en la LCD Pause 300 LCDOUT $fe, 1 ' Limpia la pantalla LCD LCDOUT $FE,POS3, 2 ' Muestra Palabra 2 en la LCD LCDOUT $FE,POS4, 3 ' Muestra Palabra 3 en la LCD Pause 300 ' Aumentamos la posición de cada símbolo en la pantalla para dar el efecto ' de movimiento: POS1 = POS1 + 3 POS2 = POS2 + 3 POS3 = POS3 + 3 POS4 = POS4 + 3 If POS4 > $CF Then RETRO ' Pregunta si llega al tope derecho de la LCD ' si POS4 = $CF salta a la etiqueta "RETRO" GoTo inicio ' Salta a la etiqueta "inicio" ' Antes de retroceder nos aseguramos de que las figuras E,F,G y H tengan una ' posición inicial en la pantalla LCD: RETRO: POS1 = $CF POS2 = $CE POS3 = $CD POS4 = $CC RETROCEDE: LCDOUT $fe, 1 ' Limpia la pantalla LCD LCDOUT $FE,POS1, 7 ' Muestra Palabra 7 en la LCD LCDOUT $FE,POS2, 6 ' Muestra Palabra 6 en la LCD Pause 300 LCDOUT $fe, 1 ' Limpia la pantalla LCD LCDOUT $FE,POS3, 5 ' Muestra Palabra 5 en la LCD LCDOUT $FE,POS4, 4 ' Muestra Palabra 4 en la LCD Pause 300 ' Disminuimos la posición de cada símbolo en la pantalla para dar el efecto ' de movimiento en sentido contrario: POS1 = POS1 - 3 POS2 = POS2 - 3 POS3 = POS3 - 3 POS4 = POS4 - 3 If POS4 < $C0 Then REINICIA ' Pregunta si llega al tope Izquierdo de la LCD GoTo RETROCEDE ' Nos aseguramos de que las figuras A,B,C y D tengan una posición inicial en la ' pantalla LCD:
  • 158.
    148 REINICIA: POS1 = $C0 POS2= $C1 POS3 = $C2 POS4 = $C3 GoTo inicio ' Se repite el proceso saltando a la etiqueta "inicio" End
  • 159.
    149 Teclado Matricial CapituloVII 7.1.- Teclado Matricial: Para introducir datos de forma manual en un microcontrolador, nada mejor que un teclado matricial para este fin. Los teclados matriciales más comunes son de 3 columnas por 4 filas, y de 4 columnas por 4 filas, como los mostrados en la figura 7.1: Figura 7.1. Figura 7.2.
  • 160.
    150 El principio defuncionamiento de un teclado matricial es muy sencillo. Básicamente cuando pulsamos un botón en el teclado, estamos uniendo una fila con una columna. Por ejemplo, al presionar la tecla “1”, estaremos conectando la columna 1 con la fila 1; si pulsamos la tecla “4”, estaremos conectando nuevamente la columna 1, esta ves con la fila 2; si pulsamos la tecla “9”, entonces estaremos conectando la columna 3 con la fila 3. Existen diversas formas de conectar e interpretar el funcionamiento de un teclado matricial. En el diagrama de la figura 7.3 se puede apreciar un teclado matricial 3x4 conectado a los pines del puerto B, los cuales se han distribuido y configurado de la siguiente manera: Puerto B TrisB Teclado 3x4 RB0 0 (Salida) Columna 1 RB1 0 (Salida) Columna 2 RB2 0 (Salida) Columna 3 RB3 1 (Entrada) Fila 1 RB4 1 (Entrada) Fila 2 RB5 1 (Entrada) Fila 3 RB6 1 (Entrada) Fila 4 RB7 1 (Entrada) Sin Conexión Tabla 7.1. Observe en el diagrama esquemático que los pines RB3, RB4, RB5 y RB6 tienen una resistencia “Pull-up”, lo cual significa que si leemos cualquiera de estas entradas, asumiendo que ninguna tecla ha sido presionada, entonces siempre habrá un uno lógico presente en cada una de ellas.
  • 161.
    151 Figura 7.3. Entonces parasaber si una tecla ha sido presionada, podemos aplicar el siguiente análisis: 1. Enviamos un cero “0” por la columna 1, y enviamos un “1” por las columnas 2 y 3. PORTB.0 = 0 ' Columna 1 = 0 PORTB.1 = 1 ' Columna 2 = 1 PORTB.2 = 1 ' Columna 3 = 1 2. Leemos las filas 1, 2, 3 y 4 para verificar si alguna de ellas cambió su estado a cero “0”. Si esto sucede, quiere decir que una de las teclas en la columna 1 ha sido presionada, entonces: Si PORTB.3 = 0 La tecla "1" fue presionada. Si PORTB.4 = 0 La tecla "4" fue presionada. Si PORTB.5 = 0 La tecla "7" fue presionada. Si PORTB.6 = 0 La tecla "*" fue presionada.
  • 162.
    152 3. Enviamos uncero “0” por la columna 2, y enviamos un “1” por las columnas 1 y 3. PORTB.0 = 1 ' Columna 1 = 1 PORTB.1 = 0 ' Columna 2 = 0 PORTB.2 = 1 ' Columna 3 = 1 4. Leemos las filas 1, 2, 3 y 4 para verificar si alguna de ellas cambió su estado a cero “0”. Si esto sucede, en este caso quiere decir que una de las teclas en la columna 2 ha sido presionada, entonces: Si PORTB.3 = 0 La tecla "2" fue presionada. Si PORTB.4 = 0 La tecla "5" fue presionada. Si PORTB.5 = 0 La tecla "8" fue presionada. Si PORTB.6 = 0 La tecla "0" fue presionada. 5. Enviamos un cero “0” por la columna 3, y enviamos un “1” por las columnas 1 y 2. PORTB.0 = 1 ' Columna 1 = 1 PORTB.1 = 1 ' Columna 2 = 1 PORTB.2 = 0 ' Columna 3 = 0 6. Leemos nuevamente las filas 1, 2, 3 y 4 para verificar si alguna de ellas cambió su estado a cero “0”. Si esto sucede, entonces quiere decir que una de las teclas en la columna 3 ha sido presionada. Si PORTB.3 = 0 La tecla "3" fue presionada. Si PORTB.4 = 0 La tecla "6" fue presionada. Si PORTB.5 = 0 La tecla "9" fue presionada. Si PORTB.6 = 0 La tecla "#" fue presionada. A continuación veremos el algoritmo capaz de leer el teclado matricial conectado al puerto B, y el cual a su vez genera el digito correspondiente a la tecla presionada en un display de 7 segmentos conectado al puerto D.
  • 163.
    153 Observe que eldisplay de 7 segmentos es de ánodo común, lo cual significa que para encender un segmento será necesario enviar un cero “0” a través del pin que corresponda a éste, en el puerto D. ' Programa en PIC Basic Pro Define Osc 8 ' Define el Oscilador para un Cristal ' de 8 Mhz. TRISB = %01111000 ' Configura los pines del puerto B. TRISD = %00000000 ' Configura los pines del puerto D. Inicio: Call Teclado ' Llama a la rutina barrido del teclado matricial. Pause 300 ' Hace una pausa de 300 ms. GoTo Inicio ' Salta a la etiqueta “Inicio”. Teclado: PORTB.0 = 0 ' Columna 1 = 0 PORTB.1 = 1 ' Columna 2 = 1 PORTB.2 = 1 ' Columna 3 = 1 If PORTB.3 = 0 Then PORTD = %11111001 ' tecla "1" If PORTB.4 = 0 Then PORTD = %10011001 ' tecla "4" If PORTB.5 = 0 Then PORTD = %11111000 ' tecla "7" If PORTB.6 = 0 Then PORTD = %10011100 ' tecla "*" PORTB.0 = 1 ' Columna 1 = 1 PORTB.1 = 0 ' Columna 2 = 0 PORTB.2 = 1 ' Columna 3 = 1 If PORTB.3 = 0 Then PORTD = %10100100 ' tecla "2" If PORTB.4 = 0 Then PORTD = %10010010 ' tecla "5" If PORTB.5 = 0 Then PORTD = %10000000 ' tecla "8" If PORTB.6 = 0 Then PORTD = %11000000 ' tecla "0" PORTB.0 = 1 ' Columna 1 = 1 PORTB.1 = 1 ' Columna 2 = 1 PORTB.2 = 0 ' Columna 3 = 0 If PORTB.3 = 0 Then PORTD = %10110000 ' tecla "3" If PORTB.4 = 0 Then PORTD = %10000010 ' tecla "6" If PORTB.5 = 0 Then PORTD = %10011000 ' tecla "9" If PORTB.6 = 0 Then PORTD = %10100011 ' tecla "#" Return End
  • 164.
    154 7.2.- Proyecto #20.En el siguiente proyecto utilizaremos una pantalla LCD 16x2, y un teclado matricial 3x4, conectados según el diagrama esquemático de la figura 7.4. El objetivo de este proyecto será visualizar el valor o símbolo correspondiente a cada una de las teclas. Figura 7.4. Proyecto # 20 - 21 - 22 - 23 Componente Cantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x2 1 Resistencia de 1K Ohm 4 Potenciómetro de 5K Ohm 1 Teclado Matricial 3x4 1 Fuente regulada de 5 Vdc 1 Tabla 7.2.
  • 165.
    155 Utilizaremos la técnicade lectura de teclado mostrada anteriormente para la programación de este proyecto. Realice un análisis detallado del siguiente programa, y compare el algoritmo de lectura del teclado matricial con el algoritmo comentado anteriormente. ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. TRISA = %00000000 ' Configuración del puerto A TRISB = %00000000 ' Configuración del puerto B TRISD = %01111000 ' Configuración del puerto D VAR1 VAR Byte ' Declaramos la Variable VAR1 var1 = 0 ' Inicializamos la variable VAR1 Pause 200 ' Pausa de 200 milisegundos Lcdout $fe, 1 ' Limpia la pantalla Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "* Pantalla LCD *" Lcdout $fe,$C0, "* Teclado Mat. *" PAUSE 3000 ' Pausa de 3 segundos Inicio: Call Teclado Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Tecla Pulsada: " Lcdout $fe,$C0, "--> ",#var1," " GoTo Inicio Teclado: PORTD.0 = 0 ' Columna 1 = 0 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then VAR1 = 1 ' tecla "1" If PORTD.4 = 0 Then VAR1 = 4 ' tecla "4" If PORTD.5 = 0 Then VAR1 = 7 ' tecla "7" If PORTD.6 = 0 Then VAR1 = 10 ' tecla "*" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 0 ' Columna 2 = 0 PORTD.2 = 1 ' Columna 3 = 1
  • 166.
    156 If PORTD.3 =0 Then VAR1 = 2 ' tecla "2" If PORTD.4 = 0 Then VAR1 = 5 ' tecla "5" If PORTD.5 = 0 Then VAR1 = 8 ' tecla "8" If PORTD.6 = 0 Then VAR1 = 11 ' tecla "0" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 0 ' Columna 3 = 0 If PORTD.3 = 0 Then VAR1 = 3 ' tecla "3" If PORTD.4 = 0 Then VAR1 = 6 ' tecla "6" If PORTD.5 = 0 Then VAR1 = 9 ' tecla "9" If PORTD.6 = 0 Then VAR1 = 12 ' tecla "#" Return ' Retorna una línea después del llamado "Call" End
  • 167.
    157 Memoria de DatosCapitulo VIII 8.1.- La Memoria de Datos: La memoria EEPROM de datos resulta muy importante cuando necesitamos almacenar información que no queremos que se pierda al desconectar la energía de nuestros proyectos. La capacidad de esta memoria varía según el modelo de microcontrolador que escojamos, y no todos cuentan con esta característica. Por ejemplo, el PIC16F84 cuenta con una memoria de datos de 64 bytes y el PIC16F877 cuenta con una memoria de datos de 256 bytes. Esta información puede ser verificada directamente en la hoja de características técnicas de cada microcontrolador. Sin embargo, haremos un mapa de memoria de datos para estos dos microcontroladores PIC: 0000: 00 01 02 03 04 05 06 07 0008: 08 09 0A 0B 0C 0D 0E 0F 0010: 10 11 12 13 14 15 16 17 0018: 18 19 1A 1B 1C 1D 1E 1F 0020: 20 21 22 23 24 25 26 27 0028: 28 29 2A 2B 2C 2D 2E 2F 0030: 30 21 32 33 34 35 36 37 0038: 38 39 3A 3B 3C 3D 3E 3F Memoria de Datos PIC16F84 Tabla 8.1. Podemos ver claramente en la tabla de memoria de datos, que tenemos 64 bytes que podemos utilizar para almacenar información, a partir de la posición 00 hasta la posición 3F.
  • 168.
    158 En un microcontroladorPIC16F877 la capacidad de almacenamiento aumenta considerablemente y lo podemos ver en el siguiente mapa: 0000: 00 01 02 03 04 05 06 07 0008: 08 09 0A 0B 0C 0D 0E 0F 0010: 10 11 12 13 14 15 16 17 0018: 18 19 1A 1B 1C 1D 1E 1F 0020: 20 21 22 23 24 25 26 27 0028: 28 29 2A 2B 2C 2D 2E 2F 0030: 30 21 32 33 34 35 36 37 0038: 38 39 3A 3B 3C 3D 3E 3F 0040: 40 41 42 43 44 45 46 47 0048: 48 49 4A 4B 4C 4D 4E 4F 0050: 50 51 52 53 54 55 56 57 0058: 58 59 5A 5B 5C 5D 5E 5F 0060: 60 61 62 63 64 65 66 67 0068: 68 69 6A 6B 6C 6D 6E 6F 0070: 70 71 72 73 74 75 76 77 0078: 78 79 7A 7B 7C 7D 7E 7F 0080: 80 81 82 83 84 85 86 87 0088: 88 89 8A 8B 8C 8D 8E 8F 0090: 90 91 92 93 94 95 96 97 0098: 98 99 9A 9B 9C 9D 9E 9F 00A0: A0 A1 A2 A3 A4 A5 A6 A7 00A8: A8 A9 AA AB AC AD AE AF 00B0: B0 B1 B2 B3 B4 B5 B6 B7 00B8: B8 B9 BA BB BC BD BE BF 00C0: C0 C1 C2 C3 C4 C5 C6 C7 00C8: C8 C9 CA CB CC CD CE CF 00D0: D0 D1 D2 D3 D4 D5 D6 D7 00D8: D8 D9 DA DB DC DD DE DF 00E0: E0 E1 E2 E3 E4 E5 E6 E7 00E8: E8 E9 EA EB EC ED EE EF 00F0: F0 F1 F2 F3 F4 F5 F6 F7 00F8: F8 F9 FA FB FC FD FE FF Memoria de Datos PIC16F877 Tabla 8.2. Guardar y leer datos resulta muy sencillo al trabajar en PicBasic. Este compilador tiene instrucciones muy específicas las cuales estudiaremos a continuación. Si deseamos grabar algunos datos, será necesario saber la posición en la cual estarán almacenados para luego poder ser consultados. La instrucción
  • 169.
    159 en PicBasic paragrabar datos en la memoria de datos EEPROM es “Write” y la estructura de la sentencia es la siguiente: WRITE dirección, dato WRITE Sintaxis: WRITE dirección, variable La instrucción WRITE almacena datos en la memoria EEPROM de un microcontrolador en una dirección específica. Ejemplo: Write $00,1 ' graba el dato o valor “1” en la dirección $00 Write $21,155 ' graba el dato o valor “155” en la dirección $21 Write $A0,VAR1 ' graba el dato almacenado en la variable VAR1, ' en la dirección $A0 Si deseamos leer alguno de los datos almacenados, la instrucción en PicBasic para este fin es “Read”, y la estructura de la sentencia es la siguiente: Read dirección, variable READ Sintaxis: READ dirección, variable La instrucción READ permite leer datos desde la memoria EEPROM de datos de un microcontrolador almacenándolos en una variable previamente definida.
  • 170.
    160 Ejemplo: Read $00, VAR1' lee el dato de la dirección especificada y lo guarda ' en la variable VAR1 Read $21, VAR2 ' lee el dato de la dirección especificada y lo guarda ' en la variable VAR2 Read $A0, VAR3 ' lee el dato de la dirección especificada y lo guarda ' en la variable VAR3 A continuación realizaremos una serie de ejercicios, en los cuales deberán ser aplicados los todos conocimientos adquiridos en los capítulos anteriores. La idea principal en cada proyecto será familiarizarse con el uso de la memoria de datos, almacenando en ella información que deberá poder ser consultada aunque el circuito sea reiniciado o apagado. Como se puede observar en la figura 8.1, se requiere el uso de un teclado matricial 3x4 para el ingreso de datos y una pantalla LCD, con la cual se podrá visualizar toda la información a ser consultada. Figura 8.1.
  • 171.
    161 8.2.- Proyecto #21.En este proyecto vamos a almacenar datos en la memoria EEPROM, para luego ser consultados y mostrados uno por uno en la pantalla LCD. Basados en el diagrama esquemático de la figura 8.1, empezamos el programa asegurando que los puertos A, B y D están configurados de acuerdo a los dispositivos conectados a él: ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. ' Configuración de Puertos: TRISA = %00000000 TRISB = %00000000 TRISD = %01111000 VAR1 VAR Byte ' Declaramos la variable “VAR1” Seguidamente generamos una pausa de 200 milisegundos y damos un mensaje de entrada el cual deberá permanecer durante 3 segundos: Pause 200 ' Pausa de 200 milisegundos Lcdout $fe, 1 ' Limpia la pantalla Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Memoria de Datos" Lcdout $fe,$C0, "****************" Pause 3000 ' Pausa de 3 segundos Para almacenar un dato es necesario especificar una dirección en la memoria de datos. En este ejemplo, veamos a almacenar el valor “1” en la posición de memoria $00; “2” en la posición de memoria $01 y “3” en la posición de memoria $02: Write $00,1 ' Escribe el valor “1” en la posición “$00” Write $01,2 ' Escribe el valor “2” en la posición “$01” Write $02,3 ' Escribe el valor “3” en la posición “$02”
  • 172.
    162 La siguiente subrutinalee el valor almacenado en la dirección $00 y lo muestra en la pantalla LCD, espera tres segundos y lee el segundo valor almacenado en la posición $01, lo muestra en la pantalla LCD y nuevamente hace una pausa de tres segundos. Por último se lee el valor almacenado en la posición $02 y lo muestra en la pantalla LCD durante tres segundos, para luego volver a empezar el proceso de lectura. Inicio: Read $00,VAR1 Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Dirección 00: " Lcdout $fe,$C0, "Dato: ",#VAR1," " Pause 3000 Read $01,VAR1 Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Dirección 01: " Lcdout $fe,$C0, "Dato: ",#VAR1," " Pause 3000 Read $02,VAR1 Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Dirección 02: " Lcdout $fe,$C0, "Dato: ",#VAR1," " Pause 3000 GoTo inicio End Para comprobar que estos datos están en la memoria de datos EEPROM del microcontrolador, también es posible utilizar el programador P16Pro para este fin, desde el cual podemos extraer el contenido completo de la memoria de datos sin problemas, debido a que el software del programador cuenta con una pequeña ventana llamada “Data Memory”, en la cual se pueden ver los datos almacenados como se muestra en la figura 8.2:
  • 173.
    163 Figura 8.2. 8.3.- Proyecto#22. En el ejemplo presentado a continuación se desea almacenar una serie de datos a partir de una dirección específica en la memoria de programa. Se puede experimentar cambiando las direcciones y datos a ser almacenados. Veamos el siguiente programa, el cual está basado en el diagrama de la figura 8.1: ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. ' Configuración de Puertos: TRISA = %00000000 TRISB = %00000000 TRISD = %01111000 I VAR Byte ' Declaramos la Variable I VAR1 var Byte ' Declaramos la Variable VAR1 DIRECCION var Byte ' Declaramos la Variable DIRECCION DATO var Byte ' Declaramos la Variable DATO Pause 200 ' Pausa de 200 milisegundos Lcdout $fe, 1 ' Limpia la pantalla Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Memoria de Datos" Lcdout $fe,$C0, "****************" Pause 3000 ' Pausa de 3 segundos DIRECCION = $00 ' Asignamos una dirección inicial DATO = 1 ' Primer dato que será almacenado
  • 174.
    164 ' Almacenaremos acontinuación 20 datos en 20 direcciones ' consecutivas; los datos a almacenar serán: 1,3,5,7,9,11,13 ' 15,17,19,21,23,25,27,29,31,33,35,37 y 39. For I = 1 To 20 ' ejecuta la subrutina 20 veces Write DIRECCION,DATO ' escribe el dato en la dirección especificada DIRECCION = DIRECCION + 1 ' aumenta en una unidad la posición de la Mem. DATO = DATO + 2 ' aumenta en dos unidades el valor del dato a almacenar. Next I Inicio: DIRECCION = $00 For I = 1 To 20 ' ejecuta la subrutina 20 veces Read DIRECCION,VAR1 ' lee el dato y lo almacena en VAR1 Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Dirección ",#DIRECCION,": " ' muestra la dirección Lcdout $fe,$C0, "Dato: ",#var1," " ' muestra el dato DIRECCION = DIRECCION + 1 ' aumenta en uno la posición de la memoria Pause 2000 ' Pausa de 2 segundos para poder visualizar la información Next I GoTo Inicio ' inicia el proceso de lectura de la memoria de datos End Si apagamos el circuito y leemos la memoria de datos, podremos observar los valores almacenados en el siguiente mapa de la memoria: Figura 8.3. Se puede ver en la figura 8.3 que están almacenados 20 valores (el equivalente de cada valor o dato en hexadecimal).
  • 175.
    165 8.4.- Proyecto #23.En el siguiente ejemplo vamos a utilizar la rutina para el control de un teclado matricial, ya que con ella podremos insertar valores que serán almacenados en la memoria de datos. Analice el siguiente programa, el cual ha sido desarrollado en base al diagrama de la figura 8.1. ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. ' Configuración de Puertos: TRISA = %00000000 TRISB = %00000000 TRISD = %01111000 I VAR Byte ' Declaramos la Variable I VAR1 VAR Byte ' Declaramos la Variable VAR1 DIRECCION VAR Byte ' Declaramos la Variable DIRECCION DATO VAR Byte ' Declaramos la Variable DATO Pause 200 ' Pausa de 200 milisegundos Lcdout $fe, 1 ' Limpia la pantalla Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Memoria de Datos" Lcdout $fe,$C0, "****************" Pause 3000 ' Pausa de 3 segundos DIRECCION = $00 ' Asignamos una dirección inicial Inicio: Lcdout $fe, 1 ' Limpia la pantalla Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout "Direccion: ",#DIRECCION," " Lcdout $fe,$C0, "Dato?: " espera1: Call Teclado If VAR1 = 0 Then espera1 ' Si ninguna tecla fue pulsada salta a “espera1” If VAR1 = 10 Then espera1 ' Si pulsamos la tecla asterisco salta a “espera1” If VAR1 = 11 Then VAR1 = 0 ' Si pulsamos la tecla “0”, entonces VAR1 = 0 If VAR1 = 12 Then espera1 ' Si pulsamos la tecla numeral salta a “espera1” Lcdout $fe,$C0, "Dato?: ",#VAR1," " Write DIRECCION,VAR1 ' Escribe el valor en la memoria de datos DIRECCION = DIRECCION + 1 ' Aumentamos la posición en una unidad Pause 1000 ' Espera 1 segundo para simular un tiempo de grabación
  • 176.
    166 Lcdout $fe,$C0, "DatoAlmacenado" Pause 1000 ' Espera 1 segundo para visualizar el mensaje If DIRECCION = $0F Then Aviso ' Revisa si llegamos al límite asignado por ' el programador en la memoria de datos GoTo inicio Aviso: Lcdout $fe, 1 ' Limpia la pantalla Lcdout $fe, 2 ' Posiciona el cursor en el inicio Lcdout " Memoria llena! " Lcdout $fe,$C0, "****************" Parada: GoTo Parada Teclado: VAR1 = 0 PORTD.0 = 0 ' Columna 1 = 0 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then VAR1 = 1 ' tecla "1" If PORTD.4 = 0 Then VAR1 = 4 ' tecla "4" If PORTD.5 = 0 Then VAR1 = 7 ' tecla "7" If PORTD.6 = 0 Then VAR1 = 10 ' tecla "*" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 0 ' Columna 2 = 0 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then VAR1 = 2 ' tecla "2" If PORTD.4 = 0 Then VAR1 = 5 ' tecla "5" If PORTD.5 = 0 Then VAR1 = 8 ' tecla "8" If PORTD.6 = 0 Then VAR1 = 11 ' tecla "0" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 0 ' Columna 3 = 0 If PORTD.3 = 0 Then VAR1 = 3 ' tecla "3" If PORTD.4 = 0 Then VAR1 = 6 ' tecla "6" If PORTD.5 = 0 Then VAR1 = 9 ' tecla "9" If PORTD.6 = 0 Then VAR1 = 12 ' tecla "#" Return ' Retorna una línea después del llamado "Call" End
  • 177.
    167 Una vez compiladoy puesto a prueba el programa, los valores podrán ser introducidos a la memoria de datos a través del teclado matricial, y el límite de datos a ser grabados será de 16 registros, ya que hemos fijado como límite la dirección “$0F” en la memoria de datos, para luego mostrar un mensaje en la pantalla LCD que nos indicará que hemos llenado cada uno de los 16 registros disponibles. Recuerde que un microcontrolador PIC16F877 tiene una capacidad de memoria de datos de 256 bytes, por lo tanto el límite que hemos fijado en el programa anterior puede ser llevado a su capacidad máxima de ser necesario.
  • 178.
    168 8.5.- Proyecto #24:En el siguiente ejemplo hemos desarrollado un sistema de control de acceso, en el cual el usuario deberá introducir una contraseña previamente almacenada en la memoria de datos. Si la contraseña es correcta, se genera un mensaje de confirmación y sonido (“Beep”). Si la contraseña es incorrecta, se genera un mensaje de error y un sonido intermitente (“Beep, Beep, Beep”). El dispositivo encargado de generar el sonido (Buzzer), se encuentra conectado al pin RC0. Figura 8.4.
  • 179.
    169 Proyecto # 24 ComponenteCantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x2 1 Resistencia de 1K Ohm 4 Potenciómetro de 5K Ohm 1 Teclado Matricial 3x4 1 Transistor 2N3904 1 Buzzer 5 Vdc 1 Fuente regulada de 5 Vdc 1 Tabla 8.3. Antes de empezar a programar, es importante tomar en cuenta cuales serán las posiciones en la memoria de datos para guardar la contraseña. Para un sistema de acceso donde la contraseña será de seis dígitos, y donde cada dígito deberá ser almacenado en una posición específica, convenientemente podemos tomar las posiciones en el mapa de la memoria de datos a partir de la dirección “$10” por ejemplo, hasta la dirección “$15”, como se puede apreciar en la siguiente tabla:
  • 180.
    170 0000: 00 0102 03 04 05 06 07 0008: 08 09 0A 0B 0C 0D 0E 0F 0010: 10 11 12 13 14 15 16 17 0018: 18 19 1A 1B 1C 1D 1E 1F 0020: 20 21 22 23 24 25 26 27 0028: 28 29 2A 2B 2C 2D 2E 2F 0030: 30 21 32 33 34 35 36 37 0038: 38 39 3A 3B 3C 3D 3E 3F 0040: 40 41 42 43 44 45 46 47 0048: 48 49 4A 4B 4C 4D 4E 4F 0050: 50 51 52 53 54 55 56 57 0058: 58 59 5A 5B 5C 5D 5E 5F 0060: 60 61 62 63 64 65 66 67 0068: 68 69 6A 6B 6C 6D 6E 6F 0070: 70 71 72 73 74 75 76 77 0078: 78 79 7A 7B 7C 7D 7E 7F 0080: 80 81 82 83 84 85 86 87 0088: 88 89 8A 8B 8C 8D 8E 8F 0090: 90 91 92 93 94 95 96 97 0098: 98 99 9A 9B 9C 9D 9E 9F 00A0: A0 A1 A2 A3 A4 A5 A6 A7 00A8: A8 A9 AA AB AC AD AE AF 00B0: B0 B1 B2 B3 B4 B5 B6 B7 00B8: B8 B9 BA BB BC BD BE BF 00C0: C0 C1 C2 C3 C4 C5 C6 C7 00C8: C8 C9 CA CB CC CD CE CF 00D0: D0 D1 D2 D3 D4 D5 D6 D7 00D8: D8 D9 DA DB DC DD DE DF 00E0: E0 E1 E2 E3 E4 E5 E6 E7 00E8: E8 E9 EA EB EC ED EE EF 00F0: F0 F1 F2 F3 F4 F5 F6 F7 00F8: F8 F9 FA FB FC FD FE FF Memoria de Datos PIC16F877 Tabla 8.4. Ahora analice detenidamente el siguiente programa tomando en cuenta cada comentario. Notará que la clave que hemos establecido en el programa es una serie de dígitos consecutivos “123456””. También podrá notar que seguimos utilizando la misma rutina para el control del teclado matricial.
  • 181.
    171 ' Programa enPic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. ' Configuración de Puertos: TRISA = %00000000 TRISB = %00000000 TRISD = %01111000 ' Declaramos las variables: X VAR Byte VAR1 VAR Byte DIGITO VAR Byte[7] CLV VAR Byte[7] ' Guardamos cada digito de la clave en las posiciones elegidas previamente: Write 10, 1 ' Primer dígito de la clave Write 11, 2 ' Segundo dígito de la clave Write 12, 3 ' Tercer dígito de la clave Write 13, 4 ' Cuarto dígito de la clave Write 14, 5 ' Quinto dígito de la clave Write 15, 6 ' Sexto dígito de la clave ' Iniciamos el sistema con una bienvenida: Inicio: LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Cont. de Acceso" LCDOut $fe,$C0, "** Bienvenido **" Pause 2000 ' Hacemos una pausa de 2 segundos Call Beep ' Generamos un sonido Clave: X = 0 ' inicializamos la variable X = 0 Read 10, CLV[1] ' leemos el primer dígito y lo guardamos en CLV[1] Read 11, CLV[2] ' leemos el segundo dígito y lo guardamos en CLV[2] Read 12, CLV[3] ' leemos el tercer dígito y lo guardamos en CLV[3] Read 13, CLV[4] ' leemos el cuarto dígito y lo guardamos en CLV[4] Read 14, CLV[5] ' leemos el quinto dígito y lo guardamos en CLV[5] Read 15, CLV[6] ' leemos el sexto dígito y lo guardamos en CLV[6] LCDOut $fe, 1 ' Limpia la LCD LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Introduzca su " LCDOut $fe,$C0, "Clave de Acceso:" Call Beep ' Generamos un sonido
  • 182.
    172 Consulta: Call Teclado 'Consultamos el teclado If VAR1 = 0 Then consulta ' Si no hay una tecla pulsada vuelve a consultar ' Si VAR1 es diferente de cero, significa que pulsamos una tecla, por lo ' tanto generamos un sonido y continuamos… Call Beep ' Generamos un sonido ' Seguidamente lo que hacemos es almacenar ' en seis variables definidas ' por el programador los dígitos introducidos ' desde el teclado matricial ' para luego ser comparados con los valores ' almacenados en la memoria de datos. X = X + 1 DIGITO[X] = VAR1 ' El valor de la tecla pulsada lo ' guardamos en la variable correspondiente If X = 6 Then comprobar ' Si X = 6 estamos guardando en DIGITO[6] ' el último valor introducido desde el ' teclado matricial GoTo consulta ' Si X es diferente de 6 continuamos ' esperando el siguiente valor a ser ' ingresado desde el teclado ' A partir de la siguiente etiqueta empezamos la comprobación, ' y el formato es: ' ' Si DIGITO[X] es igual a CLV[X] el digito es correcto, ' y salta a la etiqueta “paseX”, ' si es diferente salta a la subrutina “error”; veamos… Comprobar: If DIGITO[1] = CLV[1] Then pase1:GoTo error pase1: If DIGITO[2] = CLV[2] Then pase2:GoTo error pase2: If DIGITO[3] = CLV[3] Then pase3:GoTo error pase3: If DIGITO[4] = CLV[4] Then pase4:GoTo error pase4: If DIGITO[5] = CLV[5] Then pase5:GoTo error pase5: If DIGITO[6] = CLV[6] Then correcto:GoTo error ' Si los seis dígitos han sido correctos ' se ejecuta la subrutina correspondiente.
  • 183.
    173 Correcto: Pause 500 LCDOut $fe,1 ' Limpia la LCD LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut " * * * * * * " LCDOut $fe,$C0, "Clave Correcta!" Call beep ' Generamos un sonido Pause 3000 ' Pausa para visualizar el mensaje GoTo inicio Error: Pause 500 LCDOut $fe, 1 ' Limpia la LCD LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut " * * * * * * " LCDOut $fe,$C0, " ERROR! " Call beep ' Generamos un sonido Call beep ' Generamos un sonido Call beep ' Generamos un sonido Pause 1500 ' Pausa para visualizar el mensaje GoTo clave ' Salta a “clave” para nueva oportunidad ' La siguiente subrutina genera un “Beep” en el Buzzer ' conectado en RC0. Beep: High portc.0 ' Estado Lógico Alto para RC0 Pause 100 ' Pausa de 100 milisegundos Low portc.0 ' Estado Lógico Bajo para RC0 Pause 100 ' Pausa de 100 milisegundos Return ' Retorna una línea después del llamado "Call" Teclado: VAR1 = 0 PORTD.0 = 0 ' Columna 1 = 0 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then VAR1 = 1 ' tecla "1" If PORTD.4 = 0 Then VAR1 = 4 ' tecla "4" If PORTD.5 = 0 Then VAR1 = 7 ' tecla "7" If PORTD.6 = 0 Then VAR1 = 10 ' tecla "*"
  • 184.
    174 PORTD.0 = 1' Columna 1 = 1 PORTD.1 = 0 ' Columna 2 = 0 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then VAR1 = 2 ' tecla "2" If PORTD.4 = 0 Then VAR1 = 5 ' tecla "5" If PORTD.5 = 0 Then VAR1 = 8 ' tecla "8" If PORTD.6 = 0 Then VAR1 = 11 ' tecla "0" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 0 ' Columna 3 = 0 If PORTD.3 = 0 Then VAR1 = 3 ' tecla "3" If PORTD.4 = 0 Then VAR1 = 6 ' tecla "6" If PORTD.5 = 0 Then VAR1 = 9 ' tecla "9" If PORTD.6 = 0 Then VAR1 = 12 ' tecla "#" Return ' Retorna una línea después del llamado "Call" End
  • 185.
    175 Interrupciones Capitulo IX 9.1.-¿Qué son las Interrupciones? Las interrupciones son cambios de trayectorias del flujo de un programa causadas por agentes externos de mayor prioridad. Cuando esto ocurre, el microcontrolador detiene el programa en curso, almacena la dirección en la cual se ha detenido y salta a un vector de interrupción previamente definido en el programa. 9.2.- Fuentes de Interrupciones: A continuación mencionaremos cuatro posibles fuentes de interrupción en un microcontrolador PIC16F84: 1. Activación de interrupción por el pin RB0/INT. 2. Desbordamiento del temporizador TMR0. 3. Cambio de estado de uno de los pines más significativos del puerto B (RB4-RB7). 4. Finalización de la escritura en la EEPROM de datos. Estas posibles fuentes de interrupción pueden aumentar en microcontroladores mas avanzados. 9.3.- Registro INTCON: Para aprender a controlar una de estas fuentes de interrupción, debemos estudiar el registro de control de interrupciones “INTCON”, con el cual podremos habilitar el inspector de interrupciones, seleccionar el tipo de interrupción y consultar las banderas de interrupciones. Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 GIE EEIE TOIE INTE RBIE TOIF INTF RBIF Figura 9.1.
  • 186.
    176 GIE: 1 = habilitatodas las interrupciones. 0 = deshabilita las interrupciones. EEIE: 1 = habilita la interrupción por escritura de la EEPROM. 0 = deshabilita la interrupción por escritura de la EEPROM. TOIE: 1 = habilita la interrupción por temporizador TMR0. 0 = deshabilita la interrupción por temporizador TMR0. INTE: 1 = habilita la interrupción por RB0/INT. 0 = deshabilita la interrupción por RB0/INT. RBIE: 1 = habilita la interrupción por puerto B (RB4-RB7). 0 = deshabilita la interrupción por puerto B. TOIF: (Bandera de interrupción por desborde del TMR0) 1 = cuando TMR0 pasa de FFh a 00h. Este bit debe ponerse a cero por software. INTF: (Bandera de interrupción por RB0/INT) 1 = cuando ocurre una interrupción en RB0/INT. Este bit debe ponerse a cero por software. RBIF: (Bandera de interrupción por puerto B) 1 = cuando las entradas RB7 a RB4 cambian de estado. Este bit debe ponerse a cero por software.
  • 187.
    177 9.4.- Activación deinterrupción a través del pin RB0/INT: Para activar esta interrupción, lo primero que debemos tomar en cuenta es la configuración del bit 4 (INTE) del registro INTCON, el cual deberá estar en “1”. Otro paso importante antes de empezar a ejecutar la rutina principal de un programa, será definir el vector de interrupción y habilitar el inspector de interrupciones. Estos pasos se pueden ver claramente en el programa propuesto para el proyecto que presentamos a continuación. 9.5.- Proyecto #25. En el siguiente circuito hemos conectado un diodo LED en el pin RA0, el cual deberá destellar a una frecuencia de 1 Hz. La interrupción ocurre cuando activamos P1, lo cual produce un salto hacia el vector de interrupción, en el cual habrá una rutina encargada de hacer destellar un LED conectado en el pin RA1. Figura 9.2.
  • 188.
    178 Proyecto # 25 ComponenteCantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 LED 2 Resistencia de 220 Ohm 2 Resistencia de 10K Ohm 1 Pulsador Normalmente Abierto 1 Fuente regulada de 5 Vdc 1 Tabla 9.1. Figura 9.3. Lea detenidamente los comentarios en cada línea y analice el funcionamiento del programa y del registro INTCON: ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz.
  • 189.
    179 TRISA = %00000000' Configura el Puerto A como salida TRISB = %00000000 ' Configura el Puerto B como salida I VAR Byte Symbol LED1 = PORTA.0 Symbol LED2 = PORTA.1 Symbol INTEDG = OPTION_REG.6 ' Bit 6 del registro “Option” ' El bit 6 (INTEDG) del registro Option define si la interrupción será ' activada por flanco positivo o negativo. On Interrupt GoTo Interrup ' Define el vector de interrupción. INTCON = %10010000 ' Activa el inspector de interrupciones y ' habilita la interrupción RB0/INT. PORTA = $00 ' Inicializa el puerto A. LED1 = 0 ' Apaga el Led1 LED2 = 0 ' Apaga el Led2 INTEDG = 0 ' Cero (0) para activación de RB0/INT en flanco descendente ' Uno (1) para activación de RB0/INT en flanco ascendente Inicio: LED1 = 1 ' Enciende el Led1 Pause 1000 ' Pausa de 1000 ms (1 segundo) LED1 = 0 ' Apaga el Led1 Pause 1000 ' Pausa de 1000 ms (1 segundo) GoTo Inicio ' Salta a la etiqueta inicio ' Rutina de interrupción: Interrup: Disable ' Detiene al inspector de interrupciones mientras ' ejecuta las siguientes líneas: For I = 1 To 6 LED2 = 1 ' Enciende el Led2 Pause 200 ' Pausa de 200 ms LED2 = 0 ' Apaga el Led1 Pause 200 ' Pausa de 200 ms Next I INTCON = %10010000 ' Habilita las interrupciones (GIE=1) ' Habilita la interrupción RB0/INT (INTE=1) ' Inicializa la interrupción (INTF=0) Enable ' Habilita el inspector de interrupciones. Resume ' GIE = 1 y retorna al punto donde había quedado ' antes de la interrupción. End
  • 190.
    180 9.6.- Interrupción TMR0: Elregistro TMR0 es un contador ascendente de ocho bits, el cual también puede ser configurado como temporizador. Este registro produce una interrupción cuando su conteo pasa de 255 ($FF) a 0 ($00). Cuando esto ocurre, la bandera de interrupción TOIF en el registro INTCON se activa, es decir, TOIF = 1. La Figura 9.4 representa el funcionamiento del registro TMR0: Figura 9.4.
  • 191.
    181 El Bit “TOSE”del registro OPTION, elige el tipo de flanco activo cuando el contador TMR0 es incrementado a través del pin RA4/TOCKI, es decir, determina si el incremento se hará con el flanco de bajada o con el flanco de subida de la señal aplicada. “TOCKI” es una señal generada por un circuito externo aplicada al pin RA4/TOCKI. A través de esta entrada es posible contar el número de pulsos que lleguen a ella, y producir una interrupción por desborde cuando el contador pasa de 255 ($FF) a 0 ($00). Se utiliza cuando deseamos que el registro TMR0 se comporte como contador, y esto es posible configurando el Bit “TOCS” del registro OPTION (TOCS = 1). “FOSC/4” es una señal de reloj interna que genera pulsos que tienen una frecuencia conocida y la cual depende del oscilador principal. FOSC/4 se utiliza cuando queremos que el registro TMR0 se comporte como temporizador, y esto se logra configurando el Bit “TOCS” del registro OPTION (TOCS = 0). “PRESCALER” el un divisor programable de frecuencia el cual se configura seleccionando los bits PS2, PS1 y PS0 (bits menos significativos del Registro OPTION). Para programar el PRESCALER, contamos con una tabla que define los valores del Divisor (ver tabla 9.2). “PSA” asigna el divisor de frecuencias y también puede ser programado a través del bit 3 del registro OPTION. 9.7.- Registro OPTION: Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 RBPO# INTEDG TOCS TOSE PSA PS2 PS1 PS0 Figura 9.5. RBP0#: 1 = resistencias Pull-Up del puerto B activadas. 0 = resistencias Pull-Up del puerto B desactivadas.
  • 192.
    182 INTEDG: (Flanco activode interrupción externa) 1 = activación de la interrupción con flanco ascendente 0 = activación de la interrupción con flanco descendente TOCS: 1 = señal de reloj introducida a través de RA4/TOCKI 0 = señal de reloj interno FOSC/4 TOSE: 1 = incrementa TMR0 con flanco descendente de RA4/TOCKI 0 = incrementa TMR0 con flanco ascendente de RA4/TOCKI PSA: 1 = asigna el divisor de frecuencia a WDT 0 = asigna el divisor de frecuencia a TMR0 PS2,PS1,PS0: PS2 PS1 PS0 Divisor de TMR0 Divisor de WDT 0 0 0 1:2 1:1 0 0 1 1:4 1:2 0 1 0 1:8 1:4 0 1 1 1:16 1:8 1 0 0 1:32 1:16 1 0 1 1:64 1:32 1 1 0 1:128 1:64 1 1 1 1:256 1:128 Tabla 9.2.
  • 193.
    183 9.8.- Proyecto #26.Para dar un ejemplo de aplicación del Registro TMR0 como temporizador, crearemos un programa que haga destellar un Led con una frecuencia de 1 Hz. Este proceso se debe cumplir de la siguiente manera: 1. Encender el Led. 2. Esperar un segundo (1000 milisegundos). 3. Apagar el Led. 4. Esperar un segundo (1000 milisegundos). 5. Repetir todo el proceso. En este punto resulta importante saber cuanto es la temporización máxima que se puede lograr con TMR0. Para esto, será necesario aplicar una fórmula sencilla: Temporización TMR0 = 4 / Fosc x (256 - Valor a cargar en TMR0) x Prescaler Fosc: Depende del Oscilador que usemos, y en este ejemplo utilizamos un cristal de 4 Mhz, por lo tanto Fosc = 4000000. Valor a cargar en TMR0: es el valor desde el cual se inicia el conteo para generar el desborde. En este caso cargaremos cero, para garantizar que cuente los 256 ciclos completos. Prescaler: según la tabla 9.2, el valor máximo para el divisor del TMR0 es 256. Entonces; Temporización TMR0 = (4 / 4000000) x (256 - 0) x (256) Temporización TMR0 = 0,065536 Segundos 65,536 milisegundos Obviamente este tiempo no es suficiente para generar el retardo deseado de 1000 milisegundos, por lo cual proponemos entonces calcular el valor a cargar en el registro TMR0, para un tiempo de desborde de 50 milisegundos, el cual repetiremos 20 veces, dando como resultado un retardo de 1000 milisegundos, es decir, 1 segundo.
  • 194.
    184 Entonces, aplicando laformula tenemos: Temporización TMR0 = (4 / Fosc) x (256 – Valor a cargar en TMR0) x Prescaler 50 ms= (4 / 4000000) x (256 – Valor a cargar en TMR0) x 256 Despejando la incógnita tenemos que: Valor a cargar en TMR0 = 256 – (50ms / (256 x 0,000001)) Valor a cargar en TMR0 = 256 – 195 Valor a cargar en TMR0 = 61 El valor a cargar en el registro TMR0 para que se produzca un desborde cada 50 milisegundos es 61. Realice el montaje correspondiente al diagrama esquemático de la figura 9.6 y analice detenidamente el programa que se muestra a continuación: Figura 9.6.
  • 195.
    185 Proyecto # 26 ComponenteCantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 LED 1 Resistencia de 220 Ohm 1 Fuente regulada de 5 Vdc 1 Tabla 9.3. ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. I var Byte ' Declaración de la variable “I” tipo Byte. On Interrupt GoTo retardo ' Define el vector de Interrupción Symbol TOIF = INTCON.2 ' Alias para el bit 2 del registro INTCON. Symbol GIE = INTCON.7 ' Alias para el bit 7 del registro INTCON. Symbol LED = PORTA.0 ' Alias para el pin RA0 OPTION_REG = %0000111 ' Configuración del Registro OPTION INTCON = %10100000 ' Configuración del Registro INTCON Disable Inicio: High LED ' Enciende el Led Call Retardo ' Llama a la rutina de retardo Low LED ' Apaga el Led Call Retardo ' Llama a la rutina de retardo GoTo Inicio ' Salta a la etiqueta “inicio”. Retardo: For I = 1 To 20 ' Repetimos la interrupción 20 veces para ' obtener un retardo de 1 segundo. Call Retardo1 Next I Return Retardo1: ' Retardo de 50 ms ' TMR0 se desborda cada 50 ms. Para calcular este valor ' Utilizamos la formula: ' Tiempo = 4 x Periodo x Valor a cargar en TMR0 x Valor del Divisor ' El cálculo del dato a cargar en TMR0 es:
  • 196.
    186 ' TMR0 =256 - (0.050/0.000256) = 60,68 = 61 TMR0 = 61 ' Cargamos el dato en TMR0 Espera: If TOIF = 1 Then Reseteo ' pregunta si TOIF es igual a 1, es decir, ' pregunta si TMR0 se desbordo. GoTo Espera ' Salta a la etiqueta “Espera”. Reseteo: TOIF = 0 ' Inicializa la bandera TOIF Return Resume End 9.9.- Interrupción por cambio de estado de uno de los pines más significativos del puerto B (RB4-RB7): Activar la interrupción por cambio de estado en los pines RB4, RB5, RB6 y RB7 es muy sencillo, y lo podemos hacer a través del registro INTCON, donde contamos con un bit llamado RBIE, que activa o desactiva este tipo de interrupción, es decir, podemos configurar este registro de la siguiente manera: Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 GIE EEIE TOIE INTE RBIE TOIF INTF RBIF Figura 9.7. INTCON = %10001000 GIE = 1, con este bit en estado lógico “1”, habilitamos las interrupciones. RBIE = 1, con este bit en estado lógico “1”, habilitamos las interrupciones por cambio de estado en el puerto B.
  • 197.
    187 Es importante tomaren cuenta el registro de configuración del puerto B (TrisB), en el cual debemos configurar los bits más significativos como entrada. TRISB = %1111XXXX, donde las X representan cualquier estado I/O debido a que estos pines no serán utilizados. 9.10.- Proyecto #27. Para verificar el funcionamiento de estas interrupciones, realice el circuito de la figura 9.8. En esta oportunidad el LED conectado en el pin RA0 destella a una frecuencia de 1 Hz. Cuando se produce una interrupción en cualquiera de los pines RB4, RB5 RB6 y RB7, el LED conectado en el pin RA1 destella seis veces a una frecuencia de 1 Hz. Figura 9.8.
  • 198.
    188 Proyecto # 27 ComponenteCantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 LED 2 Resistencia de 220 Ohm 2 Resistencia de 10K Ohm 4 Pulsador Normalmente Abierto 4 Fuente regulada de 5 Vdc 1 Tabla 9.4. En este circuito las entradas RB4, RB5, RB6 y RB7 están normalmente en “0”; para producir una interrupción bastará con activar cualquiera de los pulsadores, para poner un “1” en la entrada correspondiente. ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. TRISA = %00000000 ' Configura el puerto A como salida. TRISB = %11110000 ' Configura los 4 bits más significativos como ' entrada. I VAR Byte ' Declaración de la variable "I" tipo Byte Symbol LED1 = PORTA.0 ' Alias para el pin RA0 Symbol LED2 = PORTA.1 ' Alias para el pin RA1 On Interrupt GoTo Interrup ' Define el vector de interrupción INTCON = %10001000 ' habilita la interrupción RB4-RB7 Inicio: LED1 = 1 ' Enciende el Led 1 Pause 1000 ' Pausa de 1 segundo LED1 = 0 ' Apaga el Led 1 Pause 1000 ' Pausa de 1 segundo GoTo Inicio ' Salta a la etiqueta "Inicio"
  • 199.
    189 Interrup: Disable For I =1 To 6 LED2 = 1 ' Enciende el Led 2 Pause 1000 ' Pausa de 1 segundo LED2 = 0 ' Apaga el Led 2 Pause 1000 ' Pausa de 1 segundo Next I INTCON = %10001000 ' habilita las interrupciones (GIE=1) ' habilita la interrupción RB4-RB7 (RBIE=1) ' Inicializa la interrupción (RBIF=0) Resume Enable End
  • 200.
    190 Memoria Serial I2CCapitulo X 10.1.- ¿Qué es el bus I2C? Se puede definir al Bus I2C como un puente de comunicaciones a dos hilos entre los circuitos integrados de un sistema, desarrollado por la empresa Philips y el cual se ha convertido en un estándar mundial para el control de dispositivos como memorias EEPROM, sensores de temperatura, convertidores A/D y D/A, entre otros dispositivos. La tasa de transferencia de datos llega a niveles que van desde los 100 Khz para un oscilador de 4 Mhz, hasta 400 khz para un oscilador de 20 Mhz. Si deseamos utilizar una taza de transferencia inferior a 100 Khz la siguiente directiva deberá ser definida al inicio del programa: DEFINE I2C_SLOW 1 También es importante mencionar que el bus I2C tiene una capacidad de conexión máxima de carga de 400 pF, que se traduce en aproximadamente 25 dispositivos entre memorias, sensores, convertidores A/D, etc. En el bus I2C es necesario que al menos exista un chip maestro, que en nuestro caso será un microcontrolador. A él podrán conectarse varios dispositivos I2C esclavos a través del bus, donde cada uno de ellos se puede comunicar con el dispositivo maestro, transmitiendo información de un lado a otro. En el bus I2C también puede haber más de un chip maestro, todos con las mismas prioridades. Cada dispositivo I2C cuenta con una única dirección de 7 bits, de tal manera que el microcontrolador podrá saber exactamente a cual de ellos transferir información y a cual de ellos solicitar información en cualquier momento. Los cuatro bits más significativos de esta dirección regularmente siempre estarán fijos y su estado depende del tipo de dispositivo a ser conectado. Por ejemplo, para una memoria EEPROM serial, los cuatro bits mas significativos en la dirección siempre será 1010.
  • 201.
    191 Bit 7 Bit6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 1 0 1 0 A2 A1 A0 R/W Figura 10.1. Los Bits 1, 2 y 3 son programables a través de los pines A0, A1 y A2 (ver figura 10.2), con ellos seleccionamos la dirección de cada memoria EEPROM conectada al Bus: Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 1 0 1 0 A2 A1 A0 R/W Figura 10.2. Figura 10.3. El bit 0 es una bandera que indica el estado actual de la memoria, “lectura” o “escritura”. El Pin WP (Write Protection) debemos conectarlo a tierra (Gnd) si deseamos escribir datos en la memoria. El Pin SDA (Serial Data) es bi-direccional y es utilizado para transferir direcciones y datos a un dispositivo I2C. El Pin SCL (Serial Clock) se utiliza para sincronizar la transferencia de datos y los dispositivos conectados al bus I2C. Las instrucciones de programa en PicBasic para el control del bus I2C son “I2Cread” e “I2CWrite”, con las cuales realizaremos los siguientes proyectos, y
  • 202.
    192 en los cualespodremos almacenar datos y extraer datos de una memoria serial 24LC256. 10.2.- Proyecto #28. En el siguiente ejemplo hemos empleado como dispositivo maestro un microcontrolador PIC16F877, el cual tiene conectado una memoria EEPROM 24LC256, además de una pantalla LCD para visualizar los datos al momento de realizar la lectura de la memoria (figura 10.4). Figura 10.4.
  • 203.
    193 Proyecto # 28- 29 Componente Cantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 22 pF 2 Pantalla LCD 16x2 1 Resistencia de 4,7K Ohm 2 Potenciómetro de 5K Ohm 1 Memoria EEPROM 24LC256 1 Fuente regulada de 5 Vdc 1 Tabla 10.1. I2CWRITE Sintaxis: I2CWrite SDA, SCL, Control, Dirección, [dato], {etiqueta de salto opcional} La instrucción I2CWrite enviará el dato de control y la dirección en la cual se almacenará el dato cargado en la variable previamente cargada. La primera actividad consiste en escribir un dato en una dirección específica de la memoria de datos EEPROM conectada al bus I2C. Analice el siguiente programa: Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Symbol SDA = PORTB.0 ' Alias para RB0 Symbol SCL = PORTB.1 ' Alias para RB1
  • 204.
    194 Direc VAR Word' Declaración de variable "Direc" Control VAR Byte ' Declaración de variable "Control" Dato VAR Byte ' Declaración de variable "Dato" Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Inicio: Control = $A0 ' Dato de Control Direc = $10 ' Dirección en la memoria externa Dato = $23 ' Dato a ser cargado en la dirección ' especificada ($23 = 35 Decimal) I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria Pause 10 ' Pausa de 10 milisegundos LCDOUT $fe, 2, "Dato Grabado" ' Muestra mensaje por la LCD Loop: GoTo Loop End A partir de la etiqueta “Inicio”, asignamos valores a las variables declaradas. El dato de control, el cual contiene la dirección de la memoria 24LC256 es “$A0”; la dirección en la cual vamos a almacenar un dato en este ejemplo será “$10”; y por último el dato a ser almacenado será “$23”. Si se pregunta porqué el dato de control es $A0, podrá obtener la respuesta verificando la conexión de la memoria en el circuito de la figura 10.4. Observe que los pines A2, A1 y A0, los hemos conectado a tierra. Recuerde que estos tres pines definen la dirección del dispositivo; entonces, debemos tomar en cuenta que para una memoria serial, los cuatro bits más significativos están configurados como “1010xxxx”; los tres bits A2, A1 y A0 están conectados a tierra en este proyecto; y el bit R/W debe estar en “0” para poder escribir un dato en la memoria (ver figura 10.5). Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 (A2) Bit 2 (A1) Bit 1 (A0) Bit 0 (R/W) 1 0 1 0 0 0 0 0 A 0 Figura 10.5.
  • 205.
    195 Para enviar eldato a la memoria en la dirección especificada, utilizamos la instrucción I2CWrite de la siguiente manera: I2Cwrite PORTB.0, PORTB.1, $A0, $10, [$23] Note que en el programa utilizamos los alias y las variables: I2Cwrite SDA, SCL, Control, Direc, [dato] Seguidamente se requiere de una pausa de 10 milisegundos, para asegurar el tiempo necesario para la grabación del dato en la memoria. Una vez finalizada la pausa, procedemos a mostrar un mensaje en la pantalla LCD, indicando que el dato ya ha sido grabado. I2CREAD Sintaxis: I2Cread SDA, SCL, Control, Dirección, [dato], {etiqueta de salto opcional} La instrucción I2Cread enviará el dato de control y la dirección específica a un dispositivo conectado a un bus I2C y almacenará el dato obtenido en una variable definida. Al utilizar la etiqueta opcional, el programa saltará si no se recibe ninguna respuesta del dispositivo consultado. Para verificar que este dato en realidad está grabado en la memoria, y en la dirección correcta, veamos el siguiente programa: Define Osc 4 ' Define el Oscilador para un Cristal de 4 Mhz. Symbol SDA = PORTB.0 ' Alias para RB0 Symbol SCL = PORTB.1 ' Alias para RB1 A1 Var Byte ' Declaración de variable "A1" Direc var Word ' Declaración de variable "Direc" Control Var Byte ' Declaración de variable "Control" Pause 200 ' Pause de 200 milisegundos
  • 206.
    196 LCDOut $fe, 1' Limpia la LCD Inicio: Direc = $10 ' Dirección en la memoria externa Control = $A0 ' Dato de Control I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de Memoria LCDOUT $fe, 2,"Dato: ",#A1 ' Muestra el dato leido Ciclo: GoTo Ciclo End 10.3.- Proyecto #29: El siguiente programa almacena datos a partir de la dirección cero ($00) de la memoria EEPROM conectada al bus I2C. Se almacenan números que se incrementan de dos en dos, donde el dato inicial es igual a 1. Este proyecto está basado en el diagrama de la figura 10.4. Analice el siguiente programa: ' Programa en Pic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Symbol SDA = PORTB.0 ' Alias para RB0 Symbol SCL = PORTB.1 ' Alias para RB1 I VAR Byte ' Declaración de variable "I" A1 VAR Byte ' Declaración de variable "A1" Direc VAR Word ' Declaración de variable "Direc" Control VAR Byte ' Declaración de variable "Control" Dato VAR Byte ' Declaración de variable "Dato" Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Direc = $00 ' Dirección en la memoria externa Control = $A0 ' Dato de Control Dato = 1 ' Dato inicial a ser grabado Escribir: For I = 0 To 50 ' Repetición I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria Pause 10 ' Pausa de 10 milisegundos If I = 50 Then leer ' Condicional Direc = Direc + 1 ' Suma 1 a la variable "Direc" Dato = Dato + 2 ' Suma 2 a la variable "Dato" Next I
  • 207.
    197 Leer: LCDOUT $fe, 2,"DatosGrabados" ' Muestra mensaje por la LCD Pause 2000 ' Pausa de 2 segundos LCDOut $fe, 2,"Inicia Lectura" ' Muestra mensaje por la LCD Pause 2000 ' Pausa de 2 segundos Direc = $00 ' Inicializa la dirección en la memoria externa For I = 0 To 50 ' Repetición I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de memoria LCDOUT $fe, 2,"Dato ",#I,": ",#A1," " ' Muestra el dato leido Pause 1000 ' Pausa de 1 segundo If I = 50 Then final ' Condicional Direc = Direc + 1 ' Suma 1 a la variable "Direc" Next I Final: GoTo Final ' Salta a la etiqueta "final" End En caso de requerir mayor capacidad de memoria de datos para nuestros proyectos, podemos utilizar memorias como la 24LC512 o varias de menor o igual capacidad conectadas al bus I2C como se observa en la figura 10.6. Por supuesto, es importante resaltar que cuando se tiene mas de una memoria conectada al bus, se debe considerar el conexionado de los Pines 1, 2 y 3 (A0, A1 y A2 respectivamente). En el programa también debemos tomar en cuenta que para leer cada una de estas memorias, tenemos que especificar la dirección del “dispositivo”.
  • 208.
    198 10.4.- Proyecto #30:Veamos el siguiente programa en el cual se almacenan datos en dos memorias conectadas al bus I2C, para luego ser extraídos y verificados. Figura 10.6. Proyecto # 30 Componente Cantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 22 pF 2 Pantalla LCD 16x2 1 Resistencia de 4,7K Ohm 2 Potenciómetro de 5K Ohm 1 Memoria EEPROM 24LC256 2 Fuente regulada de 5 Vdc 1 Tabla 10.2.
  • 209.
    199 Analice el siguenteprograma, prestando atención a los comentarios de cada línea: Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Symbol SDA = PORTB.0 ' Alias para RB0 Symbol SCL = PORTB.1 ' Alias para RB1 I VAR Byte ' Declaración de variable "I" A1 VAR Byte ' Declaración de variable "A1" Direc VAR Word ' Declaración de variable "Direc" Control VAR Byte ' Declaración de variable "Control" Dato VAR Byte ' Declaración de variable "Dato" Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD memoria1: ' Escribimos en la memoria 1 (Pin A0 = 0; Pin A1 = 0; Pin A2 = 0) ' xxxxAAAx ' xxxx210x Control = %10100000 ' Dato de Control Direc = $00 ' Dirección en la memoria externa Dato = 1 ' Dato inicial a ser grabado For I = 0 To 20 ' Repetición I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria Pause 10 ' Pausa de 10 milisegundos If I = 20 Then confirma1 ' Condicional Direc = Direc + 1 ' Suma 1 a la variable "Direc" Dato = Dato + 2 ' Suma 2 a la variable "Dato" Next I confirma1: LCDOUT $fe, 2,"Datos Grabados" ' Muestra mensaje por la LCD LCDOut $fe,$C0,"Memoria 1 " Pause 2000 ' Pausa de 2 segundos ' Escribimos en la memoria 2 (Pin A0 = 1; Pin A1 = 0; Pin A2 = 0) memoria2: ' xxxxAAAx ' xxxx210x Control = %10100010 ' Dato de Control
  • 210.
    200 Direc = $00' Dirección en la memoria externa Dato = 150 ' Dato inicial a ser grabado For I = 0 To 20 ' Repetición I2Cwrite SDA, SCL, Control, Direc, [dato] ' Escribe la memoria Pause 10 ' Pausa de 10 milisegundos If I = 20 Then confirma2 ' Condicional Direc = Direc + 1 ' Suma 1 a la variable "Direc" Dato = Dato + 5 ' Suma 2 a la variable "Dato" Next I confirma2: LCDOUT $fe, 2,"Datos Grabados" ' Muestra mensaje por la LCD LCDOut $fe,$C0,"Memoria 2 " Pause 2000 ' Iniciamos la lectura en la memoria 1: lectura1: LCDOut $fe, 2,"Inicia Lectura" ' Muestra mensaje por la LCD LCDOut $fe,$C0,"Memoria 1 " Pause 2000 ' Pausa de 2 segundos ' xxxxAAAx ' xxxx210x Control = %10100000 ' Dato de Control Direc = $00 ' Dirección en la memoria externa For I = 0 To 20 ' Repetición I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de memoria LCDOUT $fe, 2,"Dato ",#I,": ",#A1," " ' Muestra el dato leido Pause 1000 ' Pausa de 1 segundo If I = 20 Then lectura2 ' Condicional Direc = Direc + 1 ' Suma 1 a la variable "Direc" Next I lectura2: LCDOut $fe, 2,"Inicia Lectura" ' Muestra mensaje por la LCD LCDOut $fe,$C0,"Memoria 2 " Pause 2000 ' Pausa de 2 segundos ' xxxxAAAx ' xxxx210x Control = %10100010 ' Dato de Control Direc = $00 ' Dirección en la memoria externa For I = 0 To 20 ' Repetición I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de memoria
  • 211.
    201 LCDOUT $fe, 2,"Dato",#I,": ",#A1," " ' Muestra el dato leido Pause 1000 ' Pausa de 1 segundo If I = 20 Then final ' Condicional Direc = Direc + 1 ' Suma 1 a la variable "Direc" Next I final: GoTo final ' Salta a la etiqueta "final" End
  • 212.
    202 Conversor A/D enel PIC16F877 Capitulo XI 11.1.- Conversor A/D. Los microcontroladores de las familias PIC16F87x y PIC18Fxxx de los cuales estaremos hablando a continuación, poseen un convertidor Analógico-Digital que convierte una señal analógica en un número de 8 o 10 bits, según sea la configuración elegida por el diseñador. En los microcontroladores PIC de 28 pines como el PIC16F870, encontraremos que solo poseen 5 entradas para la conversión A/D, y en el caso particular de los microcontroladores de 40 pines como el PIC16F877 o el PIC18F442 por ejemplo, se puede observar que poseen 8 canales para conversión A/D, identificadas por las siglas AN(n), las cuales se encuentran distribuidas entre el puerto A y el puerto E, como se muestra en el diagrama de pines de la figura 11.1: Figura 11.1.
  • 213.
    203 En el microcontroladorPIC16F877, cada canal de conversión A/D está conectado a un pin ubicado en el puerto “A” y en el puerto “E”. Por ejemplo, el canal AN0 corresponde al pin # 2 del microcontrolador, o expresado de otra manera, al pin RA0 del puerto A. El canal AN1 corresponde al pin # 3; el canal AN2 corresponde al pin # 4 y así sucesivamente; entonces se puede ver claramente que el puerto A cuenta con cinco de los ocho canales del conversor A/D, y los otros tres canales están ubicados en los pines correspondientes al puerto E del microcontrolador. Un punto importante a considerar al momento de utilizar el convertidor A/D, será decidir si la conversión se hará configurando el conversor a 8 o 10 bits, con lo cual a su vez estaremos definiendo la resolución en el proceso de conversión. Esto significa que si elegimos la conversión de una señal analógica a solo 8 bits (28 = 256), los valores digitales resultantes de la conversión estarán comprendidos entre 0 y 255 (en binario es de 00000000 hasta 11111111), como se puede observar en la tabla 11.1: Decimal BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 1 0 3 0 0 0 0 0 0 1 1 4 0 0 0 0 0 1 0 0 250 1 1 1 1 1 0 1 0 251 1 1 1 1 1 0 1 1 252 1 1 1 1 1 1 0 0 253 1 1 1 1 1 1 0 1 254 1 1 1 1 1 1 1 0 255 1 1 1 1 1 1 1 1 …………. …………. REGISTRO BAJO (ADRESL) Tabla 11.1.
  • 214.
    204 Cuando la conversiónse hace a 10 bits, la resolución aumenta considerablemente en relación a la de 8 bits, ya que tenemos 210 = 1024 datos de conversión, como se puede observar en la tabla 11.2: Decimal BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 1 0 3 0 0 0 0 0 0 0 0 1 1 4 0 0 0 0 0 0 0 1 0 0 1018 1 1 1 1 1 1 1 0 1 0 1019 1 1 1 1 1 1 1 0 1 1 1020 1 1 1 1 1 1 1 1 0 0 1021 1 1 1 1 1 1 1 1 0 1 1022 1 1 1 1 1 1 1 1 1 0 1023 1 1 1 1 1 1 1 1 1 1 …………. …………. REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH) …………. Tabla 11.2. Para comprender aún mejor este punto, veamos el siguiente ejemplo: Si configuramos el conversor A/D a 8 bits e introducimos una señal cuya amplitud varía entre 0 y 5 voltios, y donde el voltaje de referencia del conversor es 5 voltios, entonces la resolución que obtendremos en la conversión sería la siguiente: Resolución = n Vi 2 max Resolución = 8 2 5V
  • 215.
    205 Resolución = 256 5V Resolución =0.0196 ≈ 0.02 V Esto significa que la resolución a 8 bits para el ejemplo planteado es de 20 mV por cada paso que da el conversor A/D entre 0 y 255. Si configuramos el conversor A/D a 10 bits, entonces tenemos que 210 = 1024, y por lo tanto obtenemos una resolución mayor, lo cual podemos demostrar realizando los cálculos correspondientes: Resolución = n Vi 2 max Resolución = 10 2 5V Resolución = 1024 5V Resolución = 0.00488 ≈ 0.0049 V Entonces la resolución a 10 Bits es de 4.9 mV por cada paso que da el conversor A/D entre 0 y 1023.
  • 216.
    206 Veamos el diagramade bloques del conversor A/D (figura 11.2): Figura 11.2. Resulta interesante saber que se puede obtener más resolución en términos de voltios por paso, si utilizamos un voltaje de referencia menor al de la alimentación del microcontrolador a través de los pines “Ref+” o “Ref-“ según sea el caso. Por ejemplo, si aplicamos un voltaje de referencia positivo igual a 2.5 voltios en el pin RA3/AN3/Ref+ del puerto A, el cual ha sido previamente configurado para esto, entonces: Resolución = n Vi 2 max
  • 217.
    207 Resolución = 10 2 5.2V Resolución = 1024 5.2 V Resolución = 0.00244 ≈ 0.0025 V La resolución del conversor A/D sería de 2.5 mV por cada paso entre 0 y 1023. Hay una serie de pasos que debemos tomar en cuenta para llevar a cabo una conversión A/D, basados en el diagrama de bloques de la figura 11.2: Lo primero, será configurar los canales de entrada que utilizaremos para introducir la señal analógica al conversor A/D y los canales para voltajes de referencia, en el caso de ser necesario. Esto se hace seleccionando la combinación correspondiente en los bits PCFG3, PCFG2 PCFG1 y PCFG0 del registro de control ADCON1 (figura 11.3). Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 ADFM ------ ------ ------ PCFG3 PCFG2 PCFG1 PCFG0 Figura 11.3. En este punto es muy conveniente detenerse a analizar la tabla 11.3, que define cuales pines del puerto A y E serán entradas al conversor A/D, según la combinación elegida.
  • 218.
    208 PCFG3 PCFG2 PCFG1PCFG0 AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 Vref+ Vref- 0 0 0 0 A A A A A A A A Vdd Vss 0 0 0 1 A A A A Vref+ A A A RA3 Vss 0 0 1 0 D D D A A A A A Vdd Vss 0 0 1 1 D D D A Vref+ A A A RA3 Vss 0 1 0 0 D D D D A D A A Vdd Vss 0 1 0 1 D D D D Vref+ D A A RA3 Vss 0 1 1 x D D D D D D D D Vdd Vss 1 0 0 0 A A A A Vref+ Vref- A A RA3 RA2 1 0 0 1 D D A A A A A A Vdd Vss 1 0 1 0 D D A A Vref+ A A A RA3 Vss 1 0 1 1 D D A A Vref+ Vref- A A RA3 RA2 1 1 0 0 D D D A Vref+ Vref- A A RA3 RA2 1 1 0 1 D D D D Vref+ Vref- A A RA3 RA2 1 1 1 0 D D D D D D D A Vdd Vss 1 1 1 1 D D D D Vref+ Vref- D A RA3 RA2 Tabla 11.3. El segundo paso será activar el canal en el cual se encuentra presente la señal analógica para que pase a la etapa de muestreo. La selección de las entradas analógicas se realiza configurando los bits CHS2 (bit 5), CHS1 (bit 4) y CHS0 (bit 3) del registro ADCON0 (figura 11.4): Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE ------ ADON Figura 11.4. CHS2 CHS1 CHS0 Canal/Pin 0 0 0 = Canal 0 (AN0)/RA0 0 0 1 = Canal 1 (AN1)/RA1 0 1 0 = Canal 2 (AN2)/RA2 0 1 1 = Canal 3 (AN3)/RA3 1 0 0 = Canal 4 (AN4)/RA5 1 0 1 = Canal 5 (AN5)/RE0 1 1 0 = Canal 6 (AN6)/RE1 1 1 1 = Canal 7 (AN7)/RE2 Tabla 11.4.
  • 219.
    209 También es posibleseleccionar el canal que deseamos utilizar, con la instrucción de programa ADCin, en la cual sólo se especifica cual será el canal de entrada de la señal a ser convertida y la variable en la cual se almacenará el resultado de la conversión. Por ejemplo: ADCin 0, temperatura Significa que el resultado de la conversión de una señal presente en la entrada “AN0” será almacenado en la variable “temperatura”, la cual ha sido previamente definida en el programa. Aunque la instrucción ADCin se encarga de controlar el registro ADCON0 ahorrando algunas líneas de programa, consideramos conveniente hacer una revisión de los registros de control del conversor A/D. 11.2.- El registro ADCON0: Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE ------ ADON Figura 11.5. Bit 7 y Bit 6: Selección del reloj del conversor A/D. ADCS1 ADCS0 0 0 = Fosc/2 0 1 = Fosc/8 1 0 = Fosc/32 1 1 = FRC Conversión del Reloj Tabla 11.5.
  • 220.
    210 Bit 5, Bit4 y Bit 3: Selección del canal de entrada. CHS2 CHS1 CHS0 Canal/Pin 0 0 0 = Canal 0 (AN0)/RA0 0 0 1 = Canal 1 (AN1)/RA1 0 1 0 = Canal 2 (AN2)/RA2 0 1 1 = Canal 3 (AN3)/RA3 1 0 0 = Canal 4 (AN4)/RA5 1 0 1 = Canal 5 (AN5)/RE0 1 1 0 = Canal 6 (AN6)/RE1 1 1 1 = Canal 7 (AN7)/RE2 Tabla 11.6. Bit 2: Estado de la conversión. GO/DONE: Solo funciona si ADON = 1 1 = Conversión A/D en progreso. 0 = Conversión A/D detenida. Bit 1: Este bit no está implementado. Bit 0: Enciende el conversor A/D. 1 = conversor A/D encendido. 0 = conversor A/D apagado. 11.3.- El registro ADCON1: Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 ADFM ------ ------ ------ PCFG3 PCFG2 PCFG1 PCFG0 Figura 11.6. Bit 7: Justificación del resultado de la conversión a 10 bits a la derecha o izquierda.
  • 221.
    211 1 = Justificaa la derecha. 0 = Justifica a la Izquierda. Bit 6 al Bit 4: No están implementados. Bit3, Bit 2, Bit 1 y Bit 0: Configuración PCFG3 PCFG2 PCFG1 PCFG0 AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 Vref+ Vref- 0 0 0 0 A A A A A A A A Vdd Vss 0 0 0 1 A A A A Vref+ A A A RA3 Vss 0 0 1 0 D D D A A A A A Vdd Vss 0 0 1 1 D D D A Vref+ A A A RA3 Vss 0 1 0 0 D D D D A D A A Vdd Vss 0 1 0 1 D D D D Vref+ D A A RA3 Vss 0 1 1 x D D D D D D D D Vdd Vss 1 0 0 0 A A A A Vref+ Vref- A A RA3 RA2 1 0 0 1 D D A A A A A A Vdd Vss 1 0 1 0 D D A A Vref+ A A A RA3 Vss 1 0 1 1 D D A A Vref+ Vref- A A RA3 RA2 1 1 0 0 D D D A Vref+ Vref- A A RA3 RA2 1 1 0 1 D D D D Vref+ Vref- A A RA3 RA2 1 1 1 0 D D D D D D D A Vdd Vss 1 1 1 1 D D D D Vref+ Vref- D A RA3 RA2 Tabla 11.7. A = Entrada Analógica D = I/O Digital Para definir en un programa si la conversión A/D se hará a 8 bits o a 10 bits, se deben utilizar las siguientes directivas: Conversión a 8 Bits: Define ADC_BITS 8
  • 222.
    212 Esta directiva defineque el resultado de la conversión A/D de una señal, aplicada a cualquiera de los canales, será de 8 bits. Este resultado será almacenado en un registro definido por el fabricante denominado ADRESL. BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 REGISTRO BAJO (ADRESL) Figura 11.7. Conversión a 10 Bits: Define ADC_BITS 10 Cuando realizamos la conversión A/D a 10 bits, el resultado de la conversión se almacena en dos registros, ADRESH y ADRESL, los cuales unidos forman un solo registro de 16 bits, solo que en la parte alta de éste, los 6 bits mas significativos (Bit 2 al Bit 7 de ADRESH, figura 11.8) no son tomados en cuent, es decir, son considerados como “0”. Esto da como resultado que el valor máximo a ser almacenado en él será: 0000001111111111, es decir, 1023. BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 0 0 0 0 0 0 REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH) Figura 11.8. En la conversión a 10 bits también es muy importante considerar el bit 7 (ADFM) del registro de control ADCON1, ya que este bit mantiene el resultado de la conversión de 10 bits justificado, ya sea a la derecha si ADFM = 1, como lo demuestra la figura 11.9, o a la izquierda si ADFM = 0 como lo demuestra la figura 11.10:
  • 223.
    213 BIT 7 BIT6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 0 0 0 0 0 0 REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH) Figura 11.9. BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 0 0 0 0 0 0 REGISTRO BAJO (ADRESL)REGISTRO ALTO (ADRESH) Figura 11.10. Cuando justificamos el resultado de la conversión A/D a la izquierda, el bit menos significativo de éste es el bit 6 del registro ADRESL, y el bit más significativo es el bit 7 del registro ADRESH. Nota: En el proceso de conversión A/D, resulta importante considerar un tiempo mínimo requerido en la etapa de muestreo, necesario para cargar el condensador de mantenimiento “C-Hold” (ver figura 11.2). El tiempo de muestreo se define a través de la siguiente directiva: Define ADC_SAMPLEUS {tiempo} Ejemplo: Define ADC_SAMPLEUS 50
  • 224.
    214 11.4.- Proyecto #31:A continuación presentamos un ejemplo de conversión A/D a 8 bits, el cual consta básicamente de un microcontrolador PIC16F877, un oscilador externo de 10 Mhz, una pantalla LCD para visualizar los resultados, y un potenciómetro de 5Kohm para introducir un voltaje variable en un canal de entrada al conversor A/D. Figura 11.11.
  • 225.
    215 Proyecto # 31 ComponenteCantidad PIC16F877A 1 Cristal de 10 Mhz 1 Capacitor cerámico de 22 pF 2 Pantalla LCD 16x2 1 Resistencia de 220 Ohm 2 Potenciómetro de 5K Ohm 2 Fuente regulada de 5 Vdc 1 Tabla 11.8. ADCin Sintaxis: ADCin canal, Variable Esta instrucción solo es válida para microcontroladores que tienen convertidor A/D, por ejemplo, el PIC16F877, el PIC18F442, el PIC18F452, el PIC18F458 entre otros. Realice el montaje del circuito propuesto en la figura 11.11, y analice cada línea de programa leyendo detenidamente los comentarios. DEFINE OSC 10 ' Define el Oscilador a 10 Mhz DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto (0 o 4) en caso ' de utilizar los cuatro Bits mas significativos de la LCD DEFINE LCD_RSREG PORTB ' Indica al uC que el pin "RS" estará en el Puerto B DEFINE LCD_RSBIT 1 ' "RS" estará conectado en RB1 DEFINE LCD_EREG PORTB ' Indica al uC que el pin "E" estará en el Puerto B DEFINE LCD_EBIT 0 ' "E" estará conectado en RB0 DEFINE LCD_LINES 2 ' Define el número de líneas de la pantalla
  • 226.
    216 DEFINE ADC_BITS 8' Define la conversión A/D a 8 Bits DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS A VAR Byte ' Declaración de una variable tipo Byte (8 bits) ADCON1 = %00000000 ' Configura el registro ADCON1 LCDOut $fe, 1 ' Limpia la LCD Inicio: ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A" LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOUT "C-AD a 8 Bit: " ' Muestra mensaje en la línea 1 LCDOUT $fe,$C0," ",Dec A," " ' Muestra dato en la línea 2 PAUSE 100 ' Pausa de 100 milisegundos GoTo Inicio ' Salta a inicio End En este ejemplo, podemos observar como varía el resultado cargado en la variable “A” al modificar el valor del potenciómetro conectado al canal AN0 del conversor A/D (figura 11.11). Recordemos que la variable “A”, definida al inicio del programa, es del tipo Byte (8 Bits), suficiente para una conversión A/D de 8 Bits. Además es importante observar que hemos seleccionado una configuración en el registro ADCON1, para que todos los canales estén activos y disponibles para una posible solicitud de conversión, y también para que el voltaje de referencia sea el mismo de la fuente de alimentación del circuito. Otro detalle importante es que el resultado de la conversión A/D se muestra en la pantalla LCD en decimal, debido a que se antepone a la variable “A” la directiva “Dec”. El resultado de la conversión también lo podemos ver en binario anteponiendo la directiva “Bin”, o en hexadecimal, anteponiendo la directiva “Hex”. Si deseamos obtener una mayor resolución en la conversión A/D, podemos hacer unos cambios en la configuración del conversor, sin necesidad de modificar el circuito de la figura 11.11.
  • 227.
    217 Esto significa quepodemos configurar el conversor A/D a 10 Bits, lo cual nos lleva a considerar los siguientes cambios: 1. Debemos definir ADC_BITS = 10. 2. La variable en la cual será almacenado el resultado, debe ser del tipo Word (16 Bits), ya que una vez que se desborde el registro ADRESL, se requerirá disponer de más bits, debido a que el resultado para una conversión de 10 bits varía entre 0 y 1023. 3. Debemos recordar justificar el resultado de la conversión A/D a la derecha, configurando el bit 7 del registro ADCON1, es decir, ADFM = 1. 4. El mensaje mostrado en la primera línea de la pantalla LCD deberá ser: “C-AD a 10 Bit:”. Analice el siguiente programa en el cual se pueden observar los cambios antes mencionados: DEFINE OSC 10 ' Define Oscilador a 10 Mhz DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto (0 o 4) en caso ' de utilizar los cuatro Bits mas significativos de la LCD DEFINE LCD_RSREG PORTB ' Indica al uC que el pin "RS" estará en el Puerto B DEFINE LCD_RSBIT 1 ' "RS" estará conectado en RB1 DEFINE LCD_EREG PORTB ' Indica al uC que el pin "E" estará en el Puerto B DEFINE LCD_EBIT 0 ' "E" estará conectado en RB0 DEFINE LCD_LINES 2 ' Define el número de líneas de la pantalla Define ADC_BITS 10 ' Define la conversión A/D a 10 Bits DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS A VAR Word ' Declaración de una variable tipo word (16 bits) ADCON1 = %10000000 ' Configura el registro ADCON1 LCDOut $fe, 1 ' Limpia la LCD Inicio: ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A"
  • 228.
    218 LCDOut $fe, 2' Posiciona el cursor en el inicio LCDOUT "C-AD a 10 Bit: " ' Muestra mensaje en la línea 1 LCDOUT $fe,$C0," ",Dec A," " ' Muestra dato en la línea 2 PAUSE 100 ' Pausa de 100 milisegundos GoTo Inicio ' Salta a inicio End Al modificar el valor del potenciómetro conectado al canal AN0, podemos observar cómo varía el resultado de la conversión en la pantalla LCD entre 0 y 1023. Mueva el potenciómetro hasta obtener un resultado cercano a 512 en la pantalla LCD, y mida con un multímetro el voltaje aplicado en el canal AN0, el cual deberá ser aproximadamente 2,5 voltios, ya que el voltaje de referencia según la configuración elegida en el registro de control ADCON1 es el mismo voltaje que alimenta al circuito, es decir, 5 voltios.
  • 229.
    219 Comunicación Serial Transmisión yRecepción de Datos Capitulo XII 12.1.- Comunicación Serial. En este capítulo nos dedicaremos a estudiar la comunicación serial asíncrona, la cual resulta muy útil cuando necesitamos transmitir o recibir datos entre circuitos gobernados por microcontroladores PIC, o inclusive cuando deseamos establecer una comunicación entre nuestros circuitos y nuestro PC. Las instrucciones en PicBasic para la comunicación serial, se rigen bajo el protocolo de comunicación RS-232, el cual es una norma o estándar mundial que define los parámetros en la comunicación serial. Este protocolo define además estándares como la velocidad de transmisión en baudios (300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200 y 128000 bps), niveles de voltaje, distancia entre dispositivos, entre otros. Cuando se trata de comunicación serial entre un microcontrolador y un PC, es importante tomar en cuenta que los niveles de voltaje entre ambos dispositivos deben ser acoplados, ya que en un puerto serial de un PC, los niveles de voltaje están comprendidos entre +12V y -12V, y en un microcontrolador los niveles de voltaje están comprendidos entre 0V y 5V. Estas y otras características han sido detalladas a lo largo del capítulo a través de algunas recomendaciones y ejemplos. A continuación estudiaremos las instrucciones SerIn y SerOut con las cuales haremos posible la comunicación serial asíncrona entre diversos dispositivos. Estas dos instrucciones son capaces de emular una comunicación RS-232 en cualquier microcontrolador que no posea en su hardware USART (Universal Synchronous / Asynchronous Receiver / Transmitter). 12.2.- Instrucción SerIn: La instrucción SerIn se encarga de recibir uno o mas valores a través de un pin específico, usando el formato asíncrono estándar 8N1 que significa 8 bits de datos, sin revisión de paridad y 1 bit de parada (stop). SerIn trabaja por defecto con un oscilador de 4 Mhz, y para
  • 230.
    220 tener una transferenciade datos segura con otros osciladores de mayor valor, será necesario utilizar la directiva “Define Osc” al inicio del programa. Ejemplo: Define Osc 20 (para un oscilador de 20 Mhz). Sintaxis: SERIN pin, modo,{tiempo, etiqueta}, variable Pin: en este campo definiremos cual será el pin de entrada entre los puertos disponibles del microcontrolador. Ejemplo: PortB.1 Modo: define la velocidad de transmisión en baudios. Valor Numérico Modo Tasa de Bps 0 T2400 2400 1 T1200 1200 2 T9600 9600 3 T300 300 4 N2400 2400 5 N1200 1200 6 N9600 9600 7 N300 300 Tabla 12.1. Ejemplo: Serin PortC.1, 0, variable Velocidad de transmisión: 2400 bps Serin PortA.1, 1, variable Velocidad de transmisión: 1200 bps Serin PortE.0, 2, variable Velocidad de transmisión: 9600 bps Serin PortC.4, 3, variable Velocidad de transmisión: 300 bps El campo “Modo” también puede ser definido como se muestra en la columna 2 de la tabla 12.1, incluyendo la librería MODEDEFS.BAS en el inicio del programa (Include "modedefs.bas"), o utilizando directamente la instrucción “SYMBOL” como se muestra a continuación:
  • 231.
    221 Symbol T2400 =0 ' Dato verdadero (Driven True) Symbol T1200 = 1 ' Dato verdadero (Driven True) Symbol T9600 = 2 ' Dato verdadero (Driven True) Symbol T300 = 3 ' Dato verdadero (Driven True) Symbol N2400 = 4 ' Dato invertido (Driven inverted) Symbol N1200 = 5 ' Dato invertido (Driven inverted) Symbol N9600 = 6 ' Dato invertido (Driven inverted) Symbol N300 = 7 ' Dato invertido (Driven inverted) Tiempo: este campo es opcional al igual que el campo “etiqueta”, y su objetivo es establecer un tiempo en milisegundos definido por el programador, el cual una vez vencido, hará que se realice un salto a la “etiqueta”, también definida por el programador. Ejemplo: Serin PortA.3, 2, 10, inicio, variable Este ejemplo se interpreta de la siguiente forma: el microcontrolador recibe los datos por el pin RA3 a 9600 bps en formato de dato verdadero; si no se reciben datos durante 10 milisegundos, salta a la etiqueta “inicio”; si recibe datos lo almacena en la variable y continúa con el programa. Variable: En este campo se especifica la variable en la cual se desea sean almacenados los datos recibidos. Ejemplo: Serin PortC.7, 4, dato 12.3.- Proyecto #32: En este proyecto vamos a transmitir datos desde un PC hacia un microcontrolador PIC16F877, utilizando un circuito integrado MAX232 entre ambos dispositivos y donde los datos enviados desde el PC serán visualizados en una pantalla LCD. Para enviar datos desde el PC hacia el microcontrolador, explicaremos como realizar un pequeño proyecto en Visual Basic, en el cual haremos un teclado matricial 3x4, que enviará un dato por cada tecla presionada a través del puerto serial COM1. Para ello será necesario construir el circuito de la figura 12.1. Es importante tomar en cuenta en la construcción de este circuito, la polaridad de los
  • 232.
    222 condensadores de 1uF, ya que una polaridad invertida afectará negativamente el funcionamiento del MAX232 (Observe la polaridad de cada condensador en la figura 12.2). Entre los pines 15 (Gnd) y 16 (Vcc) del MAX232 se debe conectar un condensador de 1 uF como se muestra en la figura 12.2, ya que la ausencia de este componente también afectará el funcionamiento del circuito produciendo errores en la recepción de datos. Figura 12.1.
  • 233.
    223 Proyecto # 32 ComponenteCantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 22 pF 2 Pantalla LCD 16x2 1 Resistencia de 220 Ohm 1 Capacitor Electrolítico de uF 5 Conector DB-9M 1 IC MAX232 1 Fuente regulada de 5 Vdc 1 Tabla 12.2. Figura 12.2.
  • 234.
    224 ' Programa enPic Basic Pro Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Symbol T9600 = 2 ' Dato verdadero (Driven True) dato var Byte ' Define la variable “dato” como Byte pause 500 ' Pausa de 500 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD inicio: SerIn PORTC.7, T9600, dato ' espera datos durante 1 ms LCDOUT $fe, 2,"Dato: " LCDOut $fe,$C0,#dato," " GoTo inicio ' Salta a inicio End Como velocidad de transmisión, hemos elegido utilizar 9600 bps, por lo cual debemos definir este valor en nuestro programa. Las señales con las que actúa el puerto del PC son digitales y la tensión con la cual trabaja es +12V y -12V; adicionalmente resulta importante saber que la lógica es invertida, es decir: +12 V Lógica = “0” -12 V Lógica = “1” De ahí la importancia de saber cual será el formato que debemos utilizar a la hora de definir los parámetros para la comunicación (dato verdadero, o dato invertido). En este caso y como se puede observar en la segunda línea de programa (Symbol T9600 = 2), esteremos utilizando el formato “driven true”, debido a que el MAX232 tiene en sus salidas un inversor para los datos provenientes del puerto serial del PC hacia el microcontrolador y vice versa.
  • 235.
    225 Programa en VisualBasic 6.0: Para crear un nuevo proyecto en Visual Basic, hacemos clic en el menú Archivo Nuevo Proyecto y seleccionamos la opción “EXE estándar” (figura 12.3). Figura 12.3. Figura 12.4.
  • 236.
    226 Figura 12.5. Una vezcreado un nuevo proyecto, será importante activar el componente para manejar la comunicación serial “Microsoft Comm Control 6.0”. Esto se realiza haciendo clic en el menú Proyectos Componentes Controles. Figura 12.6.
  • 237.
    227 Al hacer clicen el botón “Aceptar” veremos que en la barra de herramientas aparece un nuevo icono representado por un teléfono. Figura 12.7. Inserte en el formulario el icono “MsComm” como se muestra en la figura 12.8, y configure los siguientes parámetros en la ventana de propiedades: CommPort: 1 (ver figura 12.9) Settings: 9600,n,8,1 (ver figura 12.10) Figura 12.8.
  • 238.
    228 Figura 12.9. Figura12.10. Seguidamente haga doble clic sobre el formulario para visualizar la ventana de código en la cual introduciremos las siguientes líneas de programa, las cuales se encargarán de abrir el puerto serial del PC (Figura 12.11). Figura 12.11.
  • 239.
    229 Utilice el icono“CommandButton” en la barra de herramientas para agregar botones en el formulario: Figura 12.12. Para cambiar el nombre del botón, busque la celda “Caption” en la ventana de propiedades del mismo (ver figura 12.13): Figura 12.13.
  • 240.
    230 Este procedimiento serepite hasta lograr obtener un formulario con 12 botones debidamente identificados como se observa en la figura 12.14: Figura 12.14. El siguiente paso es designar a cada botón la instrucción que se encargará de enviar un dato específico a través del puerto serial del PC. Haga doble clic en el primer botón del formulario y agregue la siguiente línea de comando (ver figura 12.15): MSComm1.Output = Chr$(1) Figura 12.15.
  • 241.
    231 Se repite elpaso anterior para el resto de los botones: Botón #2: MSComm1.Output = Chr$(2) Botón #3: MSComm1.Output = Chr$(3) Botón #4: MSComm1.Output = Chr$(4) Botón #5: MSComm1.Output = Chr$(5) Botón #6: MSComm1.Output = Chr$(6) Botón #7: MSComm1.Output = Chr$(7) Botón #8: MSComm1.Output = Chr$(8) Botón #9: MSComm1.Output = Chr$(9) Botón #10: MSComm1.Output = Chr$(10) Botón #11: MSComm1.Output = Chr$(11) Botón #12: MSComm1.Output = Chr$(12) Por último, haga clic en el botón “Iniciar” (ver figura 12.16), para hacer funcionar el teclado 3x4 desde el cual se enviarán datos hacia el microcontrolador. Al hacer clic en cualquiera de los botones del teclado, estará enviando al microcontrolador el dato correspondiente el cual podrá ser observado en la pantalla LCD de su circuito.
  • 242.
    232 Figura 12.16. Por último,generamos el archivo ejecutable desde el menú Archivo Generar “Nombre del archivo.exe”
  • 243.
    233 12.4.- Instrucción SerOut:La instrucción SerOut en PicBasic se encarga de enviar uno o mas valores a través de un pin específico, usando el formato asíncrono estándar 8N1, que significa 8 bits de datos, sin revisión de paridad y 1 bit de parada (stop). Sintaxis: SEROUT pin, modo, [variable] Pin: en este campo definiremos cual será el pin de salida entre los puertos disponibles del microcontrolador. Ejemplo: PortB.5 Modo: define la velocidad de transmisión en baudios y emplea la misma tabla de la instrucción Serin (Tabla 12.1). Variable: En este campo se especifica la variable que contiene los datos que serán enviados a través de pin especificado. Ejemplo: SerOut PORTC.6, T9600, [variable] 12.5.- Proyecto #33: Comenzaremos por realizar el circuito de la figura 12.17, el cual será conectado al PC a través del puerto serial COM1, y a través del HyperTerminal de Windows veremos como son transmitidos los datos desde el microcontrolador hasta el PC. Veamos el siguiente programa en PBP: Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Symbol T9600 = 2 ' Dato verdadero (Driven True) I VAR Byte ' Define la variable “I” como Byte inicio: For I = 0 To 9 ' Repetición de 0 a 9 SerOut PORTC.6, T9600, [#I] ' Envía los datos a través del pin RC6 pause 1000 ' Pausa de 1 segundo Next I
  • 244.
    234 GoTo inicio 'Salta a inicio End Podemos ver en el programa anterior como es enviado el contenido de la variable “I”, la cual incrementa su valor de cero a nueve, dato que sale en formato serial asíncrono a través del Pin RC6 a 9600 bps. Figura 12.17.
  • 245.
    235 Proyecto # 33 ComponenteCantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 22 pF 2 Capacitor Electrolítico de uF 5 Conector DB-9M 1 IC MAX232 1 Fuente regulada de 5 Vdc 1 Tabla 12.3. En caso de no disponer de un MAX232 para el acople entre el microcontrolador y el puerto serial del PC, también se pueden utilizar dos resistencias limitadoras de corriente, como se muestra en el diagrama de la figura 12.18. Figura 12.18.
  • 246.
    236 Deberá tomar encuenta entonces, que los parámetros de comunicación cambian, debido a que los datos ya no pasarán a través del inversor integrado en el MAX232. Esto significa que el programa a utilizar para el circuito de la figura 12.18 es el siguiente: Define Osc 4 ' Define el Oscilador para un Cristal ' de 4 Mhz. Symbol N9600 = 6 ' Dato invertido (Driven inverted) dato var Byte ' Define la variable “dato” como Byte I var Byte ' Define la variable “I” como Byte Inicio: For I = 0 To 9 ' Repetición de 0 a 9 SerOut PORTC.6, N9600, [#I] ' envía los datos a través del pin RC6 Pause 1000 ' Pausa de 1 segundo Next I GoTo Inicio ' Salta a inicio End Para abrir el HyperTerminal de Windows, haga clic en el menú Inicio Todos los Programas Accesorios Comunicaciones HyperTerminal. Escriba un nombre para la conexión y haga clic en “Aceptar”.
  • 247.
    237 Figura 12.19. Normalmente elpuerto disponible para la comunicación serial es el COM1. Seleccione el puerto disponible en su PC para realizar la prueba de transmisión y luego haga clic en el botón “Configurar” (figura 12.20).
  • 248.
    238 Figura 12.20. En lafigura 12.21 se observan los campos en los cuales se pueden establecer los parámetros para la comunicación serial, los cuales deben coincidir con los parámetros seleccionados para la instrucción SerOut. Figura 12.21.
  • 249.
    239 También es convenientetomar en cuenta en la configuración de la conexión, el tipo de emulación (figura 12.22). Figura 12.22. Finalmente, al aceptar todos estos cambios en la ventana de configuración del HyperTerminal de Windows, podremos ver la siguiente ventana (figura 12.23), en la cual se recibirán los datos enviados desde el microcontrolador. Una vez conectada la alimentación del circuito, el microcontrolador empezará a enviar los datos desde cero hasta nueve, con intervalos de tiempo de un segundo.
  • 250.
    240 Figura 12.23. 12.6.- Proyecto#34: En base a los conocimientos adquiridos hasta ahora, realizaremos a continuación un circuito capaz de medir un voltaje variable aplicado a una de las entradas del conversor A/D de un PIC16F877A, el cual a su vez deberá enviar el resultado de la conversión en decimal a una pantalla LCD, y enviar este mismo resultado a un PC, a través del puerto serial donde los datos serán recibidos y “convertidos”, en una hoja de cálculo (Excel), para posteriormente graficar el conjunto de datos de una muestra de diez lecturas acumuladas. Antes de iniciar con la programación, será importante considerar los siguientes puntos: • La conversión A/D será a 10 Bits, por lo cual debemos tener presente realizar esta definición, es decir, Define ADC_BITS 10.
  • 251.
    241 • La pantallaLCD estará conectada en el puerto “D”, por lo cual será necesario definir los pines de la misma al inicio del programa. Figura 12.24.
  • 252.
    242 Proyecto # 34 ComponenteCantidad PIC16F877A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 33 pF 2 Pantalla LCD 16x2 1 Resistencia de 220 Ohm 1 Capacitor Electrolítico de uF 5 Conector DB-9M 1 IC MAX232 1 Potenciómetro de 5K Ohm 1 Fuente regulada de 5 Vdc 1 Tabla 12.4. Programa en Pic Basic Pro: '**************************************** '* Nombre : Proyecto34.pbp * '* Autor : Nombre del Autor * '* Copyright : Copyright (Año) * '* Fecha : Fecha * '* Versión : 1.0 * '**************************************** DEFINE OSC 4 ' Define Oscilador a 4 Mhz DEFINE LCD_DREG PORTD ' Indica que el Bus estará conectado en el Puerto D DEFINE LCD_BITS 4 ' El bus será de cuatro bits. DEFINE LCD_DBIT 4 ' Selección del Bit de inicio del puerto (0 o 4) en caso ' de utilizar los cuatro Bits mas significativos de la LCD DEFINE LCD_RSREG PORTD ' Indica al uC que el pin "RS" estará en el Puerto B DEFINE LCD_RSBIT 2 ' "RS" estará conectado en RB1 DEFINE LCD_EREG PORTD ' Indica al uC que el pin "E" estará en el Puerto B DEFINE LCD_EBIT 3 ' "E" estará conectado en RB0 DEFINE LCD_LINES 2 ' Define el número de líneas de la pantalla Symbol T9600 = 2 ' Dato verdadero (Driven True) Define ADC_BITS 10 ' Define la conversión A/D a 10 Bits DEFINE ADC_SAMPLEUS 50 ' Tiempo de muestreo en el conversor A/D es 50 uS A VAR Word ' Declaración de una variable tipo word (16 bits)
  • 253.
    243 ADCON1 = %10000000' Configura el registro ADCON1 LCDOut $fe, 1 ' Limpia la LCD inicio: ADCIN 0, A ' Inicia la conversión, almacena el resultado en "A" LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOUT "C-AD a 10 Bit: " ' Muestra mensaje en la línea 1 LCDOUT $fe,$C0,"Dato: ",Dec A," " ' Muestra dato en la línea 2 SerOut PORTC.6, T9600, [#A] ' envía los datos al PC pause 500 ' Pausa de 500 milisegundos GoTo inicio ' Salta a inicio End En el programa se puede observar cómo hemos definido el conexionado de la pantalla LCD, así como también la configuración básica establecida para el conversor A/D, el cual hará la conversión a 10 bits con el fin de obtener una mayor resolución en el proceso de medición del voltaje aplicado al pin RA0. Una vez iniciada la conversión, se puede observar que el resultado de la misma es almacenada en la variable “A”, la cual hemos declarado como una variable de 16 bits (word), debido a que el resultado de la conversión requiere mas de ocho bits de datos. Este resultado puede ser mostrado fácilmente en la pantalla LCD en decimal anteponiendo la directiva “Dec” a la variable en la cual hemos almacenado el dato resultado de la conversión. El siguiente paso en el programa consiste en enviar el dato obtenido al PC a través del puerto serial, para luego hacer una pequeña pausa de 500 milisegundos y empezar nuevamente el proceso para una nueva lectura. Un paso importante en este punto, una vez obtenido el resultado de la conversión A/D en la pantalla LCD, será verificar la transferencia de datos hacia el PC con la ayuda del HyperTerminal de Windows.
  • 254.
    244 Para esto debemosconectar el cable serial entre el circuito y el PC, desde la cual realizaremos una nueva conexión con el HyperTerminal, como se muestra en figura 12.25: Figura 12.25. En este punto solo debemos dar un nombre a la conexión y configurar el puerto con el cual estaremos trabajando como se muestra a continuación:
  • 255.
    245 Figura 12.26. Figura 12.27. Esimportante recordar que la configuración del puerto en el PC debe coincidir con la configuración elegida para el microcontrolador PIC. Una vez configurado el HyperTerminal de Windows, se podrán observar los datos en la ventana, los cuales estarán llegando cada 500 milisegundos, tiempo definido
  • 256.
    246 anteriormente en elprograma que hemos cargado en el microcontrolador PIC (figura 12.28). Figura 12.28. Después de verificar la correcta recepción de datos desde el HyperTerminal, se debe asegurar de cerrar esta ventana (Figura 12.28) para garantizar la disponibilidad del puerto serial. La idea principal de esta práctica, será llevar estos datos a una hoja de Excel, en la cual podamos realizar los cálculos para expresar estos valores en sus equivalentes en voltios para luego tomar una muestra significativa y graficarlos como se observa en la figura 12.29.
  • 257.
    247 Figura 12.29. El primerpaso para configurar la hoja de Excel, será ubicar las herramientas de Visual Basic y agregar a la hoja de cálculo el control “Microsoft communications control, Version 6.0”. Para esto debemos seguir los siguientes pasos:
  • 258.
    248 1.- Al abrirla hoja de cálculo, podemos ver un menú de opciones en la parte superior de la ventana denominado “Herramientas”. Haga clic en el menú “Herramientas” y seleccione la opción “Personalizar”. Figura 12.30. Al seleccionar esta opción podrá observar que en la ventana “Personalizar” hay tres fichas de configuración. Seleccione la ficha “Barra de herramientas” como se muestra en la figura 12.31.
  • 259.
    249 Figura 12.31. En estaficha encontrará una serie de opciones disponibles, de las cuales deberá seleccionar “Visual Basic”. Haga clic en al botón “Cerrar” y verá que aparece en la hoja de cálculo una caja de herramientas nueva llamada “Visual Basic” (Figura 12.32), la cual podemos trasladar a la parte superior de la hoja de cálculo, la cual contiene el resto de las herramientas típicas usadas en Excel (Figura 12.33).
  • 260.
  • 261.
    251 Figura 12.33. Haga clicen el botón “Cuadro de controles” (figura 12.33), y desplace la caja de herramientas nuevamente a la parte superior de la hoja de cálculo junto con el resto de herramientas comunes de Excel (Figura 12.34).
  • 262.
    252 Figura 12.34. En estaserie de botones, podemos encontrar uno denominado “Mas controles” (ver Figura 12.35), el cual despliega una lista de opciones. Ubique el siguiente control: “Microsoft communications control, Version 6.0”. Al hacer doble clic en este control la lista de opciones desaparece y es en este momento en el cual debemos agregar el mismo sobre la hoja de cálculo. Para esto, debe mantener el botón izquierdo del mouse activado y arrastrar el
  • 263.
    253 puntero hasta queaparezca un pequeño recuadro. Al soltar el botón izquierdo el control aparece sobre la hoja. La figura de un Teléfono sobre un “MODEM” lo identifica claramente, como se muestra en la figura 12.35. Figura 12.35. El siguiente paso será agregar un botón en el cual se configura el código necesario para la apertura del puerto serial en el PC (Figura 12.36).
  • 264.
    254 Figura 12.36. Al hacerdoble clic sobre el nuevo botón, estamos entrando al editor de Visual Basic, en el cual podemos agregar las siguientes líneas de programa, las cuales permitirán abrir el puerto al hacer clic sobre el botón que hemos agregado para tal fin: Private Sub CommandButton1_Click() 'abre el puerto de comunicación If Hoja1.MSComm1.PortOpen = False Then Hoja1.MSComm1.PortOpen = True End If End Sub Observe la figura 12.37, en la cual se puede ver el campo “Caption”, correspondiente a la etiqueta del botón de comando que estamos configurando, la cual podemos personalizar con un nombre adecuado como “Abrir Puerto” o “Abrir Comm1”.
  • 265.
    255 Figura 12.37. En figura12.37 también podemos apreciar las líneas de programación agregadas al botón de comando, y el icono que nos permitirá regresar a la hoja de cálculo para continuar con la programación. Al regresar a la hoja de cálculo podremos notar el cambio en la etiqueta del botón de comando, como se muestra en la figura 12.38:
  • 266.
    256 Figura 12.38. Ahora solonos queda configurar el evento OnComm, relativo a la recepción de datos, haciendo doble clic sobre el control de comunicaciones (figura 12.39): Figura 12.39.
  • 267.
    257 Veremos a continuaciónla ventana del editor de Visual Basic (Figura 12.40): Figura 12.40. Recordemos que para almacenar datos en una variable, es importante considerar la declaración de la misma antes de ejecutar cualquier otra línea de programa que así la requiera. Es por esto que para este ejemplo, el primer
  • 268.
    258 paso en laconfiguración del control de comunicaciones ha sido la declaración de dos variables, las cuales hemos denominado “Apuntador” y “datainput”. La variable “Apuntador” será declarada como “Byte” y la variable “datainput” será declarada como “String”. Analice el uso de la variable “Apuntador” en el código del evento OnComm, el cual detallamos unas líneas más adelante. Esta variable se usa básicamente como acumulador y determina la posición en un rango predeterminado de las filas en la hoja de cálculo. Esto se debe a que estamos interesados en mantener una muestra de los diez últimos valores capturados en el puerto para poder realizar una gráfica de líneas suavizadas, la cual se estará actualizando cada 500 milisegundos. Para almacenar un dato presente en el puerto serial (Comm1), utilizamos el comando “MSComm1.Input”, entonces, para almacenar un dato en la variable “datainput”, debemos realizar el siguiente arreglo: datainput = MSComm1.Input Luego para llevar el dato almacenado en la variable a una celda en la hoja de cálculo, podemos utilizar el siguiente comando: Hoja1.Cells(Fila, Columna) Un punto importante a considerar es que la variable “datainput” por estar declarada como “String”, almacenará una serie de datos consecutivos uno tras otro. Podemos extraer un dato de la cadena de caracteres almacenada en la variable “datainput” de la siguiente manera: Hoja1.Cells(Fila, Columna) = Mid(Variable, Bit de inicio, longitud) Ejemplo: Si datainput = 643645650681701718745776 Para extraer los tres primeros caracteres y llevarlos por ejemplo a la celda (40,2) debemos hacer el siguiente arreglo:
  • 269.
    259 Hoja1.Cells(40, 2) =Mid(datainput, 1, 3) Para mantener este dato y capturar uno mas actualizado, simplemente debemos hacer un arreglo para desplazar el contenido de la celda (40,2) a la celda (39,2). Cuando llegue el próximo dato actualizado, el contenido de esta celda deberá pasar a la celda (38,2) y así sucesivamente. Al repetir el desplazamiento de celdas diez veces, podremos tomar estos valores y graficarlos en la hoja de cálculo. Veamos a continuación el código para el evento OnComm: Private Sub MSComm1_OnComm() 'Declara variable Dim Apuntador As Byte Dim datainput As String datainput = MSComm1.Input For Apuntador = 30 To 40 Hoja1.Cells(Apuntador, 2) = Hoja1.Cells(Apuntador + 1, 2) Next Hoja1.Cells(40, 2) = Mid(datainput, 1, 4) End Sub
  • 270.
    260 Figura 12.41. Analice cuidadosamenteel contenido del código en el evento OnComm. Verifique la rutina encargada de apilar los datos entre las celdas (40,1) y (30, 1). Por último, analice la extracción de datos de la cadena de caracteres almacenada en la variable “datainput”. Completados todos estos pasos, lo siguiente será volver a la hoja de cálculo y salir del modo de diseño, haciendo clic en el icono señalado en la siguiente figura:
  • 271.
    261 Figura 12.42. Cuando sesale del modo de diseño, el control de comunicaciones desaparece de la hoja de cálculo. Ahora, haciendo clic en el botón “Abrir Comm1” y activando el circuito, podremos ver que aparecen los datos de la conversión A/D del microcontrolador en la pantalla LCD y en la hoja de cálculo, específicamente en las celdas B40, B39, B38, B37, B36, B35, B34, B33, B32, B31 y B30. En la figura 12.43 se pueden ver unos datos de prueba almacenados en las celdas anteriormente mencionadas. Estos datos pueden ser identificados poniendo un nombre o encabezado en la celda B29, por ejemplo, podemos escribir la palabra “Lecturas: “. En la columna C de la hoja de cálculo, haremos la conversión de datos para expresar los valores obtenidos en Voltios. Para esto aplicaremos la siguiente formula en las celdas C40, C39, C38, C37, C36, C35, C34, C33, C32, C31 y C30: • =(B40*5)/1024 para la celda C40 • =(B39*5)/1024 para la celda C39 • =(B38*5)/1024 para la celda C38 • =(B37*5)/1024 para la celda C37
  • 272.
    262 • =(B36*5)/1024 parala celda C36 • =(B35*5)/1024 para la celda C35 • =(B34*5)/1024 para la celda C34 • =(B33*5)/1024 para la celda C33 • =(B32*5)/1024 para la celda C32 • =(B31*5)/1024 para la celda C31 • =(B30*5)/1024 para la celda C30 Figura 12.43.
  • 273.
    263 Figura 12.44. Observe enla figura 12.44, la formula para la celda C40. Observe también que hemos ocultado una serie de filas de la hoja de cálculo, las cuales hemos reservado para agregar un gráfico de líneas suavizadas. Para graficar esta serie de datos, seleccionamos las diez celdas (desde la celda C30 hasta la celda C40) y hacemos clic en el icono “Asistente para Gráficos” (Figura 12.45), donde aparecerá una ventana en la cual podremos elegir el tipo de gráfico que deseamos utilizar. Seleccione la ficha “Tipos personalizados” y haga clic en la opción “Líneas suavizadas” de la lista (Figura 12.46).
  • 274.
  • 275.
    265 En la siguienteventana podemos ver el rango de datos que será graficado (Figura 12.47): Figura 12.47. Si se desea personalizar aún mas el gráfico, se puede hacer en la ficha “Serie”, en cual es posible editar el recuadro que contiene la leyenda. En la siguiente ventana encontraremos una serie de fichas con una gran variedad de opciones que nos permitirán añadir detalles como el título del gráfico, identificar los ejes, agregar líneas de división, y algunos otros detalles útiles para mejorar la apariencia del gráfico. (figura 12.48).
  • 276.
    266 Figura 12.48. Seguidamente, podemosseleccionar si el gráfico será colocado en una hoja nueva, o en la hoja de cálculo en la cual hemos estado trabajando (figura 12.49): Figura 12.49. Finalmente podremos ver en la hoja de Excel los datos enviados desde el microcontrolador, los cuales a su vez serán graficados constantemente, como se puede observar en la figura 12.50.
  • 277.
  • 278.
    268 Servomotores Capitulo XIII 13.1.-¿Qué es un Servomotor? Un servomotor es un dispositivo electromecánico capaz de rotar su eje a una posición específica a lo largo de su recorrido, inyectando un tren de pulsos controlados, a un circuito de control que posee dentro de su caja o chasis. Esta señal se introduce a través de un cable de control que se distingue entre los tres cables que posee y que según la marca del servomotor puede ser de color blanco o amarillo. Los cables de alimentación se distinguen por sus colores rojo (Positivo) y negro (Negativo). Un servomotor estándar tiene dimensiones muy apropiadas para realizar proyectos de robótica, y aunque se pueden encontrar en diferentes tamaños, es importante resaltar que la fuerza de un servo en su eje no es directamente proporcional al tamaño del mismo. Esto significa que su fuerza depende en gran sentido de su diseño interior, es decir, de la mecánica y material que componen sus engranajes. Veamos a continuación algunas características técnicas importantes en un servomotor estándar: Control: Control por ancho de pulso. Pulso: 3-5 Voltios Pico a Pico. Voltaje de operación: 4.8 a 6.0 Voltios.
  • 279.
    269 Torque (4.8V): 3.0kg/cm (42 oz/in) Torque (6.0V): 4.5 kg/cm (48.60 oz/in) Rango de Temperatura Operacional: -20 a +60 ºC. Velocidad (4.8V): 0.19sec/60 grados. Velocidad (6.0V): 0.15sec/60 grados. Corriente (4.8V): 7.4mA activo y 160mA al aplicar fuerza. Corriente (6.0V): 7.7mA activo y 180mA al aplicar fuerza. Figura 13.1. Para controlar la posición del eje de un servomotor, hace falta enviar un tren de pulsos, donde el ancho de cada pulso determina el punto en el cual el eje mantiene su posición, siempre y cuando esté presente el tren de pulsos. El recorrido será en la mayoría de los modelos de 180º y los tiempos correspondientes al pulso en la señal para las posiciones principales (0º, 90º y
  • 280.
    270 180º) se especificanen la tabla 13.1. (Estos tiempos pueden variar de acuerdo al modelo y marca del servomotor). Tabla 13.1. Entonces, si deseamos llevar el eje a 0º, se deben introducir al servo pulsos de 0.6 milisegundos (T1) aproximadamente, cada 20 milisegundos, como se muestra en la figura 13.3. T2 corresponde por consiguiente al tiempo que debemos esperar para enviar un nuevo pulso, el cual mantiene actualizada la posición de eje. El tiempo T2 puede estar dentro del rango 10 ms ≤ T2 ≤ 40 ms. Figura 13.3.
  • 281.
    271 A medida queaumentamos gradualmente el tiempo T1, el eje del servomotor se irá moviendo en sentido horario. Cuando T1 = 1.5 ms podremos ver que el eje forma un ángulo de 90º con respecto al punto de inicio (0º). En la figura 13.4 se puede observar la señal correspondiente a esta posición (90º), donde T2 se mantiene en 20 milisegundos. Figura 13.4. La señal correspondiente a la posición máxima (180º) en un servomotor estándar, tendría entonces valores para T1 = 2.6 ms y T2 = 20 ms. (figura 13.5). Figura 13.5.
  • 282.
    272 13.2.- Proyecto #35:Se puede crear un programa en PicBasic que cumpla con estas características, en el cual variando solo una variable, podemos modificar el ángulo de giro de un servomotor. Veamos el siguiente ejemplo: Figura 13.6. Proyecto # 35 Componente Cantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 22 pF 2 Servomotor 1 Fuente regulada de 5 Vdc 1 Tabla 13.2.
  • 283.
    273 PAUSEUS Sintaxis: PAUSEUS periodo Lainstrucción Pause realiza un pausa en el programa por un periodo definido en microsegundos. Esta instrucción no pone al microcontrolador en modo de bajo consumo de energía. Programa en Pic Basic Pro: DEFINE OSC 4 ' Define el oscilador en 4 Mhz PULSO VAR Word ' Define la variable "Pulso" (16 Bits) PULSO = 1550 ' Inicializamos la variable "Pulso" Inicio: High PORTB.0 ' RB0 = 1 PauseUs PULSO ' Pausa en microsegundos Low PORTB.0 ' RB0 = 0 Pause 20 ' Pausa de 20 milisegundos GoTo Inicio ' Salto a inicio End Al compilar, grabar y ejecutar el programa anterior en el microcontrolador, podremos ver en un osciloscopio el tren de pulsos presente en el pin RB0 como se muestra en la figura 13.7.
  • 284.
    274 Figura 13.7. Volt/Div: 2V Time/Div:5ms Período: 21,55 ms T1: 1,55 ms (Ancho de pulso positivo). T2: 20 ms Vpp: 5,44 Voltios. Ciclo de trabajo: 8,16% Tiempo de subida: 160,0 us Tiempo de bajada: 160,0 us Al aplicar el tren de pulsos al servomotor, su eje rotará hasta una posición en el punto medio de su recorrido total. Si analizamos el programa, podremos observar que la instrucción “PauseUs” realiza una parada durante un tiempo definido por la variable “Pulso”, cuyo valor es de 1550, es decir, se está generando una pausa de 1550 microsegundos, o lo que es igual, 1,55 milisegundos. Seguidamente hacemos una pausa de 20 milisegundos antes de enviar nuevamente el pulso al Pin RB0.
  • 285.
    275 Entonces, si deseáramosmodificar el ángulo de giro, podemos cambiar el valor de la variable “Pulso”, siempre y cuando el valor esté dentro del rango de tiempo permitido (0,65 ms ≤ T1 ≤ 2.6 ms), es decir, 650 ≤ PauseUs ≤ 2600. Una forma aún más práctica para generar el tren de pulsos de la figura 13.7, sería haciendo uso de la instrucción “PulsOut”, como se muestra a continuación: DEFINE OSC 4 ' Define el oscilador en 4 Mhz Inicio: PulsOut PORTB.0,65 ' Genera pulsos de 650 microsegundos de ' duración. Low PORTB.0 ' RB0 = 0 Pause 20 ' Pausa de 20 milisegundos. GoTo Inicio ' Salto a inicio. End
  • 286.
    276 13.3.- Proyecto #36:Para hacer un poco más interesante la práctica, en la cual el objetivo ha sido controlar el ángulo de giro de un servomotor, proponemos incorporar al circuito dos pulsadores para aumentar y disminuir el ángulo y una pantalla LCD para visualizar el valor en microsegundos de cada pulso enviado al servomotor (Figura 13.8). Figura 13.8.
  • 287.
    277 Proyecto # 36 ComponenteCantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 22 pF 2 Pantalla LCD 16x2 1 Resistencia de 10K Ohm 3 Potenciómetro de 5K Ohm 1 Servomotor 1 Pulsador Normalmente Abierto 2 Fuente regulada de 5 Vdc 1 Tabla 13.3. Programa en PBP: DEFINE OSC 4 ' Define el oscilador en 4 Mhz TRISB = %11110110 ' Configuración del puerto B PULSO VAR Word ' Define la variable "Pulso" (16 Bits) PULSO = 1550 ' Inicializamos la variable "Pulso" Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Inicio: High PORTB.0 ' RB0 = 1 PauseUs PULSO ' Pausa en microsegundos Low PORTB.0 ' RB0 = 0 Pause 15 ' Pausa de 15 milisegundos ' Considerando que las siguientes instrucciones consumen ' 1 ms cada una y la instrucción de salto consume 2 ms, la ' pausa anterior será de 15 ms para lograr un tiempo entre ' cada pulso de 20 ms. If PORTB.1 = 1 And PULSO < 2600 Then Call SUMA ' Si RB1 = 1 significa que se ha activado el pulsador ' conectado a él. La condición se cumple sólo si el pulsador ' está activado y la variable "Pulso" es menor a 2600. If PORTB.2 = 1 And PULSO > 650 Then Call RESTA ' Si RB2 = 1 significa que se ha activado el pulsador
  • 288.
    278 ' conectado aél. La condición se cumple sólo si el pulsador ' está activado y la variable "Pulso" es mayor a 650. LCDOUT $fe, 2,"PULSO: ",#PULSO," uS " ' Muestra el dato cargado en la variable "Pulso" GoTo Inicio ' Salto a inicio SUMA: PULSO = PULSO + 100 ' Suma 100 a la variable "Pulso" Pause 40 ' Pausa de 40 milisegundos Return ' Retorno RESTA: PULSO = PULSO - 100 ' Resta 100 a la variable "Pulso" Pause 40 ' Pausa de 40 milisegundos Return ' Retorno ' Si se aumenta o disminuye la pausa en las subrutinas ' suma y resta, se logra un efecto de aumento o disminución ' de la velocidad variación del ángulo. End Si empleamos la instrucción “PulsOut”: DEFINE OSC 4 ' Define el oscilador en 4 Mhz TRISB = %11110110 ' Configuración del puerto B PULSO VAR Word ' Define la variable "Pulso" (16 Bits) PULSO = 155 ' Inicializamos la variable "Pulso" Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Inicio: PulsOut PORTB.0, PULSO ' Genera un pulso en RB0 Low PORTB.0 ' RB0 = 0 Pause 15 ' Pausa de 15 milisegundos ' Considerando que las siguientes instrucciones consumen ' 1 ms cada una y la instrucción de salto consume 2 ms, la ' pausa anterior será de 15 ms para lograr un tiempo entre ' cada pulso de 20 ms. If PORTB.1 = 1 And PULSO < 260 Then Call SUMA ' Si RB1 = 1 significa que se ha activado el pulsador ' conectado a él. La condición se cumple sólo si el pulsador
  • 289.
    279 ' está activadoy la variable "Pulso" es menor a 260. If PORTB.2 = 1 And PULSO > 65 Then Call RESTA ' Si RB2 = 1 significa que se ha activado el pulsador ' conectado a él. La condición se cumple sólo si el pulsador ' está activado y la variable "Pulso" es mayor a 65. LCDOUT $fe, 2,"PULSO: ",#PULSO,"0 uS " ' Muestra el dato cargado en la variable "Pulso" GoTo Inicio ' Salto a inicio SUMA: PULSO = PULSO + 10 ' Suma 10 a la variable "Pulso" Pause 40 ' Pausa de 40 milisegundos Return ' Retorno RESTA: PULSO = PULSO - 10 ' Resta 10 a la variable "Pulso" Pause 40 ' Pausa de 40 milisegundos Return ' Retorno ' Si se aumenta o disminuye la pausa en las subrutinas ' suma y resta, se logra un efecto de aumento o disminución ' de la velocidad variación del ángulo. End
  • 290.
    280 13.4.- Proyecto #37:En la siguiente actividad se desea controlar un servomotor y visualizar el tiempo de cada pulso en una pantalla LCD, conectados a un microcontrolador principal. Desde un microcontrolador secundario se enviará el dato correspondiente al ángulo del eje, estableciendo una comunicación serial con el microcontrolador principal, de tal manera que cuando se requiera aumentar o disminuir el ángulo, sean utilizados dos pulsadores conectados en cualquiera de los puertos disponibles del microcontrolador secundario. El circuito propuesto se muestra en la figura 13.9. Figura 13.9.
  • 291.
    281 Proyecto # 37 ComponenteCantidad PIC16F84A 2 Cristal de 4 Mhz 2 Capacitor cerámico de 22 pF 4 Pantalla LCD 16x2 1 Resistencia de 10K Ohm 3 Potenciómetro de 5K Ohm 1 Pulsador Normalmente Abierto 2 Fuente regulada de 5 Vdc 1 Tabla 13.4. Programa para el microcontrolador principal U1: DEFINE OSC 4 ' Define el oscilador en 4 Mhz Symbol T9600 = 2 ' Dato verdadero (Driven True) PULSO VAR Word ' Define la variable "Pulso" (16 Bits) PULSO = 155 ' Inicializa variable "Pulso" pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Inicio: SerIn PORTB.7, T9600, 16, Sigue, PULSO ' Espera dato ' durante 16 ms Sigue: LCDOUT $fe, 2,"PULSO: ",#PULSO,"0 uS " ' Muestra dato. PulsOut PORTB.1, PULSO ' Genera pulso en RB1 GoTo Inicio ' Salto a inicio End
  • 292.
    282 Programa para elmicrocontrolador secundario U2: DEFINE OSC 4 Symbol T9600 = 2 ' Dato verdadero (Driven True) PULSO VAR Word ' Define la variable "Pulso" (16 Bits) PULSO = 155 ' Inicializa variable "Pulso" inicio: If PORTA.0 = 1 And PULSO < 250 Then Call suma ' Si RA0 = 1 significa que se ha activado el pulsador ' conectado a él. La condición se cumple sólo si el pulsador ' está activado y la variable "Pulso" es menor a 250. If PORTA.1 = 1 And PULSO > 60 Then Call resta ' Si RA1 = 1 significa que se ha activado el pulsador ' conectado a él. La condición se cumple sólo si el pulsador ' está activado y la variable "Pulso" es mayor a 60. GoTo inicio ' Salto a inicio suma: PULSO = PULSO + 10 ' Suma 10 a la variable "Pulso" SerOut PORTA.2, T9600, [PULSO] ' Envía dato serial por RA2 PAUSE 40 ' Pausa de 40 milisegundos Return ' Retorno resta: PULSO = PULSO - 10 ' Resta 10 a la variable "Pulso" SerOut PORTA.2, T9600, [PULSO] ' Envía dato serial por RA2 PAUSE 40 ' Pausa de 40 milisegundos Return ' Retorno End
  • 293.
    283 13.5.- Proyecto #38:En la siguiente actividad se controlará un servomotor desde el puerto serial de un PC, desde donde enviaremos el dato a ser cargado en la instrucción “PulsOut” en el código de programa del microcontrolador, y el cual definirá el ancho de pulso a ser introducido en el servomotor cada 20 milisegundos. El circuito consta de un microcontrolador PIC16F84A con oscilador de 4 Mhz y un servomotor, donde la línea de control estará conectada al Pin RB1. Para la comunicación entre el PC y el circuito, emplearemos un circuito integrado MAX-232 (Figura 13.10). Figura 13.10.
  • 294.
    284 Proyecto # 38 ComponenteCantidad PIC16F84A 1 Cristal de 4 Mhz 1 Capacitor cerámico de 22 pF 2 IC MAX232 1 Capacitor electrolítico de 0,1 uF 5 Potenciómetro de 5K Ohm 1 Conector DB-9M 1 Fuente regulada de 5 Vdc 1 Tabla 13.5. Programa en Pic Basic Pro: DEFINE OSC 4 ' Define el oscilador en 4 Mhz Symbol T9600 = 2 ' Dato verdadero (Driven True) PULSO VAR Word ' Define la variable "Pulso" (16 Bits) PORTB.1 = 0 ' Inicializa RB1 inicio: SerIn PORTB.7, T9600, 18, sigue, PULSO ' Espera dato ' durante 18 ms sigue: PulsOut PORTB.1, PULSO ' Genera pulso en RB1 GoTo inicio ' Salto a inicio End
  • 295.
    285 Para la comunicaciónserial, se ha definido el modo de dato verdadero a 9600 bps (T9600). A partir de la etiqueta “inicio”, el primer paso será esperar un dato serial durante 18 milisegundos antes de saltar a la etiqueta “sigue”, para generar el pulso correspondiente y donde su duración se calcula en decenas de microsegundos. Seguidamente se genera un salto a la etiqueta “inicio” para repetir el proceso. La interfaz gráfica para el control del servomotor la hemos realizado en Visual Basic (Figura 13.11), desde la cual podremos seleccionar el tiempo de duración de los pulsos enviados al servomotor. Además hemos agregado tres botones con valores fijos para las tres posiciones principales (0º, 90º y 180º). Veamos a continuación el desarrollo de la interfaz gráfica paso a paso: Figura 13.11.
  • 296.
    286 Paso 1: creamosun nuevo proyecto “EXE estándar” (Figura 13.12): Figura 13.12. Paso 2: Identificamos el formulario en las propiedades del mismo, ingresando un nombre que identifique nuestra aplicación: Figura 13.13.
  • 297.
    287 Figura 13.14. Paso 3:activamos el componente para manejar la comunicación serial “Microsoft Comm Control 6.0”. Esto se realiza haciendo clic en el menú Proyectos Componentes Controles. Seguidamente se inserta el icono “MsComm” como se muestra en la figura 13.15, y se configuran los parámetros de conexión en la ventana de propiedades (Figuras 13.16 y 13.17): Figura 13.15.
  • 298.
    288 Figura 13.16. Figura13.17. Paso 4: cerramos la ventana de código e incluimos los botones, el campo de texto y la imagen en el formulario (Figura 13.18). Recuerde identificar cada botón en la ventana de propiedades (Figura 13.19): Figura 13.18. Figura 13.19.
  • 299.
    289 Figura 13.20. Paso 5:se asigna un nombre a cada botón en la ventana de propiedades (Figura 13.21):
  • 300.
    290 Figura 13.21. Paso 6:se hace doble clic sobre el formulario para agregar el siguiente código, con el cual habilitaremos el puerto serial del PC, y asignaremos una función específica a cada botón (Figura 13.20): Dim Servo As Byte ' Declaración de Variable "Servo" ' tipo byte ______________________________________________________________________________ Private Sub Form_Load() ' Rutina para abrir el puerto serial MSComm1.PortOpen = True If MSComm1.PortOpen = False Then MSComm1.PortOpen = True End If Servo = 155 ' Inicializamos la variable "Servo" MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1 Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto End Sub ______________________________________________________________________________
  • 301.
    291 Private Sub Boton1_Click()' Boton 0º Servo = 70 ' Carga el valor para 0º Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1 End Sub ______________________________________________________________________________ Private Sub Boton2_Click() ' Boton 90º Servo = 155 ' Carga el valor para 90º Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1 End Sub ______________________________________________________________________________ Private Sub Boton3_Click() ' Boton 90º Servo = 250 ' Carga el valor para 180º Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1 End Sub ______________________________________________________________________________ Private Sub Boton4_Click() ' Boton <-- If Servo > 70 Then ' Restará solo si Servo es > 70 Servo = Servo - 5 ' Resta 5 a la variable "Servo" Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto End If End Sub ______________________________________________________________________________ Private Sub Boton5_Click() ' Boton --> If Servo < 250 Then ' Sumará solo si Servo es < 250 Servo = Servo + 5 ' Suma 5 a la variable "Servo" Text1.Text = Servo * 10 ' Muestra dato * 10 en la caja de texto End If End Sub ______________________________________________________________________________ Private Sub Boton6_Click() ' Boton "Enviar Dato" MSComm1.Output = Chr$(Servo) ' Envía dato al puerto Comm1 End Sub
  • 302.
    292 Nota Importante: Recuerde queel dato a ser cargado en la instrucción “PulsOut” del programa de control del PIC16F84A, se mide en decenas de microsegundos para un oscilador de 4 Mhz, por ejemplo: PulsOut PORTB.1, 100 Esto significa que el tiempo del pulso generado será de 100 decenas de microsegundos: 10 microsegundos x 100 = 1000 microsegundos ó 1 milisegundo. Por lo tanto, los datos que enviamos al microcontrolador a través del puerto serial desde la aplicación que hemos creado en Visual Basic, deben ser considerados como la cantidad de decenas de microsegundos que deseamos que dure cada pulso enviado al servomotor. Esta es la razón por la cual hemos multiplicado por diez el dato a ser mostrado en la caja de texto, especificando además la unidad de tiempo correspondiente, que en este caso se expresa con la palabra “Microsegundos”. Paso 7: generamos el archivo ejecutable desde el menú Archivo Generar “Nombre del archivo.exe”.
  • 303.
    293 Módulos RF paracomunicaciones Capítulo XIV 14.1.- Proyectos con Módulos RF. A continuación realizaremos algunos proyectos donde la base de éstos serán los módulos inalámbricos RF de la empresa Linx Technologies Inc. (http://www.linxtechnologies.com), los cuales ofrecen una gran variedad de modelos en diferentes rangos de frecuencias y donde la característica más resaltante radica en que no requieren componentes externos a excepción de la antena (figura 14.1). Su interfaz serial nos permite realizar una comunicación directa o sin modificaciones en el protocolo RS-232, haciendo muy sencillo el trabajo de comunicar dos circuitos que se encuentran a distancias considerablemente largas en sus versiones de módulos LR (Long Range), para distancias que pueden llegar a exceder los 900 metros en su frecuencia estándar de 418 Mhz. También se pueden adquirir para trabajar en frecuencias de 315 Mhz o 433 Mhz. Figura 14.1. El voltaje de alimentación no debe exceder los 3.3 Vdc, por lo cual se debe considerar el uso de una regulador de voltaje para el transmisor y receptor, considerando que el voltaje estándar en nuestros circuitos ha sido de 5 Vdc.
  • 304.
    294 Transmisor: TXM-418-LR-S Figura 14.2. Receptor:RXM-418-LR-S Figura 14.3. El pin 4 (LADJ/VCC) en el transmisor puede ser utilizado para el ajuste en la potencia del transmisor, variando el valor de una resistencia o potenciómetro, y la relación resistencia versus potencia se puede ver en la figura 14.4:
  • 305.
    295 Figura 14.4. El pinPDN (Power Down) se encuentra disponible en el transmisor y receptor y puede ser utilizado para poner el dispositivo en bajo consumo de energía (menor a 5nA). Si se desea utilizar la opción de bajo consumo de energía se requiere de una resistencia Pull-up de 10Kohm a Vcc o de menor valor en el pin PDN. Cuando PDN = 0, entonces el transmisor o receptor entran en reposo. Todas estas consideraciones pueden ser ampliadas en la hoja de datos de cada dispositivo suministradas por el fabricante. A continuación realizaremos una serie de proyectos en los cuales implementaremos la comunicación serial inalámbrica, y los cuales resultan muy interesantes como base para nuevos proyectos.
  • 306.
    296 14.2.- Proyecto #39:En el siguiente proyecto se requiere la construcción de dos circuitos, figura 14.5 y figura 14.6. En el transmisor hemos empleado un microcontrolador PIC16F877 debido a que en los siguientes proyectos iremos incorporando más dispositivos externos a demás de la pantalla LCD. El circuito receptor estará controlado por un PIC16F84 al cual le hemos conectado una pantalla LCD para visualizar los datos recibidos. Circuito Transmisor: Figura 14.5.
  • 307.
  • 308.
    298 Proyecto # 39 ComponenteCantidad PIC16F877A 1 PIC16F84A 1 Cristal de 4 Mhz 2 Capacitor cerámico de 22 pF 4 TXM-418-LR-S con antena 1 RXM-418-LR-S con antena 1 Pantalla LCD 16x2 2 Potenciómetro de 5K Ohm 2 Resistencia de 390 Ohm 2 Resistencia de 750 Ohm 1 Resistencia de 10K Ohm 1 Fuente regulada de 3.3 Vdc / 5 Vdc 2 Tabla 14.1. La primera actividad consiste en enviar una secuencia de dígitos (0 al 9) hacia el receptor, los cuales deben poder ser visualizados en la pantalla LCD del mismo. Esto significa que cuando transmitimos el primer dígito al receptor, éste será mostrado en la pantalla LCD del circuito transmisor y receptor y ambos deberán ser iguales para confirmar que la transmisión de datos ha sido exitosa. Programa para el circuito transmisor: Symbol T9600 = 2 ' Dato verdadero (Driven True) I VAR Byte ' Define la variable "I" como Byte Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD inicio:
  • 309.
    299 For I =0 To 9 ' Repetición de 0 a 9 SerOut PORTB.0, T9600, [I] ' Envía los datos por RB0 LCDOut $fe, 2,"Dato: ",#I ' Muestra dato por la LCD Pause 1000 ' Pausa de 1 segundo Next I GoTo inicio ' Salta a inicio y reinicia el conteo End Programa para el circuito receptor: Symbol T9600 = 2 ' Dato verdadero (Driven True) dato var Byte ' Define la variable "dato" como Byte pause 500 ' Pausa de 500 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD inicio: SerIn PORTB.7, T9600, dato ' espera datos durante 1 ms LCDOUT $fe, 2,"Dato: ",#dato," " GoTo inicio ' Salta a inicio End Como podemos observar en los diagramas de los circuitos, los módulos TXM- 418-LR-S y RXM-418-LR-S conforman el medio a través del cual viajan los datos, sustituyendo al cable, cuyas limitaciones son de apenas unos pocos metros cuando se requiere de comunicación serial RS-232.
  • 310.
    300 14.3.- Proyecto #40:Incorporando un teclado matricial al proyecto anterior, podemos enviar datos asignados a cada tecla. Circuito transmisor: Figura 14.7.
  • 311.
  • 312.
    302 Proyecto # 40 ComponenteCantidad PIC16F877A 1 PIC16F84A 1 Cristal de 4 Mhz 2 Capacitor cerámico de 22 pF 4 Pantalla LCD 16x2 2 TXM-418-LR-S con antena 1 RXM-418-LR-S con antena 1 Resistencia de 1K Ohm 4 Resistencia de 390 Ohm 2 Resistencia de 750 Ohm 1 Resistencia de 10K Ohm 1 Potenciómetro de 5K Ohm 2 Teclado Matricial 3x4 1 Fuente regulada de 3.3 Vdc / 5 Vdc 2 Tabla 14.2. Programa para el circuito transmisor con teclado matricial: Symbol T9600 = 2 ' Dato verdadero (Driven True) TRISD = %01111000 ' Configuración de Puerto D TECLA VAR Byte ' Declaración de variable "Tecla" pause 500 ' Pausa de 500 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD inicio: Call teclado ' Llama a rutina de barrido de teclas PAUSE 100 ' Pausa de 1050 milisegundos SerOut PORTB.0, T9600, [TECLA] ' Envía dato por RB0 LCDOUT $fe, 2,"Dato: ",#TECLA ' Muestra dato por la LCD
  • 313.
    303 GoTo inicio 'Salto a inicio teclado: PORTD.0 = 0 ' Columna 1 = 0 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then TECLA = 1 ' tecla "1" If PORTD.4 = 0 Then TECLA = 4 ' tecla "4" If PORTD.5 = 0 Then TECLA = 7 ' tecla "7" If PORTD.6 = 0 Then TECLA = 10 ' tecla "*" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 0 ' Columna 2 = 0 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then TECLA = 2 ' tecla "2" If PORTD.4 = 0 Then TECLA = 5 ' tecla "5" If PORTD.5 = 0 Then TECLA = 8 ' tecla "8" If PORTD.6 = 0 Then TECLA = 11 ' tecla "0" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 0 ' Columna 3 = 0 If PORTD.3 = 0 Then TECLA = 3 ' tecla "3" If PORTD.4 = 0 Then TECLA = 6 ' tecla "6" If PORTD.5 = 0 Then TECLA = 9 ' tecla "9" If PORTD.6 = 0 Then TECLA = 12 ' tecla "#" Return End Se puede apreciar en la rutina de barrido del teclado que hemos asignado un valor específico en cada condición, es decir, si presionamos la tecla #1, el valor asignado a la variable “TECLA” será igual a uno. Si presionamos la tecla #2, entonces la variable “TECLA” será igual a dos, y así sucesivamente hasta la última tecla.
  • 314.
    304 Cada vez quepresionamos una tecla, el dato correspondiente a la misma es cargado y enviado al receptor el cual a su vez almacena este dato en una variable, e inmediatamente lo muestra en la pantalla LCD. Esta acción se puede apreciar en el código de programa que se muestra a continuación. Programa para el circuito receptor: Symbol T9600 = 2 ' Dato verdadero (Driven True) dato VAR Byte ' Define la variable "dato" como Byte Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD inicio: SerIn PORTB.7, T9600, dato ' Espera de datos LCDOUT $fe, 2,"Dato: ",#dato," " GoTo inicio ' Salta a inicio End A partir de la etiqueta “inicio” se espera la llegada de los datos enviados desde el circuito transmisor. En este punto la instrucción “SerIn” mantiene al microcontrolador en espera, de tal manera que cuando llega un dato, éste se almacena en la variable correspondiente “dato” y seguidamente salta a la siguiente línea, que en este caso corresponde a la instrucción LCDout la cual se encargará de mostrar el dato en la pantalla. Es importante resaltar que cuando el circuito transmisor es apagado, el módulo receptor (RXM-418-LR-S) pierde sincronía y puede entregar datos errados o aleatorios al microcontrolador. Esto es un problema que puede ser corregido con unas pocas líneas de programación como lo demostraremos en el siguiente proyecto.
  • 315.
    305 14.4.- Proyecto #41:En este proyecto se plantea realizar un sistema de control a distancia que maneje ocho salidas de potencia en el circuito receptor, de tal manera que pueda ser encendida o apagada cualquiera de ellas al presionar el botón correspondiente en el teclado del circuito transmisor. Esto significa que al pulsar la tecla “1”, el estado de la salida correspondiente a esta tecla en el circuito receptor debe cambiar. Si la salida se encuentra en estado lógico cero, la misma debe cambiar a estado lógico uno y viceversa. Lo mismo debe aplicar para el resto de las salidas de potencia del circuito receptor. Para el circuito transmisor podemos emplear el mismo diagrama de la actividad anterior. Circuito transmisor: Figura 14.9.
  • 316.
    306 Diagrama del circuitoreceptor: Figura 14.10.
  • 317.
    307 Programa para elcircuito transmisor con teclado matricial: Symbol T9600 = 2 ' Dato verdadero (Driven True) TRISD = %01111000 ' Configuración de Puerto D TECLA VAR Byte ' Declaración de variable "Tecla" Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD inicio: Call teclado ' Llama a rutina de barrido de teclas. If tecla = 0 Then inicio ' Si TECLA = 0 ninguna tecla fue ' presionada y salta de nuevo a ' la etiqueta inicio. SerOut PORTB.0, T9600, [%10011001] ' Envía código de confirmación. PAUSE 200 SerOut PORTB.0, T9600, [TECLA] ' Envía dato por RB0 PAUSE 300 ' Pausa de 300 milisegundos LCDOUT $fe, 2,"Dato: ",#TECLA," " ' Muestra dato por la LCD GoTo inicio ' Salto a inicio teclado: tecla = 0 PORTD.0 = 0 ' Columna 1 = 0 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then TECLA = 1 ' tecla "1" If PORTD.4 = 0 Then TECLA = 4 ' tecla "4" If PORTD.5 = 0 Then TECLA = 7 ' tecla "7" If PORTD.6 = 0 Then TECLA = 10 ' tecla "*" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 0 ' Columna 2 = 0 PORTD.2 = 1 ' Columna 3 = 1 If PORTD.3 = 0 Then TECLA = 2 ' tecla "2" If PORTD.4 = 0 Then TECLA = 5 ' tecla "5" If PORTD.5 = 0 Then TECLA = 8 ' tecla "8"
  • 318.
    308 If PORTD.6 =0 Then TECLA = 11 ' tecla "0" PORTD.0 = 1 ' Columna 1 = 1 PORTD.1 = 1 ' Columna 2 = 1 PORTD.2 = 0 ' Columna 3 = 0 If PORTD.3 = 0 Then TECLA = 3 ' tecla "3" If PORTD.4 = 0 Then TECLA = 6 ' tecla "6" If PORTD.5 = 0 Then TECLA = 9 ' tecla "9" If PORTD.6 = 0 Then TECLA = 12 ' tecla "#" Return End En el programa del circuito transmisor se pueden observar algunas mejoras. A partir de la etiqueta “inicio” se puede observar que no se envían datos al receptor a menos que se presione una tecla. Si una tecla es presionada, entonces enviamos un código elegido al azar al receptor (Ej. 10011001), para indicar que el siguiente dato corresponde al de la tecla presionada. De esta manera evitaremos observar datos errados en la pantalla LCD del circuito receptor, ya que su programa ha sido diseñado para que solo cambie el estado lógico de las salidas de potencia, solo si recibe el código correcto enviado desde el circuito transmisor. Programa para el circuito receptor: TRISD = %00000000 Symbol T9600 = 2 ' Dato verdadero (Driven True) dato VAR Byte ' Define la variable "dato" como Byte salida VAR Byte Pause 500 ' Pausa de 500 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD PORTD = 0 ' Inicializamos el puerto D inicio: SerIn PORTB.7, T9600, dato ' Espera datos. If DATO = %10011001 Then sigue ' Salta a la etiqueta "sigue"
  • 319.
    309 ' si serecibe el código correcto ' que hemos elegido (10011001) GoTo inicio ' Salto a inicio. sigue: SerIn PORTB.7, T9600, dato ' espera datos durante 1 ms If dato = 1 Then Toggle PORTD.0 ' Invierte el Bit en RD0 If dato = 2 Then Toggle PORTD.1 ' Invierte el Bit en RD1 If dato = 3 Then Toggle PORTD.2 ' Invierte el Bit en RD2 If dato = 4 Then Toggle PORTD.3 ' Invierte el Bit en RD3 If dato = 5 Then Toggle PORTD.4 ' Invierte el Bit en RD4 If dato = 6 Then Toggle PORTD.5 ' Invierte el Bit en RD5 If dato = 7 Then Toggle PORTD.6 ' Invierte el Bit en RD6 If dato = 8 Then Toggle PORTD.7 ' Invierte el Bit en RD7 LCDOUT $fe, 2,"Salida #: ",#dato," " ' Muestra dato en LCD GoTo inicio ' Salta a inicio End
  • 320.
    310 Instrucciones de programade PicBasic Capítulo XV @ Sintaxis: @ instrucción en lenguaje ensamblador Esta instrucción es utilizada para insertar dentro del código PicBasic, líneas de programa en lenguaje ensamblador. En este caso, cada línea en lenguaje ensamblador debe llevar el símbolo @ al inicio. Ejemplo: Led Var Byte ' Declaración de Variable Led TRISB = $00 ' Configura el puerto B como salida Led = $00 ' Inicializamos la variable Led Inicio: @bsf _Led,0 ' pone en 1 el bit 0 de la variable Led Pause 1000 ' Pausa de 1 segundo PORTB = Led ' Saca dato por el puerto B Pause 1000 ' Pausa de 1 segundo @bcf _Led,0 ' pone en 0 el bit 0 de la variable Led PORTB = Led ' Saca dato por el puerto B GoTo Inicio ' Salto a inicio End Nota Importante: para acceder a una variable declarada en PicBasic, desde el lenguaje ensamblador se debe anteponer el símbolo “_” (Guión bajo), ya que de lo contrario no será posible el acceso a ésta. En el ejemplo, se puede ver que para acceder a la variable “Led” desde el lenguaje ensamblador, se antepuso el guión bajo a la variable, quedando “_Led”.
  • 321.
    311 ADCin Sintaxis: ADCin canal, Variable Leeuna entrada del conversor A/D y el resultado es almacenado en una variable. Esta instrucción solo es válida para microcontroladores que tienen convertidor A/D, por ejemplo, el PIC16F877, el PIC18F442, el PIC18F452, el PIC18F458 entre otros. Asm… EndAsm Sintaxis: Asm * * Instrucciones en lenguaje ensamblador * * EndAsm Esta instrucción permite insertar un conjunto de instrucciones en lenguaje ensamblador y al igual que en la instrucción “@”, también aplica el uso del símbolo “_” (Guión Bajo), el cual debe anteceder a las variables que se deseen utilizar.
  • 322.
    312 Branch Sintaxis: Branch Variable,[Etiqueta1, Etiqueta2,…EtiquetaN] Lainstrucción Branch hace un salto a una etiqueta dependiendo del valor de la variable, es decir, si la variable es igual a 0, el salto se hace a la etiqueta 1; si la variable es igual a 1, el salto se hace a la etiqueta 2; si la variable es igual a 2, el salto se hace a la etiqueta 3, y así sucesivamente. Ejemplo: I var Byte ' Declaración de Variable I TRISB = $00 ' Configura el puerto B como salida PORTB = $00 ' Inicializa el puerto B I = 0 ' Inicializa la variable I inicio: Branch I,[Led1,Led2,Led3] Led1: PORTB = %00000001 ' enciende el led en RB0 pause 1000 ' pause de 1 segundo PORTB = %00000000 ' apaga el led I = I + 1 ' suma 1 a la variable I GoTo inicio ' salta a inicio Led2: PORTB = %00000010 ' enciende el led en RB1 pause 1000 ' pause de 1 segundo PORTB = %00000000 ' apaga el Led I = I + 1 ' suma 1 a la variable I GoTo inicio ' salta a inicio Led3: PORTB = %00000100 ' enciende el led en RB2 pause 1000 ' pause de 1 segundo PORTB = %00000000 ' apaga el Led I = 0 ' Inicializa la variable I GoTo inicio ' salta a inicio End
  • 323.
    313 Button Sintaxis: Button pin,estado, retardo, rango, variable, acción, etiqueta La instrucción “Button” elimina los rebotes de un “pulsador” o “switch”, y genera auto-repetición. Pin: especifica el pin del puerto en el cual será conectado el pulsador. Estado: indica cual es estado lógico que debe ocurrir cuando el pulsador es presionado (0 o 1). Si es 0, el pulsador deberá ser activo-bajo y si es 1, el pulsador deberá ser activo-alto (Ver figura 15.1). Activo-Alto S1 Pulsador Al Pin R1 10 Kohm +5V R1 10 Kohm S1 Pulsador Al Pin +5V Activo-Bajo Figura 15.1. Retardo: es una variable o constante (0 – 255) que especifica cuantos ciclos deben pasar antes de efectuar la auto-repetición. Este campo tiene dos funciones especiales: si el campo retardo es igual 0, no permite anti-rebote y no permite auto-repetición. Si el campo retardo es igual a 255, permite el anti- rebote pero no permite la auto-repetición. Rango: es una variable o constante (0 – 255) que especifica el número de ciclos entre auto-repeticiones.
  • 324.
    314 Variable: es unavariable auxiliar tipo Byte, definida también al inicio del programa para uso exclusivo de la instrucción Button, por lo cual no deberá ser utilizada con otro fin en el programa. Siempre debe ser inicializada antes del comando Button. Acción: indica el estado del botón cuando éste no es presionado. Etiqueta: la instrucción realiza un salto a la etiqueta definida en este campo cuando el pulsador no ha sido presionado. Ejemplo: TRISB = %11111101 ' Configuración del puerto B A0 Var Byte ' declaración de la variable A0 Lcdout $fe,1 A0 = 0 ' inicializa la variable A0 inicio: Button PORTB.0,1,2,2,A0,0,NoPres PulsOut PORTB.1,150 NoPres: Pause 10 GoTo inicio ' Salta a inicio End
  • 325.
    315 Call Sintaxis: Call etiqueta La instrucción“Call”, llama a una subrutina la cual está identificada con una etiqueta, y una vez culminada la subrutina la cual contiene al final la instrucción “Return”, vuelve a la siguiente línea después del llamado. Ejemplo: inicio: Call Teclado If A0 = 1 Then led1 . . . Teclado: . . . . Return End Clear Sintaxis: Clear La instrucción “Clear” inicializa todos los registros de la RAM a cero, es decir, todas las variables simultáneamente pasarán a ser cero.
  • 326.
    316 ClearWDT Sintaxis: ClearWDT La instrucción “ClearWDT”inicializa el Perro Guardián (Watchdog Timer). Count Sintaxis: Count pin, duración, variable La instrucción “Count” puede medir la frecuencia de una señal simple determinando el número de pulsos por segundo. Se pueden medir frecuencias de hasta 25 khz con un oscilador de 4 MHz. Para un oscilador de 20 MHz la frecuencia máxima a ser medida será de 125 khz. Pin: especifica el pin del puerto en el cual se introducirán los impulsos. Este pin es designado como entrada automáticamente por la instrucción Count. Duración: es el tiempo durante el cual se realizará el conteo de impulsos sobre el pin especificado. Variable: es una variable definida por el programador en la cual se grabará el resultado del conteo.
  • 327.
    317 Data Sintaxis: Data {@Dirección inicial},constante1, constante2,…constanteN La instrucción “Data” solo puede ser utilizada para las familias de microcontroladores que incorporan memoria EEPROM en su arquitectura. Para los microcontroladores que no cuentan con esta memoria, existe la posibilidad de agregar una memoria EEPROM externa a través del protocolo de comunicación I2C. Básicamente esta instrucción guarda varias constantes a partir de una dirección que especificamos en el campo correspondiente. Ejemplo: Data @10,1,3,5,7,9 En este ejemplo, la instrucción Data almacenará los valores 1, 3, 5, 7 y 9 en las direcciones de memoria 10, 11, 12, 13 y 14 respectivamente. DTMFout Sintaxis: DTMFout pin, {On-ms, Off-ms}, [tono, tono,...tono] La instrucción DTMFout genera tonos DTMF en secuencia y a través de un puerto cualquiera del microcontrolador. Pin: especifica el pin del puerto en el cual se emitirán los tonos DTMF. On-ms: es una variable, constante o expresión que especifica la duración de cada tono en milisegundos. En caso de no utilizar este parámetro, el tiempo por defecto de cada tono es de 200 ms.
  • 328.
    318 Off-ms: es unavariable o constante que especifica el tiempo en milisegundos del silencio que hay entre cada tono. En caso de no utilizar este parámetro, el tiempo por defecto será de 50 ms. Tono: puede ser una variable o constante (entre 0 – 15), que especifica el tono que debe ser generado. Dígito en la Instrucción DTMFout Dígito en un Teclado Telefónico Frecuencias Bajas Frecuencias Altas 1 1 697 HZ 1209 HZ 2 2 697 HZ 1336 HZ 3 3 697 HZ 1477 HZ 4 4 770 HZ 1209 HZ 5 5 770 HZ 1336 HZ 6 6 770 HZ 1477 HZ 7 7 852 HZ 1209 HZ 8 8 852 HZ 1336 HZ 9 9 852 HZ 1477 HZ 10 0 941 HZ 1209 HZ 11 * 941 HZ 1336 HZ 12 # 941 HZ 1477 HZ 13 A 697 HZ 1633 HZ 14 B 770 HZ 1633 HZ 15 C 852 HZ 1633 HZ 0 D 941 HZ 1633 HZ Tabla 15.1.
  • 329.
    319 Figura 15.2. Ejemplo: DTMFout PortC.0,[0,1,2,3,4,5,6,7,8,9] Conectando el pin de salida (RC0) adecuadamente a una línea telefónica, estaremos marcando sin problemas un número telefónico. En algunos casos es recomendable utilizar los tiempos On-ms y Off-ms para realizar un marcado más exacto. Ejemplo: DTMFout PortC.0,400,150, [6,4,3,8,7,1,0]
  • 330.
    320 Los tonos tendránuna duración de 400 milisegundos cada uno y un tiempo en silencio entre ellos de 150 milisegundos. En cuanto al oscilador se recomienda usar del tipo HS (desde 10 Mhz o superior) para obtener mejores resultados en la generación de tonos DTMF, así como también se recomienda utilizar un circuito de acople entre el microcontrolador y el dispositivo externo al cual enviaremos los tonos. C2 0.1 uF Parlante R1 1K Al Pin C2 10 uF GND R2 1K C1 10 uF GNDGND Al Pin Al amplif icador de Audio C1 0.1 uF Figura 15.3.
  • 331.
    321 EEPROM Sintaxis: EEPROM dirección,[constante1, constante2,….constanteN] Lainstrucción “EEPROM” es capaz de almacenar datos en la memoria de datos de un microcontrolador siempre y cuando éste cuente con esta característica y a partir de la dirección indicada, almacena constantes específicas en las posiciones consecutivas a la inicial. Es importante resaltar que los datos solo son almacenados al momento de grabar el microcontrolador en nuestro programador para microcontroladores PIC, por lo tanto, para realizar lecturas o grabaciones de nuevos datos durante la ejecución de un programa se debe recurrir a las instrucciones Read y Write. END Sintaxis: End La instrucción “END” detiene la ejecución de un programa y pone el microcontrolador en bajo consumo de energía. FREQOUT Sintaxis: FreqOut pin, On-ms, Frecuencia1, Frecuencia2 La instrucción “FreqOut” genera una o dos señales de frecuencia entre 0 y 32767 Hz previamente definidas, durante un período de tiempo también definido.
  • 332.
    322 Pin: especifica elpin del puerto en el cual se va a generar la señal. On-ms: Es una variable o constante que determina el tiempo de duración de la señal. Frecuencia1: puede ser una variable o constante (entre 0 – 32767) que especifica la frecuencia del primer tono. Frecuencia2: puede ser una variable o constante (entre 0 – 32767) que especifica la frecuencia del segundo tono, el cual sale mezclado con la frecuencia 1. En cuanto al oscilador también se recomienda usar del tipo HS (20 Mhz) para obtener mejores resultados en la generación de tonos, así como también se recomienda utilizar un circuito de acople entre el microcontrolador y el dispositivo externo al cual enviaremos los tonos (ver figura 15.3). Ejemplo: FreqOut PortC.2, 1000, 2000 Genera un tono de 2000Hz durante 1 segundo. FreqOut PortC.2, 1000, 1500, 3500 Genera dos tonos a la vez durante 1 segundo, uno de 1500Hz y otro de 3500Hz.
  • 333.
    323 FOR… NEXT Sintaxis: For variable= inicio to final {step {-} incremento} * * Instrucciones… * * Next {variable} La instrucción “For…Next” se encarga de hacer repeticiones de instrucciones que permanecen dentro del lazo For… Next. El parámetro Step afecta el incremento según el valor asignado después de esta palabra. Si este parámetro es omitido, el incremento es en una unidad. Ejemplo: Z Var Byte ' Declaración de la Variable Z Inicio: For Z = 0 To 10 PORTD.0 = 1 ' Pone en 1 el pin RD0 Pause 1000 ' Pausa de 1 segundo PORTD.0 = 0 ' Pone en 0 el pin RD0 Pause 1000 ' Pausa de 1 segundo Next Z End
  • 334.
    324 Gosub Sintaxis: Gosub etiqueta La instrucción“Gosub” ejecuta subrutinas dentro de un programa principal donde la ubicación de las mismas estará definida por la etiqueta correspondiente. Una vez ejecutada la subrutina y encontrada la instrucción Return, la ejecución del programa continúa en la línea siguiente a la instrucción Gosub. GOTO Sintaxis: GOTO etiqueta La instrucción “Goto” continúa la ejecución de un programa a partir de la etiqueta especificada. Esta instrucción no tiene retorno. HIGH Sintaxis: HIGH pin La instrucción “High” pone en uno lógico el pin especificado, el cual configura automáticamente como salida. Ejemplo: Inicio: HIGH PORTA.0 ' Pone en 1 el pin RA0
  • 335.
    325 GoTo inicio End I2CREAD Sintaxis: I2Cread SDA,SCL, Control, Dirección, [dato], {etiqueta de salto opcional} La instrucción “I2Cread” enviará el dato de control y la dirección específica a un dispositivo conectado a un bus I2C y almacenará el dato obtenido en una variable definida. Al utilizar la etiqueta opcional, el programa saltará si no se recibe ninguna respuesta del dispositivo consultado. Ejemplo: SDA VAR PORTB.0 SCL VAR PORTB.1 A1 VAR Byte Direc VAR Word Control VAR Byte Pause 500 ' Pause de 500 milisegundos LCDOut $fe, 1 ' Limpia la LCD inicio: Direc = $10 ' Dirección en la memoria externa Control = $A0 ' Dato de Control I2CREAD SDA, SCL, Control, Direc, [A1] ' Lectura de ' memoria LCDOUT $fe, 2,"Dato: ",#A1 ' Muestra el dato leído ciclo: GoTo ciclo End
  • 336.
    326 I2CWRITE Sintaxis: I2CWrite SDA, SCL,Control, Dirección, [dato], {etiqueta de salto opcional} La instrucción “I2CWrite” enviará el dato de control y la dirección en la cual se almacenará el dato cargado en la variable previamente cargada. Ejemplo: SDA VAR PORTB.0 SCL VAR PORTB.1 Direc var Word Control Var Byte inicio: Direc = $10 ' Dirección en la memoria externa Control = $A0 ' Dato de Control I2Cwrite SDA, SCL, Control, Direc, [$21] ' Escribe la ' memoria pause 10 ' Pausa de 10 milisegundos Loop: GoTo Loop End IF – THEM – ELSE Sintaxis: If expresión 1 {AND / OR expresión 2} Then etiqueta Con la instrucción “If – Them” podemos seleccionar uno, dos o mas posibles comportamientos de programa, tomando decisiones en una estructura de programación sencilla y la cual será considerada casi en la totalidad de los programas.
  • 337.
    327 Ejemplo 1: Sipulsamos un botón conectado al pin RA0 se cumple la condición y salta a la etiqueta “Espera”. inicio: Input PORTA.0 ' Designa el PIN RA0 como entrada If PORTA.0 = 1 Then Espera ' Si RA0 = 1 salta a la etiqueta GoTo inicio ' Salta a "inicio" si RA0 = 0 Espera: GoTo Espera End Ejemplo 2: inicio: Input PORTA.0 ' Designa el PIN RA0 como entrada If PORTA.0 = 1 Then ' Si RA0 = 1 ... GoTo Espera ' salta a la etiqueta "Espera" Else ' de lo contrario... GoTo inicio ' salta a la etiqueta "inicio" EndIf ' Fin de la instrucción IF-Them-Else Espera: GoTo Espera End Solo se utiliza “EndIf” cuando deseamos tener más de una condición o toma de decisión.
  • 338.
    328 Ejemplo 3: A VARByte inicio: Input PORTA.0 ' Designa el PIN RA0 como entrada If PORTA.0 = 1 Then A = A + 1 If A = 10 Then Espera ' Si A = 10 salta a la etiqueta “Espera” EndIf GoTo inicio ' Salta a "inicio" Espera: GoTo Espera End INPUT Sintaxis: INPUT PIN Designa un pin específico como entrada. Ejemplo: inicio: Input PORTA.0 ' Designa el PIN RA0 como entrada Espera: GoTo Espera End
  • 339.
    329 LCDIN Sintaxis: LCDin dirección, [variable1,variable2,…] La instrucción “LCDin” carga el dato almacenado en una dirección de la memoria RAM de la LCD en una variable previamente definida. Ejemplo: A VAR Byte inicio: LCDIn $10,[A] ' Lee el dato en la dirección de memoria $10 ' y lo carga en la variable "A". Espera: GoTo Espera End
  • 340.
    330 LCDout Sintaxis: LCDout comando, dato Lainstrucción “Lcdout” envía datos específicos a una pantalla LCD Alfanumérica para que puedan ser mostrados en la misma. Tabla 15.2. Ejemplo: Pause 200 LCDOut $fe, 1 ' Limpia la pantalla LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "* Pantalla LCD *" ' escribe LCDOut $fe,$C0, "* Alfanumerica *" LCDOut $fe,$90, "* 1234567890 *" LCDOut $fe,$D0, "* AaBbCcDdEeFf *" Inicio: GoTo Inicio End Comando Acción $FE, 1 Limpia la pantalla $FE, 2 Retorna al inicio de la primera línea $FE, $0C Apaga el Cursor $FE, $0E Cursor bajo (Underline "_") activo $FE, $0F Cursor intermitente activo $FE, $10 Mueve el cursor un espacio a la izquierda $FE, $14 Mueve el cursor un espacio a la derecha $FE, $C0 Mueve el cursor al inicio de la segunda línea $FE, $90 Mueve el cursor al inicio de la tercera línea $FE, $D0 Mueve el cursor al inicio de la cuarta línea
  • 341.
    331 LOW Sintaxis: LOW pin La instrucción“LOW” coloca en cero lógico un pin específico. Ejemplo: inicio: Low PORTA.0 ' configura RA0 = 0 espera: GoTo espera End NAP Sintaxis: NAP periodo La instrucción “NAP” pone el microcontrolador en modo de bajo consumo de energía por periodos de tiempo definidos en la siguiente tabla:
  • 342.
    332 Periodo Retardo (ms) 018 1 36 2 72 3 144 4 288 5 576 6 1152 7 2304 Tabla 15.3. Ejemplo: inicio: NAP 6 ' Bajo consumo de energía durante 1152 milisegundos espera: GoTo espera End OUTPUT Sintaxis: OUTPUT pin La instrucción “OUTPUT” configura un pin específico como salida. Ejemplo: inicio: OUTPUT PORTA.0 ' configura RA0 como salida espera: GoTo espera End
  • 343.
    333 PAUSE Sintaxis: PAUSE periodo La instrucción“Pause” realiza una pausa en el programa por un periodo definido en milisegundos. Esta instrucción no pone al microcontrolador en modo de bajo consumo de energía. Ejemplo: inicio: High PORTA.0 ' RA0 = 1 Pause 1000 ' Pausa de 1 segundo Low PORTA.0 ' RA0 = 0 Pause 1500 ' Pausa de 1.5 segundos GoTo inicio ' Salta a la etiqueta "inicio" End PAUSEUS Sintaxis: PAUSEUS periodo La instrucción “PauseUs” realiza una pausa en el programa por un periodo definido en microsegundos. Esta instrucción no pone al microcontrolador en modo de bajo consumo de energía. Ejemplo:
  • 344.
    334 inicio: High PORTA.0 'RA0 = 1 PauseUs 200 ' Pausa de 200 microsegundos Low PORTA.0 ' RA0 = 0 PauseUs 1500 ' Pausa de 1.5 milisegundos GoTo inicio ' Salta a la etiqueta "inicio" End POT Sintaxis: POT pin, escala, variable La instrucción “POT” lee un potenciómetro, foto celda, termistor, o cualquier otro dispositivo capaz de variar su valor resistivo. Básicamente esta instrucción calcula el tiempo de descarga del condensador C1 el cual varía según el valor resistivo presente en la resistencia variable. Pin: especifica el pin del puerto en el cual se va a conectar el potenciómetro. Escala: Es una variable o constante que aumenta o disminuye el rango de lectura en un porcentaje determinado. Esta escala es utilizada para ajustar el rango de salida en la lectura del dispositivo, y es afectada directamente por las constantes RC. El valor de la escala será correcto cuando el valor cargado en la variable se aproxime a cero, cuando la resistencia medida sea mínima; y también cuando el valor de la variable se aproxime a 255, cuando la resistencia medida sea máxima. Variable: es una variable en la cual se almacena el resultado obtenido de la lectura del potenciómetro o componente resistivo.
  • 345.
    335 PULSIN Sintaxis: PULSIN pin, nivel,variable La instrucción “PULSIN” mide la duración de un pulso alto o bajo con una resolución de 10 microsegundos para un oscilador de 4 Mhz y el valor obtenido es almacenado en una variable definida de 8 bits (variable tipo byte) o 16 bits (variable tipo Word). Pin: especifica el pin del puerto en el cual se introducirán los pulsos. Nivel: define si la medición se hace en nivel alto o bajo. (1 = alto, 0 = bajo). Variable: es una variable de 8 bits (variable tipo byte) o 16 bits (variable tipo word) definida por el programador en la cual se grabará el resultado de la lectura. Ejemplo: Define OSC 4 ' Define el oscilador en 4 Mhz LECTURA VAR Word ' Definición de variable de 16 bits Pause 200 ' Pausa de 200 milisegundos LCDOut $fe, 1 ' Limpia la pantalla Inicio: LECTURA = 0 ' Inicializa la variable PulsIn PORTB.0,1,LECTURA LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Lect. en ms:",#LECTURA," " ' Muestra mensaje y ' dato por pantalla Pause 1000 ' Pausa de 1 segundo GoTo Inicio ' Salta a inicio End
  • 346.
    336 PULSOUT Sintaxis: PULSOUT pin, nivel,variable La instrucción “PULSOUT” genera pulsos con una duración definida en decenas de microsegundos. (Tiene una resolución de 10 microsegundos para un oscilador de 4 Mhz). Ejemplo: DEFINE OSC 4 ' Define el oscilador en 4 Mhz Inicio: PulsOut PORTB.0,100 ' Genera un pulso de 1 milisegundo de ' duración o 100 decenas de uS. Pause 1 ' Pausa de 1 milisegundo. GoTo Inicio ' Salto a inicio End PWM Sintaxis: PWM pin, nivel, ciclo La instrucción “PWM” envía pulsos PWM (Pulse Width Modulation) a un pin específico. Pin: especifica el pin del puerto en el cual se genera PWM. Nivel: es una variable o constante que determina la duración del pulso en su nivel alto, es decir, partiendo de nivel = 1 si se incrementa este valor, el ancho de pulso positivo se incrementa hasta nivel = 254 donde el ciclo de trabajo es
  • 347.
    337 aproximadamente 100%. Cuandonivel = 0 la salida se mantiene en cero lógico; cuando nivel = 255 la salida se mantiene en uno lógico. Ciclo: es una variable o constante en el cual se define el número de ciclos en un pin específico. Ejemplo: DEFINE OSC 4 ' Define el oscilador en 4 Mhz Inicio: PWM PORTB.0,127,100 ' Señal PWM GoTo Inicio ' Salto a inicio End RANDOM Sintaxis: RANDOM variable La instrucción RANDOM almacena números aleatorios en una variable de 16 Bits (Word). Ejemplo: A0 VAR Word ' Declaración de variable "A0" Word (16 Bits) Pause 200 ' Pausa de 200 milisegundos LCDOut $fe, 1 ' Limpia la pantalla Inicio: Random A0 ' Almacena un número aleatorio en A0
  • 348.
    338 LCDOut $fe, 2' Posiciona el cursor en el inicio LCDOut "RANDOM: ",#A0," " ' Muestra mensaje y ' dato por pantalla Pause 1500 ' Pausa de 1.5 segundos GoTo Inicio ' Salto a inicio End READ Sintaxis: READ dirección, variable La instrucción “READ” permite leer datos desde la memoria EEPROM de datos de un microcontrolador almacenándolos en una variable previamente definida. Ejemplo: ' Declaración de Variables: I VAR Byte DIRECCION VAR Byte DATO VAR Byte WRITE 1, 3 ' Escribe en la memoria de datos WRITE 2, 5 ' Escribe en la memoria de datos WRITE 3, 7 ' Escribe en la memoria de datos WRITE 4, 9 ' Escribe en la memoria de datos WRITE 5, 11 ' Escribe en la memoria de datos DIRECCION = 1 ' Dirección inicial de lectura Pause 200 ' Pausa de 200 milisegundos LCDOut $fe, 1 ' Limpia la pantalla Inicio: For I = 1 To 5 ' Repite la lectura cinco veces
  • 349.
    339 Read DIRECCION,DATO 'Lee la dirección especificada y la ' guarda en la variable "Dato". LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Direccion: ",#DIRECCION," " ' Muestra dirección LCDOut $fe,$C0, "Dato: ",#DATO," " ' Muestra el dato leído DIRECCION = DIRECCION + 1 ' Suma uno (1) a la variable Pause 1500 ' Pausa de 1.5 segundos Next I End RETURN Sintaxis: RETURN Retorno de una subrutina desde donde se ha generado un salto del tipo Call o Gosub. Ejemplo: inicio: Call Teclado If A0 = 1 Then led1 . . . Teclado: . . . . Return End
  • 350.
    340 REVERSE Sintaxis: REVERSE pin La instrucción“REVERSE” cambia el estado de un pin I/O, es decir, si el pin es entrada, éste pasa a ser salida. Si un pin es “salida”, éste pasa a ser entrada. Ejemplo: TRISB = %00000000 ' Configura los pines del puerto B como ' salida. Inicio: High PORTB.5 ' RB5 = 1 Pause 1000 ' Pausa de 1 segundo Low PORTB.5 ' RB5 = 0 Reverse PORTB.5 ' RB5 ahora es entrada End SELECT CASE Sintaxis: SELECT CASE variable La instrucción “SELECT CASE” es un condicional que permite seleccionar entre un número determinado de subrutinas. Ejemplo: ' Declaración de Variables I VAR Byte Z VAR Byte Pause 200 ' Pausa de 200 milisegundos LCDOut $fe, 1 ' Limpia la pantalla
  • 351.
    341 Z = 0' Inicializa la variable Z Inicio: Z = Z + 1 ' Incrementa la variable Z If Z = 4 Then Final ' Si Z = 4 salta a la etiqueta "Final" Select Case Z ' Condicional Select Case para la ' variable Z. Case 1 LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Select Case 1" ' Muestra mensaje por la LCD Pause 1500 ' Pausa de 1.5 segundos GoTo Inicio ' Salto a inicio Case 2 LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Select Case 2" ' Muestra mensaje por la LCD Pause 1500 ' Pausa de 1.5 segundos GoTo Inicio ' Salto a inicio Case 3 LCDOut $fe, 2 ' Posiciona el cursor en el inicio LCDOut "Select Case 3" ' Muestra mensaje por la LCD Pause 1500 ' Pausa de 1.5 segundos GoTo Inicio ' Salto a inicio End Select Final: GoTo Final End
  • 352.
    342 SERIN Sintaxis: SERIN pin, modo,{tiempo,etiqueta}, variable La instrucción “SerIn” se encarga de recibir uno o mas valores a través de un pin específico usando el formato asíncrono estándar 8N1 que significa 8 bits de datos, sin revisión de paridad y 1 bit de parada (stop). SerIn trabaja por defecto con un oscilador de 4 Mhz y para tener una transferencia de datos segura con otros osciladores de mayor valor, será necesario utilizar la directiva “Define Osc” al inicio del programa. Pin: en este campo definiremos cual será el pin de entrada entre los puertos disponibles del microcontrolador. Ejemplo: PortB.1 Modo: define la velocidad de transmisión en baudios. Tiempo: este campo es opcional al igual que el campo “etiqueta” y su objetivo es establecer un tiempo en milisegundos definido por el programador, el cual una vez vencido, hará que se realice un salto a la “etiqueta” también definida por el programador. Variable: en este campo se especifica la variable en la cual se desea sean almacenados los datos recibidos. Ejemplo: Symbol T9600 = 2 ' Dato verdadero (Driven True) dato var Byte ' Define la variable “dato” como Byte Pause 500 ' Pausa de 500 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Inicio: SerIn PORTC.7, T9600, dato ' espera datos durante 1 ms
  • 353.
    343 LCDOUT $fe, 2,"Dato:" LCDOut $fe,$C0,#dato," " GoTo Inicio ' Salta a inicio End SEROUT Sintaxis: SEROUT pin, modo, [variable] La instrucción “SerOut” se encarga de enviar uno o mas valores a través de un pin específico usando el formato asíncrono estándar 8N1 que significa 8 bits de datos, sin revisión de paridad y 1 bit de parada (stop). Pin: en este campo definiremos cual será el pin de salida entre los puertos disponibles del microcontrolador. Modo: define la velocidad de transmisión en baudios y emplea la misma tabla de la instrucción SerIn. Variable: en este campo se especifica la variable que contiene los datos que serán enviados a través de pin especificado. Ejemplo: Symbol T9600 = 2 ' Dato verdadero (Driven True) I VAR Byte ' Define la variable “I” como Byte Inicio: For I = 0 To 9 ' Repetición de 0 a 9 SerOut PORTC.6, T9600, [#I] ' “#” envía los datos en ASCII Pause 1000 ' Pausa de 1 segundo Next I
  • 354.
    344 GoTo Inicio 'Salta a inicio End SLEEP Sintaxis: SLEEP período La instrucción “SLEEP” lleva a un estado de bajo consumo de energía a un microcontrolador por un período de tiempo definido en segundos. Ejemplo: Inicio: Sleep 10 ' Bajo consumo de energía durante 10 segundos Espera: GoTo Espera ' Salta a la etiqueta "Espera" End SWAP Sintaxis: SWAP variable, variable La instrucción “SWAP” intercambia el contenido de dos variables. Ejemplo: A1 VAR Byte ' Define la variable "A1" como Byte B1 VAR Byte ' Define la variable "B1" como Byte
  • 355.
    345 A1 = 10 B1= 15 Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Inicio: Swap A1,B1 ' Intercambia datos entre variables LCDOUT $fe, 2,"A1: ",#A1 ' Muestra variable A1 por la LCD LCDOut $fe,$C0,"B1: ",#B1 ' Muestra variable B1 por la LCD Espera: GoTo Espera ' Salta a la etiqueta "Espera" End TOGGLE Sintaxis: TOGGLE pin La instrucción “TOGGLE” invierte el estado lógico de un pin específico, es decir, si un pin se encuentra en estado lógico cero (0), éste pasa a ser uno lógico (1) y viceversa. Ejemplo: High PORTA.0 ' Pone en uno (1) RA0 Inicio: Toggle PORTA.0 ' invierte el estado lógico de RA0 Pause 1000 ' Pausa de 1 segundo
  • 356.
    346 GoTo Inicio 'Salto a inicio End WHILE-WEND Sintaxis: WHILE condición ...instrucciones... WEND La instrucción “WHILE – WEND” mantiene la ejecución de las instrucciones involucradas, es decir, entre While y Wend, hasta que se cumpla la condición establecida. Ejemplo: A VAR Byte ' Declaración de variable "A" A = 0 ' Inicializa la variable "A" Pause 200 ' Pausa de 200 milisegundos para la LCD LCDOut $fe, 1 ' Limpia la LCD Inicio: While A < 5 ' Condicional While - Wend High PORTB.0 ' RB0 = 1 Pause 1000 ' Pausa de 1 segundo Low PORTB.0 ' RB0 = 0 PAUSE 1000 ' Pausa de 1 segundo A = A + 1 ' incrementa en uno (1) la variable "A" Wend
  • 357.
    347 LCDOUT $fe, 2,"While - Wend" ' Muestra mensaje LCDOut $fe,$C0,"ha terminado!" ' Muestra mensaje Espera: GoTo Espera ' Salta a la etiqueta "espera" End WRITE Sintaxis: WRITE dirección, variable La instrucción “WRITE” almacena datos en la memoria EEPROM de un microcontrolador en una dirección específica. Ejemplo: Inicio: WRITE 1, $03 ' Escribe en la dirección 1 o $01 el dato $03 WRITE 2, $A1 ' Escribe en la dirección 2 o $02 el dato $A1 WRITE 3, 7 ' Escribe en la dirección 3 o $03 el dato $07 WRITE 9, 13 ' Escribe en la dirección 9 o $09 el dato $0D WRITE 5, $F0 ' Escribe en la dirección 15 o $0F el dato $0F espera: GoTo espera End
  • 358.
    348 Apéndice A Programador deMicrocontroladores PIC Existe una gran diversidad de programadores para microcontroladores PIC los cuales puede adquirir en tiendas de electrónica OnLine o en su proveedor local de componentes electrónicos. Sin embargo, consideramos una excelente experiencia llevar a cabo la construcción de su propio programador por lo cual le proponemos uno de los más populares y prácticos, capaz de programar una gran variedad de modelos de microcontroladores PIC, de muy bajo costo y fácil construcción. Recomendamos P16Pro, programador de microcontroladores desarrollado por Bojan Dobaj de Slovenia, cuyo sitio oficial en la red es http://www.picallw.com. Figura A.1.
  • 359.
    349 Software: Descargue el softwareen su última versión en el sitio Web http://www.picallw.com, en la sección denominada “Download”. Una vez descargado el archivo, se precede a descomprimir el mismo para luego iniciar la instalación del software haciendo doble clic sobre el archivo ejecutable que ha resultado disponible, denominado “Setup.exe” A continuación se muestran las pantallas que se generan en el proceso de instalación del software: • La figura A.2 muestra el inicio del proceso de instalación del software. Figura A.2. • El instalador le mostrara un mensaje de bienvenida en el cual deberá seleccionar la opción “NEXT” para continuar con la instalación (Figura A.3).
  • 360.
    350 Figura A.3. • Luegodeberá indicar la ruta de instalación del software en el disco duro. La ruta propuesta por defecto es C:Picall (Figura A.4). Figura A.4. • En la siguiente pantalla, el programa instalador le sugiere un nombre para el icono o acceso al programa en la barra de inicio de Windows (Figura A.5).
  • 361.
    351 Figura A.5. • Alhacer clic en el botón “Install” (Figura A.6), empieza la instalación de archivos para finalmente completar el proceso haciendo clic en el botón “Finish” (Figura A.7). Figura A.6.
  • 362.
    352 Figura A.7. Configuración delSoftware Picall/P16Pro PIC: Para dar inicio al software Picall/P16Pro, haga clic en el menú “Inicio” de Windows Picall Picall v0.16. Inmediatamente se despliega la ventana de la figura A.9. Figura A.8.
  • 363.
    353 Figura A.9. Antes decomenzar a programar cualquier microcontrolador, se deberán seleccionar ciertos parámetros importantes en el software. Estos parámetros son los que mencionamos a continuación.
  • 364.
    354 Tipo de programador: Elprogramador se identifica en el software como “P16PRO” y usted deberá seleccionarlo en el campo correspondiente como se muestra en la Figura A.10. Figura A.10.
  • 365.
    355 Modelo del microcontrolador: Enel siguiente paso se deberá seleccionar el modelo de microcontrolador que desea programar. Figura A.11. Otro punto importante a verificar será el puerto seleccionado, el cual deberá estar en LPT Port = Auto. Esta opción se encuentra en el menú “Settings”.
  • 366.
    356 Figura A.12. El softwaretambién cuenta con ayuda visual para saber la posición exacta del microcontrolador en la base del programador, como se muestra en la figura A.13. Notará que al cambiar el modelo de microcontrolador a ser programado, la figura cambia indicando la posición adecuada para evitar daños irreversibles en el dispositivo.
  • 367.
  • 368.
    358 Apéndice B TablaASCII ASCII Control Characters Decimal Hex ASCII Function Key 0 0 NUL (null) Ctrl-@ 1 1 SOH (start of heading) Ctrl-A 2 2 STX (start of text) Ctrl-B 3 3 ETX (end of text) Ctrl-C 4 4 EOT (end of transmission) Ctrl-D 5 5 ENQ (enquiry) Ctrl-E 6 6 ACK (acknowledge) Ctrl-F 7 7 BEL (bell) Ctrl-G 8 8 BS (backspace) Ctrl-H 9 9 HT (horizontal tab) Ctrl-I 10 A LF (line feed) Ctrl-J 11 B VT (vertical tab) Ctrl-K 12 C FF (form feed) Ctrl-L 13 D CR (carriage return) Ctrl-M 14 E SO (shift out) Ctrl-N 15 F SI (shift in) Ctrl-O 16 10 DLE (data link escape) Ctrl-P 17 11 DC1 (device control 1) Ctrl-Q 18 12 DC2 (device control 2) Ctrl-R 19 13 DC3 (device control 3) Ctrl-S 20 14 DC4 (device control 4) Ctrl-T 21 15 NAK (negative acknowledge) Ctrl-U 22 16 SYN (synchronous idle) Ctrl-V 23 17 ETB (end of trans. block) Ctrl-W 24 18 CAN (cancel) Ctrl-X 25 19 EM (end of medium) Ctrl-Y 26 1A SUB (substitute) Ctrl-Z 27 1B ESC (escape) Ctrl-[ 28 1C FS (file separator) Ctrl- 29 1D GS (group separator) Ctrl-] 30 1E RS (record separator) Ctrl-^ 31 1F US (unit separator) Ctrl-_ Tabla B.1. Fuente: http://www.melabs.com/resources/pbpmanual/
  • 369.
    359 Caracteres ASCII Standard DecimalHex Display / Key 32 20 Space 33 21 ! 34 22 " 35 23 # 36 24 $ 37 25 % 38 26 & 39 27 ' 40 28 ( 41 29 ) 42 2A * 43 2B + 44 2C , 45 2D - 46 2E . 47 2F / 48 30 0 49 31 1 50 32 2 51 33 3 52 34 4 53 35 5 54 36 6 55 37 7 56 38 8 57 39 9 58 3A : 59 3B ; 60 3C < 61 3D = 62 3E > 63 3F ? Decimal Hex Display / Key 64 40 @ 65 41 A 66 42 B 67 43 C 68 44 D 69 45 E 70 46 F 71 47 G 72 48 H 73 49 I 74 4A J 75 4B K 76 4C L 77 4D M 78 4E N 79 4F O 80 50 P 81 51 Q 82 52 R 83 53 S 84 54 T 85 55 U 86 56 V 87 57 W 88 58 X 89 59 Y 90 5A Z 91 5B [ 92 5C 93 5D ] 94 5E ^ 95 5F _ Decimal Hex Display / Key 96 60 ` 97 61 a 98 62 b 99 63 c 100 64 d 101 65 e 102 66 f 103 67 g 104 68 h 105 69 i 106 6A j 107 6B k 108 6C l 109 6D m 110 6E n 111 6F o 112 70 p 113 71 q 114 72 r 115 73 s 116 74 t 117 75 u 118 76 v 119 77 w 120 78 x 121 79 y 122 7A z 123 7B { 124 7C | 125 7D } 126 7E ~ 127 7F DEL Tabla B.2. Fuente: http://www.melabs.com/resources/pbpmanual/
  • 370.
    360 Apéndice C Softwarey Practicas en Formato Digital
  • 371.
    361 Se pueden obtenerlos archivos digitales de cada uno de los proyectos planteados en esta obra (archivo fuente en pbp de cada proyecto y archivo compilado .hex), ingresando al sitio Web: http://www.conexionelectronica.com
  • 372.
    362 Bibliografía INTERNET: Microchip Technology Inc.,http://www.microchip.com microEngineering Labs, Inc., http://www.melabs.com Mecanique, http://www.mecanique.co.uk Picallw, http://www.picallw.com Wikipedia, http://es.wikipedia.org Linx Technologies, http://www.linxtechnologies.com Empresas: microEngineering Labs, Inc. Box 60039 Colorado Springs CO 80960 Tel. (719) 520-5323 Fax. (719) 520-1867 http://www.melabs.com Microchip Technology Inc. 2355 W. Chandler Blvd. Chandler AZ 85224-6199 Tel. (602) 786-7200 Fax. (602) 899-9210 http://www.microchip.com Mecanique 85 Marine Parade SaltBurn by the Sea TS12 1BZ United Kingdom Tel. +44 1287 622382 Fax. +44 8700 520279 http://www.mecanique.co.uk