Autor Tema: Reloj binario PIC 16F628A ASm (en proceso)  (Leído 24180 veces)

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

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #30 en: 13 de Septiembre de 2015, 17:20:30 »
Una vez más has dado en el clavo Killer, como siempre muy agradecido. Ahora ya no me puedo ronear más y toca darle caña a las interrupciones a ver como salen. Primero haré algo sencillo a ver que sale.
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #31 en: 14 de Septiembre de 2015, 04:13:51 »
Una vez más has dado en el clavo Killer, como siempre muy agradecido. Ahora ya no me puedo ronear más y toca darle caña a las interrupciones a ver como salen. Primero haré algo sencillo a ver que sale.

Para casos como esto, lo que haces es irte al datasheet y lo primero es ir a los puertos, al final de la seccion de los puertos B te muestra todos los registros que le afecta, si esos estan todos correctos. Entonces deberias ver que otras opciones tienen esos pines.
Sino me equivoco unade las primeras cosas es ponerte una tabla con la funcion de cada pin, ahi miras cada modulo. por ejemplo en este caso tenian:

ISCP
Timer1

Sobre el ISCP me fije si habia una palabra de configuracion que lo manteniera en esa funcion y no permitiera cambiarlo, al tener LVP en OFF eso no era. Y solo queda ... el Timer 1. dentro de la seccion del timer 1 busque por RB6 y ese pedacito de texto aparecio.

En fin si ves que algo es muy simple y no le estas errando ( como por ejemplo poner a 1 un bit ) y no funciona. Es la configuracion. no queda otra xD

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #32 en: 17 de Septiembre de 2015, 04:28:43 »
No te creas que no intento mirar los datasheet pero entre que están en inglés y que no me entero, no le saco mucha info. Aunque poco a poco vamos aprendiendo cosas. Más cosas, he empezado un programa sencillo para las interrupciones (que obviamente, no hace lo que esparaba). Mi idea es que el programa simule un conteo y que aunque toque un botón y se encienda o se apague un led, el conteo continue mediante una interrupción del TMR. Este es mi aborto de programa.

Código: [Seleccionar]
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST    P=16F628A
INCLUDE  <P16F628A.INC>

CBLOCK  0x20
contador
W_Temp
Status_temp
ENDC

; ZONA DE CÓDIGOS ********************************************************************

    goto Inicio

ISR_VECTOR    ORG 0x04
    goto Interrupcion

Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw 0x07
movwf OPTION_REG
movwf CMCON
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf PORTB

movlw   b'00111100'   ; Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
    movwf   T1CON
    movlw   b'00001011'   ; Se configura CCP modo captura cada flanco de subida.-
    movwf   CCP1CON
movlw   b'11110100'   
movwf   CCPR1H
movlw   b'00100100'   
movwf   CCPR1L
CLRF    TMR1H
CLRF    TMR1L         
bsf T1CON,TMR1ON

movlw d'0'
movwf contador

Principal
btfss PORTA,0
bcf PORTB,0
bsf PORTB,0
goto Principal

Interrupcion
movwf   W_Temp
    swapf   STATUS,W
    bcf   STATUS,RP0
    movwf   Status_temp

btfss PIR1,CCP1IF
goto Fin_interrupcion
incf contador

movf contador,W
movwf PORTB
bcf PIR1,CCP1IF
clrf TMR1H 
goto Fin_interrupcion

Fin_interrupcion
swapf   Status_temp,W
    movwf   STATUS
    swapf   W_Temp,F
    swapf   W_Temp,W
retfie

END

Y aquí mis dudas. Primero que el programa solo hace parpadear el led y se olvida por completo de la interrupción. Y segundo el tema de la memoria. Para el conteo uso "contador" para la memoria y creo que no voy bien.  Debería usar W_Temp, Status_temp para la interrupción??

Como veis, las interrupciones no son mi fuerte, pero este año me he planteado descifrarlas.

Como siempre, muchas gracias
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #33 en: 17 de Septiembre de 2015, 06:12:07 »
El codigo esta bien, y si te das cuenta cual es el error vas a pegar cabezasos en la mesa :P
Hay algo que te tenes que acostumbrar.

Cada modulo/programa/etc podes pensarlo como una cajita que tiene sus "entradas" y "salidas"

Ejemplo si hago un programita que me convierte de binario a BCD de 2 digitos, le paso el dato por W y me lo devuelve tambien por W.
Entonces
Entrada: W
Salida: W

Ejemplo una subrutina que encienda y apague una salida RB0, dependiendo de la entrada RB1
Entrada: RB1
Salida: RB0
Dependiendo de mi entrada va a responder mi codigo y me va a dar una salida.

-------------------------------------------------

Volviendo a algo mas parecido a lo tuyo
Por ejemplo el modulo del timer posee como entradas:

El/Los registros de configuracion del Timer (entrada)
T1CON

El/Los registros que mantienen el valor (entrada)
TMR1H:TMR1L

