sábado, 4 de mayo de 2013

PIC12F629, 3 Canales PWM y algunas pruebas.

Hola a todos. El proyecto, como se deduce del titulo XD, se trata de obtener 3 canales PWM con un PIC12F629.

La idea es usar este circuito para comandar 3 cooler de una PC. Si bien es mas fácil hacerlo con tres 555, o con dos 556 y podría aumentarse a 4 canales. La idea era probar si se podía hacerlo con el micro para, mas que nada, ir aprendiendo en el camino, así que acá los resultados que obtuve de las experiencias.

Al principio, la idea, era tratar de obtener la mayor frecuencia de salida para evitar el ruido generado en los motores. De usarse para manejar LEDs, por ejemplo, no hubiese sido necesario. Pero este no era mi caso.
Como no podía usar un cristal para usar la máxima frecuencia (20Mhz) tuve que usar el oscilador interno (4Mhz) y de ahí el primer ensayo: ¿ Que frecuencia máxima podía sacarle al oscilador interno ?

Microchip graba en los micros que poseen oscilador interno, un valor de configuración, de usarse ese valor la frecuencia de oscilación es de 4Mhz 1%. ¿ Pero que pasa si se carga otro valor ? la frecuencia varia, en mi caso y con las pruebas que hice logre llevarlo a 1,43 Mhz máximo aproximadamente (5,7Mhz). En el otro extremo 890Khz aprox (3,56Mhz). Así que en un principio "overclokee" el oscilador para que me de la máxima frecuencia. Esto se logra de la siguiente forma:

movlw    0xFC            ; Los primeros 2 bit son ignorados por el micro.
movwf   OSCCAL
Dado que tenia que variar la velocidad de los motores necesitaba una método para decirle al micro que hacer. Con 5 pines de entrada/salida y uno que es solo de entrada había que optimizar las cosas un poco.
El método que emplee es con 3 pulsadores. Complicando un poco las cosas logre hacerlo funcionar de la siguiente manera:

Presionando un pulsador se selecciona uno de los motores y mientras se mantiene presionado con lo otros dos pulsadores se aumenta o disminuye la velocidad.

Ejemplo: Mantengo presionado el pulsador 1 con lo que selecciono el primer motor.
Si presiono ahora el pulsador 2 aumento la velocidad.
Y si en cambio presiono el tercer pulsador la disminuyo.

Ahora estaba el tema del programa, con todo lo que ensaye no logre sacarle mas de 2Khz en la señal del PWM. Sabia que no le sacaría mas así que de nuevo a investigar.
Buscando encontré el siguiente texto de microchip al respecto que da algunos consejos.

http://ww1.microchip.com/downloads/e...tes/00771b.pdf

Finalmente me decante por usar un capacitor a masa en la salida del transistor de potencia. Debido a la inercia del mismo cooler comprobe que era mejor usar una baja frecuencia de PWM. Jugando con los valores me quedo bastante decente. En el diagrama dichos capacitores no están, estos van entre colector y masa y su valor depende de la frecuencia del PWM y del cooler con lo que hay que experimentar hasta encontrar el valor correcto.

En el programa esta implementado un sistema que guarda el valor de las velocidades de los motores en la memoria EEPROM del micro. A medida que se modifica algún valor se guarda en la memoria.
Cuando se alimenta el circuito lee los valores almacenados y empieza desde ahí.
La primera vez que se usa el programa tiene los valores en 0.

El diagrama que uso es este:



Así como esta implementado en C y en el programa que subí la resolucion es de 40 pasos entre 0-100%, osea tiene un incremento de 2,5%. Con eso la frecuencia de salida esta en el orden de los 725hz.
Si reduzco la cantidad de pasos a 15 por ejemplo, osea incrementos de 7% aprox la frecuencia sube hasta los 1,8Khz.

La cantidad de pasos esta en la siguiente linea:

#define VelMax  40            // Velocidad máxima
También había probado con hacer la parte de la interrupción (la que maneja el pwm) en ensamblador con lo que llegue a 2,1Khz con una resolución de 15 pasos. Para el que lo quiera solo hay que reemplazar toda la parte de la interrupción por esta:


void interrupt isr()  // Interrupcion
{
    #asm
        bcf        0x0B, 2            // TOIF = 0;


        movf    _VelMot1, w
        subwf    _VMI1, w
        
        btfsc    0x03, 2
        goto    M1
        bsf        0x05, Mt1
        incf    _VMI1, f        
        goto    M1a
    M1:
        bcf        0x05, Mt1
    M1a:

        movf    _VelMot2, w
        subwf    _VMI2, w
        
        btfsc    0x03, 2
        goto    M2
        bsf        0x05, Mt2
        incf    _VMI2, f        
        goto    M2a
    M2:
        bcf        0x05, Mt2
    M2a:

        movf    _VelMot3, w
        subwf    _VMI3, w
        
        btfsc    0x03, 2
        goto    M3
        bsf        0x05, Mt3
        incf    _VMI3, f        
        goto    M3a
    M3:
        bcf        0x05, Mt3
    M3a:

        decfsz    _Cuenta, f  
        goto    M4               
        movlw    VelMax
        movwf    _Cuenta     
        clrf    _VMI1            
        clrf    _VMI2            
        clrf    _VMI3            
    M4:
        movlw    ValTMRO
        movwf    0x01          
    #endasm
}


































Como en mi caso era mejor usar baja frecuencia de PWM por el tipo de carga que manejo (Cooler) incremente la resolucion a 40 y deje el valor de calibración del reloj a 4Mhz. Para la máxima frecuencia hay que agregar el siguiente código al principio de la funcion Main():


OSCCAL = 0xFC;
También se me ocurrió una variante para ver si llego a 20Khz de PWM y es usando la RAM para guardar las salidas. Hay que tener presente que en 20Khz solo hay 50us para hacer todo y ya se pierde 2us en ir a la interrupción, 2us en volver de ella, 1us en desactivar la interrupción, 2us en cargar de nuevo el valor en el timer y 1us en activar la interrupción de nuevo. Ya con eso suma 8us. El valor del TMRO lo cargo con 252 para que me de una interrupción cada 6us (el micro pasa mas de 98% del tiempo en la interrupción). Ya con eso y haciendo cálculos a groso modo la máxima frecuencia esta en el orden de los 50Khz y aun no he incluido los tiempos de las instrucciones dentro de la rutina de la interrupción XD.

Un Vídeo del circuito en funcionamiento:



El ruido generado al extraer el capacitor que filtra la salida:




Antes que nada aclaro que esta echo para comandar 3 coolers de una PC. El programa esta echo para motores grandes, los que uso son de 12 Cm, dado su inercia motores mas chicos quizás no logren arrancar en las velocidades mas bajas.
Por si las dudas de los 3 motores ninguno es el que refrigera el Microprocesador y no lo recomiendo bajo ninguna circunstancia.

El programa posee una rutina la cual verifica si la velocidad esta en cero (Motor apagado), al subir a la primera velocidad (velocidad mínima) pone a los motores a máxima velocidad por 1/2 segundo para darles inercia, de otra forma no arrancarían.

En la placa se puede notar que faltan los capacitores de filtro, no están puesto porque aun no me convencía que valor usar. Encontré que lo mejor es usar (para el cooler que uso) uno de 220uf. Como los cables los tendré que alargar los pondré en el cooler mismo.

Algunas fotos de la placa terminada:



Y acá, para el que lo quiera, la placa con el código: Codigo.zip

La placa es la misma que use yo y por ahora no le encontré problemas. Esta echa para usar el método de la plancha. En caso de usar por ejemplo transparencias hay que hacer un espejo de la imagen.

No hay comentarios:

Publicar un comentario