Autor Tema: Dudas sobre tiempos (delay) y periodo PWM  (Leído 3500 veces)

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

Desconectado r00lz_ness

  • PIC10
  • *
  • Mensajes: 20
Dudas sobre tiempos (delay) y periodo PWM
« en: 30 de Abril de 2009, 08:30:59 »
Buenas, soy nuevo en esto y supongo que mis dudas seran bastante básicas pero llevo tiempo dándole vueltas y no encuentro solución. Explico primero mi programa y de que va para que se entienda bien y luego especifico mis dudas.

Estoy haciendo un proyecto sobre un seguidor solar que se autoposiciona y primero estoy probando con programas para simular lo que hará el seguidor. El seguidor solar para autoposicionarse se ayuda de 2 sensores colocados perpendicularmente entre si para saber si el seguidor, por ejemplo, tiene que girar hacia la izquierda o hacia la derecha (dependiendo donde tengamos menos luz); la comparación se hace mediante una tensión de referencia 2.5V y si el sol esta más a la derecha o más a la izquierda pues al puerto analógico le llegará un valor menor de 2.5V o mayor de 2.5V y entonces tendrá que encender un LED y sacará un PWM con un duty cycle u otro para mover el motor hacia al derecha o hacia la izquierda. El seguidor consta de Finales de Carrera para que no se exceda en posición; cuando un final de carrera se pone a estado alto se paran el motor (los dos LED's).

No detallo el control del motor o la obtención de la señal analógica a comparar porque como he dicho, este es un programa de prueba y no el programa real y la información esta es irrelevante a mi parecer.

Detallo los pines:
B7 y B6: Finales de Carrera
B1 y B3: motor a izquierda y motor a derecha
AN0: entrada analógica de 0 a 5 V

Programa:

#include <16F877.h>
#device adc=10      // resolución 1024 bits del ADC, 512=2.5V

#FUSES HS      // configuración fusibles
#FUSES NOWDT
#FUSES NOBROWNOUT
#FUSES NOPROTECT
#FUSES NOPUT
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT
#FUSES NODEBUG

#use delay(clock=16000000)  // reloj externo utilizado

#use fast_io(A)
#use fast_io(B)

#byte port_a=5
#byte port_b=6

#org 0x1F00,0x1FFF{} // para proteger el código

// inicializacion variables

float value1=0x00;
int i=0;


// subrutina de lectura del ADC

void lectura_adc(){            //función de lectura del ADC y su respectiva configuración
   setup_adc(ADC_CLOCK_INTERNAL);
   delay_ms(1);
   setup_adc_ports(AN0);
   delay_ms(1);
   set_adc_channel(0);
   delay_ms(1);
   value1=(float)read_adc();
   delay_ms(1);
   setup_adc(ADC_OFF);
}

//main

void main(){               //configuración PORTA y PORTB, timer2 (para el periodo del PWM) y el módulo CCP como PWM

   set_tris_a(0xFF);   
   set_tris_b(0xF0);
   setup_timer_2(T2_DIV_BY_16,255,16);
   setup_ccp1(CCP_PWM);

inicio:

while(i!=20){      //parpadeo de 2 LED's cada 250ms, durante un total de 10S ((250ms+250ms)*20)
bit_set(port_b,1)
delay_ms(250);
bit_clear(port_b,1);
bit_set(port_b,3);
delay_ms(250);
bit_clear(port_b,3);
i++;
}
i=0;


do{
   while((!input(PIN_B6))&&(!input(PIN_B7))){      // mientras no se produzca las "interrupciones" a estado alto del PIN B6 o el B7 haz:

   lectura_adc();

   if(value1<(512)){               // si el valor del ADC está por debajo de 2.5V haz:
   bit_clear(port_b,3);      
   delay_ms(1);
   bit_set(port_b,1);
   delay_ms(1);
   set_pwm1_duty(51);               // duty cycle del PWM del 20%
   }
   
   if(value1>=(512)){               // si el valor del ADC está por encima o igual a 2.5V haz:
   bit_clear(port_b,1);   
   delay_ms(1);
   bit_set(port_b,3);
   delay_ms(1);
   set_pwm1_duty(204);               // duty cycle del PWM del 80%
   }

   delay_ms(5000);                  // delay 5s
}   
                        // si se produce la "interrupción" de B6 o de B7 haz esto:
   bit_clear(port_b,1);
   bit_clear(port_b,3);
   
   delay_ms(5000);                  // delay 5s
   goto inicio;

      }while(TRUE);
}


Las dudas:

1. Este programa ha sido compilado y cargado al PIC y funciona salvo que cuando ha hecho la comparación  los delays no son de 5s como yo he puesto sino que si se da una condicion me tarda cosa de unos 10s u 11s y si se da la otra me tarda menos de 5s. También cuando el pin B6 o B7 se ponen a estado alto el tiempo que tarda para volver a inicio: es menor a 5s.
Alguien me puede decir a que se deben esas variaciones de tiempo? Existe alguna manera de saber el tiempo real que tardará en frente al valor que le de al delay_ms(X)?

2. El periodo del PWM que tengo segun la configuracion del timer2 (no lo he calculado, sino que me lo han dicho) es de 1 ms visto en un osciloscopio, ahora bien, he buscado como calcular el periodo del PWM para variarlo. Se que mi preescaler y postscaler son 16 pero no m salen los cálculos.
La fórmula es esta verdad? --> Tpwm=[(PR2)+1]*4*Tosc*(PMR2 valor preescalado)
Que cojo como Tosc? Y como PR2 y PMR2?

3. Se que la lecutra de cada instrucción del PIC dura 200ns pero he estado buscando en el datasheet y nose cuanto puede durar por ejemplo activar el ADC o leer el ADC (read_adc()). Como puedo saber cuanto dura cierta instrucción para poner posteriormente un delay tal que de tiempo a acabarse la instrucción anterior y que empiece la siguiente sin problema?



Espero no haber sido muy pesado y que mis dudas sean de ayuda para alguien más. También decir que he utilizado el buscador y no he visto alguna duda como la mía. Como ya he dicho soy princpipiante en esto de la programación de PIC's y espero que alguien me pueda dedicar unos minutillos para aclararme.

Muchas gracias de antemano. Hasta pronto.


Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Dudas sobre tiempos (delay) y periodo PWM
« Respuesta #1 en: 30 de Abril de 2009, 09:09:09 »
Bueno, en C estas indicando que el oscilador que estas utilizando es de 16MHz, y al hacer un delay_ms() te realiza la rutina automáticamente. Si tú realmente estas utilizando ese valor en el oscilador no deberías tener problemas como los que has comentado.
Para el cálculo del periodo del PWM se utiliza la fórmula que mostrastes.  PR2 puede tomar cualquier valor entre 0 y 255, Tosc=1/16MHz, PMR2 es el preescaler del timer2, ósea que puede tomar los valores 1:1, 1:4 y 1:16. Pero tu necesitas cambiar la frecuencia o el ciclo de trabajo?
En C es difícil determinar cuanto dura cada instrucción, yo particularmente cuando he necesitado determinar estos tiempos, lo hago simulando y determinando cuantas instrucciones se ejecutan, o utilizando un osciloscopio y generando un pulso para poder medirlo. El pulso seria seteando una salida al comenzar la instrucción a medir y reseteándola cuando sale.
« Última modificación: 30 de Abril de 2009, 09:11:43 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado r00lz_ness

  • PIC10
  • *
  • Mensajes: 20
Re: Dudas sobre tiempos (delay) y periodo PWM
« Respuesta #2 en: 04 de Mayo de 2009, 05:02:53 »
Tengo que variar el periodo y con la fórmula no me dan los resultados. El valor preescaler de, por ejemplo, 1:16 es 1/16?

Los problemas de delay_ms que no son reales del todo ya lo tuvieron compañeros mios. Ellos por ejemplo, para hacer un delay de 1 minuto, en vez de poner delay_ms(60000) ponian delay_ms(65555) o un valor muy parecido a ese. Y yo simplemente quiero saber el porque, si alguien me peude ayudar por favor...

Y gracias por la información del cálculo de cada instrucción, me ayudará, aunque me podrías decir tu que instruccion de mi programa podria tardar más en ejecutarse? Cual intuyes que tardaría más vaya.

Muchas gracias y a ver si alguien más me puede echar una mano.

Saludos.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Dudas sobre tiempos (delay) y periodo PWM
« Respuesta #3 en: 04 de Mayo de 2009, 10:45:13 »
Primero que nada el cálculo del periodo se hace como habíamos dicho con la siguiente fórmula:
\mathrm{Periodo PWM}=\left(\mathrm{PR2} + 1 \right)\cdot 4\cdot\mathrm{Tosc}\cdot\mathrm{TMR2 Preescaler}
\mathrm{Frecuencia PWM}=\frac {1}{\mathrm{Periodo PWM}}
PR2 entre 0 y 255
Tosc= 1/16MHz = 62.5 ns
TMR2 Preescaler= 1:1, 1:4, 1:16 -> x1, x4, x16
Con estos valores el rango de frecuencia de la señal PWM es:
4MHz a 976.56 Hz.
4Mhz = 1 / { (0 + 1) . 4. 62.5ns . 1 }   y   976.56 Hz = 1 / {(255 + 1) . 4 . 62.5ns . 16}

El tema del error de temporización no se que decir, nunca tuve problemas al respecto.  :?

Y este sector del código:
 
Citar
void lectura_adc(){            //función de lectura del ADC y su respectiva configuración
   setup_adc(ADC_CLOCK_INTERNAL);
   delay_ms(1);
   setup_adc_ports(AN0);
   delay_ms(1);
   set_adc_channel(0);
   delay_ms(1);
   value1=(float)read_adc();
   delay_ms(1);
   setup_adc(ADC_OFF);
}

se puede cambiar y quedar así:
Código: C
  1. void lectura_adc(){            //función de lectura del ADC y su respectiva configuración
  2.    set_adc_channel(0);
  3.    delay_us(20);
  4.    value1=(float)read_adc();
  5. }

Esto colocarlo al principio de main:

Código: C
  1. setup_adc(ADC_CLOCK_INTERNAL);
  2. setup_adc_ports(AN0);

Y no apagarlo nunca.


Las instrucciones que más demoras son:

value1=(float)read_adc();
if(value1<(512)){
if(value1>(512)){
No contesto mensajes privados, las consultas en el foro

Desconectado r00lz_ness

  • PIC10
  • *
  • Mensajes: 20
Re: Dudas sobre tiempos (delay) y periodo PWM
« Respuesta #4 en: 06 de Mayo de 2009, 04:56:35 »
Muchas gracias Suky.
Respecto a las demoras que no me las hace correctamente, pregunté a un profesor de mi universidad y me dijo que seria problema del reloj que n lo tendria bien calibrado, pero como pongo utilizo un cristal oscilador de 16MHz y lo configuro como tal, asi que no deberia haber problemas. También me dijo que sino, programara que los delays lso hiciera otro timer, puede ser? Como se hace eso?

Muchas gracias.

Desconectado r00lz_ness

  • PIC10
  • *
  • Mensajes: 20
Re: Dudas sobre tiempos (delay) y periodo PWM
« Respuesta #5 en: 06 de Mayo de 2009, 07:15:58 »
Otra pregunta, cuando sé yo cuando se precisa un delay? Y cual seria el valor más correcto a poner en el delay cuando lo precise?

Muchas gracias otra vez.


 

anything