De acuerdo a como esten estas "entradas" el modulo va a funcionar de una u otra forma. ( Va a tomar clocks 1 de cada 4 clocks, o 1 de cada 8, tomo elvalor del reloj interno o externo, etc )

Y como salida puede ser un pin, o un flag. supongamos que nomas tenes el flag:
PIR1,TMR1IF

El hardware del timer  cuando ocurre un overflow pone a uno ese flag. Pero esto lo hace el modulo.
Separa por un momento mentalmente el Nucleo del PIC (el que ejecuta las instruccion, esta a la espera de las interrupcion, es el que lleva el Contador de programa) y cada modulo (Como si fueran 2 cajitas, cada uno con su entradas y salidas). Es decir tenes el nucleo por un lado y el modulo por el otro. Como le dice el modulo este que debe entrar a una interrupcion al Nucleo? Lo hace con esa bandera.

Pero si fuera solo eso cada ves que pongo a funcionar un modulo y cada ves que se cumple la condicion de la bandera de ese modulo se va a poner a 1. y por ende va a entrar a la interrupcion.
Ejemplo interrumpiria por que hubo un pulso ascendente en RB0 (yo no lo active, pero la bandera se pone a 1 igual)
o un cambio en RB4:RB7
O el timer0 que no se puede parar, cada ves que se produce el overflow estaria entrando a la interrupcion por que se pone a 1 la bandera, ya que es esa la funcion de ese modulo.
ETC.

Yo necesito un control de cuales banderas quiero que pasen a mi Nucleo.
(Si no te diste cuenta aca en un rato te vas a dar cuenta)

(Si no te diste cuenta)Solucion: No habilitaste las interrupciones en INTCON (globales GIE y de perifericos PEIE) y PIE1.CCP1IE (del periferico CCP1 y en ves de terminar IF, interrupt flag, termina en IE, interrupt enable )
(te dije que te ibas a dar cuenta en un "rato")

Activalos luego de configurar el timer y el CCP1, previamente antes de activarlo borra el flag del CCP1 por las dudas que este en alto, es solo una precaucion.

Por que te lo explico de esta manera? Por que me sucedio algo cuando empeze a trabajar con un ARM en el que hacer funcionar una interrupcion no es lo mismo que aca que es poner 2 bits a 1, sino que cada modulo tiene SU habilitacion, como 3/4 registros solo para la interrupcion xD y luego el nucleo tambien tiene su habilitacion!! . Al igual que los micros PIC32 con nucleo MIPS en el que el nucleo es de un fabricante y lo que hacen microchip es ponerle los perifericos, si tenes una imagen clara que el nucleo esta separado fisicamente del modulo es mas facil de entenderlo, son como 2 circuitos totalmente independientes uno de otro y que se deben comunicar entre ellos con esas señales, en nuestro caso son las flags
« Última modificación: 17 de Septiembre de 2015, 06:32:08 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #34 en: 17 de Septiembre de 2015, 19:49:18 »
Vaya por Dios (por no poner un taco mayor) veo que muchos de mis problemas son por temas de configuración en los pines, eso es bueno porque quiere decir que el lenguaje lo voy controlando y malo porque de este tema aun me queda mucho que aprender. Volviendo a tus consejos añadí la parte de programa que me faltaba (que he usado uno que colgaste tu hace un tiempo). Ahora la cosa ha avanzado un poco, por un lado empieza el conteo ascendente, y cuando pulso el botón, parpadea el led pero el conteo se detiene. Pensaba que al pulsar el botón parpadearía el led pero el contador se para y prosigue una vez no pulso el botón.

No debería continuar?? como siempre cuelgo el código.

Código: [Seleccionar]
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST    P=16F628A
INCLUDE  <P16F628A.INC>

CBLOCK  0x20
contador
W_Temp
Status_temp
ENDC

; ZONA DE CÓDIGOS ********************************************************************


; RES_VECT  CODE    0x0000            ; processor reset vector
    goto Inicio

ISR_VECTOR    ORG 0x04
    goto Interrupcion

Inicio
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB
movlw 0x07
movwf OPTION_REG
movwf CMCON
bcf STATUS,RP0 ; Acceso al Banco 0.
clrf PORTB

movlw   b'00111100'   ; Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
    movwf   T1CON
    movlw   b'00001011'   ; Se configura CCP modo captura cada flanco de subida.-
    movwf   CCP1CON
movlw   b'11110100'   
movwf   CCPR1H
movlw   b'00100100'   
movwf   CCPR1L
CLRF    TMR1H
CLRF    TMR1L

BANKSEL PIE1
    BSF     PIE1,CCP1IE     ;Activamos interrupcion
    BANKSEL PIR1
    BCF     PIR1,CCP1IF     ;Limpiamos flag
    BSF     INTCON,PEIE
    BSF     INTCON,GIE
         
bsf T1CON,TMR1ON

movlw d'0'
movwf contador

Principal
btfss PORTA,0
bcf PORTB,0
bsf PORTB,0
goto Principal

