Sei sulla pagina 1di 8

4.

4 EJEMPLO 2
Utilizar instrucciones en ensamblador y el oscilador interno LFINTOSC...
En realidad, esto es una continuacin del ejemplo anterior, pero se ocupa de un problema un poco ms
complicado... El propsito es hacer los LEDs en el puerto PORTB parpadear lentamente. Se puede realizar al
introducir un valor suficiente grande para el parmetro del tiempo de retardo en la funcin Delay. No obstante,
hay otra manera ms eficiente para ejecutar el programa lentamente. Acurdese de que este microcontrolador
tiene un oscilador incorporado LFINTOSC que funciona a una frecuencia de 31kHz. Ahora lleg la hora de
darle una oportunidad.

El programa se inicia con el bucle do-while y se queda all por 20 ciclos. Despus da cada iteracin, llega el
tiempo de retardo de 100ms, indicado por un parpadeo relativamente rpido de los LEDs en el puerto PORTB.
Cuando el programa salga de este bucle, el microcontrolador se inicia al utilizar el oscilador LFINTOSC como
una fuente de seal de reloj. Los LEDs parpadean ms lentamente aunque el programa ejecuta el mismo
bucle do-while con un tiempo de retardo 10 veces ms corto.

Con el propsito de hacer evidentes algunas situaciones potencialmente peligrosas, se activan los bits de
control por medio de las instrucciones en ensamblador. Dicho de manera sencilla, al entrar o salir una
instruccin en ensamblador en el programa, el compilador no almacena los datos en un banco actualmente
activo de la RAM, lo que significa que en esta seccin de programa, la seleccin de bancos depende del
registro SFR utilizado. Al volver a la seccin de programa escrito en Basic, los bits de control RP0 y RP1
deben recuperar el estado que tenan antes de introducir la secuencia en ensamblador. En este caso se utiliza
la variable auxiliar saveBank para guardar el estado de estos dos bits.
'Cabecera *********************************************
program example_2 ' Nombre de programa
dim k as byte ' Variable k es de tipo byte
dim saveBank as byte ' Variable saveBank es de tipo byte
main: ' Inicio del programa
k = 0 ' Valor inicial de la variable k
ANSEL = 0 ' Todos los pines de E/S se configuran como
digitales
ANSELH = 0
PORTB = 0 ' Todos los pines del puerto PORTB se ponen a 0
TRISB = 0 ' Pines del puerto PORTB se configuran como salidas

do
PORTB = not PORTB ' Invertir el estado lgico del puerto PORTB
Delay_ms(100) ' Tiempo de retardo de 100mS
k = k+1 ' Incrementar k en 1
loop until k=20 ' Quedarse en bucle hasta que k<20

k=0 ' Reiniciar variable k
saveBank = STATUS and %01100000 ' Guardar el estado de los bits RP0 y
RP1
' (bits 5 y 6 del registro STATUS)
asm ' Inicio de una secuencia en ensamblador
bsf STATUS,RP0 ' Seleccionar el banco de memoria que contiene el
bcf STATUS,RP1 ' registro OSCCON
bcf OSCCON,6 ' Seleccionar el oscilador interno LFINTOSC
bcf OSCCON,5 ' de frecuencia de 31KHz
bcf OSCCON,4
bsf OSCCON,0 ' Microcontrolador utiliza oscilador interno
end asm ' Final de la secuencia en ensamblador

STATUS = STATUS and %10011111 ' Bits RP0 y RP1 recuperan el estado
original
STATUS = STATUS or saveBank

do
PORTB = not PORTB ' Invertir el estado lgico del puerto PORTB
Delay_ms(10) ' Tiempo de retardo de 10 mS
k = k+1 ' Incrementar k en 1
loop until k=20 ' Quedarse en el bucle hasta que k<20

stay_here: goto stay_here ' Bucle infinito

