Programación Específica > Microcontroladores
Uso De Interrupciones Con Pic 16f877
SinChip:
Gracias Oldkami por tu rápida respuesta. No obstante, cambiando el origen de la interrupcion a la direccion 100 hex, funciona, no sé por qué no me deja empezar desde la direccion 5 que se supone que es la posicion libre inmediatamente despues del vector de interrupción.
además , he intentado añadir "pagesel" en el vector de interrupcion para saltar a la ISR y me dice que no cabe. No será pq sólo hay una palabra de espacio para el mapeo del vector de int. en la 04?
Bueno, más cositas. Tengo un programa que hace una cuenta binaria de 3 bits (Típico contador Johnson, o como se diga) y la saco por tres líneas del puerto B y ok, pero la saco en RA2,3 y 4 y no lo consigo. El hecho es que siempre que activo un bit del puerto A se desactiva el que hubiere anteriormente, ¿inquietante eh? (con RA4 no pasa esto, es la única que fluctua debidamente sin que la afecten las demás)
He tenido en cuenta el drenador abierto de RA4, pero se ve que la inversión del dato se resuelve de forma transparente al usuario, ya que tengo un pull-up a la salida y el dato sale tal y como lo escribo en el puerto, no invertido como esperaba que lo hiciese.
Por cierto RA2,3 y 4 van colgadas a la entrada de un MUX 8 a 1, y éste funciona aparentemente bien.
Aquí os dejo un pequeño ejemplo que ilustra el fallo mediante una barrido de tres lineas del puerto, parece simple, pero ocurre lo que os he mencionado.
--- Citar ---MAIN CODE ; Zona de Programa
inicio:
;-------Configuración de puertos-------
movlw b'00000011' ; como salida, y ent RA0, RA1 y RA3 b'00001011'
banksel TRISA ; configurando el puerto B
movwf TRISA
movlw b'00001001' ; como salida, y ent RB0 y RB3 -> b'00001001'
banksel TRISB ; configurando el puerto B
movwf TRISB
movlw b'00001010' ;
banksel PORTB
movwf PORTB
movlw b'00000000' ; como salida
banksel TRISC ; configurando el puerto B
movwf TRISC
movlw b'00000000' ; como salida
banksel TRISD ; configurando el puerto B
movwf TRISD
movlw b'00000000' ; como salida
banksel TRISE ; configurando el puerto B
movwf TRISE
banksel PORTA
;movwf PORTA
bcf PORTA,BIT2
bcf PORTA,BIT3
bcf PORTA,BIT4 ; limpiamos puerto
salta
call delay_1s
bsf PORTA,BIT3
call delay_1s
bsf PORTA,BIT2
call delay_1s
bsf PORTA,BIT4
call delay_1s
goto salta
--- Fin de la cita ---
No sé si es un fallo software, porque he cambiado por varios micros, incluso usé un 648A programado (sin usar el modo depuración) y pasa lo mismo. Tengo un header que me he hecho yo que convierte 40 a 18 pines, pero esto tampoco falla, ya que la placa destino tiene como os digo 18 pines, y allí es donde usé el 648.
Los pines restantes de los puertos del 877, como veis los configuro como salida, recomendacion que te da Microchip cuando no los vas a usar.
Bueno, o bien encomiendo a San Silicio, aunque me gustaría que me comentarais sobre esto en breve.
Saludito para todos, y gracias de nuevo
:alien:
oldkami:
--- Citar ---no sé por qué no me deja empezar desde la direccion 5 que se supone que es la posicion libre inmediatamente despues del vector de interrupción.
además , he intentado añadir "pagesel" en el vector de interrupcion para saltar a la ISR y me dice que no cabe. No será pq sólo hay una palabra de espacio para el mapeo del vector de int. en la 04?
--- Fin de la cita ---
Ese sintoma... sip, tienes razon, no compila. Disculpas a todos :hola: . pero olvide mencionarlo, se debe precisamente a las restricciones que impone el script *.lkr que utiliza el linker . en la definicion del espacio de inicio (vectors), una de las posibles la soluciones la coloco a continuación:
--- Código: Text --- title "Ejemplo ISR" list P=16F877 #include "P16F877.inc" UDATA_SHRirq_w res d'1'irq_status res d'1' RESET_VEC CODE 0x0000 pagesel INICIO goto INICIO ;hasta aqui 3 instrucciones nopINT_VEC bcf INTCON,GIE ;vector de interrupcion 0x0004 y fin de ;seccion (vectors)ISR code 0x0005 ;colocar el ISR inmediatamente despuesISR: btfsc INTCON,GIE ;paranoia goto INT_VEC ;o goto $-2 movwf irq_w swapf irq_w,F movfw STATUS movwf irq_status ;cambio de contexto btfsc INTCON,(mi interrupcion);[PIR1,(mi interrupcion)]probar aqui ;el tipo de interrupcion goto ATENDER ;atiende la interrupcion goto END_ISR ;sale del ISR ATENDER ;el codigo necesario END_ISR movfw irq_status ;vuelve al contexto anterior movwf STATUS swapf irq_w,W retfie ;esta instruccion coloca el GIE en ON INICIO goto $ ;mi codigoEND
es lo mejor, ya que se atiende la interrupcion de la manera mas rapida posible (con pagesel + goto ISR se toma 4 instrucciones mas) y te permite compilar :).
otra alternativa es modificar el archivo *.lkr para extender la seccion Vectors con el fin de colocar el codigo apropiado:
--- Código: Text --- ;ejemplo con 16F877.lkr; codigo originalCODEPAGE NAME=vectors START=0x0 END=0x4 PROTECTEDCODEPAGE NAME=page0 START=0x5 END=0x7FF ; codigo modificadoCODEPAGE NAME=vectors START=0x0 END=0x6 PROTECTEDCODEPAGE NAME=page0 START=0x7 END=0x7FF
con esto obtienes 2 palabras adicionales en la seccion STARTUP para ubicar
pagesel ISR y goto ISR.
--- Código: Text --- RESET_VEC CODE 0x0000 pagesel MAIN goto MAIN ;hasta aqui 3 instrucciones nop INT_VEC code 0x0004 pagesel ISR ;aqui 0x0004 (vect Interrupt) y 0x0005 goto ISR ;0x0006 final de Vectors ISR CODE ;donde sea... o asignado por el linker ISR: ; Aqui mi ISR
Aunque esta alternativa le quita portabilidad al codigo (tendrias que modificar cada *.lkr que necesites), aunque yo la utilice en el codigo que envie anteriormente :) extendiendo mucho la seccion vectors.
Con estos ejemplos creo que ya se pueden defender en la construccion de la seccion de interrupciones.
En cuanto a la segunda pregunta, deberias iniciar una nueva discusion y anexar el codigo para ser evaluado, ya que se sale un poco del tema de esta discusion que es el uso de interrupciones en pic 16f877, sin embargo te adelanto que no veo mayor problema en ese codigo, a menos que la subrutina "delay_1s" o alguna otra rutina sobreescriba el puerto. Dificil saberlo con la información que enviaste.
Saludos
Oldkami
SinChip:
Gracias de nuevo Oldkami, desde luego que estás ducho en este tema. Respecto al codigo nuevo sobre el fallo del puerto, en realidad no es mucho más que eso, es realmente simple. Voy a colgar otra discusión con lo dicho sobre esto y ademas la rutina de delay_1s, para que veas que no influye en los puertos.
Un saludo, sigo en el tajo :comp:
gelito:
Hola!!
Estoy programando un PIC16F877, en su rutina principal trabaja con el ADC interno del PIC pero no he logrado q una interrupcion por Recepción funcione correctamente. Por fa ayudenme!!
Navegación
[*] Página Anterior
Ir a la versión completa