51 single-chip microcomputer is capable of output PWM, the trouble of comparison. In this case, an internal timer is needed to implement it, which can be implemented with two timers or with a timer.
The method of using two timers is to control the frequency with the timer T0, and the timer T1 to control the duty ratio. The general programming idea is this: T0 timer interrupt let a I0 port output high level, in this timer T0 interrupt in the start Timer T1, and this T1 is let IO port output low level, so change the initial value of the timer T0 can change the frequency, change the initial value of the timer T1 can change the duty ratio.
The following focuses on the implementation of a PWM method with a timer. Take the period of 1ms (1kHZ) For example, to generate other frequencies of the PWM wave, the program only need to make simple changes. With a timer (such as timer T0), first to determine the PWM period T and duty cycle D, after determining these, you can use the timer to generate a time reference T, such as the time the timer overflow n times is the high level of PWM time, then D*t=n*t, Similarly, it is possible to find out how much time reference n is required between PWM low-voltage.
Because here we are generating a cycle of 1ms (1kHZ) PWM, so the time to set the interrupt base is 0.01ms, and then interrupt 100 times is 1ms. Within the interrupt subroutine, you can set a variable such as time, within the interrupt subroutine, there are three important statements:
1, when time>=100, time clear 0 (this statement guaranteed frequency is 1kHZ);
2, when the Time>n (n should change between 0-100 open), so that the corresponding I/O port output low level;
3, when the Time<=n, let a single chip corresponding I/O port output High level, at this time the duty-free ratio is%n.
The following program generates 30% duty-free PWM:
#include <reg51.h>
#define UINT unsigned int
#define UCHAR unsigned char
sbit pwm=p2^0;// P2.0 output PWM
uchar time; Defines the duty ratio of the variable
void main ()
{
tmod=0x01;//timer 0 Mode of operation 1
th0=0xff;//(65536-10)/256;//assigned initial value timing
Tl0=0xf7 ;//(65536-10)%256;//0.01ms
ea=1;//Open Total interrupt
et0=1;//Open Timer 0 interrupt
tr0=1;//start timer 0 while
(1)
{
}
}
void Tim0 () Interrupt 1
{
tr0=0;//when assigned initial value, turn off timer
th0=0xff;//(65536-10)/256;//Assign initial value timing
tl0=0xf7;//( 65536-10)%256;//0.01ms
tr0=1;//Open timer
time++;
if (time>=100) //1khz
time=0;
if (time<=30) //Duty ratio%30, can be modified
pwm=1;
else pwm=0;
}
The final to the waveform, shown on the oscilloscope as in the following figure:
If you want to modify the duty ratio, directly in the program to modify the following sentence can be. if (time<=30)//Duty%30, can be changed to duty ratio
Of course, we can add other means to dynamically change the duty ratio, such as keys, the upper computer and so on. Press the button to dynamically adjust the duty ratio can refer to my other blog: http://blog.csdn.net/dmfylb/article/details/72605221