TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: rosalva40 en 30 de Mayo de 2015, 14:29:05
-
Hola, estoy intentando usar el modo PWM para controlar las RPM de un cooler : el codigo es el siguiente:
;-------------------------------------------------
;
;Palabra de configuracion
;
;-------------------------------------------------
list P=16F877A ;Comando que indica el Pic usado
#include "p16F877A.inc" ;Etiquetas genéricas para el Pic16F887
; __config 0xFFFD
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
;-------------------------------------------------
;
; Definicion de variables
;
;-------------------------------------------------
;-------------------------------------------------
;
; Vectores de reset/interrupcion
;
;-------------------------------------------------
ORG 0x00
GOTO EMPEZAR
ORG 0x04
GOTO INTERRUPCION
;-------------------------------------------------
;
; Configuracion
;
;-------------------------------------------------
EMPEZAR
MOVLW 0x07
MOVWF CMCON
BSF STATUS, RP0 ; Banco 1
BCF STATUS, RP1
BCF TRISC,2
;-----------Congurar PWM
MOVLW D'255'
MOVWF PR2 ; PERIODO del PWM
;----------------------
MOVLW B'10000111' ; ------ Configuramos el option REG con disivor 1:64 y R PULL up
MOVWF OPTION_REG
MOVLW B'11000000' ; ------ Habilito Interrupcione por EXT
MOVWF INTCON
MOVLW 0x06
MOVWF ADCON1
BCF STATUS, RP0 ; Banco 0
;-------Configuracion PWM
MOVlW B'00011100' ; Habilita el MODO-PWM , Bits 4 y 5 se confugran en base al ciclo que queramps ( ver 2 bits restantes de ccpr1l)
MOVWF CCP1CON
;MOVLW D'255' ; Ciclo de trabajo 100% , los bit restantes del CCp1 van en Restante (11)
;MOVLW D'166' ; Ciclo a 65%; los restantes(01)
MOVLW D'76' ; Ciclo a 30%; los restantes (11)
MOVWF CCPR1L
BCF PIR1,TMR2IF ; Limpia bandera por desbordamiento de TMR2
MOVLW B'00000100' ; Habilita y selecciona el prescaler del TMR2 ( divisor 1:1)
MOVWF T2CON
; HAY que esperar desbordamiento de tmr2 para poner el tris como salida
;-----------------
BSF INTCON, GIE
;-------------------------------------------------
;
; Programa Principal
;
;-------------------------------------------------
INICIO
nop
BTFSC PIR1, TMR2IF
BCF,TMR2IF
GOTO INICIO
;-------------------------------------------------
INTERRUPCION
GOTO INICIO
END
El problema que se me presenta es que, si no le pongo la instruccion " BCF,TMR2IF " en el main que es para limpiar el flag de cuando TMR2 iguala al PR2 en el proteus me tira error de "Stack overflow interruption" o algo asi, supongo que es porque nunca limpio la bandera esa, agregando esa instruccion, que limpia la bandera, no me tira mas ese error, pero la idea mia es que si hay que limpiar esa bandera lo pueda hacer desde una sub-rutina de interrupcion y no todo el tiempo preguntando desde el "main" , como estoy haciendo en el codigo que subi, si esa bandera esta en 1 o 0. En teoria deberia saltarme la interrupcion ( cuando se pone en 1 la flag de TRM2) e irme a la posicion 0x04 y de ahi a la subrutina de INTERRUPCION, pero no pasa eso como las demas interrupcion que use antes ( TMR0, INT/RB0 , RB4-RB7), obviamente algo mal estoy haciendo. Con esas dos instrucciones "BTFSC PIR1, TMR2IF y BCF,TMR2IF " que estan en el main anda bien en el proteus, pero no me agrada la idea, como dije anteriormente, de preguntar todo el tiempo si esta o no en 1 esa bandera, espero que me puedan ayudar.
Saludos.
-
Hola rosalva40.ese error me suena a que has desbordado la pila.que borres ese flag y no te salga el error sera porque
al borrarlo.se da la condición de que no se desborda.sera mejor que analices en que línea se desborda y porque.
para evitar futuros problemas.
Saludos.
-
Tenes varios problemas.
1-
El problema ese ocurre por varios motivos, el PIC tiene un stack ( creo que ese es de 8 niveles ), en ese stack, cuando se usa un CALL o se entra a una interrupcion, se guarda la direccion ( o contenido del PC) desde donde se llamo. Asi luego con un RETURN o RETFIE (para la interrupcion ) vuelve al punto donde estaba.
Claramente ahi tenes un problema, ya que cada ves que entra a la interrupcion el micro guarda una direccion en el stack, pero luego en ves de utilizar un RETFIE ( RETURN + INTCON.GIE=1 ) estas usando un GOTO lo cual no se saca esa direccion del stack, continua asi hasta llegar a los 8 (o los que tenga el PIC) cuando marca un error por que ya no puede guardar mas direcciones por que se encuentran todas ocupadas.
2-
Sinceramente no se por que estas usando interrupciones para un programa asi.
3-
Si usas interrupciones una buena practica es salvar el contexto ( STATUS y W ) en registros auxiliares y luego volverlo a su estado, asi cuando vuelve de la interrupcion el programa continua y no se han modificado ninguno de los registros.
Tambien en la interrupciones es donde borras el flag.
---------
Al menos eso es lo que vi, no me fije exactamente el codigo del PWM ni los valores cargados, pero pienso que no deberias tocar para nada las interrupciones. El mismo modulo PWM limpia el TMR2 cuando encuentra una coincidencia con PR2 asi que vuelvo a repetir, no veo la necesidad de usar interrupciones.
-
Muchas graicas por las respuestas muchachos.
Tenes varios problemas.
1-
El problema ese ocurre por varios motivos, el PIC tiene un stack ( creo que ese es de 8 niveles ), en ese stack, cuando se usa un CALL o se entra a una interrupcion, se guarda la direccion ( o contenido del PC) desde donde se llamo. Asi luego con un RETURN o RETFIE (para la interrupcion ) vuelve al punto donde estaba.
Claramente ahi tenes un problema, ya que cada ves que entra a la interrupcion el micro guarda una direccion en el stack, pero luego en ves de utilizar un RETFIE ( RETURN + INTCON.GIE=1 ) estas usando un GOTO lo cual no se saca esa direccion del stack, continua asi hasta llegar a los 8 (o los que tenga el PIC) cuando marca un error por que ya no puede guardar mas direcciones por que se encuentran todas ocupadas.
2- Sisi eso lo se que hay una pila y si no vuelvo con un retfie o return, no me descarga la pila, el tema es que yo no llamo ninguna subrutina con ningun CALL , me falto completar la subrutina de interrupcion , pero la hice asi incompleta porque nunca entra ahi, se queda en el main todo el tiempo, osea salta la interrupcion y nunca se va a la direccion 0x04, osea no puedo tirar un retfie desde el main, si el programa no se me fue a ningun lado cuando salto la interrupcion, nose si me explico
Sinceramente no se por que estas usando interrupciones para un programa asi.
Este programa esta sacado de contexto es solo una subrutina de un proyecto que estoy haciendo, no puse todo el codigo porque si no iba a ser un lio.
3-
Si usas interrupciones una buena practica es salvar el contexto ( STATUS y W ) en registros auxiliares y luego volverlo a su estado, asi cuando vuelve de la interrupcion el programa continua y no se han modificado ninguno de los registros.
Tambien en la interrupciones es donde borras el flag.
Eso en el programa principal lo tengo hecho, aca lo unico que quiero es poder probarlo aparte, fuera del programa , asi lo entiendo bien, nose si fui claro explicando pero puse la interrupcion esa vacia, solo para ver si entraba a la interrupcion, nada mas, es verdad que falta un retfie, pero en el programa pincipal si esta. Cuando le hago el debug desde el mplab, me fijo cuando TMR2 iguala al valor del PR2, en ese momento se pone en 1 el CCP1 ( esta bien) y se pone en 1 la bandera de TMR2IF ( esta bien) el tema es que en este punto, no deberia ir a la posicion de memoria 0x04 y de ahi ir a la subrutina interrupcion?. eso es loque quiero que haga y en ningun momento lo hace, nose si se manejara igual esta interrupción que las demás
---------
Al menos eso es lo que vi, no me fije exactamente el codigo del PWM ni los valores cargados, pero pienso que no deberias tocar para nada las interrupciones. El mismo modulo PWM limpia el TMR2 cuando encuentra una coincidencia con PR2 asi que vuelvo a repetir, no veo la necesidad de usar interrupciones.
Y como hago para que no me llene la pila? acordate que las interrupciones estan activas para otras interrupcion, no para esta, ( uso TMR0 , rb/int , y rb4-rb7). El programa en ningun momento pone la bandera de TRM2IF en 0 automaticamente, lo tengo que hace manual, y no se de donde hacerlo.
Nose si fui claro, es dificil explicar todo por aca jaja.
-
Si , complica un poco el tema de no conocer el codigo, pero entiendo que no lo quieras pasar.
2- Sisi eso lo se que hay una pila y si no vuelvo con un retfie o return, no me descarga la pila, el tema es que yo no llamo ninguna subrutina con ningun CALL , me falto completar la subrutina de interrupcion , pero la hice asi incompleta porque nunca entra ahi, se queda en el main todo el tiempo, osea salta la interrupcion y nunca se va a la direccion 0x04, osea no puedo tirar un retfie desde el main, si el programa no se me fue a ningun lado cuando salto la interrupcion, nose si me explico
Si la hiciste incompleta por que habilitas las interrupciones ? Entiendo que quieras simular otras interrupciones pero si ahora ese es todo tu programa entonces al menos ponele un RETURN asi quedan desactivadas las interrupciones (GIE = 0 o directamente no las actives).
Este programa esta sacado de contexto es solo una subrutina de un proyecto que estoy haciendo, no puse todo el codigo porque si no iba a ser un lio.
Eso puede ser un problema, ya que le problema puede estar en otro lado del codigo. Pero queda en vos las cuestiones de poner el codigo o no.
En resumen, el programa parece bueno, sacando de lado que siemrpe deberia haber aunque sea un RETURN luego de la bandera de interrupcion,
el tema es que no se por que habilitas las interrupciones cuando no tenes nada,aunque esto no justifica el por que entra a una interrupcion cuando estan todos en 0 los bits del PIEx y cualquier otro.
Y es lo unico que permitiria que se guarde en el stack algo. Aunque como decis estas en Proteus y al tener activo el PEIE tal ves asuma que tenes activo las interrupciones del TMR2 y no es asi.
El flag del TMR2 no te importaria para nada.
Si aun asi queres que entre a la interrupcion deberias de habilitarlo desde el registro PIEx
Aca el problema es el Proteus y no tu programa.
-
Si , complica un poco el tema de no conocer el codigo, pero entiendo que no lo quieras pasar.
2- Sisi eso lo se que hay una pila y si no vuelvo con un retfie o return, no me descarga la pila, el tema es que yo no llamo ninguna subrutina con ningun CALL , me falto completar la subrutina de interrupcion , pero la hice asi incompleta porque nunca entra ahi, se queda en el main todo el tiempo, osea salta la interrupcion y nunca se va a la direccion 0x04, osea no puedo tirar un retfie desde el main, si el programa no se me fue a ningun lado cuando salto la interrupcion, nose si me explico
Si la hiciste incompleta por que habilitas las interrupciones ? Entiendo que quieras simular otras interrupciones pero si ahora ese es todo tu programa entonces al menos ponele un RETURN asi quedan desactivadas las interrupciones (GIE = 0 o directamente no las actives).
Este programa esta sacado de contexto es solo una subrutina de un proyecto que estoy haciendo, no puse todo el codigo porque si no iba a ser un lio.
Eso puede ser un problema, ya que le problema puede estar en otro lado del codigo. Pero queda en vos las cuestiones de poner el codigo o no.
En resumen, el programa parece bueno, sacando de lado que siemrpe deberia haber aunque sea un RETURN luego de la bandera de interrupcion,
el tema es que no se por que habilitas las interrupciones cuando no tenes nada,aunque esto no justifica el por que entra a una interrupcion cuando estan todos en 0 los bits del PIEx y cualquier otro.
Y es lo unico que permitiria que se guarde en el stack algo. Aunque como decis estas en Proteus y al tener activo el PEIE tal ves asuma que tenes activo las interrupciones del TMR2 y no es asi.
El flag del TMR2 no te importaria para nada.
Si aun asi queres que entre a la interrupcion deberias de habilitarlo desde el registro PIEx
Aca el problema es el Proteus y no tu programa.
Gracias por la respuesta, te comento que tenias razon, y desactive lo que dijsite y ya no me carga la pila, no pase el codigo no porque no quiera si no que capaz se hacia lio para enteder. aca dejo el codigo:
;-------------------------------------------------
;
;Palabra de configuracion
;
;-------------------------------------------------
list P=16F877A ;Comando que indica el Pic usado
#include "p16F877A.inc" ;Etiquetas genéricas para el Pic16F887
; __config 0xFFFD
__CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
;-------------------------------------------------
;
; Definicion de variables
;
;-------------------------------------------------
W_TEMP EQU 0X21
STATUS_TEMP EQU 0X22
Cont1 EQU 0x23
Cont2 EQU 0x24
Cont3 EQU 0x25
Cont4 EQU 0x26
Cont1A EQU 0x27
Cont2A EQU 0x28
Cont3A EQU 0x29
Cont4A EQU 0x30
ContLED EQU 0x31
ContTMR EQU 0x32
FLAG EQU 0x33
Pass1 EQU 0x34
Pass2 EQU 0x35
Pass3 EQU 0x36
PassDONE EQU 0x37
Rotar_pass EQU 0x38
Pass_TEMP EQU 0x39
Flag_pass EQU 0x40
ONOFF EQU 0x41
;-------------------------------------------------
;
; Vectores de reset/interrupcion
;
;-------------------------------------------------
ORG 0x00
GOTO EMPEZAR
ORG 0x04
GOTO INTERRUPCION
;-------------------------------------------------
;
; Configuracion
;
;-------------------------------------------------
EMPEZAR
MOVLW 0x07
MOVWF CMCON
BSF STATUS, RP0 ; Banco 1
BCF STATUS, RP1
MOVLW b'11110000'
MOVWF TRISB ; Puerto B como entrada
CLRF TRISA ; Puerto C como salida
CLRF TRISD ; Puerto D como salida
BCF TRISC,2
;-----------Congurar PWM
MOVLW D'255'
MOVWF PR2 ; PERIODO del PWM
;----------------------
MOVLW B'00000111' ; ------ Configuramos el option REG con disivor 1:64 y R PULL up
MOVWF OPTION_REG
MOVLW B'00101000' ; ------ Habilito Interrupcione por EXT
MOVWF INTCON
MOVLW 0x06
MOVWF ADCON1
BCF STATUS, RP0 ; Banco 0
;-------Configuracion PWM
MOVlW B'00001100' ; Habilita el MODO-PWM , Bits 4 y 5 se confugran en base al ciclo que queramps ( ver 2 bits restantes de ccpr1l)
MOVWF CCP1CON
CLRF CCPR1L ; Ciclo de trabajo 0%
BCF PIR1,TMR2IF ; Limpia bandera por desbordamiento de TMR2
MOVLW B'00000111' ; Habilita y selecciona el prescaler del TMR2 ( divisor 1:1)
MOVWF T2CON
; HAY que esperar desbordamiento de tmr2 para poner el tris como salida
;-----------------
MOVLW B'11110000'
MOVWF PORTB
CLRF PORTA
CLRF PORTD
MOVLW D'16'
MOVWF Cont1A
MOVWF Cont2A
MOVWF Cont3A
MOVLW D'3'
MOVWF ContLED
MOVLW D'3'
MOVWF ContTMR
MOVLW D'186'
MOVWF TMR0
MOVLW D'12' ;4
MOVWF Pass3
MOVLW D'14' ;2
MOVWF Pass2
MOVLW D'15' ;1
MOVWF Pass1
MOVLW D'8'
MOVWF Rotar_pass
MOVF PORTB,W ;Leo el PORTB y limpio flags antes de activar las interrupciones.
BCF INTCON, RBIF
BCF INTCON, T0IF
BSF INTCON, GIE
;-------------------------------------------------
;
; Programa Principal
;
;-------------------------------------------------
INICIO
nop
GOTO INICIO
;-------------------------------------------------
;
; Tabla Hex - 7 segmentos
;
;-------------------------------------------------
TABLA
ADDWF PCL,F
RETLW B'00000000'
RETLW B'00111100' ; F
GOTO Ver_contraseña ; E ( ON / OFF)
GOTO ON_OFF ;D
GOTO Velocidad_3 ;C
GOTO Velocidad_2 ;B
GOTO Velocidad_1 ;A
RETLW B'01111001' ;9
RETLW B'01111111'
RETLW B'01100001' ;7
RETLW B'00111111'
RETLW B'00111011';5 (11)
RETLW B'01011001'
RETLW B'01101011';3
RETLW B'01101110'
RETLW B'01000001' ;1 (15)
RETLW B'01110111' ;0
RETLW B'01110101' ;MOSTRAR N ( N°17)
RETLW B'00000000' ; VACIO (18)
RETLW B'01010111' ; U (19)
RETLW B'00001000' ; - (20)
;-------------------------------------------------
;
; Rutina de Interrupcion
;
;-------------------------------------------------
INTERRUPCION
MOVWF W_TEMP
SWAPF STATUS,W
MOVWF STATUS_TEMP
BTFSC INTCON,T0IF ;El orden aca es importante
GOTO INTERRUPCIONINT
BTFSC INTCON,RBIF
GOTO INTERRUPCIONEXT
RETORNA
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
;-------------------------------------------------
;
; Rutina de interrupcion del PORTB
;
;-------------------------------------------------
INTERRUPCIONEXT
COMF PORTB,W ; Complemento , para saber si es que se solto el boton. Esto hace que si todas las entradas estan a 1 (1111 sin nada presionado) sean 0 y poder ver el flag Z
ANDLW 0xF0 ; Separo unicamente entradas
BTFSC STATUS,Z
GOTO INT_PORTB_SALIR ; Se solto el boton, no hay nada presionado, todas las entradas en 1111, asi que salgo
CLRF FLAG
BSF FLAG,7 ; Flag que entro aqui
MOVF ContTMR,W
IORWF FLAG,F ; Guardo el valor del contador en el nibble bajo, esto para no crear otro registro.
BCF INTCON, RBIE ; Desactivo interrupciones por PORTB asi no toma en cuenta cualquier rebote.
GOTO RETORNA
;-------------------------------------------------
;
; Rutina de interrupcion del TMR0
;
;-------------------------------------------------
INTERRUPCIONINT
BCF INTCON,T0IF
MOVLW D'186'
MOVWF TMR0
DECFSZ ContTMR,F ; Loop contador de interrupciones de timer
GOTO MANEJO_KBD
MOVLW D'3'
MOVWF ContTMR ; Si se cumplio lo recargo
MOVF ContLED,W ; Que display tengo que encender?
CALL TABLALED
DECFSZ ContLED,F ; Llego a 0? Lo recargo y vuelvo
GOTO MANEJO_KBD
MOVLW D'3'
MOVWF ContLED
MANEJO_KBD
BTFSS FLAG,7
GOTO RETORNA ; En caso de que no se activo el PORTB salgo
MOVLW 0x0F ; Separo el nibble que me interesa
ANDWF FLAG,W
SUBWF ContTMR,W ; Reviso si es igual
BTFSS STATUS,Z ; Si es igual entonces realizo mi codigo, sino
GOTO RETORNA
BCF FLAG,7 ; Borro flag
COMF PORTB,W ; Compruebo nuevamente que no sea 0, por si se solto muy rapido.
ANDLW 0xF0 ;
BTFSC STATUS,Z
GOTO INT_PORTB_AUX
MOVF Cont1A,W
MOVWF Cont1
MOVF Cont2A,W
MOVWF Cont2
MOVF Cont3A,W
MOVWF Cont3
MOVF Cont2A,W ; En caso de que realmente se haya presionado un boton
MOVWF Cont1A ; Rotacion del display
MOVF Cont3A,W
MOVWF Cont2A
CALL Ver_Teclado ; Veo que tecla se presiono
MOVWF Cont3A
MOVLW B'00000000' ; Pone a 0 el PORTB, esto implica que puede llegar a dispararse de nuevo la interrupcion o activarse el flag
MOVWF PORTB
INT_PORTB_AUX
BSF INTCON, RBIE ; Habilito la interrupcion nuevamente
INT_PORTB_SALIR
MOVF PORTB,W ; Leo asi me permite la limpieza del flag
BCF INTCON, RBIF ; Limpieza del flag
GOTO RETORNA
;-------------------------------------------------
;
; Funciones auxiliares de la interrupcion del TMR0
;
;-------------------------------------------------
TABLALED
ADDWF PCL,F
GOTO LED0
GOTO LED2
GOTO LED1
GOTO LED0
LED0
MOVF Cont1A,W
CALL TABLA
MOVWF PORTD
BCF PORTA,3 ; Acomode para que siempre desactive todo y luego active.
BCF PORTA,2
BSF PORTA,1
RETURN
LED1
MOVF Cont2A,W
CALL TABLA
MOVWF PORTD
BCF PORTA,1
BCF PORTA,3
BSF PORTA,2
RETURN
LED2
MOVF Cont3A,W
CALL TABLA
MOVWF PORTD
BCF PORTA,1
BCF PORTA,2
BSF PORTA,3
RETURN
;-------------------------------------------------
;
; Funciones auxiliares de la interrupcion del PORTB
;
;-------------------------------------------------
Ver_Teclado
BTFSS PORTB, 4 ; Fila 0
GOTO Fila0
BTFSS PORTB, 5 ; Fila 1
GOTO Fila1
BTFSS PORTB, 6 ; Fila 2
GOTO Fila2
GOTO Fila3 ; Fila 3 - No queda otra
Fila0
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 4 ; Columna 3
RETLW D'15'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 4 ; Columna 2
RETLW D'12'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 4 ; Columna 1
RETLW D'9'
RETLW D'1'
Fila1
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 5 ; Columna 3
RETLW D'14'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 5 ; Columna 2
RETLW D'11'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 5 ; Columna 1
RETLW D'8'
RETLW D'16'
Fila2
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 6 ; Columna 3
RETLW D'13'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 6 ; Columna 2
RETLW D'10'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 6 ; Columna 1
RETLW D'7'
RETLW D'2'
Fila3
MOVLW B'00001110'
MOVWF PORTB
BTFSS PORTB, 7 ; Columna 3
RETLW D'6'
MOVLW B'00001101'
MOVWF PORTB
BTFSS PORTB, 7 ; Columna 2
RETLW D'5'
MOVLW B'00001011'
MOVWF PORTB
BTFSS PORTB, 7 ; Columna 1
RETLW D'4'
RETLW D'3'
Ver_contraseña
CLRF PORTB
BCF Flag_pass,1
BCF Flag_pass,0
MOVF Pass1,W
MOVWF Pass_TEMP
MOVF Cont1,W
Call ver_pass
BTFSS Flag_pass,0
RETLW D'16'
MOVF Pass2,W
MOVWF Pass_TEMP
MOVF Cont2,W
Call ver_pass
BTFSS Flag_pass,0
RETLW D'16'
BSF Flag_pass,1
MOVF Pass3,W
MOVWF Pass_TEMP
MOVF Cont3,W
Call ver_pass
RETLW D'15'
ver_pass
SUBWF Pass_TEMP,F
BCF STATUS,C
; BTFSS STATUS,Z
; GOTO No_Pass
rotar
BTFSC Pass_TEMP,0
GOTO No_Pass
RRF Pass_TEMP,F
BCF STATUS,C
DECFSZ Rotar_pass,F
GOTO rotar
GOTO Si_Pass
Si_Pass
MOVLW D'8'
MOVWF Rotar_pass
BSF Flag_pass,0
BTFSS Flag_pass,1
RETURN
;---------Pone los contadores en la palabra SI)
MOVlW D'11'
MOVWF Cont2A
MOVlW D'15'
MOVWF Cont3A
MOVlW D'18'
MOVWF Cont1A
;-----------------------
BSF Flag_pass,2
RETURN
No_Pass
MOVLW D'8'
MOVWF Rotar_pass
;---------Pone los contadores en la palabr NO
MOVlW D'17'
MOVWF Cont2A
MOVlW D'16'
MOVWF Cont3A
MOVlW D'18'
MOVWF Cont1A
;-----------------------
BCF Flag_pass,0
BCF Flag_pass,2
RETURN
;----------PRENDER o APAGAR----------
ON_OFF
BTFSS Flag_pass,2
GOTO No_Pass
MOVLW B'00000001'
XORWF ONOFF,F
BTFSC ONOFF,0
GOTO ON
GOTO OFF
ON
MOVLW D'16'
MOVWF Cont2A
MOVLW D'18'
MOVWF Cont1A
MOVLW D'17'
MOVWF Cont3A
RETURN
OFF
MOVLW D'1'
MOVWF Cont2A
MOVLW D'16'
MOVWF Cont1A
MOVLW D'1'
MOVWF Cont3A
RETURN
;------------------------------------------
;--------CONFIGURAR VELOCIDADES-------------
Velocidad_1
;CONFIGURAR EL TEMA DEL PDM
BTFSS Flag_pass,2
GOTO No_Pass
;--------- Configuramos Ciclos de trabajo (%)
MOVLW D'255' ; Ciclo de trabajo 100% Restante (11)
MOVWF CCPR1L
MOVlW B'00111100' ; Habilita el MODO-PWM , Bits 4 y 5 se confugran en base al ciclo que queramps ( ver 2 bits restantes de ccpr1l)
MOVWF CCP1CON
;------------------------------------------------
MOVLW D'20'
MOVWF Cont2A
MOVLW D'19'
MOVWF Cont1A
MOVLW D'15'
MOVWF Cont3A
RETURN
Velocidad_2
;CONFIGURAR EL TEMA DEL PDM
BTFSS Flag_pass,2
GOTO No_Pass
;--------- Configuramos Ciclos de trabajo (%)
MOVLW B'10100110' ; Ciclo de trabajo 100% Restante (11)
MOVWF CCPR1L
MOVlW B'00011100' ; Habilita el MODO-PWM , Bits 4 y 5 se confugran en base al ciclo que queramps ( ver 2 bits restantes de ccpr1l)
MOVWF CCP1CON
;------------------------------------------------
MOVLW D'20'
MOVWF Cont2A
MOVLW D'19'
MOVWF Cont1A
MOVLW D'14'
MOVWF Cont3A
RETURN
Velocidad_3
;CONFIGURAR EL TEMA DEL PDM
BTFSS Flag_pass,2
GOTO No_Pass
;--------- Configuramos Ciclos de trabajo (%)
MOVLW B'01000000' ; Ciclo de trabajo 100% Restante (11)
MOVWF CCPR1L
MOVlW B'00001100' ; Habilita el MODO-PWM , Bits 4 y 5 se confugran en base al ciclo que queramps ( ver 2 bits restantes de ccpr1l)
MOVWF CCP1CON
;------------------------------------------------
MOVLW D'20'
MOVWF Cont2A
MOVLW D'19'
MOVWF Cont1A
MOVLW D'13'
MOVWF Cont3A
RETURN
;-------------------------------------------
END
Lo que tengo que hacer es manejar las RMP de cun cooler en 3 nivels diferentes, les puse uno del 100%, otro de 65% y el ultimo de 25%, Todo esto se usa con un teclado matricial ( no se si te acordas pero me ayudaste con el antirrebote en el teclado matricial hace un par de dias), bueno tambien tiene para apagar y prender, y el cooler solo se puede prender con una clave ( en este caso es 124). Faltan arreglar algunos detalles capaz, y por ultimo tengo que transmitir los datos por comunicacion en serie, que eso lo tengo que implementar. Hasta aca esta mas o menos terminado el tema de la primera parte, faltaria solo la transmicion de datos. El programa en Proteus anda mas o menos bien, lo unico que nose pone que la ejecucion NO es en tiempo real, por eso le puse el divisor del TMR0 y TMR0 al maximo que me permite y aun asi despues de unos segundos me dice que hay uso execivo de cpu y me salta el cartel que no se esta ejecutando en tiempo real, pero esto me pasaba antes , despues cuando lo hice en la protoboard en fisico anda bien, asi que calculo que ahora va a pasar lo mismo, lo unico hay una advertencia que me aparecio que nunca la vi : (SPICE DELMIN increase to 1.77e-015 due to lack of time precision) y despues salien varias asi (SPICE) transient GMIN stepping at time = 12.644 ... y me saltan varias asi , cambiando eltiempo, pero anda bien el programa.
-
Ahora recuerdo, vos querias hacer todo en las interrupciones :P, Por eso terminamos con ese codigo xD
Con respecto a la ejecucion en tiempo real, es por que le es demasiado al proteus para simularlo. No hay problema cno eso, solo que va a pasar mucho mas lento el tiempo "simulado"