El objetivo de la primera práctica será hacer parpadear un led cada que pase un segundo, para esto será importante conocer algunos conceptos así como parte del funcionamiento del PIC.
Lo primero será hablar de los registros PORTx y TRISx, donde la “x” indica a que puerto está asociado, por ejemplo PORTA está asociado al puerto A, PORTB al puerto B, etc.
En el registro TRISx escribiremos la información necesario para indicar si el puerto asociado será entrada o salida, en este caso como queremos hacer parpadear un led será puertos de salida, por lo tanto le tendremos que asignar al puerto TRISx el valor 0x00. Se dividirá en dos partes la descripción del código, una parte para trabajar con Miuva (18F4550) y una parte para trabajar con Miuva Pro (18F87J50).
Para escribir un valor en algún registro en particular, utilizaremos primero la instrucción movlw que lo que hará es guardar el valor indicado en el registro de trabajo, para posteriormente utilizar movwf que lo que hará es mover la información del registro de trabajo al registro f.
En Miuva el led RGB está ubicado en el puerto E:
movlw 0x00 movwf TRISE ;Configura PUERTO E como salida
Los colores del led RGB de Miuva encienden con un valor lógico “0”, y el valor por defecto del puerto E es “bajo”, por lo tanto en primera instancia todos los colores están encendidos para lo cual se requieren apagar, esto se puede hacer poniendo en alto los pines 0, 1 y 2 del puerto E, o dicho de otra forma, colocando un 0x07 en el registro PORTE:
movlw 0x07 movwf PORTE ;Valores iniciales del puerto E para apagar el led RGB
Vamos a crear ahora un retardo de 1 segundo, para el parpadeo del led, esto puede realizarse de muchas formas, una de ellas será creando diferentes variables, iremos decrementando su valor hasta que lleguen a cero, de esta forma si sabemos a que velocidad están contando y cuando llegaron de un número a otro, podremos saber cuanto tiempo ha pasado; para esto son importantes diferentes conceptos.
Ciclo de reloj
El ciclo de reloj está dado por la frecuencia del oscilador que estemos utilizando, por ejemplo, con una frecuencia del oscilador de 8MHz, el ciclo de reloj está dado por:
Ciclo_reloj = 1/Fosc = 1 / 8MHz =125ns
Ciclo máquina o ciclo de instrucción
Es el tiempo que tarda nuestro CPU en ejecutar una instrucción en lenguaje máquina, esto es equivalente a 4 ciclos de reloj, por lo tanto:
Ciclo_máquina = 4 * ciclo_reloj = 125ns*4 = 500ns
La función que utilizaremos para decrementar el valor de los contadores es DECFSZ la cual según las hojas de especificaciones tarda 3 ciclos máquina en ejecutarse. Por lo tanto, considerando que la variable será de 8 bits, el tiempo que tardará en llegar de 255 a 0 estará dado por:
tiempo = 255 * (3*500ns) = 382.5us
Si utilizamos dos contadores el tiempo será:
tiempo = 255*255*(3*500ns) = 97.5375ms
Si colocamos un tercer contador que vaya del 11 al 0, el tiempo será:
tiempo = 11*255*255*(3*500ns) = 1.073 s
Entonces tendremos que crear tres variables a las que llamaremos retardos, dos iniciadas en 255 y la otra en 11, para que cuando las tres lleguen a 0 haya pasado aproximadamente 1 segundo.
Para reservar un espacio de memoria para las variables se utilizan las siguientes líneas:
CBLOCK 0x000
Ret1 ;Variables para los retardos de 1 segundo
Ret2
Ret3
ENDC
Posteriormente tenemos que darle a cada Retx (retardo) el valor indicado:
movlw D'255' ;Cargamos los valores de los retardos a las constantes movwf Ret1 ;correspondientes movlw D'255' movwf Ret2 movlw D'11' movwf Ret3
La función DECFSZ decrementará el valor, posteriormente, si el valor es 0 saltará la siguiente línea del código, si el valor es diferente de 0, seguirá con la siguiente línea de código, por ejemplo, utilizando el siguiente código:
Ret1sON
decfsz Ret1, F ;Decrementa el valor de Ret1 y salta si es igual a 0
bra Ret1sON ;Saltamos a Ret1sON
;Continuación del código
Se decrementa Ret1, si su valor es diferente de 0, se ejecuta la siguiente línea (bra Ret1sON) la cual nos lleva a la etiqueta “Ret1sON”, y vuelve a ejecutarse el decremente, en el momento en que el valor de Ret1 se vuelva 0, saltará la línea “bra” y seguirá con la continuación del código.
De esta forma crearemos una sección para el retardo de 1 segundo y encender el led, y otra para el retardo de 1 segundo y apagar el led. Siendo ambos similares:
Retardo1sON
movlw D'255' ;Cargamos los valores de los retardos a las constantes
movwf Ret1 ;correspondientes
movlw D'255'
movwf Ret2
movlw D'11'
movwf Ret3
Ret1sON
decfsz Ret1, F ;Decrementa el valor de Ret1 y salta si es igual a 0
bra Ret1sON ;Saltamos a Ret1sON
decfsz Ret2, F ;Decremente el valor de Ret2 y salta si es igual a 0
bra Ret1sON ;Saltamos a Ret1sON
decfsz Ret3, F ;Decremente el valor de Ret3 y salta si es igual a 0
bra Ret1sON ;Saltamos a Ret1sON
movlw 0x06
movwf PORTE ;Encendemos el led ubicado en E0
Con esto ya tenemos el contenido del código para parpadear el led, solamente habrá que agregar la parte del apagado del led (que es similar a la del encendido) y las líneas de configuración, en ellas debemos especificar el pic que estamos utilizando y agregar la librería correspondiente, posteriormente agregar los fusibles necesarios para el funcionamiento adecuado.
CÓDIGO FINAL
LIST P = 18F4550 ;PIC a utilizar
INCLUDE <P18F4550.INC>
;************************************************************
;Configuración de fusibles
CONFIG FOSC = HS
CONFIG PWRT = ON
CONFIG BOR = OFF
CONFIG WDT = OFF
CONFIG MCLRE = ON
CONFIG PBADEN = OFF
CONFIG LVP = OFF
CONFIG DEBUG = OFF
CONFIG XINST = OFF
;***********************************************************
;Código
CBLOCK 0x000
Ret1 ;Variables para los retardos de 1 segundo
Ret2
Ret3
ENDC
;Código
ORG 0x0000 ;Vector de reset
goto INICIO
;Inicio del programa principal
INICIO
movlw 0x0F
movwf ADCON1 ;Configuración de entradas digitales
movlw 0x00
movwf TRISE ;Configura PUERTO E como salida
movlw 0x07
movwf PORTE ;Valores iniciales del puerto E para apagar el led RGB
BUCLE
; Calculo de los valores de las variables para el retardo de aproximadamente
; 1 segundo
;
; fosc = 8MHz
; Ciclo Reloj = 1/fosc = 1/8M = 125ns
; Ciclo Instruccion = 4*Ciclo Reloj = 500ns
; La funcion DECFSZ tarda 3 ciclos en ejecutarse
; Retardo 15ms
; Tiempo = Ret1*Ret2*Ret3*(3*500ns)
; Tiempo = Ret1*Ret2*Ret3*(1.5us)
; Ret1 = 255
; Ret2 = 255
; Ret3 = 11
; Tiempo = (255*255*11)(1.5us) = 1.0729 seg
;Retardo de un segundo para encender el LED
Retardo1sON
movlw D'255' ;Cargamos los valores de los retardos a las constantes
movwf Ret1 ;correspondientes
movlw D'255'
movwf Ret2
movlw D'11'
movwf Ret3
Ret1sON
decfsz Ret1, F ;Decrementa el valor de Ret1 y salta si es igual a 0
bra Ret1sON ;Saltamos a Ret1sON
decfsz Ret2, F ;Decremente el valor de Ret2 y salta si es igual a 0
bra Ret1sON ;Saltamos a Ret1sON
decfsz Ret3, F ;Decremente el valor de Ret3 y salta si es igual a 0
bra Ret1sON ;Saltamos a Ret1sON
movlw 0x06
movwf PORTE ;Encendemos el led ubicado en E0
;Mismo retardo pero ahora para esperar antes de apagar el LED
Retardo1sOFF
movlw .255
movwf Ret1
movlw .255
movwf Ret2
movlw .11
movwf Ret3
Ret1sOFF
decfsz Ret1, F
bra Ret1sOFF
decfsz Ret2, F
bra Ret1sOFF
decfsz Ret3, F
bra Ret1sOFF
movlw 0x07
movwf PORTE ;Apaga el LED
goto BUCLE ;Regresa al INICIO
END ;Fin de Programa
Funcionamiento
