TODOPIC

Microcontroladores PIC => dsPIC => Mensaje iniciado por: ds_chip en 14 de Abril de 2006, 19:42:17

Título: Ayuda, programa que controle servos utilizando PWM
Publicado por: ds_chip en 14 de Abril de 2006, 19:42:17
Buenas: Estoy realizando un proyecto muy simple, pero en su simplicitud no soy capaz ni de empezar  :? . Lo que quiero es que haciendo uso de un 30F2010 y de sus seis pines de PWM... controlar un servomotor tipo standar, es algo sencillo, consiste en que al hacer click en uno de sus pines el motor avance y al soltarlo el motor gire mas lentamente hasta detenerse... como digo algo sencillo. El problema es que mi profesor aun no ha enseñado como hacer eso, y el si quiere que dentro de poco le entreguemos un proyecto todo complejo, por eso necesito aprender pronto. Lo que necesito en si es el inicio, como puedo programar el dsPIC para que realice lo que les comento,como funciona el modulo de PWM, como configuro, como debe llegar la señal al puente H... eso es solo un comienzo, pero aprendiendo a hacer esto y con los data sheet puedo hacer maravillas, por el momento quiero unicamente empezar.. les ruego me colaboren con esto.... es algo no de vida o muerte, pero si muy urgente.. cualquier codigo que te tengan me puede ser de gran ayuda...
Mil Gracias
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: Nocturno en 15 de Abril de 2006, 03:14:42
Dices que estás haciendo el proyecto, pero no has pegado aquí lo que llevas hecho. Si lo pegases sería más fácil ayudarte. De todas maneras te dejo lo que yo tengo.

En una ocasión estuve jugando con servos y motores, controlados desde un dsPIC. El modelo que utilicé tenía tanto módulo CCP como módulo de Control de Motores, y los probé ambos con resultado positivo.

Aquí te pego el programa, que está completamente desordenado y sin documentar; ya te digo que estuve jugando y no me preocupé por dejarlo bonito ni didáctico. No todas las funciones que están declaradas se utilizan en el main, pero quizás algunas puedan servirte.

