蓝桥杯——PWM

一、原理部分

PWM全称为脉冲宽度调制,在实际生活中很多地方都会见到这个技术的影子,例如灯的明暗调控,电机的转动速度还有幅度等等。在这些应用中我们需要使用不同的电压来达到目的,输出不同电压的方式有两种,一种是直接输出指定的电压值,还有一种就是PWM。
在这里插入图片描述
Ton为高电平持续时间
Toff为低电平持续时间
Ts一个周期时间
占空比=高电平持续时间/周期
简单来说一个io口只能输出固定的电压值如5V或者0V,我们要获取其他的电压值就可以通过占空比来控制io口的电压输出。假如现在需要一个3V的电压值,那么占空比就是60%,高电平持续时间占周期的60%,低电平占周期的40%。假设周期为10ms,那么就要让此io口输出高电平6ms的时间然后输出低电平4ms的时间,这样我们就输出了一个3V的电压。

在单片机中我们可以通过定时器来实现PWM的输出

具体步骤

一、开一个定时器

根据题目要求,假如题目要1khz的信号也就是周期为1ms,涉及到的占空比为10的整数倍时,就可以开100us的定时器,如果设计到的占空比不是10的整数倍时那么定时器就要开10us的。其他的以此类推。

二、定义一个变量用来当做周期使用

定义变量pwm_cycle变量,每次执行中断服务函数时这个变量自加,达到了题目要求的时间便清零。

三、定义一个控制pwm占空比的变量

定义变量pwm,pwm和占空比有关系,然后让pwm和pwm_cycle进行比较,pwm大的时候执行高电平,pwm小的时候执行低电平。这样就完成了一个可以自己控制占空比的信号输出。

二、代码部分

实验平台:CT107D
实验芯片:stc15f2k60s2
实验现象:呼吸灯
代码如下

#include<stc15f2k60s2.h>
bit flag_pwn;
unsigned char led_dat;
void Timer0Init()		//[email protected]
{
		AUXR |= 0x80;		
		TMOD &= 0xF0;	
		TL0 = 0x88;		
		TH0 = 0xFF;		
		TF0 = 0;		
		TR0 = 1;		
		ET0 = 1;
		EA = 1;
}	
void ShowLed(unsigned char led_dat)
{
		P2 = P2&0x1f|0x80;
		P0 = led_dat;
		P2 = P2&0x1f;
}

void T0_time() interrupt 1
{
		static unsigned int count = 0,n = 0,pwn = 0;
		TL0 = 0x88;		
		TH0 = 0xFF;	
		if(++count >= 1000)  //周期10ms
		{
				count = 0;
		}
		if(++n >= 100)     //每隔1ms变化一次pwn
		{
				n = 0;
				if(flag_pwn == 0)   
				{
						pwn++;                 //PWN增加,灯泡由亮到暗
						if(pwn == 1000)
						{
								flag_pwn = 1;
						}					
				}
				else if(flag_pwn == 1)
				{
						pwn--;                //PWN减少,灯泡由暗到亮
						if(pwn == 0)
						{
								flag_pwn = 0;
						}
				}
		}
		
		if(count > pwn)        //亮
		{
				ShowLed(0x00);
		}
		else                   //暗
		{
				ShowLed(0xff);
		}		
}

void CloseFucker()
{
		P2 = P2&0x1f|0xa0;
		P0 = 0xaf;
		P2 = P2&0x1f;
}

void main()
{
		CloseFucker();
		Timer0Init();
		while(1)
		{
			;
		}
}

猜你喜欢

转载自blog.csdn.net/FuckerGod/article/details/105018894
今日推荐