Autor Tema: Configurar PWM para motor DC  (Leído 2411 veces)

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

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Configurar PWM para motor DC
« 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:
Código: [Seleccionar]
;-------------------------------------------------
;
;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.

Desconectado groundman

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1870
    • www.ingeniopic.com
Re: Configurar PWM para motor DC
« Respuesta #1 en: 30 de Mayo de 2015, 17:50:33 »
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.
Montando mi primera impresora 3D (Raprep Prusa i3)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Configurar PWM para motor DC
« Respuesta #2 en: 30 de Mayo de 2015, 18:20:40 »
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.

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: Configurar PWM para motor DC
« Respuesta #3 en: 30 de Mayo de 2015, 20:46:46 »
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


Citar

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.

Citar
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

---------
Citar
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.
« Última modificación: 30 de Mayo de 2015, 20:52:21 por rosalva40 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Configurar PWM para motor DC
« Respuesta #4 en: 30 de Mayo de 2015, 23:09:40 »
Si , complica un poco el tema de no conocer el codigo, pero entiendo que no lo quieras pasar.

Citar
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).

Citar
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.



Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: Configurar PWM para motor DC
« Respuesta #5 en: 30 de Mayo de 2015, 23:37:54 »
Si , complica un poco el tema de no conocer el codigo, pero entiendo que no lo quieras pasar.

Citar
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).

Citar
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:

Código: [Seleccionar]
;-------------------------------------------------
;
;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.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Configurar PWM para motor DC
« Respuesta #6 en: 31 de Mayo de 2015, 04:16:06 »
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"