Código: C
  1. #define __dsPIC30F4011__
  2. #include <p30f4011.h>
  3.  
  4. #include<pwm.h>
  5. #include<outcompare.h>
  6. #include<timer.h>
  7. #include <incap.h>
  8.  
  9.  
  10.   _FOSC( CSW_FSCM_OFF  & XT_PLL16);
  11.   _FWDT(WDT_OFF);
  12.   _FBORPOR(PBOR_ON  & PWRT_OFF & MCLR_DIS);
  13.  
  14. #define LED PORTEbits.RE0
  15. #define MOT1_ENABLE PORTEbits.RE1   // activado = 1, desactivado = 0
  16.  
  17. #define MOT2_ENABLE PORTEbits.RE2   // activado = 1, desactivado = 0
  18.  
  19. // Calibrado para FUTABA S-3003
  20. #define DutyMinimo      1000
  21. #define DutyMaximo      6000
  22.  
  23. #define PeriodoPWM 0x200        // 50Hz
  24.                                                 // Frecuencia = MIPS / ( (period+1) * PRESCALER)
  25.                                                 // Frecuencia = 20.000.000 / (25.000 * 16) = 50
  26.  
  27.  
  28. int Interrupt_Count = 0 , Int_flag, count;
  29. unsigned int timer_first_edge, timer_second_edge;
  30.  
  31.  
  32. int i;
  33.  /********************************************************/
  34.   void DelayUs(unsigned int v)  {    //  pierde 8+2
  35.  /********************************************************/
  36.  
  37.  
  38.    while(v != 0){
  39.  
  40.   asm("nop");asm("nop");
  41.   asm("nop");asm("nop");
  42.   asm("nop");asm("nop");
  43.   asm("nop");asm("nop");
  44.   asm("nop");asm("nop");
  45.  
  46.     v--;
  47.   }
  48.  }
  49.  
  50.  
  51.  /******************************************************/
  52.    void DelayMs(unsigned int v) {
  53.  /******************************************************/
  54.  
  55.    while (v != 0 ){ DelayUs(1000); v--;}
  56.  
  57.  }
  58.  
  59. int PWM1(int Duty)      // Módulo Output Compare Module
  60. {
  61.         T3CON =  0x8010;// activamos Timer3 con prescaler = 8
  62.         PR3 = 0xC34F ;  // frecuencia = 1 / ((PR3+1) * PRESCALER * MIPS)
  63.                                         // PR3 = MIPS / (Frecuencia * PRESCALER ) - 1
  64.                                         // PR3 = 20000000 / ( 50Hz * 8 ) - 1 = 49999 = C34F
  65.         OpenOC1 (OC_IDLE_CON & OC_TIMER3_SRC & OC_PWM_FAULT_PIN_DISABLE, 0, 0);
  66.         SetDCOC1PWM (Duty);
  67. }
  68.  
  69. int Servo1(int Grados)
  70. {
  71.         int Duty;
  72.  
  73.         T3CON =  0x8010;// activamos Timer3 con prescaler = 8
  74.         PR3 = 0xC34F ;  // frecuencia = 1 / ((PR3+1) * PRESCALER * MIPS)
  75.                                         // PR3 = MIPS / (Frecuencia * PRESCALER ) - 1
  76.                                         // PR3 = 20000000 / ( 50Hz * 8 ) - 1 = 49999 = C34F
  77.         OpenOC1 (OC_IDLE_CON & OC_TIMER3_SRC & OC_PWM_FAULT_PIN_DISABLE, 0, 0);
  78.  
  79.         Duty = (DutyMaximo-DutyMinimo)/180*Grados+DutyMinimo;
  80.         SetDCOC1PWM (Duty);
  81. }
  82.  
  83. void InicializaPWM () // Módulo de control de motores
  84. {
  85.         unsigned int period;
  86.         unsigned int sptime;
  87.         unsigned int config1;
  88.         unsigned int config2;
  89.         unsigned int config3;
  90.  
  91.  
  92.         period = PeriodoPWM;
  93.         sptime = 0x0;
  94.         config1 = (PWM_EN  & PWM_OP_SCALE1 & PWM_IPCLK_SCALE1 & PWM_MOD_FREE);
  95.         config2 = (PWM_MOD3_IND & PWM_PEN3H & PWM_PDIS2H & PWM_PDIS1H & PWM_PEN3L & PWM_PDIS2L & PWM_PDIS1L);
  96.         config3 = (PWM_SEVOPS1 & PWM_OSYNC_PWM & PWM_UEN);
  97.         OpenMCPWM(period,sptime,config1,config2,config3);
  98.         PTCON = PTCON & 0xFF03;
  99. }
  100.  
  101. void Duty (int Canal, int Porcentaje)
  102. {
  103.         unsigned int dutycyclereg;
  104.         unsigned int dutycycle;
  105.         unsigned char updatedisable;
  106.  
  107.         dutycyclereg = Canal;
  108.         // el Duty tiene un bit más que el periodo, y se rota una vez a la izquierda
  109.         dutycycle = ((int)((long)Porcentaje * (long) PeriodoPWM / (long)100)) << 1;
  110.         updatedisable = 0;
  111.         SetDCMCPWM(dutycyclereg,dutycycle,updatedisable);
  112. }
  113.  
  114. void Motor (int Canal, int Sentido, int Potencia)
  115. // Canal: 1 o 2, motor izquierdo o motor derecho
  116. // Sentido: 0 o 1, adelante o atrás
  117. // Potencia: de 0 a 100
  118. {
  119.         if (Canal==2)
  120.                 if (Sentido==0)
  121.                         PORTF= (PORTF & 0xFC) | 0x02;
  122.                 else
  123.                         PORTF= (PORTF & 0xFC) | 0x01;
  124.         if (Canal==1)
  125.                 if (Sentido==0)
  126.                         PORTF= (PORTF & 0xCF) | 0x20;
  127.                 else
  128.                         PORTF= (PORTF & 0xCF) | 0x10;
  129.         Duty (Canal, Potencia);
  130. }
  131.  
  132.  
  133. int main()
  134. {
  135.         int i, Porcentaje;
  136.  
  137.  
  138.         InicializaPWM();
  139.         Duty (3,50);
  140.         while (1);
  141.         for (i=1;i<100;i=i+10)
  142.                 {
  143.                         Porcentaje = i * PeriodoPWM / 100;
  144.                         Duty (3,Porcentaje );
  145.  
  146.                         DelayMs(1000);
  147.                 };
  148.  
  149. }
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: ds_chip en 15 de Abril de 2006, 16:46:36
Buenas Nocturno:
Ey gracias por el codigo que enviaste.... lamento decir que no me fue de mucha ayuda porque no se manejar ese codigo. Tienes razon en lo que dijiste de poner lo que llevo del codigo, a lo que debo decir que no llevo nada porque no se ni como empezar. Por cierto yo programo en MPLAb IDE y no entendi el codigo que enviaste, si puedes colaborarme de otra forma (ya  que veo que eres el que le ayuda a mucha gente por lo que asumo sabes mucho) seria de gran ayuda. por cierto, yo utilizo un 30F2010, no se si abra alguna diferencia.. y otra pregunta, el codigo en C me puede servir? es que no se como se hace. Hoy me pongo en la tarea de intentar programar los motores, cualquier duda que se me presente te la envio y para el proximo topico colocare lo que lleve del codigo, pero por el momento si me podes colaborar mil gracias.
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: Nocturno en 16 de Abril de 2006, 02:05:44
Es difícil prestarte la ayuda que solicitas, porque prácticamente quieres que te den el proyecto hecho. No sé si alguien lo tendrá por ahí y podrá facilitártelo, pero si no es así, te recomiendo que vayas haciendo cosas y poniendo las dudas.