Interrupcion
movwf   W_Temp
    swapf   STATUS,W
    bcf   STATUS,RP0
    movwf   Status_temp

btfss PIR1,CCP1IF
goto Fin_interrupcion
incf contador

movf contador,W
movwf PORTB
bcf PIR1,CCP1IF
clrf TMR1H 
goto Fin_interrupcion

Fin_interrupcion
swapf   Status_temp,W
    movwf   STATUS
    swapf   W_Temp,F
    swapf   W_Temp,W
retfie

END
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #35 en: 19 de Septiembre de 2015, 16:28:30 »
Disculpa que realmente no me di cuenta que habías respondido con otro problema.

Hay 3 cosas que estan mal.

- La primera es una que habíamos solucionado. Y era lo de poner un 0x07 en CMCON. Pero lo estabas haciendo desde el banco 1 y no desde el 0, ese era el problema, cuando copiaste y pegaste te olvidaste de ese error.
- La segunda es la configuracion del Timer1, corregido arriba
- La tercera es el programa principal, asi como lo tenes,  no vas a tener una buena respuesta como para analizarlo:

Cada X tiempo el Puerto B va a cambiar de valor por tu interrupcion

Pero ademas vos en tu programa principal estas escribiendo el bit 0 del puerto B. lo cual es algo complejo de que realmente veas cuando presionas y cuando no el boton.
Si supongamos que cambias la salida de ese led a uno del PORTA, (recorda modificar el TRISA), te vas a encontrar con con que si presionas el boton se va a mantener en 1 la salida, y que si lo soltas va a variar entre uno y cero, o viceversa. No es que va a quedarse en un estado definido.

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #36 en: 14 de Octubre de 2015, 19:40:54 »
Sigo clavado con esto. Mi idea es que cuando no toque ningún botón haya un LED que parpadee y cuando pulse un botón se vea un conteo ascendente, pero creo que no voy bien y no se por donde cogerlo. Es feo pedir esto, pero me puedes poner un ejemplo sencillo de interrupción, porque por más pruebas que haga no consigo nada bueno.
Estoy perdido, perdido ...
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #37 en: 14 de Octubre de 2015, 19:54:35 »
No hay problema.

Por favor explicate un poco mas en lo que necesitas.

Cuando no tocas el boton, 1 LED parpadea, eso lo entiendo, necesito que me digas donde va a estar el led, por ejemplo en RB4, o si es parte del contador, y tambien a que velocidad parpadearia.
Cuando pulsas el boton queres ver un contador ascendente, eso lo entiendo, pero no se donde van a estar ubicados los leds del contador. Tampoco se el tiempo que necesitas que se muestre hasta volver al estado anterior(el de no tener presionado nada). Y de donde saco los valores de ese contador, o cada ves que presiono el boton aumentaria en 1 el contador ?
Donde estaria ubicado el boton?.
O puedo poner los botones y leds a mi voluntad?

Utilizarias el reloj interno del 16F628, como en los ejemplos que venimos haciendo ?

Por las dudas voy a hacer ejemplos de timer y de CCP, que podria ser lo mas sencillo de ver.
« Última modificación: 14 de Octubre de 2015, 19:56:48 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #38 en: 14 de Octubre de 2015, 20:21:35 »
Mi idea es poder comprender la base de la interrupción para pasarlo al programa del reloj. Mi idea es que la interrupción haga de conteo ascendente (simulando la hora y los minutos del reloj, pero de forma simplificada).  Mientras no se toca ningún botón haya un LED parpadeando y cuando se pulsa en botón se vea ese conteo ascendente. Es como pulsar el botón para ver la hora.

