Autor Tema: Prender y Apagar un Led cada 7 segundos Timer 1 PIC 16F887  (Leído 4346 veces)

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

Desconectado Tadiuz

  • PIC10
  • *
  • Mensajes: 2
Prender y Apagar un Led cada 7 segundos Timer 1 PIC 16F887
« en: 15 de Septiembre de 2018, 14:24:27 »
Buenas tardes, soy nuevo en el foro y por lo que me decidí a poner mi duda aquí es porque llevo ya rato tratando de resolver mi problema y no lo logro.
Quiero que cada 7 segundos (Mas o menos) se prenda un led y pasados otros 7 segundos se apague. Estoy utilizando el Tmr1 con interrupciones, el preescaler está pues 1:8 para que cada 500 ms (mas o menos) se desborde y me lleve a la interrupcion, en la interrupción se cuentan 15 ciclos (que son mas o menos 7 segundos) y cuando se cumplen los 15 ciclos se prende el led, despues pasados otros 15 ciclos se deberia apagar el led, aunque el programa solo prende el led a los 15 ciclos, mas nunca lo apaga.
Soy nuevo en esto de los pic y apenas estoy aprendiendo a usar interrupciones.

Le agradecería si me pudieran ayudar.
Adjunto el código.


Código: [Seleccionar]
#include <p16F887.inc>
__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V
#DEFINE BANCO0 BCF STATUS,RP0
#DEFINE BANCO1 BSF STATUS,RP0

CONT1 EQU H'20'


;aquí inicia el programa
ORG 0x00

GOTO begin
org 0x04
       BANKSEL INTCON
       bcf INTCON,7 ;Apaga interrupciones globales
int BANKSEL PIR1
BCF PIR1,TMR1IF ;Apaga bandera de desborde

BANCO0
clrf TMR1
incf CONT1,f ;incrementa contador de 524.28ms
movlw D'15'
subwf CONT1,w
;prueba si la cuenta es igual a 15
btfss STATUS,Z ;bandera Z encendida?
retfie ;cuenta diferente a 15, regresa sin modificar CONT1
BTFSS PORTD,0 ; ¿LED 0 ENCENDIDO?
GOTO ENC
BSF PORTD,0 ;APAGA LED
CLRF CONT1

retfie
ENC BSF PORTD,0 ;ENCIENDE LED
CLRF CONT1
 
retfie
;FIN DE LA RUTINA DE INTERRUPCION

begin
   CLRF CONT1
   BANCO0
   bcf RCSTA,SPEN
   
  BANCO1

  CLRF ANSEL
  clrf TRISD
  BANCO0
  clrf PORTD
  BANKSEL PIR1
  BCF PIR1,TMR1IF
  BANKSEL T1CON
  CLRF TMR1L
  CLRF TMR1H
  movlw B'00110000' ;Prescaler 1:8
  movwf T1CON
 
  BANKSEL PIE1
  BSF PIE1,TMR1IE
  BANKSEL INTCON
  BSF INTCON,7
  BSF INTCON,6
  BANKSEL T1CON
  BSF T1CON,TMR1ON
  BANCO0
POP GOTO POP


end


Desconectado elreypic2

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1297
Re:Prender y Apagar un Led cada 7 segundos Timer 1 PIC 16F887
« Respuesta #1 en: 15 de Septiembre de 2018, 16:43:23 »
Que tal Tadiuz,

En tu código nunca apagas el LED, esta es parte de tu código:

Código: [Seleccionar]
BTFSS PORTD,0 ; ¿LED 0 ENCENDIDO?
GOTO ENC
BSF PORTD,0 ;APAGA LED
CLRF CONT1

retfie
ENC BSF PORTD,0 ;ENCIENDE LED
CLRF CONT1
 
retfie
;FIN DE LA RUTINA DE INTERRUPCION

Si te das cuenta en ambos casos siempre activas el puerto D0. En Apaga LED deberías usar:

BCF  PORTD,0    ;APAGA LED

Otra cosa es que una vez que entras en la interrupción apagas las interrupciones globales con:

bcf   INTCON,7   ;Apaga interrupciones globales

Pero si sales de la interrupción nunca la vuelves activar, esto pudiera ocasionar un problema también de que no se esté activando la interrupción correctamente. En realidad no necesitas apagarla. Simplemente elimina esa instrucció y listo.

Asi te debería de funcionar.

saludos,

elreypic.

Desconectado Tadiuz

  • PIC10
  • *
  • Mensajes: 2
Re:Prender y Apagar un Led cada 7 segundos Timer 1 PIC 16F887
« Respuesta #2 en: 15 de Septiembre de 2018, 17:02:09 »
Hola, perdón por lo del código jaja, estuve haciendo varias modificaciones y subi el codigo incorrecto.

Este es el código que tengo.
Es en este donde no se está apagando el LED, incluso ya con la instrucción cambiada a BCF.
En cuanto a las interrupciones, tenia entendido que cuando regresas con retfie se activan de nuevo las interrupciones  :shock:


Gracias por tu respuesta.
Código: [Seleccionar]
#include <p16F887.inc>
__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V
#DEFINE BANCO0 BCF STATUS,RP0
#DEFINE BANCO1 BSF STATUS,RP0

CONT1 EQU H'20'


