一、原理图

二、源程序
#include <reg51.h>
#include <intrins.h>
#define FOSC 6000000L
#define MACHINE_CYCLE (FOSC / 1000000)
#define _1US 1
#define _50US 50
#define _100US 100
#define _150US 150
#define _200US 200
#define _250US 250
sfr INT_CLKO = 0x8f;
sfr AUXR = 0x8e;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;
signed int duty_cycle;
unsigned int init_value;
unsigned int count;
sbit pwm = P3 ^ 3;
bit flag;
void init_int0(void)
{
INT0 = 1;
IT0 = 1;
EX0 = 1;
}
void init_int2(void)
{
INT_CLKO |= 0x10;
}
void init_int3(void)
{
INT_CLKO |= 0x20;
}
void set_tm0_init_value(unsigned int value) reentrant
{
switch(value) {
case 50:
TL0 = (65536 - (_50US * MACHINE_CYCLE)) % 256;
TH0 = (65536 - _50US * MACHINE_CYCLE) / 256;
break;
case 100:
TL0 = (65536 - _100US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _100US * MACHINE_CYCLE) / 256;
break;
case 150:
TL0 = (65536 - _150US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _150US * MACHINE_CYCLE) / 256;
break;
case 200:
TL0 = (65536 - _200US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _200US * MACHINE_CYCLE) / 256;
break;
case 250:
TL0 = (65536 - _250US * MACHINE_CYCLE) % 256;
TH0 = (65536 - _250US * MACHINE_CYCLE) / 256;
break;
default:
TL0 = (65536 - value * MACHINE_CYCLE) % 256;
TH0 = (65536 - value * MACHINE_CYCLE) / 256;
break;
}
}
void init_timer0(void)
{
TMOD = 0x00;
set_tm0_init_value(init_value);
TR0 = 1;
ET0 = 1;
}
void main(void)
{
P3M1 = 0x00;
P3M0 = 0xFF;
AUXR |= 0x80;
duty_cycle = 5;
count = 0;
init_value = 100;
init_int0();
init_int2();
init_int3();
init_timer0();
flag = 0;
EA = 1;
while(1);
}
void ex_int0() interrupt 0
{
EA = 0;
flag = !flag;
if(flag) {
TR0 = 0;
ET0 = 0;
} else {
TR0 = 1;
ET0 = 1;
}
pwm = flag;
EA = 1;
}
void ex_int2() interrupt 10
{
EA = 0;
if(++duty_cycle > 10) {
duty_cycle = 10;
}
INT_CLKO &= 0xEF;
INT_CLKO |= 0x10;
EA = 1;
}
void ex_int3() interrupt 11
{
EA = 0;
if(--duty_cycle < 0) {
duty_cycle = 0;
}
INT_CLKO &= 0xDF;
INT_CLKO |= 0x20;
EA = 1;
}
void tm0_isr() interrupt 1 using 1
{
EA = 0;
set_tm0_init_value(init_value);
if(++count > 9) {
count = 0;
}
if(count < duty_cycle) {
pwm = 1;
} else {
pwm = 0;
}
EA = 1;
}