Es que hasta explicándolo ya me cuesta aclararme, malditas interrupciones jejejeje.

Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #39 en: 15 de Octubre de 2015, 01:48:05 »
Código: ASM
  1. ;*****************************************************
  2. ;                  
  3. ;           ---- Programa sin sentido ----
  4. ;   Usa las interrupciones del CCP y Rb0 para hacer
  5. ;   un toggle a un LED o mostrar un contador que va desde
  6. ;   0 a 15, y vuelve a repetir todo de nuevo
  7. ;
  8. ;   Rb0 = Entrada Boton, Flanco descendiente
  9. ;   Rb7:Rb4 = Salidas de los leds
  10. ;   4Mhz / Reloj interno
  11. ;*****************************************************
  12.    
  13. ;*****************************************************
  14. ;                   Include
  15. ;*****************************************************
  16.     #include "p16f628a.inc"
  17.  
  18. ;*****************************************************
  19. ;                   Palabra de configuracion
  20. ;*****************************************************
  21.  
  22.  __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
  23.  
  24.  
  25. ;*****************************************************
  26. ;                   Quita de Warnings
  27. ;*****************************************************
  28.  
  29.  errorlevel -302
  30.  
  31. ;*****************************************************
  32. ;                   Datos
  33. ;*****************************************************
  34.  
  35.     udata_shr
  36. W_temp          res 1
  37. Status_temp     res 1
  38. Contador        res 1
  39. Flag            res 1
  40. Valor           res 1
  41. Estado          res 1
  42.  
  43.  ;*****************************************************
  44.  ;                  Vectores
  45.  ;*****************************************************
  46.  
  47. RES_VECT    CODE    0x0000      ; Vector de reset
  48.         GOTO    Start
  49. INT_VECT    CODE    0x0004      ; Vector de interrupcion
  50.         GOTO    Interrupcion
  51.        
  52. ;*****************************************************
  53. ;               Programa Principal
  54. ;*****************************************************
  55.  
  56. MAIN_PROG CODE                      ; Programa principal
  57.  
  58. Start:
  59.  
  60.         ; Banco 1
  61.        
  62.         BANKSEL TRISB
  63.         MOVLW   0x0F            ; RB3:0 Entradas
  64.         MOVWF   TRISB           ; RB7:4 Salidas
  65.         CLRF    OPTION_REG
  66.        
  67.         ; Banco 0
  68.        
  69.         BANKSEL PORTB
  70.         CLRF    PORTB           ; Digital y a 0
  71.         MOVLW   0x07
  72.         MOVWF   CMCON
  73.        
  74.         MOVLW   b'00111100'     ; Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
  75.         MOVWF   T1CON
  76.         MOVLW   b'00001011'     ; Se configura CCP modo captura cada flanco de subida.-
  77.         MOVWF   CCP1CON
  78.         MOVLW   b'11110100'     ; Cargamos 62500 al CCP
  79.         MOVWF   CCPR1H
  80.         MOVLW   b'00100100'  
  81.         MOVWF   CCPR1L
  82.         CLRF    TMR1H           ; Ponemos a 0 el TMR1
  83.         CLRF    TMR1L
  84.  
  85.         ; Activamos interrupciones
  86.        
  87.         BANKSEL PIE1
  88.         BSF     PIE1,CCP1IE     ; Activamos interrupcion del CCP
  89.         BANKSEL PIR1
  90.         BCF     PIR1,CCP1IF     ; Limpiamos flag del CCP
  91.         BSF     INTCON,PEIE     ; Habilitamos interrupciones de los perifericos
  92.        
  93.         BCF     INTCON,INTF     ; Activo interrupcion de RB0/Flanco descendente
  94.         BSF     INTCON,INTE
  95.        
  96.         BSF     INTCON,GIE      ; Habilitamos interrupciones globales
  97.          
  98.         BSF     T1CON,TMR1ON    ; Activamos el Timer1
  99.        
  100.         ; Set de registros
  101.        
  102.         CLRF    Contador
  103.  
  104. Main:
  105.         GOTO    Main            ; loop forever
  106.  
  107.  
  108. ;*****************************************************
  109. ;               Interrupcion
  110. ;*****************************************************
  111.    
  112. Interrupcion:
  113.         ; Guardo Contexto
  114.         MOVWF   W_temp
  115.         SWAPF   STATUS,W
  116.         MOVWF   Status_temp
  117.  
  118.         ; Comienza el codigo de mi interrupcion
  119.        
  120.         BANKSEL PIR1
  121.         BTFSC   PIR1,CCP1IF
  122.         CALL    Int_CCP
  123.         BTFSC   INTCON,INTF
  124.         CALL    Int_Rb0
  125.  
  126.         ; Fin de codigo de interrupcion
  127.        
  128.         ; Devuelvo el contexto
  129. Fin_interrupcion:
  130.         SWAPF   Status_temp,W
  131.         MOVWF   STATUS
  132.         SWAPF   W_temp,F
  133.         SWAPF   W_temp,W
  134.         RETFIE
  135.  
  136.         ; Interrupciones!!
  137.        
  138. Int_CCP:
  139.         CLRF    TMR1H
  140.         INCF    Contador,F
  141.         BTFSS   Contador,1      ; Entro 2 veces? (1 seg)
  142.         GOTO    Fin_int_ccp    
  143.         CLRF    Contador        ; Si: Borro el contador
  144.         INCF    Valor,F         ; Incremento Valor
  145.         ;Aca podria limitar a Valor, lo dejo a 15
  146.         MOVF    Estado,F
  147.         BTFSS   STATUS,Z        ; Estado = 0 -> Muestro Led
  148.         GOTO    Mostrar_Valor   ; Estado = 1 -> Muestro valor
  149.         BTFSS   PORTB,4         ; Led encendido?
  150.         GOTO    Led_on          ; No: Lo enciendo
  151.         BCF     PORTB,4         ; Si: Lo apago
  152.         GOTO    Fin_int_ccp     ; Salgo
  153. Led_on:
  154.         BSF     PORTB,4
  155.         GOTO    Fin_int_ccp
  156. Mostrar_Valor:                  ; Estado=1, muestro valor en el puerto
  157.         SWAPF   Valor,W
  158.         MOVWF   PORTB
  159.  
  160. Fin_int_ccp:
  161.         BTFSC   Flag,0          ; Anti rebote del RB0
  162.         BCF     Flag,0
  163.         BCF     PIR1,CCP1IF    
  164.         RETURN
  165.        
  166. Int_Rb0:
  167.         BTFSC   Flag,0          ; Entro aca y estaba seteada la flag? entro muy rapido entonces
  168.         GOTO    Fin_int_Rb0
  169.         BSF     Flag,0          ; Pongo a 1 la flag para que no entre mas
  170.         MOVF    Estado,F
  171.         BTFSC   STATUS,Z        ; Estado=0?
  172.         GOTO    Inc_Estado      ; Si -> Incremento a estado
  173.         CLRF    Estado          ; No -> lo pongo a 0
  174.         GOTO    Fin_int_Rb0
  175. Inc_Estado:
  176.         INCF    Estado,F
  177. Fin_int_Rb0:
  178.         BCF     INTCON,INTF    
  179.         RETURN
  180.    
  181.     END

