97697986 practicas en mplab
TRANSCRIPT
Prender un led con un 16F84A por RB0, de lo mas sencillo
Código
GeSHi (asm):
; 02-06-06
; Ejemplo 01
; Prender un led
; PIC 16f84a
; MPLAB 7.30
; PROTEUS 6.9 SP3
; Veguepic
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>
__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; osc XT
ORG 0
BSF STATUS,5 ; activa la pagina 1
MOVLW B'00000' ; carga 00000 en W
MOVWF TRISA ; puerto a todos salidas
MOVLW B'00000000' ; carga 00000000 en W
MOVWF TRISB ; puerto b todos salidaS
BCF STATUS,5 ; volvemos a la pagina 0
BCF PORTB,0 ; ponemos a 0 RB0
BCF PORTB,1 ; ponemos a 0 RB1
BCF PORTB,2 ; ponemos a 0 RB2
BCF PORTB,3 ; ponemos a 0 RB3
BCF PORTB,4 ; ponemos a 0 RB4
BCF PORTB,5 ; ponemos a 0 RB5
BCF PORTB,6 ; ponemos a 0 RB6
BCF PORTB,7 ; ponemos a 0 RB7
; luego haremos todos juntos
INICIO ; etiqueta
BSF PORTB,0 ; pone a 1 RB0
GOTO INICIO ; va a inicio
END ; fin de programa
Prender y apagar un led cada 0.5 segundos con un 16F84A por RB0
Código
GeSHi (asm):
; 02-06-06
; Ejemplo 02
; Prende y apagar un led cada 0.5 seg
; PIC 16f84a
; MPLAB 7.30
; PROTEUS 6.9 SP3
; Veguepic
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>
__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; osc XT
PDel0 equ 0C
PDel1 equ 0D
ORG 0
BSF STATUS,5 ; activa la pagina 1
MOVLW B'00000' ; carga 00000 en W
MOVWF TRISA ; puerto a todos salidas
MOVLW B'00000000' ; carga 00000000 en W
MOVWF TRISB ; puerto b todos salidaS
BCF STATUS,5 ; volvemos a la pagina 0
MOVLW B'00000000' ; ponemos a cero el
MOVWF PORTB ; el puerto b
; usando esta opcion se ahorran
; 6 bytes en comparacion con el
; ejemplo 01
INICIO ; etiqueta
BSF PORTB,0 ; pone a 1 RB0
CALL DEMORA ; llama a demora de 0,5 seg
BCF PORTB,0 ; pone a 0 RB0
CALL DEMORA ; llama a demora de 0,5 seg
GOTO INICIO ; va a inicio
;-------------------------------------------------------------
; La demora a sido generada con el programa PDEL
; Delay 250000 ciclos
;-------------------------------------------------------------
DEMORA movlw .197 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1
PLoop1 movlw .253 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1,1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0,1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2
return ; 2+2 Fin.
;---------------------------------------
END ; fin de programa
Prender y apagar 4 leds cada segundo (RB0 a RB3). 0,5 segundos prendido y 0,5 segundos apagado
con un 16F84A
Código
GeSHi (asm):
; 03-06-06
; Ejemplo 03
; Prender y apagar un 4 leds cada 1 seg
; PIC 16f84a
; MPLAB 7.30
; PROTEUS 6.9 SP3
; Veguepic
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>
__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; osc XT
PDel0 equ 0C
PDel1 equ 0D
ORG 0
BSF STATUS,5 ; activa la pagina 1
MOVLW B'00000' ; carga 00000 en W
MOVWF TRISA ; puerto a todos salidas
MOVLW B'00000000' ; carga 00000000 en W
MOVWF TRISB ; puerto b todos salidaS
BCF STATUS,5 ; volvemos a la pagina 0
MOVLW B'00000000' ; ponemos a cero el
MOVWF PORTB ; el puerto b
; usando esta opcion se ahorran
; 6 bytes en comparacion con el
; ejemplo 01
INICIO ; etiqueta
MOVLW B'00001111' ; prendemos leds RB0 a RB3
MOVWF PORTB ; cargamos el puerto b
CALL DEMORA ; llama a demora de 0,5 seg
MOVLW B'00000000' ; apagamos leds RB0 a RB3
MOVWF PORTB ; cargamos el puerto b
CALL DEMORA ; llama a demora de 0,5 seg
GOTO INICIO ; va a inicio
;-------------------------------------------------------------
; La demora a sido generada con el programa PDEL
; Delay 500000 ciclos
;-------------------------------------------------------------
DEMORA movlw .239 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .232 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL4 goto PDelL5 ; 2 ciclos delay
PDelL5 goto PDelL6 ; 2 ciclos delay
PDelL6 goto PDelL7 ; 2 ciclos delay
PDelL7 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;---------------------------------------
END ; fin de programa
Efecto de luces tipo Auto Fantastico con un 16F84A por el puerto b, RB0 a RB7
Código
GeSHi (asm):
; 04-06-06
; Ejemplo 04
; Luces del Auto fantastico
; PIC 16f84a
; MPLAB 7.30
; PROTEUS 6.9 SP3
; Veguepic
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>
__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; osc XT
PDel0 equ 0C
PDel1 equ 0D
ORG 0
BSF STATUS,5 ; activa la pagina 1
MOVLW B'00000' ; carga 00000 en W
MOVWF TRISA ; puerto a todos salidas
MOVLW B'00000000' ; carga 00000000 en W
MOVWF TRISB ; puerto b todos salidaS
BCF STATUS,5 ; volvemos a la pagina 0
MOVLW B'00000000' ; ponemos a cero el
MOVWF PORTB ; el puerto b
INICIO ; etiqueta
BSF PORTB,0 ; prendemos y apagamos
CALL DEMORA ; led por led
BCF PORTB,0 ; despues trataremos de
; usar otra funcion
BSF PORTB,1
CALL DEMORA
BCF PORTB,1
BSF PORTB,2
CALL DEMORA
BCF PORTB,2
BSF PORTB,3
CALL DEMORA
BCF PORTB,3
BSF PORTB,4
CALL DEMORA
BCF PORTB,4
BSF PORTB,5
CALL DEMORA
BCF PORTB,5
BSF PORTB,6
CALL DEMORA
BCF PORTB,6
BSF PORTB,7
CALL DEMORA
BCF PORTB,7
BSF PORTB,6
CALL DEMORA
BCF PORTB,6
BSF PORTB,5
CALL DEMORA
BCF PORTB,5
BSF PORTB,4
CALL DEMORA
BCF PORTB,4
BSF PORTB,3
CALL DEMORA
BCF PORTB,3
BSF PORTB,2
CALL DEMORA
BCF PORTB,2
BSF PORTB,1
CALL DEMORA
BCF PORTB,1
GOTO INICIO ; va a inicio
;-------------------------------------------------------------
; La demora a sido generada con el programa PDEL
; Descripcion: Delay 100000 ciclos - 100 ms
;-------------------------------------------------------------
DEMORA movlw .110 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .181 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------
END ; fin de programa
El codigo anterior ocupaba 65 espacios de memoria de 1024 dispònibles, optimizando el
codigo anterior ahora ocupa solo 33 usando las funciones RLF y RRF.
Código
GeSHi (asm):
; 05-06-06
; Ejemplo 05
; Luces del Auto fantastico - optimizado
; PIC 16f84a
; MPLAB 7.30
; PROTEUS 6.9 SP3
; Veguepic
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>
__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; osc XT
PDel0 equ 0C
PDel1 equ 0D
ORG 0
BSF STATUS,5 ; activa la pagina 1
MOVLW B'00000' ; carga 00000 en W
MOVWF TRISA ; puerto a todos salidas
MOVLW B'00000000' ; carga 00000000 en W
MOVWF TRISB ; puerto b todos salidaS
BCF STATUS,5 ; volvemos a la pagina 0
CLRF PORTB ; ponemos a cero el puerto b
INICIO ; etiqueta
BSF PORTB,0 ; prende RB0
BCF STATUS,0 ; limpia el carry de STATUS,C
REPETIR
IZQ
CALL DEMORA ; demora de 100ms
RLF PORTB,1 ; rota el contenido de portb a la derecha
BTFSS PORTB,7 ; hasta que prenda RB7, luego se salta
GOTO IZQ ; una linea
DER
CALL DEMORA ; demora de 100 ms
RRF PORTB,1 ; rota el contenido de portb a la izquierda
BTFSS PORTB,0 ; hasta que prenda RB0, luego salta
GOTO DER ; una linea
GOTO REPETIR ; repite el ciclo
GOTO INICIO ; va a inicio
;-------------------------------------------------------------
; La demora a sido generada con el programa PDEL
; Descripcion: Delay 100000 ciclos - 100 ms
;-------------------------------------------------------------
DEMORA movlw .110 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .181 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------
END ; fin de programa
Juego de luces, las luces se cruzan de lado a lado.
Código
GeSHi (asm):
; 06-06-06
; Ejemplo 06
; Juego de luces
; PIC 16f84a
; MPLAB 7.30
; PROTEUS 6.9 SP3
; Veguepic
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>
__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; osc XT
PDel0 equ 0C
PDel1 equ 0D
; el efecto que se busca es de dos luces que parten de los extremos expuestos y se muevan
; de lado a lado.
SEC1 equ B'10000001'
SEC2 equ B'01000010'
SEC3 equ B'00100100'
SEC4 equ B'00011000'
; se podri haber seguido con
; SEC5 equ B'00100100' pero es igual a SEC3 y asi para los demas
; por lo que se invierte la secuencia SEC3, SEC2, SEC1
ORG 0
BSF STATUS,5 ; activa la pagina 1
MOVLW B'00000' ; carga 00000 en W
MOVWF TRISA ; puerto a todos salidas
MOVLW B'00000000' ; carga 00000000 en W
MOVWF TRISB ; puerto b todos salidaS
BCF STATUS,5 ; volvemos a la pagina 0
CLRF PORTB ; ponemos a cero el puerto b
INICIO ; etiqueta
REPETIR
MOVLW SEC1 ; carga el valor de SEC1 en W
MOVWF PORTB ; carga w en el puerto b
CALL DEMORA ; demora de 100ms
MOVLW SEC2 ; carga el valor de SEC2 en W
MOVWF PORTB ; carga w en el puerto b
CALL DEMORA ; demora de 100ms
MOVLW SEC3 ; carga el valor de SEC3 en W
MOVWF PORTB ; carga w en el puerto b
CALL DEMORA ; demora de 100ms
MOVLW SEC4 ; carga el valor de SEC4 en W
MOVWF PORTB ; carga w en el puerto b
CALL DEMORA ; demora de 100ms
MOVLW SEC3 ; carga el valor de SEC3 en W
MOVWF PORTB ; carga w en el puerto b
CALL DEMORA ; demora de 100ms
MOVLW SEC2 ; carga el valor de SEC2 en W
MOVWF PORTB ; carga w en el puerto b
CALL DEMORA ; demora de 100ms
MOVLW SEC1 ; carga el valor de SEC1 en W
MOVWF PORTB ; carga w en el puerto b
CALL DEMORA ; demora de 100ms
GOTO INICIO ; va a inicio
;-------------------------------------------------------------
; La demora a sido generada con el programa PDEL
; Descripcion: Delay 100000 ciclos - 100 ms
;-------------------------------------------------------------
DEMORA movlw .110 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .181 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------
END ; fin de programa
Juego de luces, son dos luces que se mueven en 4 posiciones de lado a lado. Movemos una luz de
lado a lado entre los cuatro bits bajos y con la funcion SWAPF copiamos para los bits altos.
Código
GeSHi (asm):
; 11-06-06
; Ejemplo 07
; Juego de luces
; PIC 16f84a
; MPLAB 7.30
; PROTEUS 6.9 SP3
; Veguepic
; el efecto que se busca es de dos luces que se mueven en 4 posiciones de lado a lado.
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>
__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; osc XT
PDel0 equ 0C
PDel1 equ 0D
SEC1 equ 0E
SEC2 equ 0f
ORG 0
BSF STATUS,5 ; activa la pagina 1
MOVLW B'00000' ; carga 00000 en W
MOVWF TRISA ; puerto a todos salidas
MOVLW B'00000000' ; carga 00000000 en W
MOVWF TRISB ; puerto b todos salidaS
BCF STATUS,5 ; volvemos a la pagina 0
CLRF PORTA ; ponemos a cero el puerto a
CLRF PORTB ; ponemos a cero el puerto b
BCF STATUS,0 ; limpia el carry de STATUS,C
MOVLW B'00000001' ; carga 00000001 en w
MOVWF SEC1 ; guarda el valor en SEC1
INICIO ; etiqueta
DERECHA ; rutina para mover a derecha
CALL CAMBIAR ; llama a CAMBIAR
RLF SEC1,1 ; mueve el contenido a la izquierda y lo guarda en SEC1
BTFSS SEC1,3 ; si el bit 7 es igual a 1 salta una instruccion
GOTO DERECHA ; repite la rutina derecha
IZQUIERDA ; rutina para mover a izquierda
CALL CAMBIAR ; llama a CAMBIAR
RRF SEC1,1 ; mueve el contenido a la izquierda y lo guarda en SEC1
BTFSS SEC1,0 ; si el bit 0 es igual a 1 salta una instruccion
GOTO IZQUIERDA ; repite la rutina izquierda
GOTO INICIO ; va a inicio
CAMBIAR ; rutina para repetir los 4 bits bajos en los 4 bits altos
SWAPF SEC1,0 ; intercambia los 4 bits bajos por los 4 bits altos
MOVWF SEC2 ; guarda el valor en SEC2
MOVF SEC1,0 ; carga SEC1 en w
ADDWF SEC2,1 ; suma w y SEC2 y lo guarda en SEC2
MOVF SEC2,0 ; carga SE21 en w
MOVWF PORTB ; mueve el valor de w en el puerto b
CALL DEMORA ; demora de 200ms
RETURN
;-------------------------------------------------------------
; La demora a sido generada con el programa PDEL
; Descripcion: Delay 200000 ciclos - 200 ms
;-------------------------------------------------------------
DEMORA movlw .156 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .213 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2
decfsz PDel1,1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0,1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL3 goto PDelL4 ; 2 ciclos delay
PDelL4 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------
END ; fin de programa
Pues me di un paseo por este todo el post y no vi un ejemlo de manejo de la LCD con el PIC16F84A
asi que esta es mi contribucion al tema. Se trata de un contador de 0-9. Es algo muy basico y es
que la verdad la idea es mas bien enfocarse en el proceso de inicializacion y manejo y envio de
comandos y datos. Esta hecho para manejarse con un BUS de 8 lineas.
Código:
;**************************************************************
;* *
;* Ensamblador para microcontroladores MPASM *
;* *
;* NOMBRE : pic8lcd.asm *
;* OBJETIVO: Contador 0-9 con salida a LCD configurada a un *
;* bus de 8 lineas, controladas por el puerto B del *
;* PIC16F84A. Las lineas EN y RS estan sobre el *
;* puerto A en los bits 0 y 1 respectivamente. *
;* *
;* AUTOR : antonio gauss *
;* EMAIL : [email protected] *
;* *
;**************************************************************
title "PIC16F84A, pic8lcd.asm"
list p=16f84a, f=inhx8m
#include <p16f84a.inc>
__config _XT_OSC & _WDT_OFF & _CP_OFF & _PWRTE_ON
STATUS equ 0x03
PORTA equ 0x05
PORTB equ 0x06
PDel0 equ 0x10
PDel1 equ 0x11
COUNT equ 0x12
org 0x00
goto inicio
org 0x04
goto rsi
org 0x05
inicio: bsf STATUS,RP0
movlw 0xFC
movwf PORTA
movlw 0x00
movwf PORTB
bcf STATUS,RP0
clrf PORTA
clrf PORTB
call init
main: clrf COUNT
movlw 0x01
movwf PORTB
call en_com
mLoop: movf COUNT,0
addlw 0x30
movwf PORTB
call en_dat
movlw .250
call delay
incf COUNT,1
movlw 0x0A
xorwf COUNT,0
btfss STATUS,2
goto mLoop
goto main
init: movlw .20
call delay
movlw 0x38
movwf PORTB
call en_com
movlw 0x0C
movwf PORTB
call en_com
movlw 0x06
movwf PORTB
call en_com
return
en_com: bcf PORTA,1
bsf PORTA,0
nop
bcf PORTA,0
movlw .2
call delay
return
en_dat: bsf PORTA,1
bsf PORTA,0
nop
bcf PORTA,0
call T050us
return
T050us: movlw .15
movwf PDel0
DLoop3: decfsz PDel0,1
goto DLoop3
return
T200us: movlw .65
movwf PDel0
DLoop2: decfsz PDel0,1
goto DLoop2
return
delay: movwf PDel1
nop
DLoop0: movlw .249
movwf PDel0
DLoop1: nop
decfsz PDel0,1
goto DLoop1
decfsz PDel1,1
goto DLoop0
return
rsi: retfie
end
Les traigo un ejemplito de un PWM usando interrupciones (INT0) para incrementar/decrementar
el ancho del pulso.
Código:
;**************************************************************
;* *
;* Ensamblador para microcontroladores MPASM *
;* *
;* NOMBRE : PICpwm.asm *
;* OBJETIVO: Modulador de ancho de pulso PWM utilizando la *
;* interrupcion externa del PIC16F84A. El modulador *
;* cuenta con un par de entradas que se encargan de *
;* el incremento y decremento del pulso. *
;* *
;* AUTOR : antonio gauss *
;* EMAIL : [email protected] *
;* *
;**************************************************************
title "PIC16F84A, PICpwm.asm"
list p=16f84a, f=inhx8m
#include <p16f84a.inc>
__config _XT_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF
TMR0 equ 0x01
STATUS equ 0x03
PORTB equ 0x06
INTCON equ 0x0B
STEMP equ 0x10
WTEMP equ 0x11
ACCA equ 0x12
ACCC equ 0x13
PDelT equ 0x14
org 0x00
goto inicio
org 0x04
goto rsi
org 0x05
inicio: bsf STATUS,RP0
movlw 0xF7
movwf PORTB
bcf TMR0,6
bcf STATUS,RP0
movlw 0x90
movwf INTCON
movlw 0x7F
movwf ACCA
main: movf ACCA,0
movwf ACCC
bsf PORTB,3
call delay
movf ACCA,0
sublw 0xFF
movwf ACCC
bcf PORTB,3
call delay
goto main
delay: movf ACCC,0
movwf PDelT
DLoop: nop
decfsz PDelT,1
goto DLoop
return
IncDut: incf ACCA,1
movlw 0xFF
xorwf ACCA,0
btfss STATUS,Z
return
movlw 0xFE
movwf ACCA
return
DecDut: decf ACCA,1
btfss STATUS,Z
return
movlw 0x01
movwf ACCA
return
rsi: btfss INTCON,1
retfie
movwf WTEMP
swapf STATUS,0
movwf STEMP
start: btfss PORTB,1
call IncDut
btfss PORTB,2
fin: call DecDut
swapf STEMP,0
movwf STATUS
swapf WTEMP,1
swapf WTEMP,0
bsf INTCON,4
bcf INTCON,1
retfie
end
El módulo LCD visualiza un mensaje largo (más de 16 caracteres) que se desplaza a lo largo
; de la pantalla. Se utiliza la subrutina LCD_MensajeMovimiento de la librería LCD_MENS.INC.
;
; ZONA DE DATOS **************************************************
********************
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84A
INCLUDE <P16F84A.INC>
CBLOCK 0x0C
R_ContAA
R_ContAB
STORW
STRST
ENDC
; ZONA DE CÓDIGOS **************************************************
******************
ORG 0
goto Inicio
ORG 4
goto INT_EXT
Inicio
call LCD_Inicializa ; Prepara la pantalla.
bsf STATUS,RP0
BSF PORTB,0
BCF OPTION_REG,NOT_RBPU
BCF OPTION_REG,INTEDG
bcf STATUS,RP0
clrf R_ContAB
Principal
movlw Mensaje0 ; Apunta al mensaje.
call LCD_MensajeMovimiento
goto Principal ; Repite la visualización.
; "Mensajes" ----------------------------------------------------------------------------
;
Mensajes
addwf PCL,F
Mensaje0 ; Posición inicial del mensaje.
DT " " ; Espacios en blanco al principio para mejor
DT "Proyecto Final" ; visualización.
DT " Diseño Logico",
DT " ", 0x0 ; Espacios en blanco al final.
;
INCLUDE <LCD_MENS.INC> ; Subrutina LCD_MensajeMovimiento.
INCLUDE <LCD_4BIT.INC> ; Subrutinas de control del LCD.
INCLUDE <RETARDOS.INC> ; Subrutinas de retardos.
;================================================= ==================
; Rutina de interrupcion
; Se procede a dar servicio a la interrupcion.
; Esta corresponde a una interrupcion periferica. No se usa.
;================================================= ==================
INT_EXT
MOVWF STORW ; Respaldar el acumulador, W, en la localidad de memoria STORW.
MOVF STATUS, W ; El contenido de STATUS register se almacena en el acumulador.
MOVWF STRST ; Respaldar el STATUS register en la localidad de memoria STRST.
; Se incluye el banco en uso antes de la interrupcion.
incf R_ContAB, F ; paso 1 1 ciclo
banco0 ; Direcciona el Banco 0.
MOVF STRST, W ; Se almacena en el acumulador el registro STRST.
MOVWF STATUS ; Se restaura el STATUS register.
SWAPF STORW, F ; Se almacena en el acumulador el registro STRST.
SWAPF STORW, W ; Se almacena en el acumulador el registro STRST.
RETFIE ; Terminal la rutina de interrupcion, regresa al programa principal.
END ; Fin del programa.
------------------------------------------------------------------------------------------
; ================================================== =================
;
; Librería de subrutinas para el manejo de mensajes a visualizar en un visualizador LCD.
CBLOCK
LCD_ApuntaCaracter ; Indica la posición del carácter a visualizar
; respecto del comienzo de todos los mensajes,
; (posición de la etiqueta "Mensajes").
LCD_ValorCaracter ; Código ASCII del carácter a
ENDC ; visualizar.
; Los mensajes tienen que estar situados dentro de las 256 primeras posiciones de la
; memoria de programa, es decir, no pueden superar la dirección 0FFh.
; Subrutina "LCD_Mensaje" ---------------------------------------------------------------
;
; Visualiza por pantalla el mensaje apuntado por el registro W.
;
; Los mensajes deben localizarse dentro de una zona encabezada por la etiqueta "Mensajes" y que
; tenga la siguiente estructura:
;
; Mensajes ; ¡Etiqueta obligatoria!
; addwf PCL,F
; Mensaje0 ; Posición inicial del mensaje.
; DT ".. ..", 0x00 ; Mensaje terminado en 0x00.
; Mensaje1
; ...
; ...
; FinMensajes
;
; La llamada a esta subrutina se realizará siguiendo este ejemplo:
;
; movlw Mensaje0 ; Carga la posición del mensaje.
; call LCD_Mensaje ; Visualiza el mensaje.
;
LCD_Mensaje
movwf LCD_ApuntaCaracter ; Posición del primer carácter del mensaje.
movlw Mensajes ; Halla la posición relativa del primer carácter
subwf LCD_ApuntaCaracter,F ; del mensaje respecto de etiqueta "Mensajes".
decf LCD_ApuntaCaracter,F ; Compensa la posición que ocupa "addwf PCL,F".
LCD_VisualizaOtroCaracter
movf LCD_ApuntaCaracter,W
call Mensajes ; Obtiene el código ASCII del carácter apuntado.
movwf LCD_ValorCaracter ; Guarda el valor de carácter.
movf LCD_ValorCaracter,F ; Lo único que hace es posicionar flag Z. En caso
btfsc STATUS,Z ; que sea "0x00", que es código indicador final
goto LCD_FinMensaje ; de mensaje, sale fuera.
LCD_NoUltimoCaracter
call LCD_Caracter ; Visualiza el carácter ASCII leído.
incf LCD_ApuntaCaracter,F ; Apunta a la posición del siguiente carácter
goto LCD_VisualizaOtroCaracter ; dentro del mensaje.
LCD_FinMensaje
return ; Vuelve al programa principal.
; Subrutina "LCD_MensajeMovimiento" -----------------------------------------------------
;
; Visualiza*un mensaje de mayor longitud que los 16 caracteres que pueden representarse
; en una línea, por tanto se desplaza a través de la pantalla.
;
; En el mensaje debe dejarse 16 espacios en blanco, al principio y al final para
; conseguir que el desplazamiento del mensaje sea lo más legible posible.
;
CBLOCK
LCD_CursorPosicion ; Contabiliza la posición del cursor dentro de la
ENDC ; pantalla LCD
LCD_MensajeMovimiento
movwf LCD_ApuntaCaracter ; Posición del primer carácter del mensaje.
movlw Mensajes ; Halla la posición relativa del primer carácter
subwf LCD_ApuntaCaracter,F ; del mensaje respecto de la etiqueta "Mensajes".
decf LCD_ApuntaCaracter,F ; Compensa la posición que ocupa "addwf PCL,F".
LCD_PrimeraPosicion
clrf LCD_CursorPosicion ; El cursor en la posición 0 de la línea.
call LCD_Borra ; Se sitúa en la primera posición de la línea 1 y
LCD_VisualizaCaracter ; borra la pantalla.
movlw LCD_CaracteresPorLinea ; ¿Ha llegado a final de línea?
subwf LCD_CursorPosicion,W
btfss STATUS,Z
goto LCD_NoEsFinalLinea
LCD_EsFinalLinea
call Retardo_200ms ; Lo mantiene visualizado durante este tiempo.
call Retardo_200ms
call retardo_externo
movlw LCD_CaracteresPorLinea-1; Apunta a la posición del segundo carácter visualizado
subwf LCD_ApuntaCaracter,F ; en pantalla, que será el primero en la siguiente
goto LCD_PrimeraPosicion ; visualización de línea, para producir el efecto
LCD_NoEsFinalLinea ; de desplazamiento hacia la izquierda.
movf LCD_ApuntaCaracter,W
call Mensajes ; Obtiene el ASCII del carácter apuntado.
movwf LCD_ValorCaracter ; Guarda el valor de carácter.
movf LCD_ValorCaracter,F ; Lo único que hace es posicionar flag Z. En caso
btfsc STATUS,Z ; que sea "0x00", que es código indicador final
goto LCD_FinMovimiento ; de mensaje, sale fuera.
LCD_NoUltimoCaracter2
call LCD_Caracter ; Visualiza el carácter ASCII leído.
incf LCD_CursorPosicion,F ; Contabiliza el incremento de posición del
; cursor en la pantalla.
incf LCD_ApuntaCaracter,F ; Apunta a la siguiente posición por visualizar.
goto LCD_VisualizaCaracter ; Vuelve a visualizar el siguiente carácter
LCD_FinMovimiento ; de la línea.
return ; Vuelve al programa principal.
retardo_externo
MOVf R_ContAB,W
MOVWF R_ContAA ; +2 1 ciclo
loop
nop
DECFSZ R_ContAA, F ; paso 1 1 ciclo
GOTO loop ; paso 2 2 ciclos
return
Multimetro digital con pic
Implementación de un Instrumento Digital.
Resumen: La importancia de los instrumentos eléctricos de medición es incalculable, ya que mediante el uso de ellos se miden e indican magnitudes eléctricas, como corriente, carga, potencial y energía, o las características eléctricas de los circuitos, como la resistencia, la capacidad, la capacitancia y la inductancia. Además que permiten localizar las causas de una operación defectuosa en aparatos eléctricos en los cuales, como es bien sabidos, no es posible apreciar su funcionamiento en una forma visual, como en el caso de un aparato mecánico. Las mediciones eléctricas se realizan con aparatos especialmente diseñados según la naturaleza de la corriente; es decir, si es alterna, continua o pulsante. Los instrumentos se clasifican por los parámetros de voltaje, tensión e intensidad.
1.- Introducción: Es clara la importancia que tienen los equipos multifuncionales para los laboratorios, por lo que es evidente la necesidad de sus usuarios de sacarles el máximo provecho para fortalecer su competencia ofreciendo calibración de calidad y alta confiabilidad.
El personal de ingeniería continuamente enfrenta una variedad de exigencias cada vez más complejas, es por esto que se han desarrollado técnicas efectivas para la medición de datos de forma rápida y confiable, que ponen todo en manos de la instrumentación.
Para esta práctica se usará el PIC16F877. El resultado se mostrará en un LCD de 16x2. Para el caso del PIC, es necesario asignar ciertos valores a un par de registros.
2.- Planteamiento:
Ante el avance de las tecnologías en la educación se planea incorporar el uso del PC en prácticas de laboratorio en asignaturas como mediciones y redes eléctricas, para lo cual, se requiere entre otras cosas, construir un instrumento digital que permita la medición de: Voltaje, Corriente, Frecuencia, Período, Ciclo útil Rango, Capacitancia.
La selección de la medición a realizar se hará a través de “menús” utilizando una pantalla LCD de caracteres y pulsadores, simulando un teclado de entrada.
La visualización de la variable medida también se hará utilizando la pantalla LCD.
Es necesario que todos los valores se presenten en la pantalla con al menos un digito decimal en notación punto flotante. El equipo una vez programado, deberá trabajar independiente del PC, adicionalmente.
3.- Los convertidores A/D: Es un dispositivo electrónico capaz de convertir una entrada analógica de voltaje en un valor binario, la señal analógica, que varía de forma continua en el tiempo, se conecta a la entrada del dispositivo y se somete a un muestreo a una velocidad fija, obteniéndose así una señal digital a la salida del mismo.
Para realizar sus funciones en convertidor ADC tiene que efectuar los siguientes procesos:
1. Muestreo de la señal analógica.
2. Cuantización de la propia señal.
3. Codificación del resultado de cuantización.
El muestreo se realiza tomando diferentes muestras de tensiones o voltajes en diferentes puntos de la onda. La cuantización es el siguiente paso, para esta parte del proceso los valores continuos de la onda se convierten en series de valores numéricos decimales discretos correspondientes a niveles de voltaje que contiene la señal analógica. Y por ultimo la codificación, los valores de las tomas de voltaje se
representan numéricamente por medio de códigos y estándares previamente establecidos.
4.- Software Utilizado: Hemos programado el PIC 16F876 usando el PROTON IDE, que es el componente central del sistema ya que permite trabajar cómodamente en BASIC, facilitando mucho el proceso de programación.
Es un paquete de software para el diseño de circuitos electrónicos que incluye captura (composición) de los esquemas, simulación analógica y digitales combinadas y diseño de circuitos impresos. Está disponible en dos versiones con funcionalidad limitada: "Proteus VSM" y "Proteus PCB Design"
El paquete está compuesto por dos programas: ISIS, para la captura y simulación de circuitos; y ARES, para el diseño de PCB's. En los ordenadores que tienen activada la funcionalidad VSM sólo se puede ejecutar el programa ISIS. En ellos se realizo el diseño del multímetro digital. También permite simular y depurar el funcionamiento de todo el sistema ejecutando el software paso a paso, insertando puntos de ruptura, viendo el contenido de registros y posiciones de memoria, etc y comprobando si la respuesta del hardware es la correcta.
5.- Hardware Utilizado: Como el objetivo especifica el hardware esta basado en el PIC 16F877. Sobre este
microcontrolador se carga el software, En él se resume toda la lógica del mismo.
Sus funciones principales son:
- Realizar la comunicación con el tablero.
- Realizar la comunicación con la pantalla.
- Controlar la información que se despliega en el mismo.
En la figura adjunta se muestra el diagrama de pines del microcontrolador. Los pines que simulan las entradas y salidas son 12 pines. Las entradas están configuradas entre los pines 2 y 7, y las salidas entre los pines 11 y 16.
6.- La Familia del PIC16F877
El microcontrolador PIC16F877 de Microchip pertenece a una gran familia de microcontroladores de 8 bits (bus de datos) que tienen las siguientes características generales que los distinguen de otras familias:
- Arquitectura Harvard
- Tecnología RISC
- Tecnología CMOS
Estas características se conjugan para lograr un dispositivo altamente eficiente en el uso de la memoria de datos y programa y por lo tanto en la velocidad de ejecución.
Microchip ha dividido sus microcontroladores en tres grandes subfamilias de acuerdo al número de bits de su bus de instrucciones:
7.- Características generales del PIC16F877
La siguiente es una lista de las características del PIC16F877:
CPU:
- Tecnología RISC
- Sólo 35 instrucciones que aprender
- Todas las instrucciones se ejecutan en un ciclo de reloj, excepto los saltos que requieren dos
- Frecuencia de operación de 0 a 20 MHz (200 nseg de ciclo de instrucción)
- Opciones de selección del oscilador
Memoria:
- Hasta 8k x 14 bits de memoria Flash de programa
- Hasta 368 bytes de memoria de datos (RAM)
- Hasta 256 bytes de memoria de datos EEPROM
Lectura/escritura de la CPU a la memoria flash de programa
- Protección programable de código
- Stack de hardware de 8 niveles
Reset e interrupciones:
- Hasta 14 fuentes de interrupción
- Reset de encendido (POR)
- Timer de encendido (PWRT)
- Timer de arranque del oscilador (OST)
- Sistema de vigilancia Watchdog timer.
Otros:
- Modo SLEEP de bajo consumo de energía
- Programación y depuración serie “In-Circuit” (ICSP) a través de dos patitas
- Rango de voltaje de operación de 2.0 a 5.5 volts
- Alta disipación de corriente de la fuente: 25mA
- Rangos de temperatura: Comercial, Industrial y Extendido
- Bajo consumo de potencia:
o Menos de 0.6mA a 3V, 4 Mhz
o 20 μA a 3V, 32 Khz
o menos de 1μA corriente de standby (modo SLEEP).
8.- La Memoria de Programa
Los PIC de rango medio poseen un registro Contador del Programa (PC) de 13 bits, capaz de direccionar un espacio de 8K x 14, como todas las instrucciones son de 14 bits, esto significa un bloque de 8k instrucciones. El bloque total de 8K x 14 de memoria de programa está subdividido en 4 páginas de 2K x 14.
9.- Características Principales del Sistema de desarrollo pic16f877
Permite Leer y escribir directamente en los PUERTOS o la RAM sin necesidad de enviar ningún programa adicional.
Permite enviar programas al sistema, probarlos, detenerlos, e incluso monitorizar los puertos y la RAM mientras está en funcionamiento.
Dispone de lectura automática de datos con una frecuencia configurable por el usuario.
10.- Panel de control: En este panel de control, se trata de un menú donde, se pueden diferenciar cuatro mediciones, que son voltaje, frecuencia, ciclo útil y capacitancia, que cuya formación iremos describiendo a continuación.
El voltímetro: Instrumento digital diseñado para medir y presentar en forma digital una variable tensión de la corriente eléctrica. Este diseño de multímetro se encuentra en un rango de (10 Vdc a +10 Vdc). Salirse de éste rango de operación puede ser motivo de deterioro del mismo.
Cuando la tecnología nos permite saber, cual es la tensión, con bastante precisión, no se debe seguir con dispositivos que solo indican que „„hay‟‟ tensión pero no exactamente El voltímetro es tal vez el instrumento que más aplicaciones tiene. Fuera de la función específica de medir un voltaje, existen muchos parámetros que se miden indirectamente con voltímetros.
Para la creación del mismo se necesitara un conversor ADC, que facilita su interconexión con un microprocesador,
Frecuencia: Como sabemos la frecuencia es la tasa de recurrencia de un evento cíclico o periódico. En una forma de onda análoga o digital, podemos invertir el periodo de la señal para obtener la frecuencia. A menor sea el periodo, mayor será la frecuencia y viceversa. Para obtener la frecuencia de una señal digital, es muy sencillo, el periodo es directamente el tiempo entre flancos de subida, o entre flancos de bajada.
Capacitancia: La capacitancia siempre es una cantidad positiva y puesto que la diferencia de potencial aumenta a medida que la carga almacenada se
incrementa. En consecuencia la capacitancia de un dispositivo es una medida de su capacidad para almacenar carga y energía potencial eléctrica.
En la actualidad, en los equipos de medición de capacitancia solamente requiere de conectar el dispositivo bajo medición entre sus terminales y apretar un botón para que la lectura aparezca en un indicador, aunque también existen equipos de tipo analógico que requieren además manipular algunas perillas y visualizar una pequeña aguja dentro de una escala graduada para llevar a balance un circuito puente y realizar la lectura en base a multiplicadores y escalas limitadas en resolución.
Device 16F877
XTAL 20
Input PORTD
ALL_DIGITAL=true
Declare ADIN_RES 10
Declare ADIN_TAD FRC
Declare ADIN_STIME 50
Input PORTD
TRISA=000011
ADCON1=%11000000
CCP2_PIN = PORTC.1
'Declaracion pines pantalla LCD
Declare LCD_DTPIN PORTB.4 ' Pin de
Datos LCD conectado al PORTB.4
Declare LCD_ENPIN PORTB.3 ' Pin de
Enable LCD conectado al PORTB.3
Declare LCD_RSPIN PORTB.1 ' Pin de
RS LCD conectado al PORTB.1
TRISB.2 = %0 ' Declara
a PORTB.2 como Salida Digital
PORTB.2 = %0
Output PORTC.2
Output PORTC.3
Output PORTC.1
'Programacion para la LCD
$FE,$40,$1F,$10,$10,$10,$10,$10,$10,$10
'esquina izquierda
$FE,$50,$1F,$01,$01,$01,$01,$01,$01,$01
'esquina derecha
$FE,$48,$10,$10,$10,$10,$10,$10,$1F,$00
'esquina izquierda abajo
$FE,$58,$01,$01,$01,$01,$01,$01,$1F,$00
'esquina derecha abajo
$FE,$60,$00,$04,$06,$07,$06,$04,$00,$00
'flecha fila 1
$FE,$68,$00,$00,$00,$1F,$0E,$04,$00,$00
'flecha hacia abajo
$FE,$70,$00,$00,$04,$0E,$0E,$1F,$00,$00
'flecha hacia arriba
'declaraciones
Dim voltage As Float
Dim voltage1 As Float
Dim resultado As Float
Dim resultado1 As Float
Dim resultado2 As Float
Dim resis As Float
Dim resistencia As Float
Dim capacitancia As Float
Dim frecuencia As Float
Dim periodo As Float
Dim ciclo As Float
Dim x As Float
Dim y As Float
Dim f As Float
Dim cicloutil As Float
inicio:
Print At 1,16,2
Print At 2,16,3
Print At 2,1,1
Print At 1,1,0
Print At 1,1, "Alumno Fulano"
Print At 2,1, "Alumno Fulano"
DelayMS 2500
Cls
Print At 1,16,2
Print At 2,16,3
Print At 2,1,1
Print At 1,1,0
Print At 1,7, "Micro"
Print At 2,3, "Procesadores"
DelayMS 2500
Cls
Print At 1,16,2
Print At 2,16,3
Print At 2,1,1
Print At 1,1,0
Print At 1,4, "MULTIMETRO"
Print At 2,6, "DIGITAL"
DelayMS 2500
Cls
uno:
Print $FE, 1
Print At 1,1, "1"
Print At 1,2,4
Print At 1,3, " VOLTIMETRO "
Print At 2,1, "2"
Print At 2,2,4
Print At 2,3, " FRECUENCIA "
Print At 2,16,5
uno1:
pause 500
If PORTD.1=%1 Then
GoTo dos
EndIf
If PORTD.2=%1 Then
uno11:
voltage=ADIn 0
resultado1=(voltage*10)/1023
voltage1=ADIn 1
resultado2=(voltage1*10)/1023
resultado=resultado1 - resultado2
Print $FE, 1
Print At 1,5, SDEC2 resultado,"
VDC "
Print At 2,1, " Escala 10VDC "
pause 1000
If PORTD.4=%1 Then
GoTo control
EndIf
GoTo uno11
EndIf
'frecuencia
If PORTD.3=%1 Then
uno111:
f = Counter PORTD.5 ,1000
DelayMS 1200
frecuencia=f/1000
Print $FE, 1
Print At 1,1, "Esc: 1-30 Khz"
Print At 2,1,"F = ", DEC3 frecuencia,"
Khz"
DelayMS 500
If PORTD.4=%1 Then
GoTo control
EndIf
GoTo uno111
EndIf
GoTo uno1
dos:
pause 500
Print $FE, 1
Print At 1,1, "1"
Print At 1,2,4
Print At 1,4, "CICLO UTIL"
Print At 2,1, "2"
Print At 2,2,4
Print At 2,4, "CAPACITANCIA"
Print At 1,16,6
dos1:
If PORTD.0=%1 Then
GoTo uno
EndIf
'Ciclo util
If PORTD.2=%1 Then
dos11:
HPWM 2,x,y
f=Counter PORTD.5,1000
frecuencia=1/f
periodo=1/frecuencia
DelayMS 300
ciclo= PulsIn PORTD.5,1
cicloutil=ciclo/periodo
cicloutil=20000*cicloutil
Print $FE, 1
Print At 1,1, "Ciclo Util"
Print At 2,1, Dec cicloutil,"%"
DelayMS 500
If PORTD.4=%1 Then
GoTo control
EndIf
GoTo dos11
EndIf
'capacitancia
If PORTD.3=%1 Then
dos111:
High PORTC.3
DelayMS 300
resis= RCIn PORTC.3 , High
capacitancia=resis/950
Print $FE, 1
Print At 1,1, "Esc: 0-100 uF"
Print At 2,1,"C = ",DEC2 capacitancia,"
uF"
DelayMS 500
If PORTD.4=%1 Then
GoTo control
EndIf
GoTo dos111
EndIf
GoTo dos1
control:
GoTo uno
13.- Conclusión: El multímetro digital es un instrumento electrónico de medición que generalmente
calcula voltaje, resistencia y corriente, aunque dependiendo del modelo de multímetro puede medir otras magnitudes como capacitancia y temperatura. Gracias al multímetro podemos comprobar el correcto funcionamiento de los componentes y circuitos electrónicos.
En general, los instrumentos de medición ofrecen la precisión necesaria para la ejecución de incontables actividades tanto profesionales como cotidianas que requieren atención.