Does this code produce 60Hz sine wave? - 8051

Discussion in 'Embedded Systems and Microcontrollers' started by Anirban Raha, Oct 12, 2015.

  1. Anirban Raha

    Thread Starter Member

    Dec 4, 2013
    70
    0
    Hi,
    I have written a piece of C code for my AT89s52 to generate Sinusoidal PWM. I have taken 36 samples as you can see in the program below. Therefore, I have calulated a duty period of 230uS for each sample if the entire sinusoidal cycle (from 0 deg to 180 deg) is to be completed within (1/60 = 16.7ms). 230x36 = 8.3ms and therefore the entire cycle would be completed in 16.6ms and thus 60Hz frequency shall be achieved.
    Since I'm using a 12Mhz crystal, I have calculated one clock cycle to be equal to 1us. Using this data I have started timer 0 count from 25 in order to limit duty period to 230uS.
    I hope my above calculations are correct and that I haven't overlooked something. Kindly take a look at the following code and please tell me whether it produces a 60Hz sine wave signal? (P.S. I don't have access to any CRO or simulation software right now...so kindly help me out here)

    Code (Text):
    1. #include <REGX51.H>
    2.  
    3. //Using a 12MHz crystal. Therefore one cycle is equal to 1uS.
    4. //Therefore to acheive a duty period of 230uS for each sine sample timer counts from 25 to 255
    5.  
    6. /* Global variables and definition */
    7. #define PWMPIN1 P2_0
    8. #define PWMPIN2 P2_1
    9. unsigned char pwm_width;
    10. bit pwm_flag = 0;
    11. bit zcr=0;//zero-crossing indicator
    12. int i=0;
    13. int sin_val[36]={0,9,17,26,34,42,50,57,64,71,77,82,87,91,94,97,98,99,100,99,98,97,94,91,87,82,77,71,64,57,50,42,34,26,17,9};
    14.  
    15. void pwm_setup()
    16. {
    17.     TMOD = 0;
    18.     EA = 1;
    19.     ET0 = 1;
    20.     TR0 = 1;
    21. }
    22. /* Timer 0 Interrupt service routine */
    23. void timer0() interrupt 1
    24. {
    25.    
    26.       if(zcr==0)
    27.       {
    28.         PWMPIN2=0;
    29.         if (!pwm_flag)     /* Start of High level */
    30.         {
    31.      
    32.        TH0 = pwm_width;    /* Load timer */
    33.      
    34.     }
    35.         else             /* Start of Low level */
    36.         {
    37.         TH0 = 255 - pwm_width;    /* Load timer */
    38.         }
    39.       pwm_flag = ~pwm_flag;;    /* Toggle flag */
    40.     PWMPIN1 = ~PWMPIN1;        /* Toggle PWM o/p pin 1 */
    41.       TF0 = 0;
    42.         /* Clear interrupt flag */
    43.         }
    44.       if(zcr==1)
    45.       {
    46.         PWMPIN1=0;
    47.         if (!pwm_flag) {    /* Start of High level */
    48.      
    49.         TH0 = pwm_width;    /* Load timer */
    50.      
    51.     }
    52.         else {            /* Start of Low level */
    53.         TH0 = 255 - pwm_width;    /* Load timer */
    54.             }
    55.       pwm_flag = ~pwm_flag;;    /* Toggle flag */
    56.     PWMPIN2 = ~PWMPIN2;        /* Toggle PWM o/p pin 2 */
    57.       TF0 = 0;
    58.         /* Clear interrupt flag */
    59.        }
    60.      if(!pwm_flag) //setting next pwm_width before start of high level
    61.      {
    62.        pwm_width = 25+(sin_val[i]/100)*230;
    63.        if(i<35)
    64.          i++;
    65.        else
    66.         {
    67.          i=0;
    68.          zcr=~zcr; //[B]Edited later[/B]
    69.         }
    70.      }
    71. }
    72.  
    73. void pwm_stop()
    74. {
    75.     TR0 = 0;            /* To disable PWM */
    76. }
    77. void main()
    78. {
    79.     pwm_width = 25+(sin_val[0]/100)*230; //No. of samples = 36, Total duty period = 230uS, timer counts from 25 to 255 for 12Mhz crystal
    80.     i++;
    81.   pwm_setup();
    82.     while(1)
    83.     {
    84.         //This part is not required for the moment
    85.     }
    86. }
     
    Last edited: Oct 13, 2015
  2. Anirban Raha

    Thread Starter Member

    Dec 4, 2013
    70
    0
    Hi,
    The Proteus Demo version is not working for 8051...some "invalid customer key" error is being generated...anyone with a good simulator would be so kind as to check my code? I just want to know whether the 8051 P2.0 and P2.1 pins will produce a sinusoidal PWM signal of 60Hz (per cycle and not PWM frequency) or not with this code.
     
  3. Anirban Raha

    Thread Starter Member

    Dec 4, 2013
    70
    0
    Hi,
    Can anyone at least suggest a good simulator that is free and has an oscilloscope with which I can check my output?
     
Loading...