Suerte descifrandolo :P

Mas sencillo:

Código: ASM
  1. ;*****************************************************
  2. ;                  
  3. ;           ---- Programa sin sentido 2 ----
  4. ;   Usa las interrupciones de Rb0 para hacer
  5. ;   un toggle a un LED
  6. ;
  7. ;   Rb0 = Entrada Boton, Flanco descendiente
  8. ;   Rb4 = Salidas de Led
  9. ;   4Mhz / Reloj interno
  10. ;*****************************************************
  11.    
  12. ;*****************************************************
  13. ;                   Include
  14. ;*****************************************************
  15.     #include "p16f628a.inc"
  16.  
  17. ;*****************************************************
  18. ;                   Palabra de configuracion
  19. ;*****************************************************
  20.  
  21.  __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
  22.  
  23.  
  24. ;*****************************************************
  25. ;                   Quita de Warnings
  26. ;*****************************************************
  27.  
  28.  errorlevel -302
  29.  
  30. ;*****************************************************
  31. ;                   Datos
  32. ;*****************************************************
  33.  
  34.     udata_shr
  35. W_temp          res 1
  36. Status_temp     res 1
  37.  
  38.  ;*****************************************************
  39.  ;                  Vectores
  40.  ;*****************************************************
  41.  
  42. RES_VECT    CODE    0x0000      ; Vector de reset
  43.         GOTO    Start
  44. INT_VECT    CODE    0x0004      ; Vector de interrupcion
  45.         GOTO    Interrupcion
  46.        
  47. ;*****************************************************
  48. ;               Programa Principal
  49. ;*****************************************************
  50.  
  51. MAIN_PROG CODE                      ; Programa principal
  52.  
  53. Start:
  54.  
  55.         ; Banco 1
  56.        
  57.         BANKSEL TRISB
  58.         MOVLW   0x0F            ; RB3:0 Entradas
  59.         MOVWF   TRISB           ; RB7:4 Salidas
  60.         CLRF    OPTION_REG
  61.        
  62.         ; Banco 0
  63.        
  64.         BANKSEL PORTB
  65.         CLRF    PORTB           ; Digital y a 0
  66.         MOVLW   0x07
  67.         MOVWF   CMCON
  68.        
  69.         ; Activamos interrupciones
  70.  
  71.         BCF     INTCON,INTF     ; Activo interrupcion de RB0/Flanco descendente
  72.         BSF     INTCON,INTE
  73.         BSF     INTCON,GIE      ; Habilitamos interrupciones globales
  74.  
  75. Main:
  76.         GOTO    Main            ; loop forever
  77.  
  78.  
  79. ;*****************************************************
  80. ;               Interrupcion
  81. ;*****************************************************
  82.    
  83. Interrupcion:
  84.         ; Guardo Contexto
  85.         MOVWF   W_temp
  86.         SWAPF   STATUS,W
  87.         MOVWF   Status_temp
  88.  
  89.         ; Comienza el codigo de mi interrupcion
  90.        
  91.         BANKSEL PIR1
  92.         BTFSC   INTCON,INTF
  93.         CALL    Int_Rb0
  94.  
  95.         ; Fin de codigo de interrupcion
  96.        
  97.         ; Devuelvo el contexto
  98. Fin_interrupcion:
  99.         SWAPF   Status_temp,W
  100.         MOVWF   STATUS
  101.         SWAPF   W_temp,F
  102.         SWAPF   W_temp,W
  103.         RETFIE
  104.  
  105.         ; Interrupciones!!
  106. Int_Rb0:
  107.         BTFSS   PORTB,4         ; Led encendido?
  108.         GOTO    Led_on          ; No: Lo enciendo
  109.         BCF     PORTB,4         ; Si: Lo apago
  110.         GOTO    Fin_int_Rb0     ; Salgo
  111. Led_on:
  112.         BSF     PORTB,4
  113. Fin_int_Rb0:
  114.         BCF     INTCON,INTF    
  115.         RETURN
  116.    
  117.     END

Y...

http://www.ucontrol.com.ar/forosmf/programacion-en-asm/reloj-binario-pic-16f628a-asm-(en-proceso)/msg86485/#msg86485
Ya te habia visto...

