【定时器/中断/PWM】利用一个定时器实现一路PWM波的输出---点亮LED

时间:2021-11-23 19:34:29

------------------------------------------凑热闹的分割线------------------------------------------------

/*点亮led0(P1^0)和led7(P1^7) 其中led0以5v电压正常点亮
 led1利用pwm和按键实现可调亮度*/
#include<reg52.h>
#define ui unsigned int
#define uc unsigned char
sbit led0=P1^0;
sbit led1=P1^7;
sbit up=P3^0;
sbit down=P3^1;
ui n=0;	//定义了每个周期有几小段
uc pwm=20; //定义了占空比(pwm越大 低电平占比越大) 数据类型范围0~256
void delay();
void init_timr0();
void scan();
void main()
{
	init_timr0(); //初始化定时器
	led0=0; //正常点亮一个led 用于比较
	scan();
}
/*主函数*/
void init_timr0()
{
	TMOD=0x02; //设置定时0 工作方式2
	TH0=TL0=210; //周期中每段时间50us
	EA=1;
	ET0=1;
	TR0=1;
}
/*延时函数*/
void delay()
{
	uc x,y;
	for(x=10;x>0;x--)
		for(y=120;y>0;y--);
}
/*循环扫描检测是否要变亮或变暗*/
void scan()
{
	while(1)
	{
		if(!up)	 //按下灯变亮()
		{
			delay();  //防抖
			if(!up)
				if(pwm<=250)	 //限制了pwm的范围不能大于255 否则溢出后变为最小
					pwm++;
		}
		delay(); //使按键调速更慢些
		if(!down)
		{
			delay();
			if(!down)
				if(pwm>0)	 //限制了pwm的范围不能小于0 否则跳变到最大
					pwm--;
		}
		delay(); 
	}
}
/*中断服务程序*/
void timer0()interrupt 1
{
	n++;
	if(n==250) //设置周期有250段 则 周期=n*定时器溢出时间
	{
		n=0;
		led1=0; // 0-pwm的时间内P1^7输出低电平
	}
	if(n==pwm)
		led1=1; // pwm-250的时间内P1^7输出高电平
}


------------------------------------------搞事情的分割线------------------------------------------------
折腾了好久,PWM这块总算是有点明白了。接下来打算用一个定时器实现两路PWM波输出。继续加油!