Autor Tema: PWM de 50 Hz mediante hardware con 16f87x  (Leído 3873 veces)

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

Desconectado robotdoblador

  • PIC10
  • *
  • Mensajes: 6
PWM de 50 Hz mediante hardware con 16f87x
« en: 21 de Noviembre de 2007, 10:27:03 »
Hola a todos,
tengo que controlar un servomotor de radiocontrol con una precisión menor a un grado y no sé cómo lograrlo.

Utilizando un 16f84 he conseguido generar los pulsos con 10us de precisión mediante desbordamiento del tmr0. El problema es que no puedo lograr una frecuencia mayor para la rutina de interrupción debido al número de instrucciones (he tenido que añadir “nops” para ajustar los tiempos) y a la limitación de 20 Mhz del cristal (utilizo el 16f84A-20).

He pensado que podría lograrlo con un 16f87 usando el registro ccp (modo pwm) pero me he encontrado con un inconveniente:
Consigo generar el ciclo de trabajo pero no el periodo.
Con un cristal de 20 Mhz y preescalado 16 logro 3.2 us de precisión, que equivale a 0.32 grados de precisión en el posicionamiento del servomotor,  cargando el valor correspondiente en el TMR2 consigo generar el ciclo de trabajo adecuado.
Pero cuando quiero cargar el valor correspondiente para el periodo, me encuentro con que necesito una variable de 13 bits (PR2 = 6249) cuando PR2 tiene un tamaño de 1 byte (creo).

Por otra parte, no entiendo cómo para el ciclo de trabajo (la parte del periodo en que la señal está a 1) se puede cargar un valor de hasta 10 bits y para el ciclo, que siempre será mayor (unas 10 veces) sólo se permiten 8 bits.

De verdad que no se me ocurre qué estoy haciendo mal.

A continuación os envío el código con el que logré el grado de precisión con el 84.

A ver si me podéis echar una mano...

Raúl


   LIST      P=16F84A
   INCLUDE      <P16F84A.INC>
   __CONFIG   _CP_OFF &  _WDT_OFF & _PWRTE_ON & _HS_OSC

   CBLOCK  0x0C
   FactorAlto            
   Auxiliar
   Contador_Bucle2

   ENDC                  

TMR0_CARGA   EQU   -d'38'   

ALTO_CERO_GRADOS   EQU   d'610'      
TIEMPO_PATRON   EQU   d'10'   

FACTOR_MINIMO   EQU   ALTO_CERO_GRADOS/TIEMPO_PATRON

#DEFINE  Salida      PORTB,0   

; ZONA DE CÓDIGOS ********************************************************************

   ORG    0
     goto   Inicio
   ORG      .4
   goto   Timer0_Interrupcion
Inicio
   bsf      STATUS,RP0
   bcf      Salida            
   movlw   b'11111110'
   movwf   PORTB
   movlw   b'00001000'         
   movwf   OPTION_REG
   bcf      STATUS,RP0
   movlw    TMR0_CARGA
   movwf   TMR0         
   movlw   b'10100000'
   movwf   INTCON         
   movlw   .249
   movwf   Contador_Bucle2
Principal
   movf   PORTB,W
   movwf   Auxiliar
   rrf      Auxiliar,W
   andlw   b'01111111'
   addlw   FACTOR_MINIMO   
   movwf   FactorAlto      
   goto   Principal         

   
   CBLOCK   
   Guarda_W
   Guarda_STATUS
   Timer0_ContadorA      
   Contador_Bucle1
   
   ENDC

Timer0_Interrupcion
   movwf   Guarda_W         
   swapf   STATUS,W         
   movwf   Guarda_STATUS
   bcf      STATUS,RP0      
   movlw    TMR0_CARGA
   movwf    TMR0
   movf   Timer0_ContadorA,W
   andlw   b'11111111'
   btfss   STATUS,Z
   goto   Ajuste
   btfsc    Salida         
   goto    EstabaAlto
   movf   Contador_Bucle1,W
   andlw   b'11111111'
   btfss   STATUS,Z
   goto   Bucle_Interrupcion1
EstabaBajo   
   nop
   nop
   nop
   nop
   bsf      Salida            
   movf   FactorAlto,W      
   movwf    Timer0_ContadorA   
   goto    Fin_Timer0_Interrupcion
EstabaAlto
   nop
   nop
   nop
   nop
   nop      ;5
   nop
   nop
   nop
   bcf    Salida         
   movf   FactorAlto,W      
   sublw   .249            
   movwf    Timer0_ContadorA
   movlw   .7
   movwf   Contador_Bucle1
Fin_Timer0_Interrupcion
   swapf   Guarda_STATUS,W   
   movwf   STATUS
   swapf   Guarda_W,F
   swapf   Guarda_W,W
   bcf      INTCON,RBIF
   bcf      INTCON,T0IF
   retfie

Ajuste
   nop
   nop
   nop
   nop
   nop      ;5
   nop
   nop
   nop   
   nop
   nop      ;10
   nop
   nop   
   nop
   decf   Timer0_ContadorA
   goto   Fin_Timer0_Interrupcion

Bucle_Interrupcion1
   movf   Contador_Bucle2,W
   andlw   b'11111111'
   btfsc   STATUS,Z
   goto   Fin_Bucle2
   nop
   nop
   nop
   decf   Contador_Bucle2,F
   goto    Fin_Timer0_Interrupcion