Igual si no agarras aca con las interrupciones ya no se que mas hacerle, lo unico que queda es que vayas a leer algo por internet sobre que es una interrupcion ( a pesar que creo que lo intente explicar aca )
« Última modificación: 15 de Octubre de 2015, 02:07:53 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #40 en: 15 de Octubre de 2015, 19:24:40 »
Antes que nada, muchísimas gracias por tu rato en escribir todo esto. Empezaré por el código fácil y luego sigo con el otro. He tenido que cambiar algunas cosa porque en mi MPLAB no me iba y hay cosas que no las entendía muy bien. Creo que no la he fastidiado mucho. De momento el programa funciona.

Empiezo por mis dudas:

   
Código: [Seleccionar]
CBLOCK  0x20
W_temp         
Status_temp     
ContA
ENDC

En las interrupciones ponemos en memoría W_Temp y Status_temp, aunque más o menos ya entiendo lo que es, para este ejemplo específico se usa??

Código: [Seleccionar]
Start:
         ; Banco 1
        BANKSEL TRISB
        MOVLW   0x0F            ; RB3:0 Entradas
        MOVWF   TRISB           ; RB7:4 Salidas
        CLRF    OPTION_REG
        ; Banco 0

        BANKSEL PORTB

Porque usar un mismo puerto para entradas y salidas?? como configurarlo para diferenciarlos??

Código: [Seleccionar]
Main:
        GOTO    Main            ; loop forev

Entiendo que aquí podría poner código que actuaría mientras no haya una interrupción

Código: [Seleccionar]
        BTFSC   INTCON,INTF
        CALL    Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto

Fin_interrupcion:

        SWAPF   Status_temp,W
        MOVWF   STATUS
        SWAPF   W_temp,F
        SWAPF   W_temp,W
        RETFIE

Y supongo que en esta zona comprueba el PORTB,0 y sino esta activo se acaba la interrupción no?? Pero esta zona es controlada todo el rato??

Dejo el código completo, que es basicamente el mismo pero con algunas modificaciones para poder compilarlo con el MPLAB.

Código: [Seleccionar]
;*****************************************************
;                   
;           ---- Programa sin sentido 2 ----
;   Usa las interrupciones de Rb0 para hacer
;   un toggle a un LED
;
;   Rb0 = Entrada Boton, Flanco descendiente
;   Rb4 = Salidas de Led
;   4Mhz / Reloj interno

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST    P=16F628A
INCLUDE  <P16F628A.INC>
 ;__CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF
 
;*****************************************************
;                   Datos
;*****************************************************
;udata_shr
CBLOCK  0x20
W_temp         
Status_temp     
ContA
ENDC

 ;*****************************************************
 ;                  Vectores
 ;*****************************************************

ORG    0x0000      ; Vector de reset
        GOTO    Start
    ORG    0x0004      ; Vector de interrupcion
        GOTO    Interrupcion
;*****************************************************
;               Programa Principal
;*****************************************************

                    ; Programa principal

Start:
         ; Banco 1
        BANKSEL TRISB
        MOVLW   0x0F            ; RB3:0 Entradas
        MOVWF   TRISB           ; RB7:4 Salidas
        CLRF    OPTION_REG
        ; Banco 0

        BANKSEL PORTB

        CLRF    PORTB           ; Digital y a 0
        MOVLW   0x07
        MOVWF   CMCON
        ; Activamos interrupciones

        BCF     INTCON,INTF     ; Activo interrupcion de RB0/Flanco descendente
        BSF     INTCON,INTE
        BSF     INTCON,GIE      ; Habilitamos interrupciones globales

Main:
        GOTO    Main            ; loop forev
;*****************************************************
;               Interrupcion
;*****************************************************
Interrupcion:

; Guardo Contexto

        MOVWF   W_temp
        SWAPF   STATUS,W
        MOVWF   Status_temp
; Comienza el codigo de mi interrupcion
        BANKSEL PIR1
        BTFSC   INTCON,INTF
        CALL    Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto

Fin_interrupcion:

        SWAPF   Status_temp,W
        MOVWF   STATUS
        SWAPF   W_temp,F
        SWAPF   W_temp,W
        RETFIE
         ; Interrupciones!!
Int_Rb0:
  BTFSS   PORTB,4         ; Led encendido?
        GOTO    Led_on          ; No: Lo enciendo
        BCF     PORTB,4         ; Si: Lo apago
        GOTO    Fin_int_Rb0     ; Salgo

Led_on:
        BSF     PORTB,4

Fin_int_Rb0:
        BCF     INTCON,INTF     
        RETURN
   
    END

Vamos que sigo siendo un mar de dudas, pero bueno, antes era un oceano. Gracias por todo
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #41 en: 15 de Octubre de 2015, 22:03:13 »
Yo al mio lo hice en el MPLAB X y funciona, el compilador es el MPASM el mismo que posee el MPLAB v8.xx o el MPLAB X, pero bueno cambiaste bien,

