need 2 pwm pulses of 50hz with 180 degree phase shift

Status
Not open for further replies.

aqildad

Member level 2
Joined
Jun 8, 2014
Messages
46
Helped
1
Reputation
2
Reaction score
1
Trophy points
8
Visit site
Activity points
269
micro controller : pic16f7x
software : mikro c pic pro

my problem is pwm library of mikro c pic do not support low frequency & phase shift but i need 2 pwm pulses of 50hz with 180 degree phase shift with respect to each other .

please suggest the simplest idea how to achieve this task ???

i have achieved a single pwm pulse of 50hz using interrupt but i am confused how to get second pulse with 180 degree phase shift ??? how will it possible ? ?
 

hello,

I tested the soluce with 2 timers
Timer0 interrupt every 40µS
Timer1 interrupt every 20mS
ADC reading is done inside Timer1 interrupt ,wich arme Output RA4 to 1 and Output RA2 to 0
Timer0 count until it reach the value of ADC divided by 2 .. so 0 to 512
and some limits are applide on duty value : mini=10 and maxi=490

During my test i observed that signal overtimes 20mS at maxi=400 instead to keep inside 20mS at 490 value ...
I tested it using Logic Anlayser of Pickit2 .. see results..
I search why this difference ...
20mS = 40µS * 500 ! 20% of difference with value 400 !



i find out the problem: it was because i reloaded TMR0 16 bits value at the end of interrupt instead of beginning..
so i added some extra times elapsed by instruction inside this interrupt... so time was > 40µS !
Just moved relaoding of timer0 in the beginning of interrupt
and Now i can cover a duty value from 10 to 490 and good result.. check with oscilloscope..

and output RA2 is complementary of output RA4..
Be carreful RA4 is open collector output.

the code in MikroC with 18F258 at 20Mhz

Code:
// 1 aout 2014
//MikroC Pro C for PIC version  6.40 enregistree!
//    PIC18F258  28 pins

#include "built_in.h"     // for  Hi  Lo ..etc

#define Versus "140801"
#define PROCESSOR 18F258
#define POWER_SUPPLY  DC_5V
#define FOSC 10.0  // MHz
#define BAUD 19200  // UART1
#define CLS 12
#define CR 13
#define LF 10
#define TAB 9
#define BACK 8
#define Beep 7
#define Separator 0x20   // space

const code char mesg0[]="Mikroc pro 6.40 18F258+  IT UART1 + IT Timer0 & Timer1\n\r";
const code char mesg1[]="Version : "Versus"\n\r";
const code char * Messages[]={mesg0,mesg1};

unsigned char buffer[80];
unsigned char Tampon[32];
int Flag_Buffer;
unsigned int i1;
int Index1;
unsigned int CptErr;
volatile unsigned int Count0;
volatile volatile unsigned int Count1;
unsigned int Count2;
volatile int Flag_Timer1;
volatile int Flag_Timer2;
volatile unsigned int Duty;

int i,j,k,l;
unsigned  char TEXTE[96];
unsigned char * txt;

sbit Led_Rouge at LATA4_bit;
sbit Led_Blanche at LATA2_bit;

void Init_Hardware(void) ;
void Read_Msg_Eeprom( int depuis);
void Write_Msg_Eeprom( int Adr,const char * d1) ;
void Init_Timer0(void);
void Init_Timer1 (void);
void CRLF(void) ;
void Raz_Buffer(void) ;
void UART1_Write_CText(const char *txt);
void strConstRamCpy(unsigned char *dest, const code char *source);

//---- EEPROM PIC  bytes  ================
void Save_Msg_To_EEPROM(unsigned char * adrx, unsigned char *ptr1);
void PrintOut_Eeprom_Msg(unsigned char PtrE);  //  for 16Fxxxxx

void Interrupt_High() iv 0x0008 ics ICS_AUTO
{
   unsigned char c1;
   if  ( (TMR0IE_bit==1) && ( TMR0IF_bit==1))
   {
     TMR0L= 0xAA;
     TMR0H=0xFF;
     Count0++;
     if( Count0 >= Duty)
     {
      TMR0ON_bit=0; // stop
      Count0=0;
      TMR0IE_bit=0; // interdit IT
     // led tiree au +5V allumee
      LATA.RA4=0;
      LATA.RA2=1;
     }
     TMR0IF_bit=0;
   }
      
 if ( (RCIE_bit) && ( RCIF_bit))
   {
    c1 = UART1_Read(); // c1=RCREG; NE MARCHE PAS !!
   // traitement separe des erreurs de COM
      if (RCSTA.OERR==1)    // voir parag 16.1.26 p273
      {
       RCSTA.CREN = 0 ;
       RCSTA.CREN = 1 ;
       c1 = UART1_Read();
       c1 = UART1_Read();
       CptErr++;

       }
      if(RCSTA.FERR==1 )
      {
      RCSTA.SPEN = 0 ;
      RCSTA.SPEN= 1 ;
      CptErr++;
      }
     if (c1==CR)
      {
      Flag_Buffer=1;
      //PIE1.RCIE=0 ; //interdit IT Reception UART
      buffer[i1]=0;
      Index1=i1;
      i1=0;
      c1=0;
     }
     else
     {
        Flag_Buffer=0;
        buffer[i1]=c1;
        Index1=i1;
        i1++;
      }
   }


   // ------  timer 1  ----------------
  if  ( (TMR1IE_bit==1) && ( TMR1IF_bit==1))
   {
    // led eteinte car tiree au +5V car RA4 collecteur ouvert
      Duty=ADC_Read(0) ;
      LATA.RA4=1;
      LATA.RA2=0; // sortie complementaire
    //  CHS2_bit=0;   CHS1_bit=0; CHS0_bit=0;
    //  Duty=ADC_Get_Sample(0);

      Duty=Duty >>1;
      if(Duty<10) Duty=10;
      if(Duty>490) Duty=490;
      TMR1H= 0x9E; // Hi (40535);   // 40535 * 4 *0.2 =20 000µS  20mS @20Mhz
      TMR1L= 0x57; // Lo (40535);
      PIR1.TMR1IF=0;
      TMR0ON_bit=1;
      TMR0IE_bit=1;
   }

 }

You can remove all UART part .. it is just for cheking the behavior of ADC..
You can see that MCU can do other job.. in particular : waiting 1 seconde
and signal is allways actif..
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…