Generar PWM con 12F675

Buenas amigos,

Tengo un micro 12f675, quiero generar una PWM, pero este micro no tiene para generar PWM por lo tanto hay que hacerlo por software, cosa que me ha estado causando problemas ya que el el ciclo que variando y pareciera variar en frecuencia también...

Utilice distintas estrategias sin resultados favorables, si alguien tiene alguna idea le agradezco. Vale recalcar que trabajo en lenguaje C.
 
distiintas estrategias? cuales has pensado? en ese pic la unica manera viable que hay de hacer un pwm es con un timer, y ese pic tiene 2. Simplemente tienes que ir cambiando en cada interrupcion el tiempo de recarga.
Un saludo
 
Bueno hice comparaciones con el timer0 activando en bajo o en alto si era mayor que el valor actual del timer, use las interrupciones, use el timer1 y el timer0... y bueno...

Otro cosa que me falto decir, es que necesito que el que este pwm sea regulable por un valor leido por un puerto adc.
 
a ver, es bastante sencillo. . si quieres una señal de 1KHz, el periodo es de 1ms, pues para un ciclo de trabajo del 50% cargas en el timer 500ns, cuando salta la interrupcion, pues cargas 1ms-500ns, para un clclo del 80%, pues para ton cargas 800ns, y para toff cargas 1ms-800ns. de esta forma es variable.
para hacer lo del adc simplemente es una regla de 3, para una lectura de 1024 (el conversor es de 10 bits) haces que la salida sea de 100, y para una lectura de 0, un ciclo de trabajo 0%.
Yo tengo hecho un programa asi pero con el pic18f con el modulo CCP.
Un saludo
 
Entiendo amigo, eso es lo que he estado intentando hacer... De hecho el PWM con los micro 18f no tengo problema, la cuestión es que con los retrasos generador por cada instrucción hacen que el "PWM" varie mucho es decir nunca queda estable siempre esta como dando saltos... ese es el problema... :/

Igual gracias por responder...
 
pero es que no hay otra forma de hacerlo, de todas formas lo que pueda variar va a ser muy poco, estamos hablando de 3 instrucciones? (dentro de la interrupción), una para saber si estamos en nivel alto o nivel bajo, otra para escribir en el registro. La adquisición de datos del adc lo puedes hacer en el programa principal que seguro que te da tiempo de sobra, es decir puedes ir leyendo el adc continuamente, y cuando entre en la interrupción tan solo escribir los nuevos valores, incluso el calculo de ton y toff podrías hacerlo en el principal.
Un saludo
 
Eso pensé, pero de verdad que no funciona bien... voy a esperar probar con un osciloscopio porque en simulación con proteus no se ve muy bien...
 
Eso pensé, pero de verdad que no funciona bien... voy a esperar probar con un osciloscopio porque en simulación con proteus no se ve muy bien...

En la versión de Proteus que yo uso, el 12F629 (hermano menor del 12F675) directamente NO FUNCIONA, así que tengo que probar los algoritmos en el 16F84A o alguno superior y luego adecuar los resultados...
 
Hola
Utilizando la interrupción del timer0,seria algo parecido a esto,obtienes un pwm que puedes variar de 0 a 255 con la varible duty.

PHP:
#int_RTCC
void  RTCC_isr(void) 
{
ciclo++;
      if(ciclo==0)
         port_a.1=1;

      if(ciclo==duty)
         port_a.1=0;
set_timer0(frecuencia);
}

Un saludo,
 
Última edición por un moderador:
Buenos días a todos.

Lo que estoy intentando hacer es programar un PIC12F675 para obtener dos señales PWM (en la salida 0 y 5). Para ello utilizo 4 interruptores para variar el duty. Ya que mi sistema tiene dos entradas y para mejorar la conversión D/A, agrupe los switch de dos en dos por lo que tengo 4 posibilidades para cada pareja de interruptores.

Generar una única PWM con 2 o con los 4 switch, no hay problema pero no acabo de ver porqué, con el código que adjunto, no soy capaz de generar 2 señales PWM con diferentes duty en función de la combinación de los interruptores.

Por otro lado me gustaría que las señales PWM tuvieran una frecuencia superior. Ahora mismo, lo máximo que conseguí son poco más de 3kHz.

Vengo del mundo de los autómatas por lo que me estoy moviendo por terreno nuevo con los PIC por lo que agradecería vuestros comentarios.

Muchas gracias.
CSS:
#include<12f675.h>

#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
//#define GPIO 0b011110

#FUSES NOWDT, HS, NOMCLR
#use     delay(internal = 4MHz)

#define timer_max 225

int8 ciclo = 1;
int8 ciclox = 1;


#INT_TIMER0

               
void timer0_isr(int cicloa,int ciclob)
{
   int8 contador;
   set_timer0(timer_max);          
 
   if(contador == 0)            
   {
      contador = 4;
   }
   else
      contador --;
   if ((contador>0)&&(contador<cicloa))
      {
      output_high(PIN_A0);
      }
   else  
      output_low(PIN_A0);        
 
   if ((contador>0)&&(contador<ciclob))
      {
      output_high(PIN_A5);
      }
   else  
      output_low(PIN_A5);  
 }

void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_bit);
   enable_interrupts(INT_TIMER0);          
   enable_interrupts(GLOBAL);  

   while(true)
   {
     
      if((input(PIN_A1)==1)&&(input(PIN_A2)==1))
      {
      ciclo = 3;  
      }
     
      if((input(PIN_A1)==1)&&(input(PIN_A2)==0))
      {
      ciclo = 2;  
      }
     
      if((input(PIN_A1)==0)&&(input(PIN_A2)==1))
      {
      ciclo = 1;  
      }
     
      if((input(PIN_A1)==0)&&(input(PIN_A2)==0))
      {
      ciclo = 0;  
      }
     
     
      if((input(PIN_A3)==1)&&(input(PIN_A4)==1))
      {
      ciclox = 3;  
      }
      if((input(PIN_A3)==1)&&(input(PIN_A4)==0))
      {
      ciclox = 2;  
      }
      if((input(PIN_A3)==0)&&(input(PIN_A4)==1))
      {
      ciclox = 1;  
      }
      if((input(PIN_A3)==0)&&(input(PIN_A4)==0))
      {
      ciclox = 0;  
      }
     
      timer0_isr(ciclo,ciclox);
   }
}
1627302054046.png
 
Atrás
Arriba