Citar
En las interrupciones ponemos en memoría W_Temp y Status_temp, aunque más o menos ya entiendo lo que es, para este ejemplo específico se usa?
Si, siempre debes guardar los registros que tienen las banderas y W al entrar a las interrupciones, este PIC no las guarda por si solo.

Citar
Porque usar un mismo puerto para entradas y salidas?? como configurarlo para diferenciarlos??
Por que RB0 es el unico que posee interrupcion por flanco, Y para que iba a usar otro puerto en el ejemplo?  Todo depende de como quieras vos configurarlo o cuales sean los puertos de salida tuyos. Eso es dependiente del hardware que le pongas.

Citar
Entiendo que aquí podría poner código que actuaría mientras no haya una interrupción
Exacto, todo se hace en las interrupciones en este caso. Mientras no ejecuta la interrupcion, se queda dando vuelta ahi en el main, haciendo GOTO sin sentido ( en el ejemplo )

Citar
Y supongo que en esta zona comprueba el PORTB,0 y sino esta activo se acaba la interrupción no?? Pero esta zona es controlada todo el rato??
Esa zona comprueba que el flag se activo, no RB0 !, si activo la interrupcion del RB0 la flag es la INTF del registro INTCON, si esta en uno significa que la interrupcion ocurrio y se debio a eso, es decir existio un flanco en RB0 ( descendiente segun lo tengo configurado).
Esa zona no es controlado todo el rato, sino que entra unicamente cuando se produce el evento de la interrupcion ( en ese caso es el del flanco descendente ), en el primer ejemplo que pase esa zona entra cuando: Se activa la interrupcion del CCP y/o del RB0, por eso pregunto por ambos flags para saber cual realmente fue que hizo entrar ahi. En resumen, si tenes habilitado las interrupciones de cualquier modulo, cuando se dispare una interrupcion ( se ponga el flag a 1 ) va a ir a la posicion 0x04 y va a ejecutar la instruccion esa. Cuando llega el RETFIE vuelve donde habia dejado el programa normal.

« Última modificación: 15 de Octubre de 2015, 22:06:38 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #42 en: 18 de Octubre de 2015, 19:26:39 »
Casi me saltan las lágrimas, pero ya he conseguido hacer mi primera interrupción. Vale he usado el código de KILLERJC (millones de gracias), pero poco a poco vamos progresando.
Todavía me faltan miles de problemas pero ya me quedan menos. He tenido que modificar el hardware y aunque todavía los tiempos no son los correctos, el programa hace lo que tiene que hacer.



Y como siempre cuelgo el código completo por si alguien se anima.

Código: [Seleccionar]
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _DATA_CP_OFF & _LVP_OFF & _MCLRE_OFF
LIST    P=16F628A
INCLUDE  <P16F628A.INC>
 
;*****************************************************
;                   Datos
;*****************************************************
;udata_shr
CBLOCK  0x20
W_temp         
Status_temp     
segundos
minutos
horas
contador
memoria_boton_0
estado
est_pulsador_0
est_pulsador_2
ENDC

Max_horas EQU d'12'
Max_minutos EQU d'60'
Max_segundos EQU d'60'

 ;*****************************************************
 ;                  Vectores
 ;*****************************************************

ORG    0x0000      ; Vector de reset
    GOTO    Start
    ORG    0x0004      ; Vector de interrupcion
    GOTO    Interrupcion
;*****************************************************
;               Programa Principal
;*****************************************************

                    ; Programa principal

Start:
 
bsf STATUS,RP0
clrf TRISA
movlw b'11111111'
movwf TRISB
bcf STATUS,RP0

        CLRF    PORTA           ; Digital y a 0
        MOVLW   0x07
        MOVWF   CMCON
movlw   b'00111100'   ; Se selecciona TMR1, preescaler de 1/8, modo temporizador.-
  movwf   T1CON
    movlw   b'00001011'   ; Se configura CCP modo captura cada flanco de subida.-
    movwf   CCP1CON
movlw   b'11110100'   
movwf   CCPR1H
movlw   b'00100100'   
movwf   CCPR1L
clrf    TMR1H
clrf    TMR1L         
bsf T1CON,TMR1ON
        ; Activamos interrupciones

        BCF     INTCON,INTF     ; Activo interrupcion de RB0/Flanco descendente
        BSF     INTCON,INTE
        BSF     INTCON,GIE      ; Habilitamos interrupciones globales


movlw d'2'
movwf contador
movlw d'0'
movwf memoria_boton_0
movlw d'0'
movwf estado
movlw d'0'
movwf est_pulsador_0
movlw d'0'
movwf est_pulsador_2
movlw d'1'
movwf segundos
movlw d'1'
movwf minutos
movlw d'1'
movwf horas

Principal

inc_segundos
btfss PIR1,CCP1IF
goto inc_segundos
bcf PIR1,CCP1IF
clrf TMR1H
decfsz contador,F
goto inc_segundos

