Autor Tema: Se puede enviar algo por la USART mientras se atienda una interrupcion 0x04?  (Leído 2362 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado bones18

  • PIC12
  • **
  • Mensajes: 54
Buenas

toy haciendo un proyecto con el PIC16F876, el programa se espera a que le llegue un caracter por Rx, entonces se atiende a la interrupcion.  Programé una subrutina llamada Putchar, que envia por el Tx lo que encuentre en W.

El problema esta en que fuera de la rutina de interrupcion de llegada de caracter por Rx Putchar funciona perfectamente, pero dentro de ella no. Es mas, si hago un bucle de palo,

putchar
      
      movwf   TXREG      ; del codigo ascii   
      bsf   STATUS,RP0   ;Cambio al banco 1 -------------
      bcf   STATUS,RP1
COMP_TX      
      btfss   TXSTA,TRMT   ;comprueba si acabo de Tx.
      goto   COMP_TX
      bcf   STATUS,RP0   ;Cambio al banco 0 -------------
      return

Principal            ; Supone que el bit de entrada estará a "
   movlw a'a'
   call putchar
   goto    Principal      ; Crea un bucle cerrado e infinito.

   END            ; Fin del programa.


Escribe 'a' constantemente en el hyperterminal, pero luego nunca atienda a la interrupcion de llegada de dato por el Rx, pasa de ella olimpicamente, cosa que no pasa si tengo solo:

Principal            ; Supone que el bit de entrada estará a "
   goto    Principal      ; Crea un bucle cerrado e infinito.

   END

Tiene sentido todo esto? o debe ser un error de programacion?

gracias!

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Se puede enviar algo por la USART mientras se atienda una interrupcion 0x04?
« Respuesta #1 en: 04 de Agosto de 2006, 09:31:31 »
Es altamente probable que sea un error de programación

El punto es que la rutina que has subido de putchar no dice nada con respecto a qué haces en la rutina de atención de la interrupción y seguramente ahí tienes tu problema.

Si subes ese código, estaremos en mejores condiciones para poderte ayudar.

PD: si es largo, subelo en un archivo .zip por favor.

Saludos


- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado bones18

  • PIC12
  • **
  • Mensajes: 54
Re: Se puede enviar algo por la USART mientras se atienda una interrupcion 0x04?
« Respuesta #2 en: 04 de Agosto de 2006, 10:45:25 »
gracias por contestar. El codigo mas relevante es éste:

; ZONA DE DATOS *********************************************************************

   __CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC
   LIST      P=16F876
   INCLUDE  <P16F876.INC>
   
   estat_anterior EQU 0x21
; ZONA DE Codigo*********************************************************************
ORG    0         ; El programa comienza en la dirección 0.
   goto Inici
   
ORG 0x04 ; Sera el vector d'interrupció del USART
   ;dadaRebuda
   
   btfss PIR1,RCIF ; si el Flag de recepcio s'ha activat salta la seguent instruccio
   goto fi
   bcf    PIR1,RCIF ; restaurem el flag
                 ;****SI HEMOS LLEGADO AQUI TENEMOS UN CARACTER ESPERANDO EN RCREG****
                ; El primer pas es mirar en quin estat ens trobem
   movf estat_anterior,0 ; carreguem l'estat anterior a W
   xorlw '0'
   btfss STATUS, Z
   goto estat1
   ;som a l'estat 0
   xorlw '$' ; Comparem el valor de W amb una lletra, Si es igual el flag de Z=1
   btfss STATUS, Z
   ;per qualsevol altre cosa que no sigui un $ marxem
   goto fi
   ;hem trobar un '$' i per tant passem a l'estat 1
   movlw .1
   movwf estat_anterior
                *****AQUI COLOCO UN 1 EN EL W y LLAMO A LANZO AL SERIE
                **********ESTO ES EL MOTIVO DE MI PREGUNTA************

   movlw a'1'
   call putchar
   call encendre_taronja
   goto fi

;si estamos aqui es porque pq posiblemente estemos en en estado1
estat1   
   movf estat_anterior,0 ; carreguem l'estat anterior a W
   xorlw '1'
   btfss STATUS, Z
   goto estat2
   ;som a l'estat 1
   xorlw 'G' ; Comparem el valor de W amb una lletra, Si es igual el flag de Z=1
   btfss STATUS, Z
   ;per qualsevol altre cosa que no sigui un $ marxem
   goto fi
   ;hem trobar una 'G' i per tant passem a l'estat 2
   movlw .2
   movlw a'2'
               call putchar
   movwf estat_anterior
   goto fi

   
estat2
   call encendre_verd
   
;********FI DE LA MEVA RUTINA D'ADQUISICIÓ DE DADES********************
fi  retfie


putchar
      
      movwf   TXREG      ; del codigo ascii   
      bsf   STATUS,RP0   ;Cambio al banco 1 -------------
      bcf   STATUS,RP1
COMP_TX      
      btfss   TXSTA,TRMT   ;comprueba si acabo de Tx.
      goto   COMP_TX
      bcf   STATUS,RP0   ;Cambio al banco 0 -------------
      return
      
      
Inici
   
      
      bsf   RCSTA,SPEN   ;se activa la USART
      bsf   STATUS,RP0   ;Cambio al banco 1 -------------
      bcf   STATUS,RP1
      clrf   TRISA      ; Tot el port A es configura com a SORTIDA
      clrf   TRISB      ;Puerta B como salida
      movlw   b'10111111'   ;RC7/Rx entrada,
      movwf   TRISC       ;RC6/Tx   salida.

      movlw   b'00100100'   ;Configuracion USART
      movwf   TXSTA      ;y activacion de transmision
      movlw   .51
      ;movlw   .25      ;9600 baudios
      movwf   SPBRG
      bsf PIE1,RCIE         ;Habilitem l'interrupcio de Recepcio
      bcf   STATUS,RP0   ;Cambio al banco 0 -------------
      clrf estat_anterior ; Inicialment l'estat anterior sera 0
      movlw b'10010000' ;Usart recepcion continua
      movwf RCSTA
      movlw b'11000000'      ;Habilitem les interrupcions en general
       movwf INTCON
      bsf   RCSTA,SPEN   ;se activa la USART
   
      bsf   STATUS,RP0   ;Cambio al banco 1 -------------
      
      bcf   STATUS,RP1
      bsf   TXSTA,TXEN   ;Habilita la transmision
      bcf   STATUS,RP0   ;Cambio al banco 0 -------------
       call encendre_vermell
      
Principal            
   
   goto    Principal      ; Crea un bucle cerrado e infinito.

   END            ; Fin del programa.


Desconectado bones18

  • PIC12
  • **
  • Mensajes: 54
Re: Se puede enviar algo por la USART mientras se atienda una interrupcion 0x04?
« Respuesta #3 en: 04 de Agosto de 2006, 10:53:00 »
Si es demasiado largo, decidmelo, y editare el post, para ponerlo en un zip

El programa hace esto

Esta en un bucle infinito sin hacer nada a esperas q llegue algo por el Rx

cuando llega, atienda a la interrupción 0x04 y comprueba q el flag de recepcion se ha activado.

Dentro de la rutina de interrupcion he creado un maquina de estados, tiene estado0 , estado1 y estado2, el valor del estado donde nos encontramos se encuentra guardado en estat_anterior. Sobre este valores hago unas consultas, pero vaya aqui no debe estar el problema.

El problema viene cuando hago
              *****AQUI COLOCO UN 1 EN EL W y LLAMO A LANZO AL SERIE
                **********ESTO ES EL MOTIVO DE MI PREGUNTA************

   movlw a'1'
   call putchar

se supone q en el hyperterminal deberia salir un 1. Q si sale si pongo estas mismas lineas dentro del bucle principal, fuera de la rutina de interrupcion. El programa, pasa por ahi seguro pues la siguiente linea es

call encendre_taronja

que enciende un led de la placa, y lo enciende.

Asi que sencillamente no hace caso del putchar... es como si se lo saltase.

adios! perdon por el tocho


Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Se puede enviar algo por la USART mientras se atienda una interrupcion 0x04?
« Respuesta #4 en: 04 de Agosto de 2006, 11:49:48 »
bones18 el problema lo tienes aquí,

Código: ASM
  1. ORG 0x04 ; Sera el vector d'interrupció del USART
  2.    ;dadaRebuda
  3.    
  4.    btfss PIR1,RCIF ; si el Flag de recepcio s'ha activat salta la seguent instruccio
  5.    goto fi
  6.    bcf    PIR1,RCIF ; restaurem el flag
  7.                  ;****SI HEMOS LLEGADO AQUI TENEMOS UN CARACTER ESPERANDO EN RCREG****
  8.                 ; El primer pas es mirar en quin estat ens trobem
  9.    movf estat_anterior,0 ; carreguem l'estat anterior a W
  10.    xorlw '0'
  11.    btfss STATUS, Z
  12.    goto estat1


Si lees el datasheet verás que para que el flag de usart se borre, debes vaciar el buffer de usart.  Esto no se hace borrando el flag, sino haciendo una lectura del registro RCREG , cambia tu código y en vez de poner

bcf PIR1,RCIF

pon

movf  RCREG,w


Eso de seguro hará funcionar a tu software, lo que ocurre es que nunca sale de la rutina de interrupción porque el flag nunca se apaga.


- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado bones18

  • PIC12
  • **
  • Mensajes: 54
Re: Se puede enviar algo por la USART mientras se atienda una interrupcion 0x04?
« Respuesta #5 en: 06 de Agosto de 2006, 06:34:27 »
gracias, por la respuesta

al final resulto ser un problema de programacion del micro.

Solo con poner bcf PIR1,RCIF  parece q tambien funciona pero no me arriesgare y pondre lo q me aconsejaste

gracias!

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Se puede enviar algo por la USART mientras se atienda una interrupcion 0x04?
« Respuesta #6 en: 06 de Agosto de 2006, 12:09:20 »
gracias, por la respuesta
De nada :)


al final resulto ser un problema de programacion del micro.

Ups, bueno, a veces suele pasar

Solo con poner bcf PIR1,RCIF  parece q tambien funciona pero no me arriesgare y pondre lo q me aconsejaste

Qué raro... en realidad si tu le mandas un caracter hacia el pic debiera funcionar el software, pero lo que yo te dije es que "transmitirá todo el tiempo" porque el flag quedará siempre encendido.

El flag PIR1,RCIF es de 'solo lectura', es decir que

BCF PIR1,RCIF   no borra el flag

Sólo MOVF RCREG,W lo borrará realmente. 

De hecho si haces eso en el simulador de los ultimos mplab ide (7.3, 7.4) no te debiera borrar el bit.

Te extraigo un texto del datasheet.  DS30292C , page 101.

Flag bit RCIF is a read only bit, which is cleared by the hardware.
It is cleared when the RCREG register has been read and is empty


¿Puedes aclarar cómo es que funcionaba? Osea si realmente respondía un solo caracter cuando tu le enviabas algo o si se quedaba transmitiendo indefinidamente?



- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)