# 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?