comp
movlw d'2'
movwf contador
incf segundos,F
movf segundos,W ;revisa si ha llegado a 60 segundos.
sublw Max_segundos
btfss STATUS,Z ; si ha llegado a 60 segundos, se va a inc_minutos, sino se va a inc_segundos.
goto Principal

;=========================== INCREMENTAMOS LOS MINUTOS =====================================================
; " En el momento que los segundos llegan a 60, se incrementa 1 a minutos, se revisa si se ha llegado a 60 minutos y se pone a 0 los segundos"

inc_minutos
movlw d'1' ; Ponemos a cero los segundos para que empiece el conteo.
movwf segundos
incf minutos ; incrementamos en 1 los minutos.

movf minutos,W
sublw Max_minutos ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
goto inc_horas ; si ha llegado a 60 minutos se va a inc_horas.
goto Principal ; si no, se va ainc_segundos que empiezan a cero puesto que ya se ha reseteado en movwf segundos.

; ============================== INCREMENTAMOS LAS HORAS =====================================================
; " En el momento que los minutos llegan a 60, se incrementa 1 en horas y se ponen a 0 los minutos y los segundos"

inc_horas
movlw d'1' ; Primer número por donde quieres que empiece el conteo.
movwf minutos
incf horas

movf horas,W
sublw Max_horas ; revisa si ha llegado a 60 minutos.
btfsc STATUS,Z
call doce_horas
goto Principal

doce_horas
movlw d'1'
movwf segundos
movwf minutos
movwf horas
return

;*****************************************************
;               Interrupcion
;*****************************************************
Interrupcion:

; Guardo Contexto

        MOVWF   W_temp
        SWAPF   STATUS,W
        MOVWF   Status_temp
; Comienza el codigo de mi interrupcion
        BANKSEL PIR1
        BTFSC   INTCON,INTF
        CALL    Int_Rb0
; Fin de codigo de interrupcion
; Devuelvo el contexto

Fin_interrupcion:

        SWAPF   Status_temp,W
        MOVWF   STATUS
        SWAPF   W_temp,F
        SWAPF   W_temp,W
        RETFIE
         ; Interrupciones!!
Int_Rb0:
  movf minutos,W ; mostramos las horas por el display de leds.
movwf PORTA
call Retardo_500ms
clrf PORTA
call Retardo_500ms
clrf PORTA
movf horas,W ; mostramos las horas por el display de leds.
movwf PORTA
call Retardo_500ms
clrf PORTA


Fin_int_Rb0:
        BCF     INTCON,INTF     
        RETURN

INCLUDE<RETARDOS.INC>
   
    END




Tengo dudas?? Pues de momento no, porque no he seguido pero las tendré en breve.

          saludos a todos y gracias Killerjc
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #43 en: 18 de Octubre de 2015, 22:38:24 »
Primero que nada felicidades por hacer funcionar el codigo.

Despues, Lamento tener que arruinarte la alegria pero tenes algo mal en tu codigo. Siempre programa pensando en esto:

- La interrupcion debe ser lo mas corta posible ( en tiempo ). Entrar activar algo/sumar,etc y salir
- Esta prohibido cualquier funcion que genere demoras ( como los delays ) y rutinas de LCD entre otras cosas, que tardan mucho tiempo de ejecutarse.
- Nada de loops infinitos o que tarden mucho dentro de la interrupcion.
- Nada de esperar ahi, ejemplo que llegue un dato

Cuando entra a una interrupcion, se desactivan TODAS las demas. Asi que si tenes la interrupcion del CCP + del boton, y la del boton tarda 3 segundos, la interrupcion del CCP no va a ocurrir hasta que pasen esos 3 segundos completos. Es todo un problema mas cuando lo estas usando para tu reloj. Tambien si tu interrupcion del boton tarda 3 segundos, eso hace que tu programa principal tambien se demore 3 segundos.

Distinto hubiera sido si en tu interrupcion, pones a 1 algun bit de una variable y en tu programa principal ( en el loop principal ) preguntas por ese bit. Si es 1 que muestre la hora, si es 0 que haga lo de antes. Si no vas a usar las interrupciones para el CCP NO podes usar delays en tu programa principal. Es otra cosa que deberias tener en cuenta.
« Última modificación: 18 de Octubre de 2015, 23:24:29 por KILLERJC »

Desconectado Fulguitron

  • PIC16
  • ***
  • Mensajes: 122
    • Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.
Re:Reloj binario PIC 16F628A ASm (en proceso)
« Respuesta #44 en: 19 de Octubre de 2015, 18:28:32 »
Bueno, yo quería abrir el champagne ... en fin, me ha hecho ilusión mi primera interrupción y me he venido arriba. Mi idea era que durante la interrupción sume al tiempo del programa lo que dure la interrupcion, asi no tendré perdidas de tiempo.


Entonces, uso como interrupción el del TMR0???
Yo sigo aprendiendo, muchas gracias.
Disfruta de mi blog, hobbies y gadgets diferentes y poco comunes.

http://hobbiesygadgets.blogspot.com.es/