end. ' Final de programa
Usted ha notado que la seal de reloj ha sido cambiado al vuelo. Para asegurarse de eso, quite el cristal de
cuarzo antes de encender al microcontrolador. El microcontrolador no podr empezar a funcionar porque la
Palabra de Configuracin cargada en el programa requiere proporcionar el cristal de cuarzo. Al quitar el cristal
ms tarde durante el funcionamiento, no pasar nada, o sea, eso no afectar nada al microcontrolador.
4.5 EJEMPLO 3
Timer0 como un contador, declarar variables nuevas, utilizar smbolos,
utilizar rels...
En cuanto a los ejemplos anteriores, el microcontrolador ha ejecutado el programa sin haber sido afectado de
ninguna forma por su entorno. En la prctica, hay pocos dispositivos que funcionen de esta manera (por
ejemplo, un simple controlador de luz de nen). Los pines de entrada se utilizan tambin en este ejemplo. En
la siguiente figura se muestra un esquema, mientras que el programa est en la siguiente pgina. Todo sigue
siendo muy simple. El temporizador TMR0 se utiliza como un contador. La entrada del contador est
conectada a un botn de presin, as que cada vez que se presiona el botn, el temporizador Timer0 cuenta
un pulso. Cuando el nmero de pulsos coincida con el nmero almacenado en el registro TEST, un uno lgico
(5V) aparecer en el pin PORTD.3. Este voltaje activa un rel electromecnico, y por eso este bit se le
denomina REL en el programa.
En este ejemplo, el registro TEST almacena el nmero 5. Por supuesto, eso puede ser cualquier nmero
obtenido al calcular o definido como una constante. Adems, el microcontrolador puede activar algn otro
dispositivo en vez de rel, mientras que el sensor se puede utilizar en vez del botn de presin. Este ejemplo
muestra una de las aplicaciones ms comunes del microcontrolador en la industria; al realizar una cosa el
suficiente nmero de veces, otra cosa debe estar encendida o apagada.

' Cabecera ******************************************************
program example_3 ' Nombre del programa
symbol RELAY = PORTD.3 ' Pin del puerto PORTD.3 es denominado REL
dim TEST as byte ' Variable TEST es de tipo byte
main: ' Inicio del programa
TEST = 5 ' Constante TEST = 5
ANSEL = 0 ' All I/O pins are configured as digital
ANSELH = 0
PORTA = 0 ' Reiniciar el puerto PORTA
TRISA = 0xFF ' Todos los pines de E/S se configuran como
digitales
PORTD = 0 ' Reiniciar el puerto PORTD
TRISD = %11110111 ' Pin RD3 se configura como una salida, mientras
que los
' dems se configuran como entradas
OPTION_REG.5 = 1 ' Contador TMR0 recibe los pulsos por el pin RA4
OPTION_REG.3 = 1 ' Valor del pre-escalador es 1:1
TMR0 = 0 ' Reiniciar el temporizador/contador TMR0

while 1
if TMR0 = TEST then ' Coincide el nmero en el temporizador con la
constante TEST?
RELAY = 1 ' Nmeros coinciden. Poner el bit RD3 a uno
(salida REL)
end if
wend ' Quedarse en el bucle infinito

end. ' Final de programa
Slo un smbolo (REL) se utiliza aqu. Se le asigna el tercer pin del puerto PORTD en la declaracin.
symbol RELAY = PORTD.3 ' Smbolo REL = PORTD.3
4.6 EJEMPLO 4
Utilizar los temporizadores Timer0, Timer1 y Timer2. Utilizar interrupciones, declarar
nuevos procedimientos...
Al analizar los ejemplos anteriores, es probable que se haya fijado en la desventaja de proporcionar tiempo de
retardo por medio de la funcin Delay. En estos casos, el microcontrolador se queda esttico y no hace nada.
Simplemente espera que transcurra una cierta cantidad de tiempo. Tal prdida de tiempo es un lujo
inaceptable, por lo que se deber aplicar otro mtodo.
Se acuerda usted del captulo de los temporizadores? Se acuerda de lo de interrupciones? Este ejemplo los
conecta de una manera prctica. El esquema se queda inalterada, y el desafo sigue siendo presente. Es
necesario proporcionar un tiempo de retardo suficiente largo para darse cuenta de los cambios en el puerto.
Para este propsito se utiliza el temporizador TMR0 con el pre-escalador asignado. Siempre que se genere
una interrupcin con cada desbordamiento en el registro del temporizador, la variable cnt se aumenta
automticamente en 1 al ejecutarse cada rutina de interrupcin. Cuando la variable llega al valor 50, el puerto
PORTB se incrementa en 1. Todo el procedimiento se lleva a cabo entre bastidores, lo que habilita al
microcontrolador hacer otra tarea.

' Cabecera******************************************************
program example_4a ' Inicio del programa
dim cnt as byte ' Definir la variable cnt como un byte

sub procedure interrupt ' Este subprocedimiento determina qu se lo que
se
' debe hacer cuando se genere una interrupcin
cnt = cnt + 1 ' Interrupcin causa que la cnt se incremente en
1
TMR0 = 96 ' El valor inicial se devuelve en el
temporizador TMR0
INTCON = 0x20 ' Bit T0IE se pone a 1, el bit T0IF se pone a 0
end sub ' Final de la rutina de interrupcin

