Instruction manuals, curso, y pic">
Modulo 9: Introducción A La Programación en ENSAMBLADOR
Modulo 9: Introducción A La Programación en ENSAMBLADOR
Modulo 9: Introducción A La Programación en ENSAMBLADOR
MÓDULO 9:
Introducción a la programación
en lenguaje ENSAMBLADOR
2
Núcleo del
PIC16F876
3
Introducción
● Memoria RAM
● Capacidad de 512 Bytes
● Dividida en 4 bancos de 128 bytes: Banco 0, 1, 2 y 3
● Antes de acceder a un registro hay que especificar el banco, mediante
los bits RP0 y RP1 del registro de Status
4
Registro de status
5
Bancos de
registros
6
Mapa de memoria (flash)
7
Mapa de memoria (flash) (II)
0800h
Página 1 2K
0FFFh
1000h
Página 2 2K
17FFh
1800h El bootloader (opcional) se graba
en la parte alta de la memoria, en
Página 3 2K el banco 3
Bootloader 1FFFh
8
Juego de
instrucciones
9
Plantilla de programa
plantilla.asm
INCLUDE "p16f876a.inc" Cabecera. Indicar PIC a emplear
__CONFIG _RC_OSC & _WDT_ON &
_PWRTE_OFF & _BODEN_ON & _LVP_ON & Establecer los fusibles de
_CPD_OFF & _WRT_OFF & _DEBUG_OFF & configuración
_CP_OFF
El programa comienza en la dirección 0
ORG 0
Poner código de arranque (opcional)
...
goto start Saltar al comienzo del programa
END
10
Programa “Hola mundo”
ledon.asm Encender el LED!!!
11
Hola mundo para Bootloader
END 12
Compilando con las GPUTILS
UTILIZACIóN:
Ensamblador
Fichero en ensamblador
gpasm pPIC fichero.asm
PIC a emplear
EJEMPLO:
gpasm pp16f876a ledon2.asm
13
Ejercicio: vamos a practicar
●Primero habrá que modificar el editor para que nos permita invocar al
ensamblador
14
Sacando datos por el puerto B
outputb.asm
Sacar un byte por el puerto B
INCLUDE "p16f876a.inc"
#define VALOR 0xAA Definir una constante. Igual que en lenguaje C
15
Instrucciones de transferencia y borrado
Clear
Move literal
Move
16
Comprobación de bits
pulsador.asm Programa que enciende el led
Inicialización (igual al pulsar el botón y lo apaga
INCLUDE "p16f876a.inc" que ejemplos
al soltarlo
... anteriores)
start
Cambiar al banco 1
BSF STATUS,RP0
Configurar RB1 para salida
BCF TRISB,1
BCF STATUS,RP0 Cambiar al banco 0
bucle
Comprobar el estado de RB0 y saltar si está a 0. Es
BTFSC PORTB,0 decir, saltar si el pulsador está apretado
goto no_pulsado Si se ejecuta esta instrucción, es que no se ha realizado
el salto y por tanto RB0 estaba a 1 (no pulsado). Saltar
a la etiqueta correspondiente
BSF PORTB,1
goto bucle Este es el código que se ejecuta cuando RB0 está a 0.
Se enciende el led
no_pulsado Repetir el proceso para volver a comprobar el estado
del pulsador
BCF PORTB,1
Este es el código que se ejecuta cuando RB0 está a 1
goto bucle
Apagar el led
END
Repetir el proceso para volver a comprobar el estado
del pulsador
17
Instrucciones de comprobación de bits
Registro
Registro
18
bucles
● Los bucles se implementan con la instrucción DECFSZ
bucle
... La variable se decrementa. Cuando
DECFSZ variable,F variable==0, finaliza el bucle
goto bucle
SINTÁXIS:
F: registro=registro -1
DECFSZ registro, destino
W: W=registro-1
Registro a usar
19
Bucles: Rutina de pausa (I)
ledp.asm (parte I)
Hacer parpadear el led (RB1)
INCLUDE "p16f876a.inc"
cblock 0x20
Declaración de variables. A partir de la dirección 0x20
CONTH
Parte alta del contador para hacer la pausa
CONTL
endc Parte baja del contador para hacer la pausa
...
start
BSF STATUS,RP0 Configurar RB1 para salida
BCF TRISB,1
Bucle principal
BCF STATUS,RP0
main Cargar el valor 0x02 en W
MOVLW 0x02 Hacer la operación PORTB=PORTB xor 0x02 para
XORWF PORTB,F cambiar el pin RB1 de estado
CALL pausa Llamar a la subrutina de espera
GOTO main
Repetir. Bucle infinito
...
20
Bucles: Rutina de pausa (II)
ledp.asm (parte II)
pausa Poner parte alta del contador a 0xFF
MOVLW 0xFF
MOVWF CONTH Bucle exterior
bucle1
Poner parta baja del contador a 0xFF
MOVLW 0xFF
MOVWF CONTL Bucle interior
bucle2
Decrementar CONTL y salir del bucle cuando llegue a 0
DECFSZ CONTL,F
goto bucle2
Decrementar CONTH y salir del bucle cuando llegue a 0
DECFSZ CONTH,F
goto bucle1 Se llega aquí cuando CONTH=0 y CONTL=0. En total se
RETURN han realizado 0xFFFF iteraciones
Retorno de la subrutina
END
21
Puerto serie (I)
sci-eco.asm (I) Hacer eco por el puerto serie
INCLUDE "p16f876a.inc" Primero configuramos el puerto serie
...
Acceso al banco 1
start
BSF STATUS,RP0 Baudios: 9600
MOVLW 0x81
MOVWF SPBRG Configurar transmisor
MOVLW 0x24
MOVWF TXSTA Acceso al banco 0
BCF STATUS,RP0
Configurar receptor
MOVLW 0x90
MOVWF RCSTA
Acceso al banco 1
BSF STATUS,RP0
Configurar puerto B para salida
CLRF TRISB
BCF STATUS,RP0 Acceso al banco 0
main Bucle principal
CALL leer_car Esperar a que llegue un carácter
CALL enviar Hacer el eco
MOVWF PORTB ...y sacarlo por los leds del puerto B
GOTO main
...
22
Puerto serie (II)
Retorno de la subrutina
END
23
sci-int1.asm Interrupciones (I)
INCLUDE "p16f876a.inc"
ORG 0
Rutina de atención a las interrupciones. Se
...
ejecuta cuando llegue un carácter por el sci
GOTO start
Cambiar el led de estado
ORG 0x04
Leer el carácter recibido para limpiar el flag
MOVLW 0x02
de interrupción
XORWF PORTB,F
Retorno de interrupción
MOVFW RCREG
RETFIE Programa principal
Inicializar puerto serie. Igual que ejemplo anterior
start
Acceso al banco 1
...
BSF STATUS,RP0 Configurar RB1 para salida
BCF TRISB,1
BSF PIE1,RCIE Activar la interrupción de dato recibido
BSF INTCON,PEIE
BSF INTCON,GIE Acceso al banco 0
BCF STATUS,RP0
BSF PORTB,1 Encender el led
Regla de oro:
Al comienzo de la rutina de atención a la interrupción hay que guardar los
registros W y STATUS
Al finalizar la rutina hay que restablecer sus valores
25
sci-int2.asm (I) Interrupciones (III)
INCLUDE "p16f876a.inc" Declaración de variables
cblock 0x20
Variables para usar en la rutina de pausa
CONTH
CONTL Variable para guardar el registro W
save_w
Variable para guardar el registro STATUS
save_status
endc
ORG 0
TAREA 1: hacer eco
...
GOTO start
Guardar el contexto (registros W y STATUS)
ORG 0x04
MOVWF save_w
SWAPF STATUS,W
MOVWF save_status Leer carácter recibido
CALL leer_car
Hacer eco
CALL enviar
SWAPF save_status,W
MOVWF STATUS Recuperar el contexto
SWAPF save_w, F
SWAPF save_w, W
RETFIE 26
Interrupciones (IV)
sci-int2.asm (II)
start
Configuración puerto serie
...
BSF STATUS,RP0 Acceso al banco 1
BCF TRISB,1 Configurar RB1 para salida (led)
BSF PIE1,RCIE
BSF INTCON,PEIE Activar interrupción de dato recibido
BSF INTCON,GIE
BCF STATUS,RP0 Acceso al banco 0
BSF PORTB,1 Encender led
27
Ejercicio:
●Los valores para configurar el timer0 los podéis sacar del ejemplo timer0-
pausa10ms.c, Y para las interrupciones: timer0-onda10Khz-int.c
28
Ensamblador y C en el SDCC (I)
sdcc-asm.c Hacer parpadear el led. Parte
en C y parte en ASM
#include <pic16f876a.h>
...
Funciones de pausa (ejemplos anteriores)
void main(void)
Configurar RB1 para salida
{
TRISB1=0;
Configurar Timer 0 para hacer pausas
T0CS=0; PSA=0;
PS2=1; PS1=1; PS0=1;
RB1=0; Apagar led
while(1) {
Comienzo del bloque en ensamblador
_asm
MOVLW 0x02 Cambiar led de estado
XORWF PORTB,F
Fin del bloque en ensamblador
_endasm;
Pausa de 100ms
pausa(10);
}
}
29
Ensamblador y C en el SDCC (II)
EXPERIMENTO:
● En el ejemplo anterior eliminar la línea que pone RB1=0;
void main(void)
{
TRISB1=0;
T0CS=0; PSA=0;
PS2=1; PS1=1; PS0=1;
Eliminar esa “inocente” línea
RB1=0;
...
30
Ensamblador y C en el SDCC (III)
pausa(10);
Conclusión: Mucho cuidado cuando se
}
mezclan ambos lenguajes
}
31
Ensamblador y C en el SDCC (IV)
● ¿Para qué se usa la mezcla entre C y ASM principalmente?
while(1) {
... Meter una instrucción “nop” que sabemos que
_asm
tarda 200ns en ejecutarse (con cristal de
20Mhz)
nop
_endasm;
...
}