Documente Academic
Documente Profesional
Documente Cultură
Verá que solo el bit 0 está bajo o borrado. Esto corresponde a que PORTB.0 o RB0
se conviertan en un pin de salida y el resto como pines de entrada. Si, por ejemplo,
desea que los pines de salida PORTB.0 y PORTB.1 y el resto sean pines de entrada,
su TRISB sería:
Un reto simple
Modifique el código anterior para que otro LED esté conectado a PORTA.1. Cuando
se enciende el interruptor, el LED PORTA.0 se ilumina, mientras que el LED
PORTA.1 se apaga. A la inversa, el LED PORTA.0 se apaga y el LED PORTA.1 se
enciende cuando se apaga el interruptor.
Conjunto de instrucciones de
montaje PIC | Dispositivos de
gama media
Cada instrucción de rango medio es una palabra de 14 bits dividida en un OPCODE
que especifica el tipo de instrucción y uno o más operandos que especifican la
operación de la instrucción.
El resumen del conjunto de instrucciones de rango medio en la tabla a continuación
enumera las instrucciones reconocidas por el ensamblador MPASM. El conjunto de
instrucciones es altamente ortogonal y se agrupa en tres categorías básicas:
Operaciones orientadas a bytes.
Operaciones orientadas a bits
Operaciones literales y de control.
Para instrucciones orientadas a bytes , 'f' representa un designador de registro
de archivos y 'd' representa un designador de destino. El designador de registro de
archivo especifica qué registro de archivo debe utilizar la
instrucción. El designador de destino especifica dónde se colocará el resultado de
la operación. Si 'd' es cero, el resultado se coloca en el registro W. Si 'd' es uno, el
resultado se coloca en el registro de archivos especificado en la instrucción.
Para instrucciones orientadas a bits , 'b' representa un designador de campo de
bits que selecciona el número del bit afectado por la operación, mientras que 'f'
representa el número del archivo en el que se encuentra el bit.
Para operaciones de control y literales , 'k' representa una constante de ocho u
once bits o un valor literal.
Todas las instrucciones se ejecutan en un solo ciclo de instrucciones, a menos que
una prueba condicional sea verdadera o el contador del programa cambie como
resultado de una instrucción. En estos casos, la ejecución toma dos ciclos de
instrucción con el segundo ciclo ejecutado como un NOP. Un ciclo de instrucción
consta de cuatro períodos de oscilador. Por lo tanto, para una frecuencia de
oscilador de 4 MHz, el tiempo de ejecución de la instrucción normal es de 1 ms. Si
una prueba condicional es verdadera o el contador del programa se modifica como
resultado de una instrucción, el tiempo de ejecución de la instrucción es de 2 ms.
Las siguientes instrucciones son aplicables a dispositivos de rango medio (PIC12 y
PIC16)
Mnemónicos, Descripción Ciclos Palabra de instrucción Estado
Operandos de 14 bits afectado
Dar los bits 2 a 0 le da el valor máximo de preescala de 1: 256. Esto significa que
TMR0 ahora contará cada 256 uS en lugar de cada 1 uS. Eso es 65280 uS antes de
que TMR0 se desbordara.
Mire este código de parpadeo del LED que utiliza la interrupción PIC de
desbordamiento TMR0:
Assembly (x86)
1 ; TODO INSERT CONFIG CODE HERE USING CONFIG BITS GENERATOR
2 #INCLUDE
3
4 RES_VECT CODE 0x0000 ; processor reset vector
5 GOTO START ; go to beginning of program
6
7 INT_VECT CODE 0x0004 ; interrupt vector
8 GOTO ISR ; go to interrupt service routine
9
10
11 MAIN_PROG CODE ; let linker place main program
12
13 START
14 BSF STATUS, RP0
15 CLRF TRISB ;PORTB all output
16 MOVLW b'10100000'
17 MOVWF INTCON ;enable timer-overflow interrupt
18 MOVLW b'00000111'
19 MOVWF OPTION_REG ;instruction clock,falling edge,prescaler set to maximum
20 BCF STATUS, RP0 ;switch to Bank 0
21 CLRF TMR0 ;initialize timer
22 GOTO MAIN
23
24 ;Interrupt service routine--------------------------------------------------------
25 ISR
26 BCF INTCON, GIE ;Disable all interrupts inside interrupt service routine
27 BCF INTCON, T0IF ;disable timer-overflow interrupt flag bit
28 BCF PORTB,0 ;clear RB0
29 BSF INTCON, GIE ;re-enable all interrupts
30 GOTO MAIN
31
32 ;Main routine---------------------------------------------------------------------
33 MAIN
34 BSF PORTB,0 ;Set RB.0
35 GOTO MAIN ;Loop
36
37 END
Cuando el temporizador aún no se ha desbordado, el código se repite dentro de la
rutina principal que establece continuamente el pin RB0. Cuando el temporizador
se desborda y la interrupción se dispara, la rutina isr borra el pin RB0. Esto
efectivamente "parpadea" un LED si está conectado a RB0. Dado que se establece
el valor máximo de preescala, la velocidad de parpadeo sería de aproximadamente
65 mS.
RB cambio de interrupción
También puede adjuntar una interrupción PIC a los pines RB4, RB5, RB6 y RB7 al
igual que con RB0 / INT. La interrupción de cambio de RB se configura mediante el
ajuste RBIE (bit 3, Habilitar interrupción de cambio de RB) del registro
INTCON. Cuando se produce cualquier cambio de estado para cualquiera de los
pines mencionados, se establece el RBIF (bit 0, indicador de interrupción de
cambio de RB) del registro INTCON. Tenga en cuenta que el tiempo que llevó
cambiar el estado debe ser al menos igual al tiempo del ciclo de instrucción.
El ejemplo establece que RA0 lo borra cuando ocurre un cambio de estado en
cualquiera de los pines RB.4 a RB.7.
Interrupciones en XC8
En XC8, las interrupciones tienen su propio tipo de datos de interrupción. Esto
significa que puede crear ISR como funciones con interrupción como tipo de
retorno. Por ejemplo, esta es la forma en que implementaría el mismo código de
interrupción externo anterior en XC8:
1 #define _XTAL_FREQ 4000000
2 #include <xc.h>
3
4 void main(void) {
5 TRISB0 = 1; //Initialize RB0 as input
6 GIE = 1; //Enable Global Interrupt
7 INTE = 1; //Enable External Interrupt
8
9 while(1){
10 RA0=1; //Set RA0
11 }
12 }
13 //Interrupt Handler. Note you can use other function name as long as interrupt data type is there
14 void interrupt isr(void){
15 if(INTF){ //Check if External Interrupt Flag is set
16 RA0=0; //Clear RA0 on interrupt
17 __delay_ms(100);
18 INTF=0; //External Interrupt Flag must be cleared manually
19 }
20 }
Como puede ver, es necesario verificar el indicador de interrupción externo INTF
para verificar si esa es realmente la interrupción que se activó porque cualquier
interrupción puede activar la función isr ().
La interrupción del temporizador se codificaría así:
1 #define _XTAL_FREQ 4000000
2 #include <xc.h>
3
4 void main(void) {
5 TRISB = 0; // Initialize PORTB as all output
6 GIE = 1; // Enable Global Interrupt
7 T0IE = 1; // Enable Timer Interrupt
8 T0CS = 0; // Timer Clock Source is internal clock
9 PS = 7; // Maximum Prescale
10
11 while(1){
12 RB0=1; //Set RB0
13 }
14 }
15 //Interrupt Handler. Note you can use other function name as long as interrupt data type is there
16 void interrupt isr(void){
17 if(T0IF){ // Check if Timer Interrupt Flag is set
18 RB0 = 0; // Clear RB0 on interrupt
19 T0IF = 0; // Timer Interrupt Flag must be cleared manually
20 }
21 }
¿Cómo codificaría el cambio de RB y las interrupciones de escritura de EEPROM
en XC8?