main: ' Inicio del programa
OPTION_REG = 0x84 ' Pre-escalador se le asigna al temporizador
TMR0
ANSEL = 0 ' Todos los pines de E/S se configuran como
digitales
ANSELH = 0
TRISB = 0 ' Todos los pines de puerto PORTB se configuran
como salidas
PORTB = 0x0 ' Reiniciar el puerto PORTB
TMR0 = 96 ' Temporizador T0 cuenta de 96 a 255
INTCON = 0xA0 ' Habilitada interrupcin TMR0
cnt = 0 ' A la variable cnt se le asigna un 0

while 1 ' Bucle infinito
if cnt = 50 then ' Incrementar el puerto PORTB despus 50
interrupciones
PORTB = PORTB + 1 ' Incrementar nmero en el puerto PORTB en 1
cnt = 0 ' Reiniciar la variable cnt
end if
wend

end. ' Final de programa

Siempre que se produzca un desbordamiento en el registro del temporizador TRM0, ocurre una interrupcin.
'Cabecera******************************************************
program example_4b ' Nombre del programa
dim cnt as byte ' Definir la variable cnt

sub procedure interrupt ' Definir el subprocedimiento de interrupcin
cnt = cnt+1 ' Interrupcin causa que la cnt se incremente en
1
PIR1.TMR1IF = 0 ' Reiniciar el bit TMR1IF
TMR1H = 0x80 ' El valor inicial se devuelve en los registros
TMR1L = 0x00 ' del temporizador TMR1H y TMR1L
end sub ' Final de la rutina de interrupcin

main: ' Inicio del programa
ANSEL = 0 ' Todos los pines de E/S se configuran como
digitales
ANSELH = 0
PORTB = 0xF0 ' Valor inicial de los bits del puerto PORTB
TRISB = 0 ' Los pines del puerto PORTB se configuran como
salidas
T1CON = 1 ' Configurar el temporizador TMR1
PIR1.TMR1IF = 0 ' Reiniciar el bit TMR1IF
TMR1H = 0x80 ' Poner el valor inicial para el temporizador
TMR1
TMR1L = 0x00
PIE1.TMR1IE = 1 ' Habilitar la interrupcin al producirse un
desbordamiento
cnt = 0 ' Reiniciar la variable cnt
INTCON = 0xC0 ' Interrupcin habilitada (bits GIE y PEIE)

while 1 ' Bucle infinito
if cnt = 76 then ' Cambiar el estado del puerto PORTB despus de
76 interrupciones
PORTB = not PORTB ' Nmero en el puerto PORTB est invertido
cnt = 0 ' Reiniciar la variable cnt
end if
wend

end. ' Final de programa

En este caso, una interrupcin se habilita despus de que se produzca un desbordamiento en el registro del
temporizador TMR1 (TMR1H, TMR1L). Adems, la combinacin de los bits que vara en el puerto POTRB
difiere de la en el ejemplo anterior.
'Cabecera******************************************************
program example_4c ' Nombre del programa
dim cnt as byte ' Definir la variable cnt como un byte

sub procedure Replace ' Definir el procedimiento Reemplazar
PORTB = not PORTB ' Definir el nuevo procedimiento Reemplazar
end sub ' Procedimiento invierte el estado del puerto

sub procedure interrupt ' Definir el subprocedimiento de interrupcin
if PIR1.TMR2IF then ' Si el bit TMR2IF = 1,
cnt = cnt +1 ' Incrementar variable la cnt en 1
PIR1.TMR2IF = 0 ' Reiniciar el bit y
TMR2 = 0 ' Reiniciar el registro TMR2
end if
end sub ' Final de la rutina de interrupcin

main: ' Inicio del programa
cnt = 0 ' Reiniciar la variable cnt
ANSEL = 0 ' Todos los pines de E/S se configuran como
digitales
ANSELH = 0
PORTB = %10101010 ' Estado lgico en los pines del puerto PORTB
TRISB = 0 ' Todos los pines del puerto PORTB se configuran
como salidas
T2CON = 0xFF ' Configurar el temporizador T2
TMR2 = 0 ' Valor inicial del registro del temporizador
TMR2
PIE1.TMR2IE = 1 ' Interrupcin habilitada
INTCON = 0xC0 ' Bits GIE y PEIE se ponen a 1

while 1 ' Bucle infinito
if cnt > 30 then ' Cambiar el estado del puerto PORTB despus de
ms de 30 interrupciones
Replace ' Subprocedimiento Reemplazar invierte el estado
del puerto PORTB
cnt = 0 ' Reset variable cnt
end if
wend

end. ' Final de programa

En este ejemplo, una interrupcin ocurre despus de que se produce un desbordamiento en el registro del
temporizador TMR2. Para invertir el estado lgico de los pines del puerto se utiliza el procedimiento
Reemplazar, que normalmente no pertenece al lenguaje mikroBasic.