;aquí inicia el programa
ORG 0x00

GOTO begin
org 0x04
       BANKSEL INTCON
       bcf INTCON,7 ;Apaga interrupciones globales
BANKSEL PIR1
BCF PIR1,TMR1IF ;Apaga bandera de desborde

BANCO0
clrf TMR1
incf CONT1,f ;incrementa contador de 524.28ms
movlw D'15'
subwf CONT1,w
;prueba si la cuenta es igual a 15
btfss STATUS,Z ;bandera Z encendida?
retfie ;cuenta diferente a 15, regresa sin modificar CONT1
BTFSS PORTD,0 ; ¿LED 0 ENCENDIDO?
GOTO ENC
BCF PORTD,0 ;APAGA LED
CLRF CONT1

retfie
ENC BSF PORTD,0 ;ENCIENDE LED
CLRF CONT1
 
retfie
;FIN DE LA RUTINA DE INTERRUPCION

begin
   CLRF CONT1
   BANCO0
   bcf RCSTA,SPEN
   
  BANCO1

  CLRF ANSEL
  clrf TRISD
  BANCO0
  clrf PORTD
  BANKSEL PIR1
  BCF PIR1,TMR1IF
  BANKSEL T1CON
  CLRF TMR1L
  CLRF TMR1H
  movlw B'00110000' ;Prescaler 1:8
  movwf T1CON
 
  BANKSEL PIE1
  BSF PIE1,TMR1IE
  BANKSEL INTCON
  BSF INTCON,7
  BSF INTCON,6
  BANKSEL T1CON
  BSF T1CON,TMR1ON
  BANCO0
POP GOTO POP


end

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Prender y Apagar un Led cada 7 segundos Timer 1 PIC 16F887
« Respuesta #3 en: 15 de Septiembre de 2018, 19:45:23 »
Voy a aclarar un par de cosas:

- Al momento de entrar a las interrupciones el bit GIE se pone a 0, esto lo hace internamente el microcontrolador, asi que no es necesario que pongas a 0 el bit INTCON,7, el RETFIE pone en 1 al bit GIE y ademas funciona como RETURN, volviendo al lugar donde ocurrio la interrupcion.

- Por ahora no vas a tener problemas, PERO, te recomiendo que pongas el codigo que guarda W y STATUS al comienzo y luego lo restablezcas al momento de salir de la interrupcion. Busca por W_TEMP en el datashet del microcontrolador, y Microchip te da el codigo.

- Por favor usa los nombres de los bits, por ejemplo INTCON, GIE en ves de INTCON, 7 , estos estan definidos en el .inc, y hacen mas facil la lectura

- Voy a suponer que los tiempos calculados son los correctos. asi que solo me voy a centrar en el programa.
Una forma de apagar y encender el led, en realidad cambiar el estado del mismo es realizar una XOR


Código: ASM
  1. ;aquí inicia el programa
  2.        
  3.         ORG 0x00
  4.         GOTO begin             
  5.        
  6.         org     0x04   
  7.        
  8.         ;Aca agregar el codigo que guarda W y STATUS
  9.  
  10.         BANKSEL INTCON
  11.         bcf             INTCON, GIE     ;Apaga interrupciones globales
  12.         BANKSEL PIR1
  13.         BCF     PIR1,TMR1IF     ;Apaga bandera de desborde
  14.                
  15.         BANKSEL TMR1
  16.         clrf    TMR1
  17.         incf    CONT1,f                                 ;incrementa contador de 524.28ms
  18.         movlw   D'15'
  19.         subwf   CONT1,w                                 ;prueba si la cuenta es igual a 15
  20.         btfss   STATUS,Z                                ;bandera Z encendida?
  21.         GOTO    FIN_INTERRUPCION                ;cuenta diferente a 15, regresa sin modificar CONT1
  22.         MOVLW   1                                       ;       ¿LED 0 ENCENDIDO?
  23.         XORWF   PORTD
  24.  
  25. FIN_INTERRUPCION:
  26.  
  27.         ; Aca agregar el codigo que devuelve los valores de W y STATUS
  28.  
  29.         RETFIE
  30.  
  31.                
  32. begin: 
  33.         BANKSEL CONT1   ; Banco 0
  34.         CLRF    CONT1
  35.            
  36.         BANKSEL ANSEL   ; Banco 1
  37.        
  38.         CLRF    ANSEL
  39.         clrf    TRISD
  40.         BANKSEL PORTD   ;Banco 0
  41.         clrf    PORTD
  42.         BANKSEL PIR1
  43.         BCF             PIR1,TMR1IF
  44.         BANKSEL T1CON
  45.         CLRF    TMR1L
  46.         CLRF    TMR1H
  47.         movlw   B'00110000'     ;Prescaler 1:8                                 
  48.         movwf   T1CON
  49.          
  50.         BANKSEL PIE1
  51.         BSF             PIE1,TMR1IE
  52.         BANKSEL INTCON
  53.         BSF             INTCON, GIE
  54.         BSF             INTCON, PEIE
  55.         BANKSEL T1CON
  56.         BSF             T1CON,TMR1ON
  57.        
  58.         BANKSEL PORTA           ; Banco 0
  59.  
  60. POP                     GOTO POP
  61.  
  62.  
  63.         END