Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola, me acabo de registrar en esta web y veo que me pasare bastantes horas leyendo foros ya que soy un apasionado de la robotica, aunque nunca me he puesto en serio.
Estoy empezando a programar mis cosillas despues de comprar por ebay un programador de pic 16f690. Queria hacer el tipico programilla para empezar en que un led al cabo de 2 segundos se apagara. Llevo un buen rato mirandome otros foros y paginas de internet y esto es a lo que he llegado:
#include <P16F690.inc> ; processor specific variable definitions
__CONFIG (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
CONTADOR EQU 0x24
STATUS_TEMP EQU 0x25
W_TEMP EQU 0x26
ORG 0x000
GOTO CONFIGURATION
ORG 0x004
GOTO BREAK
BREAK:
MOVWF W_TEMP
SWAPF STATUS,W
CLRF STATUS
MOVWF STATUS_TEMP
INCF CONTADOR
MOVLW b'00001101' ;Valores inciales del contador
MOVWF TMR1H
MOVLW b'11010000'
MOVWF TMR1L
BCF PIR1,TMR1IF ;Desactivamos flag interrupcion
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
CONFIGURATION:
CLRF CONT
BSF STATUS,RP0
BCF STATUS,RP1 ;Bank1
MOVLW b'00000000' ;Configuración de los puertos entrada / salida de PORTB
; 1= Entrada
; 0= Salida
MOVWF TRISC
BCF STATUS,RP1
BCF STATUS,RP0 ;Bank0
CLRF PORTC
BSF PORTC,0 ;Encendemos el led
BSF STATUS,RP0 ;Bank1
MOVLW b'00000111' ;Oscilador interno
MOVWF OSCCON ;( 000 -> 31KHz)
BCF STATUS,RP0 ;Bank0
MOVLW b'00001101' ;Valores iniciales timer
MOVWF TMR1H
MOVLW b'11010000'
MOVWF TMR1L
MOVLW b'10110000' ;Configuracion timer
MOVWF T1CON
BSF STATUS,RP0 ;Bank1
;Mascaras
BSF PIE1,TMR1IE
BSF INTCON,PEIE
BSF INTCON,GIE
BCF STATUS,RP0 ;Bank0
BSF T1CON,TMR1ON ;Timer ON
PROGRAMA:
MOVFW CONTADOR
XORLW d'2'
BTFSS STATUS,ZERO
BCF PORTC,0 ;Apagamos el led
GOTO PROGRAMA
END
Observaciones:
En el puerto C bit zero hay un led conectado.
El timer esta configurado para que haya una interrupcion por segundo.
El oscilador local lo he configurado para que funcione a 31KHZ.
Un vez todo este rollo la pregunta es fácil....QUE COÑO FALLA? Lo he grabado en el pic y lo he ejecutado y esto no tira!
Buenas,
antes de todo una observación. Si vas a realziar este tipo de programas te recomiendo que lo hagas en C, usando CCS u otro compilador. Y solo uses ensamblador en los casos que tengas que controlar el tiempo en microsegundos o por ejmepo que tengas que gestionar 8 interrupciones y en algunas de ellas no debas estar más de 5 uS o cosas así. En este caso es muy importante embeber código ensamblador en medio del C o hacerlo todo en ensamblador.
Respecto al código lo he mirado por encima y parece coherente, seleccionas los bancos, lo salvas en las interrupciones y los recuperaas antes de ejecutar el RETURN. 🙂 Aunque no lo he podido mirar con detenimiento para ver si hay algo mal configurado.
Algo que si debes hacer es encender un led al inicio del programa, para saber si este se ejecuta. Por que te pueden estar sucediendo otras cosas, como que no se este ejecutando por no tener el reset correctamente, que no se haya grabado, etc. ¿Que placa estas usando?
Saludos
Haz una prueba y cambia:
ORG 0x004 por ORG 0x005
No se explicarte el por que, pero creo recordar que hay un problema.
mmmmmmmmmmmm
MOVWF W_TEMP
SWAPF STATUS,W
CLRF STATUS
MOVWF STATUS_TEMP
Cambialo por esto, o incluye el resto de registros que te faltan:
ORG 0x005 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into W register
movwf pclath_temp ; save off contents of PCLATH register
¿Esto que es?: CLRF CONT
Aquí además de esto configuraría el registro ANSEL también aunque no lo necesites.
¡OJO! has puesto PORTB y luego mueves el TRISC.
MOVLW b'00000000' ;Configuración de los puertos entrada / salida de PORTB
; 1= Entrada
; 0= Salida
MOVWF TRISC
mmmmmmmmmmmmmmmmmm Cambia esto por lo debajo:
MOVLW b'00000111' ;Oscilador interno
MOVWF OSCCON ;( 000 -> 31KHz)
En teoría está bien, pero por que quieres usar 31 KHz.
MOVLW 0x75
MOVWF OSCCON ; Cambiamos la velocidad del oscilador interno a 8 Mhz
Bueno yo intentaría mejorar o probar lo que te he comentado a ver si tienes suerte y te funciona.
Saludos.
Gracias Juanjo pa contestarme,pero he provado con tu codigo y esto no funciona
A ver te explico por encima lo que no entiendes de mi codigo :
Lo que dices del portb es un error de escritura soy consciente que lo muevo en el portc (trisc)
CLRF CONT es para inicializar a cero la variable CONT, lo que en c es CONT=0.
El oscilador lo configuro a 31kHz para obtener una interrupcion por segundo
tciclo=4/31K=1,29E-4 --> Tinterrupción=tciclo*2^16=8,45seg --> Luego con el preescaler del timer 1:8 obtengo que el tiempo de mi interrupcion es de 1,05 seg (con los valores de TMRL y TMRH hago que la interrupcion sea exactamente cada un segundo).
Lo de configurar el registro ANSEL...que tipo de registro es y que hace?
Al respeto de programar en c..me dices que pruebe con el ccs (es el Code Composer Studio ?). En C nunca he programado un pic lo poco que hecho de pics a sido con ensemblador...tienes o sabes alguna web donde pueda encontrar un buen tutorial de esto. Supongo que en C es mucho mas facil.
AHhh utlizo la placa de desarrollo pickit2 que esta alimentada via usb con el ordenador portatil.
CLRF CONT es para inicializar a cero la variable CONT, lo que en c es CONT=0.
Esto lo preguntaba por que has declarado tu variable como CONTADOR, y luego la inicializas como CONT.
Lo de configurar el registro ANSEL...que tipo de registro es y que hace?
El registro ANSEL es para configurar los pines en analógico o digital. En este caso concreto me da que no afecta. Pero te aconsejaría que lo hicieses.
¿Has probado a encender un led? Lo primero que debes saber es si tu programa se ejecuta. Puesto que puedes estar pensando que se ejecuta mal y quizás no se esté ejecutando. Así que haz uno simple en el cual solo pongas uno de los pines a "1" y si quieres le pones un led para verlo, pero con el multimetro puedes comprobarlo perfectamente. Prueba a resetearlo, solo con poner el master reset a cero se resetea. No se si la placa que tienes lleva el circuito de master reset.
Ahhh, te falta este flag. _MCLRE_ON, para que funcione el reset externo.
Saludos.