Fin_Bucle2
   movlw   .249
   movwf   Contador_Bucle2
   decf   Contador_Bucle1,F
   goto   Fin_Timer0_Interrupcion


   END

Desconectado Tho0oR

  • PIC10
  • *
  • Mensajes: 18
Re: PWM de 50 Hz mediante hardware con 16f87x
« Respuesta #1 en: 17 de Enero de 2008, 18:22:01 »
Este programa no me acuerdo de donde lo saque, ni ahora puedo probar si funciona o no, se que cuando tuve que presentar un proyecto para el 873 que controlara el ancho de un impulso me funciono.
De todas formas, primero te dejo esto, sirva o no, por si acaso encuentras algo que te interesa o algo. un dia de estos dejo el programa verdadero (si este no lo es) y de paso meto una preguntilla.

Nuse si te servira, pero espero que lo haga, pero por intentarlo no se pierde nada verdad??

Un saludo y a cuidarse!


;CONTROL DE POTENCIA

;DEFINIR PIC
;***********************************************************
      List      p=16F873               
      Include   "P16F873.INC"                
      __CONFIG   _XT_OSC & _WDT_OFF      
      __IDLOCS   H'0007'
      
;DEFINIR REGISTROS
;***********************************************************
RESUL   EQU      0x30

;SALTAR VECTOR DE INTERRUPCION
;********************************************************
      ORG      0x00               
      GOTO   INICIO
      ORG      0x05               

;CONFIGURAR PUERTOS
;***********************************************************
INICIO   BSF      STATUS,RP0            
      MOVLW   B'00000000'            
      MOVWF   ADCON1            
      MOVLW   B'00011111'         
      MOVWF   TRISA            
      MOVLW   B'11111011'         
      MOVWF   TRISC               
      
      MOVLW   0xAA
      MOVWF   PR2

      BCF   STATUS,RP0            
      MOVLW   B'00001100'            ;PROGRAMAR CCP1 (PWM)
      MOVWF   CCP1CON         

      
      MOVLW   B'00000110'            ;ACTIVAR  TMR2
      MOVWF   T2CON         
      MOVLW   B'11011001'            ;PROGRAMAR MODULO A/D
      MOVWF   ADCON0            

RESTART   BSF      ADCON0,2            ;CONVERSION

TIME   BTFSC   ADCON0,2
      GOTO   TIME               ;ESPERA

;GUARDAR RESULTADOS
;***********************************************************
      MOVF      ADRESH,W            
      MOVWF      RESUL            

      MOVF      RESUL,W            
      MOVWF      CCPR1L

      GOTO      RESTART

      NOP
      NOP
      END

Desconectado hernanleocb

  • PIC10
  • *
  • Mensajes: 2
Aprender
« Respuesta #2 en: 09 de Septiembre de 2008, 13:45:57 »
 :)Hola, soy nuevo en el foro, estoy tratando de aprender a usar el TIMER0 del 876A pero no tengo practicamente nada en castellano que me de una mano, e leido la hoja de datos del PIC y e podido entender ciertas cosas per se me complica un poco con el ingles. si se pudiera darme una manito lo voy a agradeces muchisimo... el fin de todo esto es haces un cuenta revoluciones de hasta 25000 rpm mas o menos, y anexarlo a un programa que mas adelante mostrare con mas tiempo...

muy agradecido y saludos... :mrgreen:

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: PWM de 50 Hz mediante hardware con 16f87x
« Respuesta #3 en: 22 de Septiembre de 2008, 16:40:50 »
http://www.alos.5u.com/indexpic877.htm
A ver si esto te vale es de 16f877 pero creo que comparten muchas caracteristicas.
suerte tapi8

Desconectado DPPIC

  • PIC10
  • *
  • Mensajes: 12
Re: PWM de 50 Hz mediante hardware con 16f87x
« Respuesta #4 en: 11 de Octubre de 2008, 07:48:37 »
Hola que tal, yo he echo lo mismo que tu, me explico para controlar el servo tienes varias opciones:

Bajar la velocidad de 16f84 del oscilador  a 2Mhz, con lo que te da menos velocidad de proceso pero mas precision en la señal para el servo.

Con el 873 puedes utilizar el puerto PWM en modo comparacion cargando los tiempos para el nivel alto y bajo en los registros , y configurando el PWM como comparador, una vez activas la salida y una vez activada configuras la salida para que cuando haga la comparacion la desactive.

co 12f629 puedes hacerlo con la interrupcion del tmr0, con el preescaler en division de 128 ,pues este funciona a 3Mhz. Espero que te ayude en algo

Desconectado DPPIC

  • PIC10
  • *
  • Mensajes: 12
Re: PWM de 50 Hz mediante hardware con 16f87x
« Respuesta #5 en: 12 de Octubre de 2008, 19:19:11 »
Hola de nuevo, en mi anterior respuesta hay un par de errores, cuando dije que el 629 va a 3Mhz es en realidad a 4 Mhz y con un preescaler de 8 consigues un total de 2048 Micros seg, que son el tope de los servos, cargando valores al tmr0 consegiras un total de 255 posibles posiciones del servo, teniendo cuidado de no llevar a este al tope mecanico, empieza cargando 125 y de ahi para arriba o abajo.

El caso del 873 tienes que usar el modulo ccp .