Autor Tema: como modificar el ciclo de trabajo de una señal de muestreo (SPWM)  (Leído 452 veces)

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

Desconectado JARU1928

  • PIC10
  • *
  • Mensajes: 1
hola buenas tardes estoy realizando un proyecto y tengo un problema con la programacion, mi codigo debe modificar tanto la frecuencia como amplitud de mi SPWM (muestreo por matlab)
pero no altero esos parametros; tengo mi codigo pero no modifica el ciclo de trabajo por los puertos RA0...
saben si hay algo mal en mi codigo ?
les agradeceria su ayuda :)



#include <18F4550.h>
#device adc=10
#fuses PROTECT, NOLVP, PUT, NoMCLR,HSPLL, PLL5, NOWDT,
#use delay(oscillator=20000000, clock=4000000)
#define use_portd_lcd TRUE
#include <lcd.c>
int16 i;
int16  ADCR,contador;
int16 const TAp[600]=
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

#int_rtcc //DESBORDAMIENTO DEL TIMER
void desborde()
{
setup_counters(rtcc_internal,rtcc_div_2);
set_rtcc(ADCR);
output_bit(PIN_B0, TAp);
delay_cycles(2);
output_bit(PIN_B1, ~TAp);
output_bit(PIN_B2, TAp[i+120]);
delay_cycles(2);
output_bit(PIN_B3, ~TAp[i+120]);
output_bit(PIN_B4, TAp[i+240]);
delay_cycles(2);
output_bit(PIN_B5, ~ TAp[i+240]);
if(i>360)
{i=0;}
i++;
}
void main()
{
setup_counters(rtcc_internal,rtcc_div_2);
set_rtcc(0);
enable_interrupts(int_rtcc);
enable_interrupts(global);
setup_adc_ports (all_analog);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(AN0);
contador = 50;
lcd_init();
lcd_putc("\f \t SPWM ");
lcd_putc("\n Inicializando ");
delay_ms(500);
do
{
set_adc_channel(0);
ADCR=(read_adc()/10-2);
if(ADCR<1)
 {ADCR=0;}
if(input(PIN_B6)==0)
 {delay_ms(10);
 contador = contador + 10;
 if(contador>240)
 {contador = 60;}
}
if(input(PIN_B7)==0)
 {delay_ms(10);
  contador = contador - 10 ;
 if(contador <60)
 {contador = 240;}
}
printf(lcd_putc,"\fFrec= %LdHz ", ADCR);
printf(lcd_putc,"\n Amp= %Ld %%",contador);
delay_ms(100);
 }
 while(true);
}
« Última modificación: 23 de Julio de 2019, 20:48:54 por JARU1928 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 7813
Re:como modificar el ciclo de trabajo de una señal de muestreo (SPWM)
« Respuesta #1 en: 24 de Julio de 2019, 17:55:48 »
Despues de leer el codigo me doy cuenta que estas compicado con varias cosas....

Me refiero a :

- No comprendes que es un PWM o al menos no te das cuenta como es que funciona (menos aun un SPWM )... Podes tener la interrupcion del Timer quien es el que te va a dar el periodo, o en el caso que sea MUCHO mas rapido cada uno de los pasos (que te da la division del duty cycle) - lo cual no creo -... Pero lo que obviamente necesitas modificar son los tiempos... en realidad mas especificamente el duty, la frecuencia no deberia variar y la amplitud varia con el duty... Por lo tanto es el duty nomas.

- Otro problema es el lenguaje C, ver cosas como estas:
Código: C
  1. output_bit(PIN_B0, TAp);
  2. output_bit(PIN_B1, ~TAp);
  3. if(i>360)
  4. {i=0;}
  5. i++;
Hacen ver que no estas muy seguro de trabajar con arrays, debido a que las primeras 2 instrucciones seguramente no tienen el efecto que VOS estas esperando.
Y las ultimas instrucciones no te estas dando cuenta de que i jamas va a ser 0 de nuevo. Lo va a ser una sola ves (al inicio).

- Lo de la variable contador no tiene sentido en tu main,
Y la lectura del ADC podria reemplazarse por un simple:
Código: C
  1. if(read_adc()<30)

- Deverias revisar el datasheet de tu microcontrolador y podrias ver que tenes un PWM a tu disposicion y que cargando un simple valor sobre un registro modificas el duty del mismo.

-------------------------------------------------------

Entonces... Como el código no ayuda demasiado...

Te sugiero que especifiques justamente que es lo que tratas de hacer. El esquematico mínimo para mostrar las partes esenciales de tu proyecto, por ejemplo no se que es B1,B2,etc, me refiero a que alimentan esos pines, que activan. El LCD es un extra que no tiene demasiado sentido... por ahora para trabajar asi que eso queda fuera de cuestion....

Yo creo que si haces bien el trabajo, usas el PWM del PIC. tendrías un código algo así:

Código: C
  1. // include,fuses, etc
  2.  
  3. // var globales y constantes (array valores de dutys)
  4.  
  5. #INT_CCP1
  6. void intccp1(void){
  7.   set_duty(arrayduty[i]);
  8.   // correccion de indice
  9. }
  10.  
  11. void main(void){
  12.   // Configuracion modulos: CCP (PWM ), Timer para el CCP
  13.  while(1);
  14. }
  15.  

Esto suponiendo un SPWM que no posea un feedback, de poseer un feedback para modificar el duty, ya vas a tener que manejarte con ADC e influir en el duty dependiendo de la lectura del ADC. Nuevamente considero ir paso a paso sea lo conveniente por lo tanto:

- Investiga sobre el PWM de tu microcontrolador, como funciona que debo cargarle, etc.
- Calcula con el MATLAB los valores de duty que debas cargarle a los registros del duty..... Estos valores dependen del valor cargado para la frecuencia, por lo tanto es necesario entender el  punto anoterior si o si.
- Crear el codigo
- Probar hasta que funcione esta parte. Al menos en la salida.

Si ya despues necesitas exitar 4 MOSFET se va a extender a eso... Pero por ahora con una simple salida, deberia bastar... Observaras cuando leas el datasheet, que el mismo PWM ofrece la capacidad de manejar un push-pull, o un H-bridge hasta con un dead-band delay.
« Última modificación: 24 de Julio de 2019, 18:08:33 por KILLERJC »


 

anything