TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: antujevy en 13 de Noviembre de 2012, 03:56:20
-
Hola , soy nuevo en el foro , necesito que alguien con tiempo" me ayude , estoy realizando un proyecto de una fuente de alimentacion para un Laser Nd:yag y ahora necesito controlar el circuito , para lo cual necesito programar un pic ,hace 2 semanas no tenia ni idea de assembler y lo que se ha sido buscando por el foro..empece con un 16f2628a y simulando con mplab , el problema esque se me quedo pequeño y ahora uso un 16f887 y ya no sirve de nada simular con mplab ya que no puedes cambiar las señales de los pines de entrada..por lo que he empezado a usar el proteus pero no hay manera humana de conseguir resultados , y mi duda es si tengo malisimamente hecho el codigo o esque no estan facil simular con proteus, os vo ya explicar que hace mi programa y si algun entendido detecta muchos fallos que me lo diga estaria agradecidoo..
mi programa trata de generar dos señales por RB1 RB0 que controlan mi circuito , estas señales se tienen que geneerar durante 220ms , esto lo hago mediante subrrutinas de retardo y contadores, bien uan vez cumplidos los 220ms mi programa debe esperar un determinado tiempo antes de volver a generar las DOS_ONDAS, este tiempo determina la potencia del laser y la introduzco mediante un teclado matricial(el numero de tecla me devuelve de una tabla el nº que quiero cargar en el registro usuario , el numero elegido debe ser visualizado por display, aparte tiene pulsadores de marcha paro y reinicio y led rojo y verde de laser=0n = off
funcionamiento:
el pic arranca y espera en un bucle hasta que pulso marcha, antes de esto debo de haber seleccionado mi potencia con el teclado , esto lo hago mediante una interrupcion (conecto los pines del teclado al peurtoC y tambien al puertoB para detectar interrupcion) esto es asi porque tambien necesito el pin RBO para la interrupcion de PARAR,una vez seleccionada la potencia pulso marcha y el pic me genera DOS_ONDAS durante 220ms con parones de tiempo determinados por el usuario.
espero que no se haga demasiado pesao jaj , nose si funcionara o no ya que en mplab lo compila bien pero en proteus es imposible que funcione , un saludo y graciass, abajo dejo el codigo.asm
;****Encabezado****
LIST P=16F887
INCLUDE P16F887.INC
;El reset se hace mediante el pin MCLR hay que activarlo en la configuracion MCLR_ON
__CONFIG _INTOSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_ON & _FCMEN_ON & _LVP_ON
;**** Definicion de variables ****
Usuario equ 0x30 ;preseleccion de potencia
Contador equ 0x31 ;Contador para detectar 256 periodos de onda
Contador1 equ 0x32 ;contador para contar 48 desbordes de contador (220ms)
Contador2 equ 0x33 ;contador para el reposo( seleccion de potencia)
NTecla equ 0x34 ;numero de tecla presionada
LED_rojo equ 2 ;define el bit de un registro (parado)
LED_verde equ 3 ;bit de un registro (funcionamiento)
W_Temp equ 0x20 ;Registro para guardar temporalmente W.-
STATUS_Temp equ 0x21 ;Registro para guardar temporalmente STATUS
PORTB_Temp equ 0x22 ;registro temporal de puerto B
PORTA_Temp equ 0x23 ;regustro temporal de puerto A
;**** Inicio del Micro ****
org 0x00
goto INICIO
;**** Vector de Interrupcion ****
org 0x04 ; Atiendo Interrupcion.-
goto ISR
;**** Programa Principal ****
;**** Configuracion de puertos ***
org 0x05 ; Origen del código de programa.-
INICIO ;sabemos que PR2 se inicia a 256
bsf STATUS,5 ;elegimos banco 1
movlw b'11110001' ;puerto B 0=salidas 1=entradas
movwf TRISB ;RB0/INT=PARAR
movlw b'00000011' ;puerto A entradas = MARCHA y REINICIO
movwf TRISA ;entradas
movlw b'00000000' ;habilitamos interrupcion por RB0/INT
movwf OPTION_REG ;(INTEDG) y resistencias pull up activadas
;es decir entradas reposo=1
movlw b'10011000' ;habilitamos GIE INTE RBIE
movwf INTCON
movlw b'11110000' ;1=entrada 0=salida
movwf TRISC
movlw b'00111111' ;ponemos dislpay a 0
movwf TRISD
bcf STATUS,5 ;elegimos banco 0
clrf PORTA
clrf PORTC
clrf PORTB
clrf PORTD
clrf Contador ;iniciamos a 0 contador
clrf NTecla ;borramos nº de tecla
movlw .208 ;precargamos el contador1 (48 ciclos=220ms)
movwf Contador1 ;iniciamos a 208
bsf PORTA,LED_rojo ;prendemos led rojo
EMPIEZA btfss PORTA,0 ;se pulso INICIO? saltasi 1 pulsador reposo=0
;al pulsarlo entrada=1 ------>salta
goto EMPIEZA ;NO, esperamos
bcf PORTA,LED_rojo ;SI, rojo=off
bsf PORTA,LED_verde ;verde=on
;**** Bucle ****
DOS_ONDAS bsf PORTB,1 ;señal del mos0 en alta (5v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
call DELAY_6_07US ;llamamos a la subrrutina de 6.07us
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
call DELAY_2_88US ;llamamos a la subrrutina de 2.88us
bcf PORTB,1 ;señal del mos0 en baja (0v)
bsf PORTB,2 ;señal del mos1 en alta (5v)
call DELAY_6_07US ;llamamos a la subrrutina de 6.07us
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
call DELAY_2_88US ;llamamos a la subrrutina de 2.88us
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1;1 ;incrementamos contador1 hasta 48 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 48
;se han cumplido los 220ms (contador1=48)
movlw .208 ;precargamos el contador1 (48 ciclos)
movwf Contador1 ;iniciamos a 208
bsf PORTB,3 ;Si,(5v)señal laser
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
SELECPOT movf Usuario,0 ; Consultamos si se han producido X desbordes
subwf Contador2,0 ; contador-X ------>contador
btfss STATUS,Z ;Z=0? salto si 1 Z=1 si contador=17
goto Actualizo_TMR2 ;No,Actualizo TMR2 y reinicio bucle
clrf Contador2 ;Si,limpiamos contador2
bcf PORTB,3 ;limpiamos la señal laser
goto DOS_ONDAS ;termina el paron y continuamos
Actualizo_TMR2
movlw b'01111111' ;habilitamos el TMR2 y escalamos
bsf T2CON,2 ;predivisor 1:16 postdivisor 1:16 en el TMR2
movlw 0x00 ;movemos a w cero
movwf TMR2 ;cargamos el temporizador tmr2=0
bcf PIR1,1 ;borramos la bandera TMR2IF
REPOSO btfss PIR1,1 ;saltamos si 1 = overflow
goto REPOSO ;no=bucle
incf Contador2,1 ;incrementamos el contador2
goto SELECPOT ;volvemos a comparar contador2
;**** Subrrutina de retardo señal alta ****
DELAY_6_07US movlw b'0000100' ;habilitamos el TMR2 y escalamos
bsf T2CON,2 ;predivisor 1:1 en el TMR2
movlw .226 ;movemos a w 226 que son 30 ciclos
movwf TMR2 ;cargamos el temporizador tmr2
bcf PIR1,1 ;borramos la bandera TMR2IF
ESPERA btfss PIR1,1 ;saltamos si 1 = overflow
goto ESPERA ;no=bucle
return ;si=salimos de la subrrutina
;**** Subrrutina de retardo señal baja ****
DELAY_2_88US movlw b'0000100' ;habilitamos el TMR2 y escalamos
bsf T2CON,2 ;predivisor 1:1 en el TMR2
movlw .242 ;movemos a w 242 que son 14 ciclos
movwf TMR2 ;cargamos el temporizador tmr2
bcf PIR1,1 ;borramos la bandera TMR2IF
ESPERA1 btfss PIR1,1 ;saltamos si 1 = overflow
goto ESPERA1 ;no=bucle
return ;si=salimos de la subrrutina
;**** Subrrutina nº tecla seleccionada ****
;Configuraremos RC0 a RC3 como salida y
;las colocaremos a nivel bajo. RC4 y RC7 configuradas como entradas,
;y en estado normal (sin presión de teclas) estarán a nivel alto.
;RBPU=0 de OPTION_REG
;conectamos tambien las entradas a RB4:RB6 para detectar que se toca la tecla
Tecla_Presionada
clrf NTecla ; Borra Numero de Tecla y
incf NTecla,1 ; prepara NTecla para primer codigo.
movlw b'00001110' ; Saca 0 a la primera fila
movwf PORTC ; de la Puerta C
nop ; Para estabilizacion de señal.
Test_Columnas
btfss PORTC,4 ; Primera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTC,5 ; Segunda columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTC,6 ; Tercera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
; En este caso se Usa teclado 3x4.-
; btfss PORTC,7 ; Cuarta columna = 0
; goto Suelta_tecla ; Sale si se ha pulsado tecla.
; incf NTecla,1 ; Si no tecla pulsada,incrementa nº Tecla.
Ultima_tecla
btfss PORTC,3 ; Ya se revisaron todas las filas?
goto Null_tecla ; Si, Falsa alarma, no se ha presionado ninguna.-
bsf STATUS,C ; No, seguimos con la siguiente.Pone a 1 Bit C
rlf PORTC,1 ; asi la Fila 1 pasa a 1 con la rotaci¢n a izqda.
goto Test_Columnas
Null_tecla
clrf NTecla ; Coloca variable Tecla a 0 (Ninguna)
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTC ; Dejamos Puerto para recibir otra tecla.-
return ; y regresa.
Suelta_tecla
; Ahora se espera a que la tecla sea soltada para evitar rebotes
; y reactivaciones de tecla
Espera1
btfss PORTC,4 ; Si no se suelta la tecla FILA 1
goto Espera1 ; vuelve a esperar.
Espera2
btfss PORTC,5 ; Si no se suelta la tecla FILA 2
goto Espera2 ; vuelve a esperar.
Espera3
btfss PORTC,6 ; Si no se suelta la tecla FILA 3
goto Espera3 ; vuelve a esperar.
Espera4
btfss PORTC,7 ; Si no se suelta la tecla FILA 4
goto Espera4 ; vuelve a esperar.
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTC ; Dejamos Puerto para recibir otra tecla.-
return ; vuelve al programa principal que hizo la llamada.
;**** Tabla preseleccion de potencia ****
TABLAPOTENCIA
addwf PCL,f
retlw .1 ;600w (1)
retlw .5 ;500w (2)
retlw .11 ;400w (3)
retlw .20 ;300w (4)
retlw .38 ;200w (5)
retlw .93 ;100w (6)
;**** Tabla display catodo comun ****
BCD7SEG:
addwf PCL,1
retlw b'0000110' ; 1
retlw b'1011011' ; 2
retlw b'1001111' ; 3
retlw b'1100110' ; 4
retlw b'1101101' ; 5
retlw b'1111101' ; 6
; retlw b'0000111' ; 7
; retlw b'1111111' ; 8
; retlw b'1101111' ; 9
;**** Rutina de servicio de Interrupcion ****
;**** Interrupcion por RB4:RB7 ****
ISR
bcf INTCON,GIE ;deshabilitamos las interrupciones
btfss INTCON,RBIF ;RBIF=1?
goto SALIR ;no,salimos
;---> Aqui haremos copia de respaldo - Guardado de registro W y STATUS.-
Inicio_ISR
movwf W_Temp ; Copiamos W a un registro Temporario.-
swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
movf PORTB,0 ;puertoB---->W
movwf PORTB_Temp ;guardamos puertob
movf PORTA,0 ;puertoA---->W
movwf PORTA_Temp ;guardamos puertoA
;**** Introducimos potencia deseada por teclado Matricial ****
call Tecla_Presionada; Se detecta que tecla fue presionada
movfw NTecla ;cargamos en W el nº de tecla presionada
call TABLAPOTENCIA ;pedimos a la tabla que nos devuelva valor
movwf Usuario ;cargamos la potencia desada en nuesto registro
movfw NTecla ;volvemos a cargar el valor de NTecla en W
call BCD7SEG ;decodificador 7 seg
movwf PORTD ; Mostarmos en diplay tecla Presionada.-
; Restauramos los valores de W y STATUS.-
Fin_ISR
movf PORTA_Temp,0
movwf PORTA
movf PORTB_Temp,0
movwf PORTB
swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
movwf STATUS
swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
SALIR bsf INTCON,GIE ;habilitamos las interrupciones
retfie ; Salimos de interrupción.
;**** Rutina de servicio de Interrupcion ****
;**** Interrupcion por RB0/INT ****
ISR
bcf INTCON,GIE ;deshabilitamos las interrupciones
btfss INTCON,INTF ;INTF=1?
goto SALIR ;no,salimos
;---> Aqui haremos copia de respaldo - Guardado de registro W y STATUS.-
Inicio_ISR
movwf W_Temp ; Copiamos W a un registro Temporario.-
swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
movf PORTB,0 ;puertoB---->W
movwf PORTB_Temp ;guardamos puertob
movf PORTA,0 ;puertoA---->W
movwf PORTA_Temp ;guardamos puertoA
movlw b'0000000' ;salidas = 0
movwf PORTB
bsf PORTA,2
REINICIO btfss PORTA,1 ;sepulso REINICIO?? salta si 1 , entradas reposo=1
;luego pulsador en reposo =0 al presionarle=1
goto REINICIO ;NO, bucle
bcf INTCON,INTF
; Restauramos los valores de W y STATUS.-
Fin_ISR
movf PORTA_Temp,0
movwf PORTA
movf PORTB_Temp,0
movwf PORTB
swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
movwf STATUS
swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
SALIR bsf INTCON,GIE ;habilitamos las interrupciones
retfie ; Salimos de interrupción.
end
-
Bienvenido al foro, si llevas poco con el assembler te recomiendo que le eches un vistazo a esto:
http://www.todopic.com.ar/foros/index.php?topic=24720.0
Lo que quieres hacer no parece muy complicado, asi en principio,
pic me genera DOS_ONDAS durante 220ms
¿Que tipo de ondas son?
16f887 y ya no sirve de nada simular con mplab ya que no puedes cambiar las señales de los pines de entrada
¿Por que no puedes cambiarlas?
-
hola , las dos ondas que genero por RB1 RB2 son dos señales cuadradas para controlas los mos de mi circuito , intento subir uan imagen de como tienen que ser (pero vamos esta parte es la mas facil es lo unico que se que funciona bien jaja), por otra parte lo que digo esque en mplab cuando esta simulando con el mplab SIM y doy a view file registers y no me deja cambiar lo que hay en los puertos A,B,C...solo me deja cambiar los registros a partir del 20h , me he dado cuanta de que mis dos interrupciones se llaman igual ISR ..como tengo que hacer para tener dos interrupciones?? si las cambio de nombre que tengo que poner en el vector de interrupcion??
;**** Vector de Interrupcion ****
org 0x04 ; Atiendo Interrupcion.-
goto ISR
lo que mas me interesa es que no haya fallos gordos lo de proteus lo queria por ver visualmente que funciona ..pero nose me daba muchos problemas , por ejemplo poniendo a 1 las resistencias push pull en el puertoC no me sacaba en reposo señal alta en las entradas (para el teclado)..y cosas asi..u nsaludo y gracias
DOS_ONDAS
(http://s2.subirimagenes.com/otros/previo/thump_8121192grafica-control.jpg) (http://www.subirimagenes.com/otros-graficacontrol-8121192.html)
-
Para simular entradas en MPLAB vas a Debugger-stimulus-new workbook te aparece una ventana con todos pines a los que les puedes dar estimulos externos, seleccionas los que tengas como entrada en Pin/SFR, en la de al lado "action" seleccionas si va a ser 1 (set high) o 0 (set low), ponlas por duplicado, RB1-SET HIGH Y abajo RB1-SET-LOW, asi durante la simulacion vas poniendoles los valores que quierasen cada momento.
En las interrupciones tienes que hacer una sola ISR, dentro de ella chequeas cual salto. para chequear pulsadores no es necesario que lo hagas por interrupcion, si quieres puedes hacerlo, pero si no quieres chequeando cada poco en el programa no tendras problema.
En el enlace que te puse antes tienes un ejemplo de lectura de teclado y otro para manejar displays (uno solo, tres multiplexados y tres con reg. de desplazamiento) puedes usarlos a modo de librerias, igual hay que cambiar alguna cosa, pero ya lo tienes casi hecho.
¿Estas poniendo como digitales PORTA y PORTB? no veo que pongas a 0 los reg. ANSEL y ANSELH, solo pregunto porque no lo veo y no simule el programa.
Yo con Proteus me llevo mal :lol: nunca me da respuestas satisfactorias, hay otra gente que esta encantada con el, pero a mi personalmente solo ma sirve para diseñar, no me fio de la simulacion.
-
HOla , lo primero muchas gracias me ha servido de gran ayuda todo lo que me dijite ,
1.ya he conseguido hacer bien la interrupcion ISR por medio de mi pulsador RB0 y por medio del teclado ,(utilizando saltos)
2.tenias razon ,he puesto los reg ANSEL Y ANSELH a 0x00 y asi puedo cambiar mis entradas de la forma que me comentaste con lo de stimulus
Ahora al simular en mplab creo que me funciona todo bien, digo creo" porque para que me funcione el teclado tengo que dar antes a cambiar algun bit del portB para que se produzca la interrupcion (esto fisicamente seria conectar los pines del portC con el portB), me parece que es la unica forma de simularlo y me va bien,si alguien quiere simularlo y comprobar que funciona adjunto el codigo.
por otro lado sigo investigando con el proteus para tener una forma visual de ver su funcionamiento , he hecho algun avance , consigo que el pic funcione correctamente , pero el teclado no funciona..nose si sera por las conexiones del proteus o porque..porlomenos consigo ver con el osciloscopio las DOS_ONDAS generadas por el pic , lo cual me ha servido para ver que no eran como yo queria , puesto que al necesitar intervalos tan pequeños (microsegundos) cada instruccion me descompensaba las ondas y por ejemplo para que se cumplan 2.88us he tenido que eliminar la subrrutina DELAY_2_88US por un simple return.,decir que la frecuencia que uso es 8MHz del oscilador interno.
adjunto las imagenes del proteus por si alguien puede aportar algo
(http://s3.subirimagenes.com:81/imagen/previo/thump_8122337proteusproyecto10.png) (http://www.subirimagenes.com/imagen-proteusproyecto10-8122337.html)
Ya solo me queda añadir una cosa mas ami programa , si me podeis ayudar lo agradeceria , mientras estoy recopilando informacion para saber como hacerlo , es algo sencillo(para quien sepa jaj) , necesito crear una interrupcion por una entrada analogica, me explico:
mi circuito carga linealmente un condensador hasta 400v en 220ms (es el tiempo que se generan las DOS_ONDAS) y luego se descarga , pues bien por seguridad quiero hacer que si por una casolidad hubiese un fallo y se cargase a mas de 400V se produjese una interrupcion y se parase el funcionamiento. ,para esto tenia reservado el pin RB4 como se ve en proteus ,ya que se peude poner como entrada analogica y ademas puede crear una interrupcion.
de momento nada mas jaj u nsaludoo
;****Encabezado****
LIST P=16F887
INCLUDE P16F887.INC
;El reset se hace mediante el pin MCLR hay que activarlo en la configuracion MCLR_ON
;__CONFIG _INTOSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_ON & _FCMEN_ON & _LVP_ON
__CONFIG _CONFIG1, _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & _DEBUG_OFF
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
;**** Definicion de variables ****
Usuario equ 0x30 ;preseleccion de potencia
Contador equ 0x31 ;Contador para detectar 256 periodos de onda
Contador1 equ 0x32 ;contador para contar 48 desbordes de contador (220ms)
Contador2 equ 0x33 ;contador para el reposo( seleccion de potencia)
NTecla equ 0x34 ;numero de tecla presionada
LED_rojo equ 2 ;define el bit de un registro (parado)
LED_verde equ 3 ;bit de un registro (funcionamiento)
W_Temp equ 0x20 ;Registro para guardar temporalmente W.-
STATUS_Temp equ 0x21 ;Registro para guardar temporalmente STATUS
PORTB_Temp equ 0x22 ;registro temporal de puerto B
PORTA_Temp equ 0x23 ;regustro temporal de puerto A
;**** Inicio del Micro ****
org 0x00
goto INICIO
;**** Vector de Interrupcion ****
org 0x04 ; Atiendo Interrupcion.-
goto Inicio_ISR
;**** Programa Principal ****
;**** Configuracion de puertos ***
org 0x05 ; Origen del código de programa.-
INICIO ;sabemos que PR2 se inicia a 256
banksel ANSEL ;banco 3
clrf ANSEL ;todos digitales i/o
clrf ANSELH
bcf STATUS,6
bsf STATUS,5 ;elegimos banco 1
movlw b'11110001' ;puerto B 0=salidas 1=entradas
movwf TRISB ;RB0/INT=PARAR
movlw b'00000011' ;puerto A entradas = MARCHA y REINICIO
movwf TRISA ;entradas
movlw b'00000000' ;habilitamos interrupcion por RB0/INT
movwf OPTION_REG ;(INTEDG) y resistencias pull up activadas
;es decir entradas reposo=1
movlw b'10011000' ;habilitamos GIE INTE RBIE
movwf INTCON
movlw b'11110000' ;habilitamos interrupciones puerto B
movwf IOCB
movlw b'11110000' ;1=entrada 0=salida
movwf TRISC
movlw b'00000000' ;ponemos dislpay a 0
movwf TRISD
bcf STATUS,5 ;elegimos banco 0
bcf STATUS,6
clrf PORTA
clrf PORTC
clrf PORTB
movlw b'00111111' ;ponemos dislpay a 0
movwf PORTD
clrf Contador ;iniciamos a 0 contador
clrf NTecla ;borramos nº de tecla
movlw .208 ;precargamos el contador1 (48 ciclos=220ms)
movwf Contador1 ;iniciamos a 208
movlw b'00000100'
movwf PORTA ;prendemos led rojo
EMPIEZA btfss PORTA,0 ;se pulso INICIO? saltasi 1 pulsador reposo=0
;al pulsarlo entrada=1 ------>salta
goto EMPIEZA ;NO, esperamos
bcf PORTA,LED_rojo ;SI, rojo=off
bsf PORTA,LED_verde ;verde=on
;**** Bucle ****
DOS_ONDAS bsf PORTB,1 ;señal del mos0 en alta (5v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
call DELAY_6_07US ;llamamos a la subrrutina de 6.07us
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
call DELAY_2_88US ;llamamos a la subrrutina de 2.88us
bcf PORTB,1 ;señal del mos0 en baja (0v)
bsf PORTB,2 ;señal del mos1 en alta (5v)
call DELAY_6_07US ;llamamos a la subrrutina de 6.07us
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
call DELAY_2_88US ;llamamos a la subrrutina de 2.88us
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1;1 ;incrementamos contador1 hasta 48 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 48
;se han cumplido los 220ms (contador1=48)
movlw .208 ;precargamos el contador1 (48 ciclos)
movwf Contador1 ;iniciamos a 208
bsf PORTB,3 ;Si,(5v)señal laser
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
SELECPOT movf Usuario,0 ; Consultamos si se han producido X desbordes
subwf Contador2,0 ; contador-X ------>contador
btfss STATUS,Z ;Z=0? salto si 1 Z=1 si contador=Usuario
goto Actualizo_TMR2 ;No,Actualizo TMR2 y reinicio bucle
clrf Contador2 ;Si,limpiamos contador2
bcf PORTB,3 ;limpiamos la señal laser
goto DOS_ONDAS ;termina el paron y continuamos
Actualizo_TMR2
movlw b'01111111' ;habilitamos el TMR2 y escalamos
movwf T2CON ;predivisor 1:16 postdivisor 1:16 en el TMR2
movlw 0x00 ;movemos a w cero
movwf TMR2 ;cargamos el temporizador tmr2=0
bcf PIR1,1 ;borramos la bandera TMR2IF
REPOSO btfss PIR1,1 ;saltamos si 1 = overflow
goto REPOSO ;no=bucle
incf Contador2,1 ;incrementamos el contador2
goto SELECPOT ;volvemos a comparar contador2
;**** Subrrutina de retardo señal alta ****
DELAY_6_07US movlw b'0000100' ;habilitamos el TMR2 y escalamos
bsf T2CON,2 ;predivisor 1:1 en el TMR2
movlw .254 ;movemos a w 226 que son 30 ciclos
movwf TMR2 ;cargamos el temporizador tmr2
bcf PIR1,1 ;borramos la bandera TMR2IF
ESPERA btfss PIR1,1 ;saltamos si 1 = overflow
goto ESPERA ;no=bucle
return ;si=salimos de la subrrutina
;**** Subrrutina de retardo señal baja ****
DELAY_2_88US
return ;salimos de la subrrutina (6 ciclos)
;**** Subrrutina nº tecla seleccionada ****
;Configuraremos RC0 a RC3 como salida y
;las colocaremos a nivel bajo. RC4 y RC7 configuradas como entradas,
;y en estado normal (sin presión de teclas) estarán a nivel alto.
;RBPU=0 de OPTION_REG
;conectamos tambien las entradas a RB4:RB6 para detectar que se toca la tecla
Tecla_Presionada
clrf NTecla ; Borra Numero de Tecla y
incf NTecla,1 ; prepara NTecla para primer codigo.
movlw b'00001110' ; Saca 0 a la primera fila
movwf PORTC ; de la Puerta C
nop ; Para estabilizacion de señal.
Test_Columnas
btfss PORTC,4 ; Primera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTC,5 ; Segunda columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTC,6 ; Tercera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
; En este caso se Usa teclado 3x4.-
; btfss PORTC,7 ; Cuarta columna = 0
; goto Suelta_tecla ; Sale si se ha pulsado tecla.
; incf NTecla,1 ; Si no tecla pulsada,incrementa nº Tecla.
Ultima_tecla
btfss PORTC,3 ; Ya se revisaron todas las filas?
goto Null_tecla ; Si, Falsa alarma, no se ha presionado ninguna.-
bsf STATUS,C ; No, seguimos con la siguiente.Pone a 1 Bit C
rlf PORTC,1 ; asi la Fila 1 pasa a 1 con la rotaci¢n a izqda.
goto Test_Columnas
Null_tecla
clrf NTecla ; Coloca variable Tecla a 0 (Ninguna)
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTC ; Dejamos Puerto para recibir otra tecla.-
return ; y regresa.
Suelta_tecla
; Ahora se espera a que la tecla sea soltada para evitar rebotes
; y reactivaciones de tecla
Espera1
btfss PORTC,4 ; Si no se suelta la tecla FILA 1
goto Espera1 ; vuelve a esperar.
Espera2
btfss PORTC,5 ; Si no se suelta la tecla FILA 2
goto Espera2 ; vuelve a esperar.
Espera3
btfss PORTC,6 ; Si no se suelta la tecla FILA 3
goto Espera3 ; vuelve a esperar.
Espera4
btfss PORTC,7 ; Si no se suelta la tecla FILA 4
goto Espera4 ; vuelve a esperar.
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTC ; Dejamos Puerto para recibir otra tecla.-
return ; vuelve al programa principal que hizo la llamada.
;**** Tabla preseleccion de potencia ****
TABLAPOTENCIA
addwf PCL,f
retlw .0 ;(0)
retlw .0 ;650w (1)
retlw .2 ;500w (2)
retlw .4 ;400w (3)
retlw .8 ;300w (4)
retlw .15 ;200w (5)
retlw .37 ;100w (6)
retlw .256 ;7 tecla no reconocida(256)carga un valor alto
;,poca potencia , por seguridad
retlw .256 ;8 tecla no reconocida
retlw .256 ;9 tecla no reconocida
retlw .256 ;10 tecla no reconocida
retlw .256 ;11 tecla no reconocida
retlw .256 ;12 tecla no reconocida
;**** Tabla display catodo comun ****
BCD7SEG:
addwf PCL,1
retlw b'00111111' ; 0
retlw b'00000110' ; 1
retlw b'01011011' ; 2
retlw b'01001111' ; 3
retlw b'01100110' ; 4
retlw b'01101101' ; 5
retlw b'01111101' ; 6
retlw b'01111001' ; E ,7 Error
retlw b'01111001' ; E ,8 Error
retlw b'01111001' ; E ,9 Error
retlw b'01111001' ; E ,10 Error
retlw b'01111001' ; E ,11 Error
retlw b'01111001' ; E ,12 Error
;**** Rutina de servicio de Interrupcion ****
;**** Interrupcion por RB4:RB7 y RB0/INT ****
;---> Aqui haremos copia de respaldo - Guardado de registro W y STATUS.-
Inicio_ISR
movwf W_Temp ; Copiamos W a un registro Temporario.-
swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
movf PORTB,0 ;puertoB---->W
movwf PORTB_Temp ;guardamos puertob
movf PORTA,0 ;puertoA---->W
movwf PORTA_Temp ;guardamos puertoA
ISR
bcf INTCON,GIE ;deshabilitamos las interrupciones
btfss INTCON,RBIF ;RBIF=1?(RB4;RB7)
goto PARAR ;no,vemos si es por INT (INTF)
goto TECLADO ;si es por teclado
;**** Introducimos potencia deseada por teclado Matricial ****
TECLADO call Tecla_Presionada; Se detecta que tecla fue presionada
movfw NTecla ;cargamos en W el nº de tecla presionada
call TABLAPOTENCIA ;pedimos a la tabla que nos devuelva valor
movwf Usuario ;cargamos la potencia desada en nuesto registro
movfw NTecla ;volvemos a cargar el valor de NTecla en W
call BCD7SEG ;decodificador 7 seg
movwf PORTD ; Mostarmos en diplay tecla Presionada.-
bcf INTCON,RBIF ;limpiamos flag y salimos
goto Fin_ISR
PARAR btfss INTCON,INTF ;INTF=1?
goto Fin_ISR ;no,salimos
;si continuamos
movlw b'0000000' ;salidas = 0
movwf PORTB
bsf PORTA,LED_rojo ;led rojo=on
bcf PORTA,LED_verde ;led verde=off
REINICIO btfss PORTA,1 ;sepulso REINICIO?? salta si 1 , entradas reposo=1
;luego pulsador en reposo =0 al presionarle=1
goto REINICIO ;NO, bucle
bcf INTCON,INTF ;limpiamos flag y salimos
; Restauramos los valores de W y STATUS.-
Fin_ISR
movf PORTA_Temp,0
movwf PORTA
movf PORTB_Temp,0
movwf PORTB
swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
movwf STATUS
swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
bsf INTCON,GIE ;habilitamos las interrupciones
retfie ; Salimos de interrupción.
end
-
Adjunte unos tutoriales sobre Proteus, a ver si lo hice bien y te sirven de algo, no me dice que son muy grandes y no me deja, creo que los subio Suki, a ver si encuentro el enlace.
El teclado matricial ¿esta copiado del tutorial de Suki, verdad? entonces funcionara, seguro.
Tienes en los DELAY un par de cosas que no son logicas, en DELAY_6:07US en medio del DELAY activas TMR2 para contar 1 millonesima???
7us los puedes temporizar haciendo 14 "NOP" o como te decia chequear ahi el RB0 y te evitas esa interrupcion y la de 2us con 4 "nop" listo.
Citar
;**** Subrrutina de retardo señal alta ****
DELAY_6_07US movlw b'0000100' ;habilitamos el TMR2 y escalamos
bsf T2CON,2 ;predivisor 1:1 en el TMR2
movlw .254 ;movemos a w 226 que son 30 ciclos
movwf TMR2 ;cargamos el temporizador tmr2
bcf PIR1,1 ;borramos la bandera TMR2IF
ESPERA btfss PIR1,1 ;saltamos si 1 = overflow
goto ESPERA ;no=bucle
return ;si=salimos de la subrrutina
;**** Subrrutina de retardo señal baja ****
DELAY_2_88US
return ;salimos de la subrrutina (6 ciclos)
DOS_ONDAS bsf PORTB,1 ;señal del mos0 en alta (5v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
nop
nop
nop
nop
continua...
Asi no queda muy bien, mejor asi:
DOS_ONDAS bsf PORTB,1 ;señal del mos0 en alta (5v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
bcf PORTB,1 ;señal del mos0 en baja (0v)
bcf PORTB,2 ;señal del mos1 en baja (0v)
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTB,0 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
Temporizas igual 7 y 2us y de paso chequeas RB0
Citar
TABLAPOTENCIA
addwf PCL,f
retlw .0 ;(0)
retlw .0 ;650w (1)
retlw .2 ;500w (2)
retlw .4 ;400w (3)
retlw .8 ;300w (4)
retlw .15 ;200w (5)
retlw .37 ;100w (6)
retlw .256 ;7 tecla no reconocida(256)carga un valor alto
;,poca potencia , por seguridad
retlw .256 ;8 tecla no reconocida
retlw .256 ;9 tecla no reconocida
retlw .256 ;10 tecla no reconocida
retlw .256 ;11 tecla no reconocida
retlw .256 ;12 tecla no reconocida
En esta tabla tienes que cambiar 256 por 255 ya te lo dice el MPLAB al compilar.
En esta linea se te escapo un punto y coma, no importa porque MPLAB al no haber nada pone un 1 pordefecto, si ahi fuera no te funcionaria, pero en este caso estas de suerte
incfsz Contador1;1 ;incrementamos contador1 hasta 48 salto si 0
Aunque no llegue ahi en la simulacion creo que estas lineas tienes que ponerlas antes porque sino CONTADOR1 empieza en 0 y cuenta 256 en vez de 48:
movlw .208 ;precargamos el contador1 (48 ciclos)
movwf Contador1 ;iniciamos a 208
Bueno habra algo mas, ves mirando estas cosas, para llevar solo 2 semanas le das muy bien.
-
hola , gracias de nuevo ,si la parte de la interrupcion del teclado la copie de donde dices me he revisado bien el foro jaja, ya la cosa va mejorando , hice caso a todo lo que me dijiste , lo unico decir que lo de:
movlw .208 ;precargamos el contador1 (48 ciclos=220ms)
movwf Contador1 ;iniciamos a 208
esta tambien definico al inicio , y el proposito de que este tambien aqui es que cuando el contador1 llege a 0 se vuelva a iniciar en 208
he cambiado la disposicion de todos mis puertos , en la imagen se ve bien y ahora en mplab la simulacion va perfecta , lo de proteus ...ya nose si hacerle caso o no..porque la primera vez que lo monte funcionaba "mas o menos" el teclado y el display pero de repente dejo de hacerlo..voy a dejar de fiarme del proteus..
(http://s2.subirimagenes.com/imagen/previo/thump_8124029mispuertos.png) (http://www.subirimagenes.com/imagen-mispuertos-8124029.html)
Bien ahora solo me queda lo que cite anteriormente en el otro mensaje , una entrada analogica de seguridad que pare el funcionamiento, mi idea por lo que he visto es que pondre como referencia 5v y esos equivaldran a 500v de mi laser , es decir si la entrada analogica llega a 5v que produzca un paron..lo veis dificil de hacer?? si teneis alguan idea..pues lo dicho un saludoo
codigo co nals nuevas modificanciones:
;****Encabezado****
LIST P=16F887
INCLUDE P16F887.INC
;El reset se hace mediante el pin MCLR hay que activarlo en la configuracion MCLR_ON
;__CONFIG _INTOSC & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_ON & _FCMEN_ON & _LVP_ON
__CONFIG _CONFIG1, _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & _DEBUG_OFF
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
;**** Definicion de variables ****
Usuario equ 0x30 ;preseleccion de potencia
Contador equ 0x31 ;Contador para detectar 256 periodos de onda
Contador1 equ 0x32 ;contador para contar 48 desbordes de contador (220ms)
Contador2 equ 0x33 ;contador para el reposo( seleccion de potencia)
NTecla equ 0x34 ;numero de tecla presionada
LED_rojo equ 4 ;define el bit de un registro (parado)
LED_verde equ 3 ;bit de un registro (funcionamiento)
W_Temp equ 0x20 ;Registro para guardar temporalmente W.-
STATUS_Temp equ 0x21 ;Registro para guardar temporalmente STATUS
PORTC_Temp equ 0x22 ;registro temporal de puerto c(MIENTRAS SE PRODUCE LA INT POR TECLAD
;**** Inicio del Micro ****
org 0x00
goto INICIO
;**** Vector de Interrupcion ****
org 0x04 ; Atiendo Interrupcion.-
goto Inicio_ISR
;**** Programa Principal ****
;**** Configuracion de puertos ***
org 0x05 ; Origen del código de programa.-
INICIO ;sabemos que PR2 se inicia a 256
banksel ANSEL ;banco 3
clrf ANSEL ;todos digitales i/o
clrf ANSELH
bcf STATUS,6
bsf STATUS,5 ;elegimos banco 1
movlw b'00000000' ;puerto A salidas
movwf TRISA
movlw b'11110000' ;puerto B teclado
movwf TRISB
movlw b'11100000' ;puerto C 1=pulsadores 0=salida
movwf TRISC
movlw b'00000000' ;puerto D como salidas display
movwf TRISD
movlw b'00000000' ;resistencias pull up puerto B activadas
movwf OPTION_REG ;es decir entradas reposo=1
movlw b'10001000' ;habilitamos GIE INTE RBIE
movwf INTCON
movlw b'11110000' ;habilitamos interrupciones puerto B
movwf IOCB
bcf STATUS,5 ;elegimos banco 0
bcf STATUS,6
clrf PORTA
clrf PORTB
movlw b'00010000' ;prendemos led rojo
movwf PORTC
movlw b'00111111' ;ponemos dislpay a 0
movwf PORTD
clrf Contador ;iniciamos a 0 contador
clrf NTecla ;borramos nº de tecla
movlw .208 ;precargamos el contador1 (48 ciclos=220ms)
movwf Contador1 ;iniciamos a 208
EMPIEZA btfss PORTC,7 ;se pulso INICIO? salta si 1 pulsador reposo=0
;al pulsarlo entrada=1 ------>salta
goto EMPIEZA ;NO, esperamos
bcf PORTC,LED_rojo ;SI, rojo=off
bsf PORTC,LED_verde ;verde=on
;**** Bucle ****
DOS_ONDAS
bsf PORTC,1 ;señal del mos0 en alta (5v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bsf PORTC,2 ;señal del mos1 en alta (5v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RB0
goto PARAR ; si esta a 1 hay que parar
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1,1 ;incrementamos contador1 hasta 48 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 48
;se han cumplido los 220ms (contador1=48)
movlw .208 ;precargamos el contador1 (48 ciclos)
movwf Contador1 ;iniciamos a 208
bsf PORTC,0 ;Si,(5v)señal laser
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
SELECPOT movf Usuario,0 ; USUARIO---->W se han producido X desbordes?
subwf Contador2,0 ; contador-X ------>contador
btfss STATUS,Z ;Z=0? salto si 1 Z=1 si contador=Usuario
goto Actualizo_TMR2 ;No,Actualizo TMR2 y reinicio bucle
clrf Contador2 ;Si,limpiamos contador2
bcf PORTC,0 ;limpiamos la señal laser
goto DOS_ONDAS ;termina el paron y continuamos
Actualizo_TMR2
movlw b'01111111' ;habilitamos el TMR2 y escalamos
movwf T2CON ;predivisor 1:16 postdivisor 1:16 en el TMR2
movlw 0x00 ;movemos a w cero
movwf TMR2 ;cargamos el temporizador tmr2=0
bcf PIR1,1 ;borramos la bandera TMR2IF
REPOSO btfss PIR1,1 ;saltamos si 1 = overflow
goto REPOSO ;no=bucle
incf Contador2,1 ;incrementamos el contador2
goto SELECPOT ;volvemos a comparar contador2
;**** Subrrutina PARAR ****
PARAR
movlw b'00010000' ;salidas =0 LED_rojo=on
movwf PORTC
REINICIO btfss PORTC,5 ;sepulso REINICIO?? salta si 1 , entradas reposo=1
;luego pulsador en reposo =0 al presionarle=1
goto REINICIO ;NO, bucle
movlw b'00001000' ;salidas =0 LED_verde=on
movwf PORTC
goto DOS_ONDAS ;volvemos a DOS_ONDAS
;**** Subrrutina nº tecla seleccionada ****
;Configuraremos RB0 a RB3 como salida y
;las colocaremos a nivel bajo. RB4 y RB7 configuradas como entradas,
;y en estado normal (sin presión de teclas) estarán a nivel alto.
;RBPU=0 de OPTION_REG
;conectamos tambien las entradas a RB4:RB6 para detectar que se toca la tecla
Tecla_Presionada
clrf NTecla ; Borra Numero de Tecla y
incf NTecla,1 ; prepara NTecla para primer codigo.
movlw b'00001110' ; Saca 0 a la primera fila
movwf PORTB ; de la Puerta B
nop ; Para estabilizacion de señal.
Test_Columnas
btfss PORTB,4 ; Primera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTB,5 ; Segunda columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTB,6 ; Tercera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
; En este caso se Usa teclado 3x4.-
; btfss PORTB,7 ; Cuarta columna = 0
; goto Suelta_tecla ; Sale si se ha pulsado tecla.
; incf NTecla,1 ; Si no tecla pulsada,incrementa nº Tecla.
Ultima_tecla
btfss PORTB,3 ; Ya se revisaron todas las filas?
goto Null_tecla ; Si, Falsa alarma, no se ha presionado ninguna.-
bsf STATUS,C ; No, seguimos con la siguiente.Pone a 1 Bit C
rlf PORTB,1 ; asi la Fila 1 pasa a 1 con la rotaci¢n a izqda.
goto Test_Columnas
Null_tecla
clrf NTecla ; Coloca variable Tecla a 0 (Ninguna)
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTB ; Dejamos Puerto para recibir otra tecla.-
return ; y regresa.
Suelta_tecla
; Ahora se espera a que la tecla sea soltada para evitar rebotes
; y reactivaciones de tecla
Espera1
btfss PORTB,4 ; Si no se suelta la tecla FILA 1
goto Espera1 ; vuelve a esperar.
Espera2
btfss PORTB,5 ; Si no se suelta la tecla FILA 2
goto Espera2 ; vuelve a esperar.
Espera3
btfss PORTB,6 ; Si no se suelta la tecla FILA 3
goto Espera3 ; vuelve a esperar.
Espera4
btfss PORTB,7 ; Si no se suelta la tecla FILA 4
goto Espera4 ; vuelve a esperar.
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTB ; Dejamos Puerto para recibir otra tecla.-
return ; vuelve al programa principal que hizo la llamada.
;**** Tabla preseleccion de potencia ****
TABLAPOTENCIA
addwf PCL,f
retlw .0 ;(0)
retlw .0 ;650w (1)
retlw .2 ;500w (2)
retlw .4 ;400w (3)
retlw .8 ;300w (4)
retlw .15 ;200w (5)
retlw .37 ;100w (6)
retlw .255 ;7 tecla no reconocida(256)carga un valor alto
;,poca potencia , por seguridad
retlw .255 ;8 tecla no reconocida
retlw .255 ;9 tecla no reconocida
retlw .255 ;10 tecla no reconocida
retlw .255 ;11 tecla no reconocida
retlw .255 ;12 tecla no reconocida
;**** Tabla display catodo comun ****
BCD7SEG:
addwf PCL,1
retlw b'00111111' ; 0
retlw b'00000110' ; 1
retlw b'01011011' ; 2
retlw b'01001111' ; 3
retlw b'01100110' ; 4
retlw b'01101101' ; 5
retlw b'01111101' ; 6
retlw b'01111001' ; E ,7 Error
retlw b'01111001' ; E ,8 Error
retlw b'01111001' ; E ,9 Error
retlw b'01111001' ; E ,10 Error
retlw b'01111001' ; E ,11 Error
retlw b'01111001' ; E ,12 Error
;**** Rutina de servicio de Interrupcion ****
;**** Interrupcion por RB4:RB7 y RB0/INT ****
;---> Aqui haremos copia de respaldo - Guardado de registro W y STATUS.-
Inicio_ISR
movwf W_Temp ; Copiamos W a un registro Temporario.-
swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
movf PORTC,0 ;puertoB---->W
movwf PORTC_Temp ;guardamos puertob
movlw b'00001000'
movwf PORTC ;mientras se produce la interrupcion mos = 0
ISR
bcf INTCON,GIE ;deshabilitamos las interrupciones
btfss INTCON,RBIF ;RBIF=1?(RB4;RB7)
goto Fin_ISR
;**** Introducimos potencia deseada por teclado Matricial ****
TECLADO call Tecla_Presionada; Se detecta que tecla fue presionada
movfw NTecla ;cargamos en W el nº de tecla presionada
call TABLAPOTENCIA ;pedimos a la tabla que nos devuelva valor
movwf Usuario ;cargamos la potencia desada en nuesto registro
movfw NTecla ;volvemos a cargar el valor de NTecla en W
call BCD7SEG ;decodificador 7 seg
movwf PORTD ; Mostarmos en diplay tecla Presionada.-
bcf INTCON,RBIF ;limpiamos flag y salimos
; Restauramos los valores de W y STATUS.-
Fin_ISR
movf PORTC_Temp,0
movwf PORTC
swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
movwf STATUS
swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
bsf INTCON,GIE ;habilitamos las interrupciones
retfie ; Salimos de interrupción.
end
-
Hola , he encontrado bastante informacion acerca de los A/D , y su utilizacion no es muy complicada .ahora bien llegan als dudas cuando eso lo quiero acoplar ami proyecto , dudas:
1.para seleccionar mi entrada analogica utilizare AN0( bit 0 puertoA) , basta con poner el ACON1 ej.00001110 y el bit0 del TRISA a 1 o tambien tengo que cambiar el bit 0 del ANSEL para seleccionarlo como analogica ya que en mi programa lo inicie a 0x00,
2.El tiempo de adquisicion ,?? ..eso significa cada cuanto muestreo la señal? en mi caso seria suficiente con muestrearla cada vez que se cumplen los 220ms??
3.el mayor problema..donde colocar el codigo??? si lo ago a modo interrupcion cada vez que por ej pasen 220ms compruebe si el valo de ADC es superior a determinado valor y si es asi que pare el programa , el problema es que mientras se ejecuta la interrupcion no esta funcionando mi programa correctamente , recordemos que necesitamos bastante precision (microsegundos) , por otro lado se podria insertar en el codigo del programa cuando el contador1 detecta 220ms , pero pasaria lo mismo al ejecutarlo ,es decir no estaria funcionando mi programa.
Alguien podria pensar que cuente el tiempo que tarda en ejecutarse el codigo y calibrar el tiempo que mi laser esta en pausa despues de los 220ms..., pero el problema es que ese tiempo es variable y dependiendo de POTENCIATABLA seleccionado estaremos en pausa mas o menos tiempo...
pues lo dicho aceptamos sugerencias y demas..un saludoo
-
Hola amigo, puedes explicar en que consiste tu fuente de alimentacion para un Laser Nd:yag, ¿ es necesario que programes en ensamblador ?, por que no en lenguaje C.
Yo tambien tenia problemas con la simulacion del teclado pero lo resolvi poniendo unas resistencias de 220 ohm a las entradas, PROTEUS es una herramienta muy poderosa, yo llevo mas de tres años usandolo y si falla lo mas probable es que el problema este en tu codigo y no en la simulacion ( a menos que realices malas conexiones).
-
hice caso a todo lo que me dijiste , lo unico decir que lo de:
movlw .208 ;precargamos el contador1 (48 ciclos=220ms)
movwf Contador1 ;iniciamos a 208
esta tambien definico al inicio , y el proposito de que este tambien aqui es que cuando el contador1 llege a 0 se vuelva a iniciar en 208
Si es cierto que tambien esta al principio, fallo mio, no lo vi. Ese bucle completo es el que tiene que dar 220ms ¿verdad? porque da 288,768us, seguramente el fallo esta en que cuentas en cada bucle los tiempos de los DELAYS pero no tienens en cuenta los tiempos de activacion y desactivacion de los mosfet??? y tampoco los incrementos de los contadores, al ser tiempos tan pequeños eso hace que se desvie mucho el tiempo final.
1.para seleccionar mi entrada analogica utilizare AN0( bit 0 puertoA) , basta con poner el ACON1 ej.00001110 y el bit0 del TRISA a 1 o tambien tengo que cambiar el bit 0 del ANSEL para seleccionarlo como analogica ya que en mi programa lo inicie a 0x00,
Si, tienes que poner ANSEL,0 a 1
Esto esta sacado del data, precisamente el ejemplo que trae es par RA0, pag. 103
;This code block configures the ADC
;for polling, Vdd and Vss as reference, Frc
clock and AN0 input.
;
;Conversion start & polling for completion
; are included.
;
BANKSEL ADCON1 ;
MOVLW B’10000000’ ;right justify
MOVWF ADCON1 ;Vdd and Vss as Vref
BANKSEL TRISA ;
BSF TRISA,0 ;Set RA0 to input
BANKSEL ANSEL ;
BSF ANSEL,0 ;Set RA0 to analog
BANKSEL ADCON0 ;
MOVLW B’11000001’ ;ADC Frc clock,
MOVWF ADCON0 ;AN0, On
CALL SampleTime ;Acquisiton delay
BSF ADCON0,GO ;Start conversion
BTFSC ADCON0,GO ;Is conversion done?
GOTO $-1 ;No, test again
BANKSEL ADRESH ;
MOVF ADRESH,W ;Read upper 2 bits
MOVWF RESULTHI ;store in GPR space
BANKSEL ADRESL ;
MOVF ADRESL,W ;Read lower 8 bits
MOVWF RESULTLO ;Store in GPR space
2.El tiempo de adquisicion ,?? ..eso significa cada cuanto muestreo la señal? en mi caso seria suficiente con muestrearla cada vez que se cumplen los 220ms??
Yo creo que deberias tomar muestras cuando acabas de enviar la señal, ¿no es esta señal la que carga el condensador?, cuando estas generando la señal no puedes hacer nada mas, con esos tiempos tan criticos, aunque sea por interrupcion, te desvirtuaria los tiempos.
3.el mayor problema..donde colocar el codigo??? si lo ago a modo interrupcion cada vez que por ej pasen 220ms compruebe si el valo de ADC es superior a determinado valor y si es asi que pare el programa , el problema es que mientras se ejecuta la interrupcion no esta funcionando mi programa correctamente , recordemos que necesitamos bastante precision (microsegundos) , por otro lado se podria insertar en el codigo del programa cuando el contador1 detecta 220ms , pero pasaria lo mismo al ejecutarlo ,es decir no estaria funcionando mi programa.
¿No tienes tiempo desde que envias una onda hasta la siguiente? puedes hacerlo por interrupcion pero ya te digo antes te desvirtua los tiempos igual y ademas mucho, al ser tan pequeños. La señal no puede ser con tiempos proporcionales a eses ¿verdad? en vez de 7/2 que sea 14/4, 28/8 etc
Esto esta sacado del data pag. 101
The ADC module allows for the ability to generate an
interrupt upon completion of an Analog-to-Digital
conversion. The ADC interrupt flag is the ADIF bit in the
PIR1 register. The ADC interrupt enable is the ADIE bit
in the PIE1 register. The ADIF bit must be cleared in
software.
Note: The ADIF bit is set at the completion of
every conversion, regardless of whether
or not the ADC interrupt is enabled.
Alguien podria pensar que cuente el tiempo que tarda en ejecutarse el codigo y calibrar el tiempo que mi laser esta en pausa despues de los 220ms..., pero el problema es que ese tiempo es variable y dependiendo de POTENCIATABLA seleccionado estaremos en pausa mas o menos tiempo...
Vale, pero cuanto es ese minimo tiempo, porque el ADC va a tardar 40 o 50us (si no estoy equivocado) y como no necesitas una gran precision puedes hacerla a 8 bits en vez de a 10 bits, ahorras dos TADs y dos movimientos de registros.
Yo tambien tenia problemas con la simulacion del teclado pero lo resolvi poniendo unas resistencias de 220 ohm a las entradas,
Pues prueba esto, a lo mejor es la solucion.
yo llevo mas de tres años usandolo y si falla lo mas probable es que el problema este en tu codigo y no en la simulacion ( a menos que realices malas conexiones).
Pues podrias hacerle un favor a antujevy y simularselo, a ver que fallos ves.
-
Hola de nuevo , gracias a lo que me vas diciendo estoy haciendo esto en tiempo record jaja (para haber empezao de 0)...bueno , hablando con mi tutor del proyecto hemos llegado a una solucion mas sencilla para la programacion y es: no hacer nada.....???? me explico:
en ved de utilizar una entrada analogica y modulo ADC..etc , puesto que es imposible integrarlo en mi programa sin que me influya en los tiempos de las ondas que debo generar,(aparte no hay que complicarse la vida), he decidido utilizar un comparador exterior al pic que me de un 1 si el condensador se pasa de 400V asi que lo vo ya conectar a la patilla RC6 (boton PARAR) asi si se superan los 400V obtendremos una parada igual que si pulsamos el boton parar ...una solucion facil no??
Bueno creo que entonces mi codigo esta terminado...salvo por un detalle que me as comentado:
. Ese bucle completo es el que tiene que dar 220ms ¿verdad? porque da 288,768us, seguramente el fallo esta en que cuentas en cada bucle los tiempos de los DELAYS pero no tienens en cuenta los tiempos de activacion y desactivacion de los mosfet??? y tampoco los incrementos de los contadores, al ser tiempos tan pequeños eso hace que se desvie mucho el tiempo final.
con 288,768us te refieres a ms(milisegundos no?) no microsegundos..
¿como eres capaz de contar exactamente el tiempo del bucle?? ya sabia que me salia mas tiempo pero creia que era imposible saber cuanto puesto que entre saltos contadores y demas me pierdo...y si tienes razon el tiempo exacto tiene que ser 220ms desde aqui hasta aqui:(inserto codigo)
;**** Bucle ****
DOS_ONDAS
bsf PORTC,1 ;señal del mos0 en alta (5v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bsf PORTC,2 ;señal del mos1 en alta (5v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1,1 ;incrementamos contador1 hasta 48 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 48
-------------------------------------------------------------------------------------------------------------------;se han cumplido los 220ms (contador1=48)
SE te ocurre que tengo que cambiar (valor de contadores o algo asi)) paraobtener los 220ms exactos bueno puede variar un poco pero no tanto como 288ms
REspecto a proteus... primero decir que ( en mi montaje sin resitencias ni nada) una vez mientras simulaba el programa y estaba corriendo..de repente empezo a detectar el teclado... todo esto sin haber modificado nada, ..pare la simulacion y nunca mas volvio a reconocer el teclado...(yo a estas cosas no las veo logica ninguna)
Tambien he probado con resistencias en las entradas y haciendome un teclado con botones..y nada no funciona..lo dicho si alguien que sepa utilizar bien proteus me peude hechar una mano... aqui dejo el codigo completo por si lo intentan simular:
;****Encabezado****
LIST P=16F887
INCLUDE P16F887.INC
;El reset se hace mediante el pin MCLR hay que activarlo en la configuracion MCLR_ON
__CONFIG _CONFIG1, _INTOSCIO & _WDT_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_ON & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & _DEBUG_OFF
__CONFIG _CONFIG2, _BOR40V & _WRT_OFF
;**** Definicion de variables ****
Usuario equ 0x30 ;preseleccion de potencia
Contador equ 0x31 ;Contador para detectar 256 periodos de onda
Contador1 equ 0x32 ;contador para contar 48 desbordes de contador (220ms)
Contador2 equ 0x33 ;contador para el reposo( seleccion de potencia)
NTecla equ 0x34 ;numero de tecla presionada
LED_rojo equ 4 ;define el bit de un registro (parado)
LED_verde equ 3 ;bit de un registro (funcionamiento)
W_Temp equ 0x20 ;Registro para guardar temporalmente W.-
STATUS_Temp equ 0x21 ;Registro para guardar temporalmente STATUS
PORTC_Temp equ 0x22 ;registro temporal de puerto c(MIENTRAS SE PRODUCE LA INT POR TECLAD
;**** Inicio del Micro ****
org 0x00
goto INICIO
;**** Vector de Interrupcion ****
org 0x04 ; Atiendo Interrupcion.-
goto Inicio_ISR
;**** Programa Principal ****
;**** Configuracion de puertos ***
org 0x05 ; Origen del código de programa.-
INICIO ;sabemos que PR2 se inicia a 256
banksel ANSEL ;banco 3
clrf ANSEL ;todos digitales i/o
clrf ANSELH
bcf STATUS,6
bsf STATUS,5 ;elegimos banco 1
movlw b'00000000' ;puerto A salidas
movwf TRISA
movlw b'11110000' ;puerto B teclado
movwf TRISB
movlw b'11100000' ;puerto C 1=pulsadores 0=salida
movwf TRISC
movlw b'00000000' ;puerto D como salidas display
movwf TRISD
movlw b'00000000' ;resistencias pull up puerto B activadas
movwf OPTION_REG ;es decir entradas reposo=1
movlw b'10001000' ;habilitamos GIE INTE RBIE
movwf INTCON
movlw b'11110000' ;habilitamos interrupciones puerto B
movwf IOCB
bcf STATUS,5 ;elegimos banco 0
bcf STATUS,6
clrf PORTA
clrf PORTB
movlw b'00010000' ;prendemos led rojo
movwf PORTC
movlw b'00111111' ;ponemos dislpay a 0
movwf PORTD
clrf Contador ;iniciamos a 0 contador
clrf NTecla ;borramos nº de tecla
movlw .208 ;precargamos el contador1 (48 ciclos=220ms)
movwf Contador1 ;iniciamos a 208
EMPIEZA btfss PORTC,7 ;se pulso INICIO? salta si 1 pulsador reposo=0
;al pulsarlo entrada=1 ------>salta
goto EMPIEZA ;NO, esperamos
bcf PORTC,LED_rojo ;SI, rojo=off
bsf PORTC,LED_verde ;verde=on
;**** Bucle ****
DOS_ONDAS
bsf PORTC,1 ;señal del mos0 en alta (5v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bsf PORTC,2 ;señal del mos1 en alta (5v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1,1 ;incrementamos contador1 hasta 48 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 48
;se han cumplido los 220ms (contador1=48)
movlw .208 ;precargamos el contador1 (48 ciclos)
movwf Contador1 ;iniciamos a 208
bsf PORTC,0 ;Si,(5v)señal laser
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
SELECPOT movf Usuario,0 ; USUARIO---->W se han producido X desbordes?
subwf Contador2,0 ; contador-X ------>contador
btfss STATUS,Z ;Z=0? salto si 1 Z=1 si contador=Usuario
goto Actualizo_TMR2 ;No,Actualizo TMR2 y reinicio bucle
clrf Contador2 ;Si,limpiamos contador2
bcf PORTC,0 ;limpiamos la señal laser
goto DOS_ONDAS ;termina el paron y continuamos
Actualizo_TMR2
movlw b'01111111' ;habilitamos el TMR2 y escalamos
movwf T2CON ;predivisor 1:16 postdivisor 1:16 en el TMR2
movlw 0x00 ;movemos a w cero
movwf TMR2 ;cargamos el temporizador tmr2=0
bcf PIR1,1 ;borramos la bandera TMR2IF
REPOSO btfss PIR1,1 ;saltamos si 1 = overflow
goto REPOSO ;no=bucle
incf Contador2,1 ;incrementamos el contador2
goto SELECPOT ;volvemos a comparar contador2
;**** Subrrutina PARAR ****
PARAR
movlw b'00010000' ;salidas =0 LED_rojo=on
movwf PORTC
REINICIO btfss PORTC,5 ;sepulso REINICIO?? salta si 1 , entradas reposo=1
;luego pulsador en reposo =0 al presionarle=1
goto REINICIO ;NO, bucle
movlw b'00001000' ;salidas =0 LED_verde=on
movwf PORTC
goto DOS_ONDAS ;volvemos a DOS_ONDAS
;**** Subrrutina nº tecla seleccionada ****
;Configuraremos RB0 a RB3 como salida y
;las colocaremos a nivel bajo. RB4 y RB7 configuradas como entradas,
;y en estado normal (sin presión de teclas) estarán a nivel alto.
;RBPU=0 de OPTION_REG
;conectamos tambien las entradas a RB4:RB6 para detectar que se toca la tecla
Tecla_Presionada
clrf NTecla ; Borra Numero de Tecla y
incf NTecla,1 ; prepara NTecla para primer codigo.
movlw b'00001110' ; Saca 0 a la primera fila
movwf PORTB ; de la Puerta B
nop ; Para estabilizacion de señal.
Test_Columnas
btfss PORTB,4 ; Primera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTB,5 ; Segunda columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
btfss PORTB,6 ; Tercera columna = 0
goto Suelta_tecla ; Sale si se ha pulsado tecla.
incf NTecla,1 ; Si no tecla pulsada, incrementa nº tecla.
; En este caso se Usa teclado 3x4.-
; btfss PORTB,7 ; Cuarta columna = 0
; goto Suelta_tecla ; Sale si se ha pulsado tecla.
; incf NTecla,1 ; Si no tecla pulsada,incrementa nº Tecla.
Ultima_tecla
btfss PORTB,3 ; Ya se revisaron todas las filas?
goto Null_tecla ; Si, Falsa alarma, no se ha presionado ninguna.-
bsf STATUS,C ; No, seguimos con la siguiente.Pone a 1 Bit C
rlf PORTB,1 ; asi la Fila 1 pasa a 1 con la rotaci¢n a izqda.
goto Test_Columnas
Null_tecla
clrf NTecla ; Coloca variable Tecla a 0 (Ninguna)
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTB ; Dejamos Puerto para recibir otra tecla.-
return ; y regresa.
Suelta_tecla
; Ahora se espera a que la tecla sea soltada para evitar rebotes
; y reactivaciones de tecla
Espera1
btfss PORTB,4 ; Si no se suelta la tecla FILA 1
goto Espera1 ; vuelve a esperar.
Espera2
btfss PORTB,5 ; Si no se suelta la tecla FILA 2
goto Espera2 ; vuelve a esperar.
Espera3
btfss PORTB,6 ; Si no se suelta la tecla FILA 3
goto Espera3 ; vuelve a esperar.
Espera4
btfss PORTB,7 ; Si no se suelta la tecla FILA 4
goto Espera4 ; vuelve a esperar.
bcf INTCON,RBIF ; Borramos bandera de Interrupcion.-
clrf PORTB ; Dejamos Puerto para recibir otra tecla.-
return ; vuelve al programa principal que hizo la llamada.
;**** Tabla preseleccion de potencia ****
TABLAPOTENCIA
addwf PCL,f
retlw .0 ;(0)
retlw .0 ;650w (1)
retlw .2 ;500w (2)
retlw .4 ;400w (3)
retlw .8 ;300w (4)
retlw .15 ;200w (5)
retlw .37 ;100w (6)
retlw .255 ;7 tecla no reconocida(256)carga un valor alto
;,poca potencia , por seguridad
retlw .255 ;8 tecla no reconocida
retlw .255 ;9 tecla no reconocida
retlw .255 ;10 tecla no reconocida
retlw .255 ;11 tecla no reconocida
retlw .255 ;12 tecla no reconocida
;**** Tabla display catodo comun ****
BCD7SEG:
addwf PCL,1
retlw b'00111111' ; 0
retlw b'00000110' ; 1
retlw b'01011011' ; 2
retlw b'01001111' ; 3
retlw b'01100110' ; 4
retlw b'01101101' ; 5
retlw b'01111101' ; 6
retlw b'01111001' ; E ,7 Error
retlw b'01111001' ; E ,8 Error
retlw b'01111001' ; E ,9 Error
retlw b'01111001' ; E ,10 Error
retlw b'01111001' ; E ,11 Error
retlw b'01111001' ; E ,12 Error
;**** Rutina de servicio de Interrupcion ****
;**** Interrupcion por RB4:RB7 y RB0/INT ****
;---> Aqui haremos copia de respaldo - Guardado de registro W y STATUS.-
Inicio_ISR
movwf W_Temp ; Copiamos W a un registro Temporario.-
swapf STATUS, W ;Invertimos los nibles del registro STATUS.-
movwf STATUS_Temp ; Guardamos STATUS en un registro temporal.-
movf PORTC,0 ;puertoB---->W
movwf PORTC_Temp ;guardamos puertob
movlw b'00001000'
movwf PORTC ;mientras se produce la interrupcion mos = 0
ISR
bcf INTCON,GIE ;deshabilitamos las interrupciones
btfss INTCON,RBIF ;RBIF=1?(RB4;RB7)
goto Fin_ISR
;**** Introducimos potencia deseada por teclado Matricial ****
TECLADO call Tecla_Presionada; Se detecta que tecla fue presionada
movfw NTecla ;cargamos en W el nº de tecla presionada
call TABLAPOTENCIA ;pedimos a la tabla que nos devuelva valor
movwf Usuario ;cargamos la potencia desada en nuesto registro
movfw NTecla ;volvemos a cargar el valor de NTecla en W
call BCD7SEG ;decodificador 7 seg
movwf PORTD ; Mostarmos en diplay tecla Presionada.-
bcf INTCON,RBIF ;limpiamos flag y salimos
; Restauramos los valores de W y STATUS.-
Fin_ISR
movf PORTC_Temp,0
movwf PORTC
swapf STATUS_Temp,W ; Invertimos lo nibles de STATUS_Temp.-
movwf STATUS
swapf W_Temp, f ; Invertimos los nibles y lo guardamos en el mismo registro.-
swapf W_Temp,W ; Invertimos los nibles nuevamente y lo guardamos en W.-
bsf INTCON,GIE ;habilitamos las interrupciones
retfie ; Salimos de interrupción.
end
-
en ved de utilizar una entrada analogica y modulo ADC..etc , puesto que es imposible integrarlo en mi programa sin que me influya en los tiempos de las ondas que debo generar,(aparte no hay que complicarse la vida), he decidido utilizar un comparador exterior al pic que me de un 1 si el condensador se pasa de 400V asi que lo vo ya conectar a la patilla RC6 (boton PARAR) asi si se superan los 400V obtendremos una parada igual que si pulsamos el boton parar ...una solucion facil no??
No es imposible integrarlo en el programa, siempre que entre una onda y otra haya 50us mas o menos, de todas maneras es una buena solucion la que habeis decidido. Si ese comparador lo pones en otra entrada, podrias sacar por el display el motivo de la parada, si es porque se pulso el pulsador de paro que ponga una P y si fue por sobrecarga del condensador una C, por ejemplo. En el programa en vez de chequear siempre PORTC,6 irias chequeando los dos y harias dos rutinas de paro iguales solo cambiaria que se sacaria por el display???
con 288,768us te refieres a ms(milisegundos no?) no microsegundos..
Si son doscientos ochenta y ocho milisegundos, lo escribi mal :lol: :lol: 288,768ms o 288.768us.
¿como eres capaz de contar exactamente el tiempo del bucle?? ya sabia que me salia mas tiempo pero creia que era imposible saber cuanto puesto que entre saltos contadores y demas me pierdo...y si tienes razon el tiempo exacto tiene que ser 220ms desde aqui hasta aqui:(inserto codigo)
El MPLAB tiene sus defectos y sus virtudes, contando tiempos de ejecucion es la hostia de bueno :lol: solo tienes que poner BREAKPOITS desde donde hasta donde quieres que cuente le das a RUN (la flecha verde de la izquierda) y todo esto con el STOPWATCH abierto del menu DEBUGGER, por defecto simula a 20MHz, vas a DEBUGGER-SETTINGS y ahi le pones tu frec. 8Mhz en este caso y salen todos los tiempos a la millonesima.
Rebajando en "contador1", por una regla de 3 me sale que con 36.6 repeticiones salen 220 exactos, como tiene que ser exacto 36 o 37 hay que jugar con "contador", mañana si tengo un momento te lo ajusto, aunque si quieres probar tu...practicas midiendo tiempos en el MPLAB.
-
hola otra vez , pues codigo terminado¡¡¡.. incluidos los cambios que me dijiste: voy chekeando las dos entradas y saco por el display el motivo del paron..y respecto a los 36 o 37 ciclos del contador , no te preocupes he puesto 37 y asi se quedaraa.. tampoco pasa nada porque el condensador se cargue un poco mas.. jaj , aunque es entretenido esto de escribir el codigo quedan bastantes mas cosas que hacer, asi que de momento esta fase la dejaremos por terminada...(por finn))
Ahora tengo que dimensionar los componentes de mi circuito..radiadores y demas...y luego elegir la fuente de alimentacion auxiliar para el pic y supongo que otra para el comparador de la tension del condensador , y los drivers para el encendido de los mos , asi que estare dedicado a ello en los proximos dias , si alguien consigue simular el codigo en proteus..pues me vendria bastante bien de cara a la "foto" ..vamos para que quede visualmente bonito , aunque igual si me doy prisa y me da tiempo lo montare en un pic real
pues nada lo dicho muxas graciass tapi8 buena ayuda...siseñorr , si surgen nuevas dudas tendreis noticias mias jaja un saludoo
-
;**** Bucle ****
DOS_ONDAS
bsf PORTC,1 ;señal del mos0 en alta (5v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bsf PORTC,2 ;señal del mos1 en alta (5v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1,1 ;incrementamos contador1 hasta 48 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 48
Veras creo que hay fallo importante en el ultimo ciclo (en negrita) ya que haces la temporizacion de los 2us chequeando POTRC,6 pero despues hace "incfsz Contador,1" que consume 1/2us y "goto DOS_ONDAS" 1us (goto siempre consume dos ciclos de instruccion) por lo que en ese PWM final hace 3,5us en vez de 2us, si estamos haciendo tiempos tan exactos y despues la cagamos con esto????
La solucion es muy sencilla solo hay que sustituir los "btfsc PORTC,6" por un nop:
bcf PORTC,1 ;señal del mos0 en baja (0v)
bcf PORTC,2 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
; btfsc PORTC,6 ;chequeamos si se pulso RC6
; goto PARAR ; si esta a 1 hay que parar
; btfsc PORTC,6 ;chequeamos si se pulso RC6
; goto PARAR ; si esta a 1 hay que parar
nop
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1,1 ;incrementamos contador1 hasta 48 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 48
Aun asi cada 256 ciclos se desborda Contador y al pasar a Contador1 vuelve a pasar lo mismo, pero es solo en eses ciclos, si esto te diera problemas, hay una solucion bastante sencilla que es hacer la cuenta de los 220ms por medio de TIMER1, se eliminarian los contadores y se generaria el PWM perfecto, bueno esto como veas tu.
Yo hice un ajuste que me da 219.686500us, se puede ajustar mejor, cargando Contador1 con 217, pero eso si yo tomo 7us en los ciclos largos que es como lo tenias al principio, ahora veo que lo cambiaste a 6us ¿es un error o va asi?
-
hola , pues si bien detectao el problema, ya habia hecho algunas correcciones el tiempo de espera grande son exactamente 6,07us aprox 6 us y el pequeño son 2,88us aprox 3us , para cuadrar a 220ms pongo el contador1 a 217 y salen exacamente 219,68ms ,,que no esta mal..lo del timer1 ya lo habia pensado y lo descarte ahora no recuerdo bien porque..jaja pero seguramente al haber cambiado tanto el programa ahora si seria factible , pero bueno de momento lo dejare asi si luego tengo tiempo de sobra ya me dedicaree a dejarlo perfecto como dices.. pongo como ha quedado ave que te parece un saludo:
;**** Bucle ****
DOS_ONDAS
bsf PORTC,MOS ;señal del mos0 en alta (5v)
bcf PORTC,MOS1 ;señal del mos1 en baja (0v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTA,6 ;chequeamos si se pulso RA6
goto PARAR1 ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTA,6 ;chequeamos si se pulso RA6
goto PARAR1 ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTA,6 ;chequeamos si se pulso RA6
goto PARAR1 ; si esta a 1 hay que parar
bcf PORTC,MOS ;señal del mos0 en baja (0v)
bcf PORTC,MOS1 ;señal del mos1 en baja (0v)
;****retardo de 3us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTA,6 ;chequeamos si se pulso RA6
goto PARAR1 ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
bcf PORTC,MOS ;señal del mos0 en baja (0v)
bsf PORTC,MOS1 ;señal del mos1 en alta (5v)
;****retardo de 6us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTA,6 ;chequeamos si se pulso RA6
goto PARAR1 ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTA,6 ;chequeamos si se pulso RA6
goto PARAR1 ; si esta a 1 hay que parar
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
btfsc PORTA,6 ;chequeamos si se pulso RA6
goto PARAR1 ; si esta a 1 hay que parar
bcf PORTC,MOS ;señal del mos0 en baja (0v)
bcf PORTC,MOS1 ;señal del mos1 en baja (0v)
;****retardo de 3us y chequeo del pulsador de PARO***
btfsc PORTC,6 ;chequeamos si se pulso RC6
goto PARAR ; si esta a 1 hay que parar
nop
incfsz Contador,1 ;incrementamos contador salto si 0
goto DOS_ONDAS ;bucle
incfsz Contador1,1 ;incrementamos contador1 hasta 39 salto si 0
goto DOS_ONDAS ;reiniciamos si es menor de 39
;se han cumplido los 220ms (contador1=39)
movlw .217 ;precargamos el contador1 (39 ciclos)
movwf Contador1 ;iniciamos a 217
bsf PORTC,LASER ;Si,(5v)señal laser
-
Si, creo que tendras que diseñar el hardware y despues ajustar tiempos, porque los mosfet tienen diferentes tiempos para turn-on y turn-off, nunca habia reparado en esto tan a fondo, ya que son muy rapidos y en la mayoria de las aplicaciones no tiene importancia pero en tu caso, si la tiene, por ejemplo uno peqqueño:
Mosfet 20V/1A:
Turn-On Delay Time tD(on) - 5.1 - ns
Turn-Off Delay Time tD(off) - 26.7 - ns
Entra en conduccion en 5.1ns corta en 26.7ns, es decir va a estar conduciendo 21.6ns mas del tiempo que tu le des en el programa. Uno que mire para un proyecto mio, que es de potencia.
Mosfet 150V/150A
td(on) 30 ns
td(off) 100 ns
A este si le das 6us en alto, el estaria realmente 6.07us, ¿estoy haciendo bien la cuenta, verdad? justo el tiempo que tu quieres. Bueno es una cirscuntancia que tendras que aprovechar, aunque creo que no va a ser facil :5]
Hay micros mas rapidos, este mismo si quieres puede trabajar a 5 MIPS (20mhZ), en la serie 16f los hay a 8 MIPS (32MHz) en la serie 18f a 12 MIPS y despues DSP y PIC32 por encima de 100 MIPS (creo) el problema es que en assembler son complicados de programar y para generar estos tiempos creo que es el lenguaje mas adecuado...