Deduzco por tus palabras que lo harás en ASM y no en C30, así que me temo que no podré ayudarte porque el ASM me produce urticaria.

Suerte.
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: ds_chip en 16 de Abril de 2006, 10:09:13
Buenas Nocturno:
Tienes razon con lo que dijiste.... pero el proyecto que pretendo realizar consiste en un robot recoje_bolas, en un laberinto  bastante complicado.. ese es en si el proyecto que voy a realizar... tienes razon en que si quiero un proyecto hecho, pero de un control de servos utilizando el modulo de PWM del dsPIC porque como lo he dicho antes, mi profesor aun no lo ha enseñado y no se que pretende el.... En todo caso te agradezco el intento. Por cieto justo ahora pienso ponerme a programar... se que te produce nauseas el ASM  pero no hay ningua posibilidad de que me ayudes asi sea en lo mas minimo??? hoy cuando termine publico mi codigo.. espero me puedas dar una mano por mas simple que sea.. gracias
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: kain589 en 16 de Abril de 2006, 10:18:18
La verdad es que si programar en ensamblador ya es un martirio, programar en ensamblador un Dspic no me lo quiero imaginar... ¿porque no lo programas en C? si ademas los dspic estan optimizados para su programacion en C
No se si has usado antes pic's o dspic, pero si no lo has hecho seria conveniente que empezaras a programar de una forma mas progresiva

Saludos
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: hg en 13 de Febrero de 2007, 09:40:41
Hola a todos,

Tengo que controlar un motor con un microcontrolador.Estoy echándole un vistazo en al código que pusiste Nocturno y me surgen algunas dudas. Soy muy novata en microcontroladores. Conforme haga mi código y me surjan dudas espero poder contar con vuestra ayuda.

Dudas:

¿Cuáles con estas instrucciones?¿para qué sirven?
  _FOSC( CSW_FSCM_OFF  & XT_PLL16);
  _FWDT(WDT_OFF);
  _FBORPOR(PBOR_ON  & PWRT_OFF & MCLR_DIS);

Gracias por su atención
Un saludo
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: aitopes en 13 de Febrero de 2007, 10:24:41
.... pero el proyecto que pretendo realizar consiste en un robot recoje_bolas, en un laberinto  bastante complicado.. ese es en si el proyecto que voy a realizar... ... se que te produce nauseas el ASM  pero no hay ningua posibilidad de que me ayudes asi sea en lo mas minimo???

Me parece que a ds_chip lo supero la complejidad del proyecto que encaro. Este hilo deberia servir de ejemplo de no comenzar con algo demasiado ambicioso: se corre el riesgo de terminar haciendo ....nada. :(

Saludos!
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: navaismo en 13 de Febrero de 2007, 11:44:44
HG esas no son instrucciones si no mas bien ahi configura los Fuses del PIC.
Título: Re: Ayuda, programa que controle servos utilizando PWM
Publicado por: Nocturno en 13 de Febrero de 2007, 14:29:06
Efectivamente, esas son las instrucciones de C30 para la configuración del oscilador, del watchdog y del BOR, PowerOff y MCLR.