Autor Tema: Ayuda interrupción Proton+  (Leído 5200 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado virolay

  • PIC12
  • **
  • Mensajes: 50
Ayuda interrupción Proton+
« en: 30 de Noviembre de 2004, 19:33:00 »
Hola a todos.

He diseñado (es un decir Enfurruñado ) un terminal para el control de entradas de claves.
Utilizo un PIC16f873, TECLADO 4X4 Y lcd 16X2.
Proton+ 2.1.3 y una interrupción basada en en TMR1 para el teclado. Como no me permite adjuntos (no sé por quéGiño os pongo al final el fuente. Lo siento.
Todo funciona perfectamente excepto que no puedo conseguir lo siguiente:

Cuando entro en modo ARMED (o sea, alarma armada) disparo una serie de sonidos temporizados de forma que indiquen que se debe salir pero no he sido capaz de lograr que mientras suena los pitidos se pueda introducir una clave para desarmar la alarma.

¿Alguien me puede ayudar?

Gracias anticipadas de un novato,




"*******************************************************************************
" TERMINAL REMOTO
" PROGRAMA: BETA.BAS
" PROPOSITO: Actuar como una llave electrónica.
"*******************************************************************************

include "LT16F873.INC"      " Variables genéricas configuración básica
   
"==== VARIABLES ================================================================   
"---- Lógicas ----
    DIM TRUE AS 1
    DIM FALSE AS 0
    DIM ON AS 1
    DIM OFF AS 0
   
"---- Aplicación ----
    DIM MODE AS BYTE                 " MODO ACTUAL (STANDBY, ARMED o ALARM)
    DIM STANDBY AS 255               " MODO STANDBY (Modo NORMAL sin ALARMA)
    DIM ARMED AS 254                 " MODO ARMED (Modo ALARMA ARMADA)
    DIM ALARMON AS 253             " MODO ALARMON (Modo ALARMA DISPARADA)
    DIM SUBMODE AS BYTE             " SUBMODO ACTUAL (PSWENTRY)
    DIM WAITING AS 250             " SUBMODO WAITING (Esperando primera tecla)
    DIM PSWENTRY AS 251              " SUBMODO PSWENTRY (Entrada de claves)
    DIM TEMP AS BYTE        

"---- Alias de Puertos ----  
    DIM GRNLED AS PORTC.0           " Alias del LED verde (STANDBY)
    DIM REDLED AS PORTC.1          " Alias del LED rojo (ARMED)
    DIM SPEAKER AS PORTC.2          " Alias del altavoz

"---- Teclado -----    
    DIM KEY AS BYTE                  " Almacena la tecla pulsada
    DIM LAST_KEY AS BYTE             " Valor de la última tecla en el último barrido   
    DIM NEW_KEY AS BIT               " Flag para indicar cuando se ha leído una nueva tecla
    DIM NO_KEY AS 255                " Valor que indica que no se ha pulsado tecla
    DIM KEY_STATUS AS BIT            " Flag para indicar control de tecla correcto

"---- Temporización ----
    DIM INPUT_TMR AS WORD            " Temporizador entrada de tecla
    DIM INPUT_TMR_RUNNING AS BIT     " Flag de funcionamiento del temporizador de tecla
    DIM INPUT_TMR_VALUE AS 300       " Centésimas de segundo entre teclas

" ---- Claves ----
    DIM PSW_POINTER AS BYTE          " Puntero al siguiente carácter de la clave
    DIM MAX_NO_NOS AS 5              " Número de caracteres en cada clave
    DIM PSW_STR[MAX_NO_NOS] AS BYTE  " Cadena en la que se almacena la clave
    DIM PSW_ENTERED AS BIT           " Flag que indica que se ha introducido una clave correcta   
    DIM PSW_TYPE AS BYTE             " Flag de tipo de clave 0: Normal, 1: Master
    DIM PSW_OK AS BIT                " Flag que indica que una clave es correcta   
    DIM PSW_ENTRY AS 0               " Submodo ENTRADA DE CONTRASEÑA (En STANDBY, ALARMON y ALARM)
    DIM NEWPSW_ENTRY AS 1            " Submodo ENTRADA NUEVA CONTRASEÑA (Sólo en Modo STANDBY)   
    DIM ATTEMPTS AS BYTE             " Contador de intentos
    DIM MAX_NO_ATT AS 3            " Número máximo de intentos de introducción clave
    DIM NO_PSWS AS 2               " Número de claves almacenadas
    DIM STD_PSW_ADDR AS MAX_NO_NOS   " La dirección de inicio de la clave normal
    DIM HIDE_PSW AS 1             " Flag ocultación de la clave (pone asteriscos)
   

"---- Lectura/Escritura EEPROM -----    
    DIM EEPSW_ADDRESS AS BYTE       " Dirección de la EEPROM          
    DIM EEPSW_DATA AS BYTE          " Byte transferido
    DIM OFFSET AS BYTE                   " Offset    


"---- Control de interrupción ----    
    DIM GIE AS INTCON.7
    DIM TIMER1REG AS TMR1L.WORD
    SYMBOL FUDGE_FACTOR = 7
    SYMBOL TMR1_VAL =((65536)-(XTAL*2500))+FUDGE_FACTOR " Cálculo de los valores
   "                                     de offset para una interrup-
   "                                  ción de 100Hz. Puede utilizar-
   "                                  se como una frecuencia de flash
   "                                  para LEDs o para el SPEAKER.
    ON_INTERRUPT INTERRUPT_ROUTINE              " Rutina en caso de interrupción

   
    GOTO START                                  " Salto de todas las subrutinas
   
   
"==== INICIALIZACION ===========================================================
     
START:

   T1CON = %00000000                           " Configuración de Tmr1 para tener un prescaler 1:1 y actuar como un temporizador
   PIR1.0 = 0                                  " Borrado del flag de interrupción de Tmr1
   INTCON = %11000000                          " Global and Peripheral interrupts on
   PIE1.0 = 1                                  " Enable Tmr1 as peripheral interrupt source
   T1CON.0 = 1
        CLEAR
        trisa = %11111100
   CLS

   SOUND SPEAKER, [100, 20, 110, 20]       " Beeps al encendido
   PRINT AT 1,1, "TRI v.BETA          "
   PRINT AT 2,1, "                    "
   DELAYMS 500
   CLS

        GOSUB SETMODE_STANDBY
   GOSUB SETSUBMODE_WAITING
       

GOTO MAIN_LOOP   

"*******************************************************************************
"**** PROGRAMA PRINCIPAL *******************************************************
"*******************************************************************************
" Llama al barrido de teclado.
" Espera a la pulsación de una tecla antes de iniciar la recogida de datos.
" Cuando se ha introducido la clave completa entonces la verifica y decide
" la acción a realizar
" Tambien permite la cancelación de la clave que se está introduciendo
"-------------------------------------------------------------------------------

MAIN_LOOP:

GOSUB KEY_SCAN         " SE BARRE EL TECLADO Y SE REGRESA   
" Solo para depuración
"IF KEY <> 255 THEN
   "PRINT AT 2,1,"                    "            
   "PRINT AT 2,1," KEY: ", KEY          " Para caracteres alfanuméricos
   "PRINT AT 2,10,"@KEY: ", @KEY       " Para caracteres numéricos
"ENDIF

" HASTA AQUI PUEDE LLEGARSE CON UNA TECLA PULSADA O NO (NO_KEY).
" En cualquiere de los casos se verifica. Con la llegada de la primera tecla
" numérica se entra en el modo PSWENTRY y se controla que en el caso de que
" entre una y otra tecla se superre el límite de tiempo dado por INPUT_TMR_VALUE
" automáticamente se suspende la entrada y se pasa al modo STANDBY

IF SUBMODE = WAITING THEN               " SI, se está en SUBMODO WAITING
   GOSUB CHKNUMKEY                   " Verificación de tecla numérica (1ª tecla)
   
   IF KEY_STATUS = TRUE THEN            " SI, la tecla es correcta, por tanto,
      GOSUB SETSUBMODE_PSWENTRY         " entramos en MODO PSW_ENTRY
      NEW_KEY = TRUE                    " Flag para indicar que la tecla es nueva
      GOSUB LOAD_INPUT_TIMER            " y hay que cargar el límite de tiempo del temporizador
      GOSUB PSW_ACC                  " ACC contraseña continúa añadiendo tecla
   ENDIF      
ELSE                                    " NO, ahora se está en MODO PSWENTRY
   IF INPUT_TMR_RUNNING = FALSE THEN    " Si, se ha superado el límite de tiempo
                                     " para la introducción de la tecla siguiente
                              
    GOSUB MODE_RETURN               " Se retorna al Modo actual
       GOTO MAIN_LOOP                     " y se entra en el bucle principal
   ENDIF    
   GOSUB PSW_ACC                  " ACC contraseña continúa añadiendo tecla
ENDIF

" CONTROL ENTRADA CLAVE.
" HASTA AQUI PUEDE LLEGARSE CON UNA CLAVE INTRODUCIDA O NO

    IF PSW_ENTERED = TRUE THEN             " SI, se han introducido todos los números
        GOSUB PSW_COMPARE                  " entonces comparar con las claves
        PSW_ENTERED = FALSE                " se BORRA EL FLAG
      
        IF PSW_OK = TRUE  THEN             " SE HA ENCONTRADO UNA CLAVE
         IF PSW_TYPE = 0 THEN               " Clave normal y MODOS STANDBY O ARMED
              GOTO NORMAL_ENTRY_ROUTINE    " Entrada de Clave Normal
         ENDIF
         IF PSW_TYPE = 1 AND MODE = STANDBY THEN   " Clave "MASTER" y MODO STANDBY
                                                           " (Sólo en modo STANDBY)
              GOTO MASTER_ENTRY_ROUTINE    " Entrada de Clave "Master"
           "PENDIENTE DE DESARROLLO
         ENDIF
      
            GOSUB CLEAR_PSW_BUFFER         " Ouesta a 0 del buffer de claves
        ELSE  
         PRINT AT 1,20,DEC ATTEMPTS      " Para caracteres numéricos
         GOSUB CLEAR_PSW_BUFFER  
         IF ATTEMPTS > MAX_NO_ATT - 1 THEN      " SUPERADO MAX. NUM. DE INTENTOS
               GOSUB SETMODE_ALARMON               " SE PASA A ALARMA
         ENDIF
        ENDIF
    ENDIF

goto MAIN_LOOP

"==== RUTINAS ==================================================================
 
"==== MODOS ====
"---- STANDBY ----
SETMODE_STANDBY:
   MODE = STANDBY
   GOSUB SETSUBMODE_WAITING
    "LOW GRNLED
   HIGH GRNLED
      LOW REDLED
      PRINT AT 1,1, "ALARMA DESARMADA  ","#", DEC ATTEMPTS
      PRINT AT 2,1, "                    "   
   IF ATTEMPTS = 0 THEN GOSUB MODE_ENTRY_SOUND
RETURN      

"---- ARMED ----
SETMODE_ARMED:
   MODE = ARMED
   GOSUB SETSUBMODE_WAITING
   LOW GRNLED        
      HIGH REDLED
      PRINT AT 1,1, "ALARMA ARMADA     ","#", DEC ATTEMPTS
      PRINT AT 2,1, "SALGA AHORA         "   
   IF ATTEMPTS = 0 THEN GOSUB MODE_ENTRY_SOUND

   TEMP = 0                      
   Repeat                        " Crea un bucle
   SOUND SPEAKER, [105,10] "PITIDOS INICIALES
   Inc TEMP                      
   DELAYMS 500
   Until TEMP = 25               " Para al llegar a 25
   PRINT AT 1,1, "ALARMA ARMADA       "
      PRINT AT 2,1, "SALGA INMEDIATAMENTE"         
    TEMP = 0
   Repeat                        " Crea un bucle
   SOUND SPEAKER, [105,10] "PITIDOS FINALES
   Inc TEMP          
   Delayms 100                
   Until TEMP = 50             " Para al llegar a 50

   PRINT AT 1,1, "ALARMA ARMADA       "
   PRINT AT 2,1, "                    "   
      
RETURN      

"---- ALARMON ----
SETMODE_ALARMON:
   MODE = ALARMON
   GOSUB SETSUBMODE_WAITING
   HIGH GRNLED
      HIGH REDLED
   ATTEMPTS = 0               " AQUI NO IMPORTA CONTROLAR LOS INTENTOS
                              " LA ALARMA YA SE HA DISPARADO
      PRINT AT 1,1, "   ¡ A L A R M A !","#", DEC ATTEMPTS
      PRINT AT 2,1, "                     "         
RETURN      

" ---- MODE_ENTRY_SOUND ----
MODE_ENTRY_SOUND:         
SOUND SPEAKER, [110, 20, 100, 20]       " Beep confirmación entrada en modo
RETURN            


"==== SUBMODOS ====

"---- WAITING ----
" Espera la llegada de la primera tecla numérica pulsada
SETSUBMODE_WAITING:
   SUBMODE = WAITING
   PRINT $FE, $0C                       " Deshabilita cursor  
   GIE = 0                              " Deshabilita interrupciones globales
   WHILE GIE = 1 : GIE = 0 : WEND              " y se asegura de que lo están
      INPUT_TMR_RUNNING = FALSE
    GIE = 1                              " Habilita las interrupciones globales otra vez
    "ATTEMPTS = 0                       " No utilizar, hay que controlar los intentos
   PRINT AT 2,1, "                    "      
    GOSUB CLEAR_PSW_BUFFER                    " Siempre parece ser necesario
RETURN      

"---- PSWENTRY ----
" Se entra inmediatamente despues de la primera tecla pulsada y espera las restantes
SETSUBMODE_PSWENTRY:
   SUBMODE = PSWENTRY
   PRINT AT 2,1, "CLAVE:              "      
RETURN      

"---- MODE_RETURN ----
" Retorno al modo actual
MODE_RETURN:

     IF MODE = STANDBY   THEN
         GOSUB SETMODE_STANDBY          " Se retorna al MODO STANDBY
     ENDIF
     IF MODE = ARMED THEN
         GOSUB SETMODE_ARMED         " Se retorna al MODO ARMED
     ENDIF
     IF MODE = ALARMON THEN
         GOSUB SETMODE_ALARMON         " Se retorna al MODO ALARMON
     ENDIF
RETURN


"==== TECLADO ====
"---- Barrido ----
KEY_SCAN:
    KEY = INKEY                                 " Barrido del teclado
   KEY = LOOKUPL KEY, [1,2,3,"A",4,5,6,"B",7,8,9,"C","*",0,"#","D",NO_KEY]
   " Si no se detecta pulsación de tecla se borra el flag NEW_KEY.   
    IF KEY = NO_KEY THEN
        NEW_KEY = TRUE
        GOTO KEY_EXIT
    ENDIF
   " Es necesario prevenir que la mísma tecla sea leída dos veces.
   " Se consigue mediante una rutina tipo cerrojo.   
    IF NEW_KEY = TRUE THEN                       " Si es la primera vez que pulsa
        IF KEY <> LAST_KEY THEN GOSUB BEEP      " esta tecla, se aplica antirrebote
        ENDIF                            
KEY_EXIT:
    LAST_KEY = KEY                          " Salvar el valor de la tecla
    RETURN
"---- Verificación tecla numérica ----
" Se verifica si se ha pulsado una tecla numérica
" Si es así se utiliza.
CHKNUMKEY:
    KEY_STATUS = FALSE               " Precondición del resultado
    IF NEW_KEY = TRUE THEN         " Si la pulsación es nueva (distinta de la anterior)
        IF KEY >= 0 THEN         " Si estamos en el rango de 0 a 9
            IF KEY <= 9 THEN
               KEY_STATUS = TRUE   " ES UNA TECLA NUMERICA
            GOSUB BEEP
               NEW_KEY = FALSE      " Confirma que la tecla ha sido leída
               RETURN
            ENDIF
        ENDIF
    ENDIF
    RETURN   
   

"---- Borra el "buffer" de la clave y resetea el puntero ----
CLEAR_PSW_BUFFER:
   FOR PSW_POINTER = 0 TO MAX_NO_NOS       " Rutina para borrar la matriz de la clave
        CLEAR PSW_STR[PSW_POINTER]         " Borra el "buffer" de la clave
   NEXT    
        CLEAR PSW_POINTER                  " Puesta a 0 del puntero
   RETURN
          
   
"==== TEMPORIZACION ====   
"---- Carga el temporizador de entrada de tecla ----
LOAD_INPUT_TIMER:
    GIE = 0                                    " Desconecta las interrupciones globales
    WHILE GIE = 1 : GIE = 0 : WEND                    " y se asegura de que lo están
    INPUT_TMR = INPUT_TMR_VALUE                     " Recarga el Temporizador de entrada de tecla
    INPUT_TMR_RUNNING = TRUE                        " y se asegura de que está en marcha
    GIE = 1                                         " Vuelve a conectar las interrupciones globales
    RETURN

"---- Acumulación Clave ----
PSW_ACC:

   GOSUB CHKNUMKEY                        " Verifica teclas entre 0 y 9
    IF KEY_STATUS = TRUE THEN              " ¿Es una de las teclas 1 a 9?    
        GOSUB LOAD_INPUT_TIMER             " SI, recarga temporizador entrada de tecla
        PSW_STR[PSW_POINTER] = KEY         " Se salva el número introducido en una matriz
        INC PSW_POINTER                    " Incrementa el puntero
      GOSUB DISPLAY_PSW
        IF PSW_POINTER > MAX_NO_NOS-1 THEN " ¿Se han superado el máximo número de caracteres?
            PSW_ENTERED = TRUE             " SI, entonces tenemos una clave completa
      GOSUB DISPLAY_PSW
      PRINT $FE, $0C
        ENDIF
    ENDIF
   RETURN
   
"---- Comparación de claves ----
PSW_COMPARE:
    EEPSW_ADDRESS = 0
    REPEAT                                 " Verifica las claves
       PSW_OK = TRUE                       " Se necesita precargar este flag para que la rutina funcione  
       CLEAR OFFSET                     " Se pone a 0 el offset
       REPEAT                              " Bucle a través de todos los caracteres del número
           EEPSW_DATA = EREAD EEPSW_ADDRESS + OFFSET  " Primero leer FIRST READ IN THE EEPROM STORE PASSWORD
           IF PSW_STR[OFFSET] <> EEPSW_DATA THEN      " despues comparar con el de la clave
            PSW_OK = FALSE                          " Este carácter no es igual, por tanto, continuar con el siguiente
           ENDIF
           INC OFFSET                            " Incrementa el offset
       UNTIL OFFSET = MAX_NO_NOS
       IF PSW_OK = TRUE THEN                          " ¡¡¡CORRECTO!!!
           ATTEMPTS = 0                          " Lo primero es poner a 0 el contador de intentos
          PSW_TYPE = EEPSW_ADDRESS / MAX_NO_NOS       " Su valor indica cuál de las dos claves es la correcta, o sea, normal= o master=1
        "print at 1,1, "                      "         
        "print at 1,1, "PASSWORD ", @PSW_TYPE
          RETURN    
       ENDIF                    
       EEPSW_ADDRESS = EEPSW_ADDRESS + MAX_NO_NOS  
    UNTIL EEPSW_ADDRESS = MAX_NO_NOS * NO_PSWS
   GOSUB ERROR_PSW
    RETURN                                             " Llegados aquí es porque no se han encontrado igualdades    
   
ERROR_PSW:
   INC ATTEMPTS                          "Se incrementa el contador de intentos
   IF ATTEMPTS <3 AND MODE <> ALARMON THEN
      PRINT AT 2,1, "QUEDAN ", DEC (3- ATTEMPTS), " INTENTOS   "
      SOUND SPEAKER, [60, 10, 80, 30]       " Beep confirmación entrada en modo
   ENDIF
   GOSUB MODE_RETURN               " Se retorna al Modo actual
   GOSUB SETSUBMODE_WAITING            " Se pasa al submodo WAITING
RETURN
   
"---- Clave normal ----   
NORMAL_ENTRY_ROUTINE:
IF MODE = STANDBY THEN   
   GOSUB SETMODE_ARMED      " Si se estaba en STANDBY, se pasa a ARMED
GOTO END_NER
ENDIF
IF MODE = ARMED OR MODE = ALARMON THEN GOSUB SETMODE_STANDBY      " Si se estaba en ARMED, se pasa a STANDBY

END_NER:

    PSW_OK = FALSE                     " Se pone a 0 el Flag de PASWORD OK
    "ATTEMPTS = 0                         " Se pone a 0 el CONTADOR DE INTENTOS     
    GOTO MAIN_LOOP              

RETURN

"---- Clave "master" ----
MASTER_ENTRY_ROUTINE:
    "SUBMODE = NEW_PWRD_ENTRY                    " Indica que se está en ese submodo
    "GOSUB MODE_CONTROL                          " !!!LED FLASH RATE
    GOSUB LOAD_INPUT_TIMER                      " Carga el temporizador de entrada
           
MASTER_ENTRY_LOOP:
    GOSUB KEY_SCAN                              " Barrido del teclado
   
    GOSUB PSW_ACC                  " Se acumula la clave

    IF INPUT_TMR_RUNNING = FALSE THEN           " ¿El temporizador ha rebasado?
        GOSUB SETMODE_STANDBY                   " SI, regreso a modo STANDBY
        GOTO MAIN_LOOP                          " y regreso al bucle principal
    ENDIF
   
    IF PSW_ENTERED = TRUE THEN             " ¿Introducidos todos los números?
        GOSUB PSW_COMPARE                 " SI, entonces compara la clave
        PSW_ENTERED = FALSE                " Borrar el flag
        IF PSW_OK = FALSE  THEN            " Proceder sólo si es una nueva clave
           CLEAR OFFSET
           REPEAT                               " ESCRIBE LA NUEVA CLAVE EN LA EEPROM
               EWRITE STD_PSW_ADDR + OFFSET,[PSW_STR[OFFSET]]
               INC OFFSET
           UNTIL OFFSET = MAX_NO_NOS
        ENDIF
        GOSUB SETMODE_STANDBY                   " Se regresa al modo STANDBY
        GOTO  MAIN_LOOP                         " y al bucle principal
    ENDIF

    GOTO MASTER_ENTRY_LOOP                    " Vuelta otra vez al bucle

   
   
"---- Visualización de la Clave ----
DISPLAY_PSW:                                       
   IF KEY<>255 THEN
      PRINT $FE , $0F
      CURSOR 2,PSW_POINTER + 15
      IF HIDE_PSW = 0 THEN
           PRINT DEC PSW_STR[PSW_POINTER-1] " Show the contents of each element.
      ELSE
            PRINT "*" " Visualiza "*" en lugar de dígitos
      ENDIF
   ENDIF  
    RETURN                                       " ALL DONE SO RETURN      
   
"---- Rutina de interrupción servicio temporizador ----

INTERRUPT_ROUTINE:

    CLEAR T1CON.0                               " PARO TMR1
    TIMER1REG = TIMER1REG + TMR1_VAL            " CARGA TMR1
    SET T1CON.0                                 " ARRANQUE TMR1
   
    IF INPUT_TMR_RUNNING = TRUE THEN            " ¿Esta en marcha?
        DEC INPUT_TMR                          " Poner en decimal
        IF INPUT_TMR = 0 THEN INPUT_TMR_RUNNING = FALSE " Flag de llegada a 0.
    ENDIF
   
    CLEAR PIR1.0                            " CLEAR TMR1 INTERRUPT FLAG

    CONTEXT RESTORE                               " END OF INTERRUPT ROUTINE
   

"---- BEEP ----
BEEP:
SOUND SPEAKER, [120,1]   
RETURN

"==== RUTINAS ==================================================================

      
      END
      
"==== RUTINAS ==================================================================
"---------------------------------------------------
" CONSTANTES POR DEFECTO
"---------------------------------------------------  
EDATA 1,4,4,7,9                               " Clave NORMAL por defecto
EDATA 1,2,3,4,5                               " Clave MASTER por defecto
Quod natura non dat Salmantica non praestat

Desconectado khasistos

  • PIC18
  • ****
  • Mensajes: 493
RE: Ayuda interrupción Proton+
« Respuesta #1 en: 01 de Diciembre de 2004, 07:22:00 »
HOLA .
No lo he analizado pero basandome en lo que tu expones si los sonidos temporizados que emites estan siendo generados por interupciones no podras o no tendras tiempo como para introducir la clave pues ya se produce la otra interrupcion y se detiene la ejecucion del programa para atender la interrupcion ,o temporiza mas largo para permitirte ingresar la clave o modifica para no quedar con un condicionante (poner clave) dentro de un ciclo repetitivo de interrupciones  o bien haz que se anulen la interrupciones "SI" se oprimio la primera tecla..o.salta a una subrutina para darte tiempo de desactivar....pero en definitiva si no me equivoco estas dentro de un ciclo de interrupciones pretendiendo hacer algo que insume mas tiempo que los intervalos de las mismas...

Saludos

Khasistos


Desconectado Lager.

  • Moderadores
  • PIC18
  • *****
  • Mensajes: 477
RE: Ayuda interrupción Proton+
« Respuesta #2 en: 01 de Diciembre de 2004, 12:39:00 »
De acuerdo con el pana khasistos, reviza el tiempo que esta dando para dichas fucniones, por que lo mas seguro es que estes de interrupcion a interrupcion.. otra cosa, la declaracion del ISR  PONLA AL PRINCIPIO; JUSTO DONDE BRINCAS A INICIO, esto es importante para el correcto funcionamiento de la interrupcion tambien HASLO MISMO CON LAS SUBRUTINAS D LOS GOSUBS, tambien es mejor que las pongas desde el principio y con un brinco pases a el principal.Una cosa mas, el 16f873 es un modelo de 14 bits cheka la sintaxis con  gosubs,(solucion :optimiza el programa) ya que  para estos modelos solo tienes 8 niveles de stack , esto es otro detalle que te puede estar quitando tiempo.
Un cosa mas, veo que tienes unos errorsillos en los comentarios:
 DEC INPUT_TMR " Poner en decimal  <----------- decrementa variable

Salu2 pana

Desconectado virolay

  • PIC12
  • **
  • Mensajes: 50
RE: Ayuda interrupción Proton+
« Respuesta #3 en: 02 de Diciembre de 2004, 04:24:00 »
Gracias kashistos y Lager.

Pues no lo consigo (nada asombroso teniendo en cuenta que es mi primer programa "serio"Giño.
Tengo la impresión de que mientras estoy haciendo que pite el altavoz, a base de REPEAT y DELAYMS, el programa hace caso omiso a la interrupción temporizada que es de, más  o menos 1/100 segundos.
La verdad es que en el manual no veo nada que diga que un SOUND o un DELAYMS puede ser interrumpido en el medio.
Lo malo es que no he sabido como poner una interrupción hardware de las líneas de teclado (PORTB).

¿Se os ocurre algo?. No tengo prisa, si podeis echarle otro vistazo os lo agradecería.

Por cierto, Lager, me has "pillao" en lo DEC (el comentario debí escribirlo después de haber utilizado DEC en PRINT).
No me había dado cuenta del detalle de poner la ISR y las subrutinas al principio, antes de la rutina principal.
Por curiosidad he mirado otros programas "ejemplo" y la práctica totalidad lo hace así. Yo pensé en VB.

Muchas gracias de nuevo y saludos,

virolay

Quod natura non dat Salmantica non praestat

Desconectado Lager.

  • Moderadores
  • PIC18
  • *****
  • Mensajes: 477
RE: Ayuda interrupción Proton+
« Respuesta #4 en: 02 de Diciembre de 2004, 14:50:00 »
pana virolay,
probaste optimizando el codigo?(cmabiando de lugar los gosubd, la ISR,etc..)
para estar mas seguros de que entre tu interrupcion, setea un led al ocurrir la interrupcion.... NO e probado las interrupciones con sund pana,  TEORICAMENTE DEBERIAN funcionar, por lo tanto no me atrevo a dcir quenFUNCIONAN enestos casos. ademas en tu interupcion no estas usando comandos que usen variables de sistema que te den problemas de informacion..  por que no al suceder la interrupcion pones en alto un led en donde quieras y asi te das cuenta si en verdad sucede la interrupcion,,, pon una linea con TOGLLE(para que cada ves que interrumpas se encienda os e apage el led... y ais ves la respuesta)
en caso de que veas que no suced la interupcion, reviza el seteo desde inicio...., si todo esta bien, quita el comando sound e intentalo de nuevo... .. en fin hay varias pruebas que puedes hacer... en un proyecto en blanco solo compila el timo de pic )con config ydemas) y el comando sound y reviza el archivo generado con la extensionPBP para ver QUE ESTA HACIENDO durante ese comando y como podria estar fallando en caso de que hayas determinado que el comando es el problema...
esta son solo uns sugerencias para que resuelvas tu problema... si sigues con el problema no dudes en postearlo y vere mas a fondo tu codigo.
Salu2 pana

Desconectado virolay

  • PIC12
  • **
  • Mensajes: 50
RE: Ayuda interrupción Proton+
« Respuesta #5 en: 12 de Diciembre de 2004, 14:08:00 »
Hola Lager:

No quería dejar pasar ni un día más sin contestarte y darte las gracias por tu generosidad.

He seguido tus indicaciones pero me he liado con lo del LED, te explico. Cuando enciendo o apago los LEDs me dí cuenta que en algunas subrutinas los LEDs ivan mal, por ejemplo, si pongo HIGH GRNLED y a continuación HIGH REDLED pues lo que sucedía era que el LED rojo se encendía pero el verde no. He recurrido a ejemplos y he visto que le ponen en el medio un DELAYMS de algunos centenares de microsegundos y por fin me están funcionando.
Veré de seguir con las pruebas y poner un LED que me conmute. De hecho ya había hecho algo pareciudo que era poner un PRINT con nulo éxito. Así que estoy buscando información del comportamiento del bucle REPEAT .... UNTIL por si me deshabilita la interrupción.

En fin, como ves voy muy lento y la documentación de Proton+ es muy aparente pero no encuentro respuestas, generalmente tengo que recurrir a buscar ejemplos en la red o a molestaros.

Si lo consigo ya te lo diré. Por cierto, voy a poner un nuevo hilo pero en este caso es para comunicar que he encontrado un fantástico editor de Proton+, muy semejante al nuevo Proton IDE v.3.0, te recomiendo que lo veas y si te parece me pones algún comentario.

Gracias,


P.S. Oye, ¿qué significa pana?


Quod natura non dat Salmantica non praestat

Desconectado Lager.

  • Moderadores
  • PIC18
  • *****
  • Mensajes: 477
RE: Ayuda interrupción Proton+
« Respuesta #6 en: 12 de Diciembre de 2004, 14:37:00 »
que onda virolay,
Mira lo del delay es necesario no se que xtal uses pero si es muy rapido no da tiempo a encender el led(si usas un xtal de 4 mhz no hay problema  pero a mayor velocidad me pasaba que con unos tipos de leds no encendia o a veces si y a  veces no), asi que que bien que te diste cuenta de ese detalle. una cosa mas en cosas de ese tipo es bueno hacerlo en montaje REAL(no se si usas el proteus para simular, pero si lo usas, cuidado ya que muchos errores tiene aun este simulador y en pequeños detalles como este, asi como encender un led despues de una espera larga o de imprimir en un LCD PUEDE sucederte que no encienda y en Montaje real SI LO HAGA, asi que no confies mucho en simulaciones)
Como te comentaba tambien esta el detalle de las pullups,, si las usas y tienes un pin de ENTRADA, este pin ESTARA en estado ALTO,, y si estas esperanco RECIVIR por este pin un cambio como la interrupcion por potb, el cambio seri llevarlo a TIERRA para que se active la interrupcion.... en fin, hay varias cosas que dbes de revizar,, y una ultima opinion, prueba por modulos... cheka que funcione un modulo y activa el otro modulo.,.. asi te daras cuenta DONDE esta el fallo(sobre todo si no lo tienes claro CUAL puede ser...)
Pana es Amigo, jejejeje ,

Salu2 pana

Desconectado Colores

  • Moderadores
  • PIC16
  • *****
  • Mensajes: 232
RE: Ayuda interrupción Proton+
« Respuesta #7 en: 14 de Diciembre de 2004, 19:55:00 »
Ups gente... no quiero interrumpir, pero veo que a alguien más le pasa lo mismo que a mí.
Resulta que estoy haciendo un proyecto que en una parte tiene que recorrer un array de switchs, y me sucede lo que estan hablando de los delays.
Si tengo el puerto C para recorrer la matriz en un primer momento tengo todos los pines en alto (PORTC = 255) y "escuchando" con un loop el puerto B que es la entrada de el teclado.
Cuando detecto que el puerto B es > que cero recorro con el puerto C todas las combinaciones de a uno. Empiezo por:
PORTC = %00000001
Y parece que el programa cuando leo el puerto B todavia esta con PORTC = 255, con los errores que esto acarrea. Si pongo un Delay 50 antes de PORTC = %00000001 funciona bien (no he probado con delays menosres).

Lo estoy simulando en Proteus (escrito con PBP) con un 16F877 y me dió a pensar que el programa iba más rápido que la respuesta en los pines.
La explicacion completa está en el foro de Simuladores bajo el titulo de "Problema de tiempo..." donde también está el código fuente y el esquematico.
Quizás a Virolay le esté pasando lo mismo. Si quieren veanlo, quizás les sirva.

Salu2.

Desconectado Lager.

  • Moderadores
  • PIC18
  • *****
  • Mensajes: 477
RE: Ayuda interrupción Proton+
« Respuesta #8 en: 14 de Diciembre de 2004, 21:36:00 »
Hola pana colores2,
Bueno en realidad hasta la fecha yo no tengo problemas de ese tipo, solo simulando me dan errores, pero cuando monto el dispositivo fnciona como lo programe.
con la posibilidad de que todo tiene error(ya que todo es posible).. creo que el problema vendria mas en el simulador, vuelvo a repetirlo.. hace un tiempo tambien encontre el problema de escribir en la CGRAM del lcd en la linea 8 de cada caracter(de plano esta linea no existe en simulacion,jjajajaja eso es un hecho).. y en el LCD real SI SUCEDE(esto es por que en simulacion no esperan que alguien escriba el caracter..igual y es solo en determinados LCDS del simulador pero lo que es un hecho es que existe... asi como este, hay varios errores de este simulador.. por eso de antemano le recomende que lo pruebe a tiempo real(armarlo)... habia veces que pones high led y enseguida un delay .. y en simulacion no se cumple(por no estar configurado,..error,etc.. pero no se cumple) esto no es problema de compilacion(del codigo generado) si no del mismo simulador.
Ojo que poner un portX.X en estado (alto o bajo) requiere un ciclo de reloj(BSF en asm) si tu usas un cristal de 4 mhz(medio dañado o trabajando con esxeso de correinte por mala fuente puede necesitar ese ciclo de tiempo y  este ocuparia 1us en suceder... si fuera de 20,seria .2us... )
En fin tu problema es un poco diferente  y habria que ver tu codigo para revizar la sintaxys del mismo. y asi poder diagnosticar tu problema en especifico.
Como bien es posible que  no se haya estabilizado como si es posible, pero no para esperar 10 ms....(es demasiado) creo que con dos nops: @nop:nop(4us o tomando un ciclo por cada pin, 8 us)se deberia de estabilizar(si fuese ese el problema), ademas acuerdate que es secuencial.. primero pone en alto el puerto y cuando termino lo cheka,,....no simultaneo o mucho menos fraccionado.

Una opinion, ya que usas el portb como salida COMPLETO,, podrias usar las pullups integradas y quitar las 8 resitencias (menos dinero. y mas espacio) , otra seria mover la rutina gosub al INICIO del programa, y brincarla para cargar el inicio.
Veo que tu codigo esta muy bien optimizado ,no usas variables inecesarias y quizas al PBP(yo ya no uso pbp) no le guste ir tan rapido y optimo, jejejejejeje, el usar los puertos directos es lo mejor que puedes hacer y evitas gastar memoria de forma inecesaria, veo que lo usaste asi.
La pregunta es ya lo probaste en montaje REAL? ... te pregunto e insisto en esto por que es muy probable que te funcione como debe en tiempo real, otra cosa son los rebotes.. acuerdate que si usas los pushhbutton te generaran rebotes,, que debes de eliminar. ya te dije los problemas que han sucedido con isis, y asi como este hay mas,, que a simple vista uno no los nota, pero estan...
Las interupciones multiples tambien dan problemas en isis, y hay veces que hay que reafirmar activar la interrupcion para que lo simule como seria realmente... y en real NADA QUE VER.. jejeje

Salu2 pana



Desconectado Colores

  • Moderadores
  • PIC16
  • *****
  • Mensajes: 232
RE: Ayuda interrupción Proton+
« Respuesta #9 en: 16 de Diciembre de 2004, 19:46:00 »
Gracias Lger por tus comentarios.
Paso a responder:

El montaje está probado SOLO en Isis. Me va a costar unos días más probarlo en el mundo real.
Con respecto a lo de los puertos... el PORTB es ENTRADA, no salida. El PORTC es salida. Quizás te confundiste al ver el esquemático, en el programa está bien claro.
Y si. Entiendo que levantar el estado de un pin lleva un ciclo de reloj, por eso no entiendo por que no funciona leyendolo inmediatamente, la lectura demora otro ciclo de reloj, así que le dá tiempo.
Igualmente se me ocurren dos cosas:
O Isis no está funcionando mal... (lo más probable)
O por ahí está tomando el delay del micro + el delay de los diodos.

Creo que el problema está en ISIS, de última le mando un NOP y listo, no se va a notar.
Eso sí, el NOP de assembler no es igual al NOP de PBP, no? Tengo entendido que @nop es igual a un ciclo, y el NOP de PBP es igual a .... uff, estoy viendo ahora que NOP en PBP no existe. Lo que existe es NAP, ahí debe estar la diferencia. El NAP más chico consume 18ms (una eternidad).

Un último comentario que me parece válido aclarar (quizás el equivocado soy yo, eh?)
Veo que muchos foristas confunden milisegundos (ms) con microsegundos (us).
Milisegundo = milesima de segundo = 1/1000 seg
Microsegundo = millonésima de segundo = 1/1000000 seg
Nanosegundo = milmillonésima de segundo = 1/1000000000 seg

Creo que 3 ceros hacen un diferencia, no?

Salu2.

Desconectado Lager.

  • Moderadores
  • PIC18
  • *****
  • Mensajes: 477
RE: Ayuda interrupción Proton+
« Respuesta #10 en: 16 de Diciembre de 2004, 20:07:00 »
Escrito originalmente por Colores2
Gracias Lger por tus comentarios.
Paso a responder:

El montaje está probado SOLO en Isis. Me va a costar unos días más probarlo en el mundo real.
Con respecto a lo de los puertos... el PORTB es ENTRADA, no salida. El PORTC es salida. Quizás te confundiste al ver el esquemático, en el programa está bien claro.
Y si. Entiendo que levantar el estado de un pin lleva un ciclo de reloj, por eso no entiendo por que no funciona leyendolo inmediatamente, la lectura demora otro ciclo de reloj, así que le dá tiempo.
Igualmente se me ocurren dos cosas:
O Isis no está funcionando mal... (lo más probable)
O por ahí está tomando el delay del micro + el delay de los diodos.

Creo que el problema está en ISIS, de última le mando un NOP y listo, no se va a notar.
Eso sí, el NOP de assembler no es igual al NOP de PBP, no? Tengo entendido que @nop es igual a un ciclo, y el NOP de PBP es igual a .... uff, estoy viendo ahora que NOP en PBP no existe. Lo que existe es NAP, ahí debe estar la diferencia. El NAP más chico consume 18ms (una eternidad).

Un último comentario que me parece válido aclarar (quizás el equivocado soy yo, eh?)
Veo que muchos foristas confunden milisegundos (ms) con microsegundos (us).
Milisegundo = milesima de segundo = 1/1000 seg
Microsegundo = millonésima de segundo = 1/1000000 seg
Nanosegundo = milmillonésima de segundo = 1/1000000000 seg

Creo que 3 ceros hacen un diferencia, no?

Salu2.


Que onda Colres2
De que hay problemas con el ISIS los hay, de eso no me cabe la menor duda a mi, crei haber visto el portb como salidas, en fin eso no es de importancia es solo de mejoramiento.
Realmente otro de tus problemas es que usas PBP , yo ya no usao mas ese compilador por sus bugs y problemas, con el proton no e tenido ese tipo de problemas, al contrario.
Un NOP es donde sea nop pana, en proton tiene la ventaja de que algunos comandos en asm como este se pueden poner sin el @ para aclarar que es asm, por ahi vi que si se puede poner el nop con asm endasm o con el @ que e slo mismo pero para una solo linea.
Sobre el ometario de aclaracion de tiempos, le va a ser util a quien tenga problemas de tiempo, eso que ni que, jajajajajajaj Muchas risas

Salu2 pana

Desconectado Lager.

  • Moderadores
  • PIC18
  • *****
  • Mensajes: 477
RE: Ayuda interrupción Proton+
« Respuesta #11 en: 16 de Diciembre de 2004, 20:42:00 »
Pana colores2,
Estoy bajando tu programa y tu circuito para simular, haber si puedo ayudarte.
Donde debo de notar tu problema para ponerlo a andar pana?

::::Pana , solo lo pase a proton y lo compile dime  donde te lo envio para que pruebes el hex, y  chekes haber si por lo menos SIRVIO mi adaptacion y ver lo de tu problema

Salu2 pana

Desconectado Colores

  • Moderadores
  • PIC16
  • *****
  • Mensajes: 232
RE: Ayuda interrupción Proton+
« Respuesta #12 en: 17 de Diciembre de 2004, 09:51:00 »
Gracias Lager.
Si querés ponelo en el mismo lugar donde yo colgué el de PBP...

todopic3.foro.st

El topic se llama:

Problema de tiempo...

Desconectado Lager.

  • Moderadores
  • PIC18
  • *****
  • Mensajes: 477
RE: Ayuda interrupción Proton+
« Respuesta #13 en: 17 de Diciembre de 2004, 11:04:00 »
Hola Colores2,
Estuve realizando varias pruebas( TODAS EN SIMULACION)... con y sin diodo surgia el mismo problema, asi que veo que esto no es el problema.
procedi a simplidicar tiempos.. donde el tiempo de .6us era el necesario para que dejara de tener ese problema... como tu bien sabes estamos hablando de (.6/.2= 3 ciclos para que SEGUN se estabilize ESPERANDO)la rutina de tiempo esta formado por 3 @nop...
En ensamblador quedaba la siguiente rutina:
   Movlw 1
   Movwf PORTC
       nop
       nop
       nop
 Un segundo metodo encontrado fue(en apoyo de teoria de FALLA en ISIS) Limpiar el registro antes de volver a escribir en el el cual funciono mejor, OJO que cada PORTC=XXXXX no es mas que un:
Movlw 1
Movwf PORTC
, en ensamblador..... esto pudo tambien conyevar  a la teoria de mal bankeo.. lo cual no es ya que deberia de funcionar bien si se setearan estos valores antes de entrar a la subrutina o usando un Bcf STATUS,5.. caso no solucionado asi.
Continuando con el limpiado del registro.. el comando CLEAR no es mas que un
clrf f
,en ensamblador..........., lo cual nos ocupa solo 1 cilo de tiempo(.2us para 20 mhz) y reduce CONSIDERABLEMENTE la perdida de tiempo INECESARIA( diferencia de ciclos 3 -1=2).
¿Por que apoya esto la teoria de falla? solo es una teoria... el hecho seria montarlo realmente y ver que sucede.. ya que hay una diferencia de ciclos no justificada entre uno y otro metodo .
No olvidemos la estabilizacion... la cual existe y claramente en el Ds de cada modelo nos previene de futuros errores, en caso de escribir en un puerto y leerlo seguidamente, que es lo que pasa indirectamente despues de setear a 0 el c1, y leer el puerto b..(antes 1 despues cero y leer enseguida....)Tema tratado en I/O programming considerations:Successive operations on I/O PORTS, en el cual tenemos la respuesta ala POSIBLE NO FALLA DE ISIS donde tenemos:
Data setup time=(0.25Tcy - Tpd) , donde Tcy=ciclo de instruccion y Tpd=delay de propagacion, con un comentario extra muy importante: "Entonces, en ALtas frecuencias de mReloj una escritura seguida de  una lectura puede ser problematico.. ¿A quien le hechamos la cuñpa de todo esto? a el Latch del puerto.. jejejejeje.  Claro que est es para puertos Bidireccionales..(usados como entrada y salida al mismo tiempo) pero podria ser la problematica.
En resumen , ambas soluciones(ya encontradas anteriormente por el autor de el codigo a analizar) hasta no probar el circuito de forma Real:

sector1:
PORTC =%00000001 "RC0
@nop
@nop
@nop

sector1:
clear portc
PORTC =%00000001 "RC0

Pana Colores2, no puedo subirte el hex, no me deja en el foro me dice que no tengo privilegios o algo asi.

Un abraso pana

Desconectado Colores

  • Moderadores
  • PIC16
  • *****
  • Mensajes: 232
RE: Ayuda interrupción Proton+
« Respuesta #14 en: 17 de Diciembre de 2004, 11:10:00 »
Gracias nuevamente por tu tiempo.
Ahora tengo que salir corriendo a rendir fianales, pero esta noche leo bien tus propuestas y las pruebo.

Salu2 y gracias nuevamente!


 

anything