[蓝桥杯单片机]学习笔记——PWM脉宽调制信号的发生与控制

一、原理部分

1、脉宽调制(PWM)基本原理

        控制方式就是对逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等但宽度不一致的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率。

 简单来说,就是通过调节一个周期内高电平的占比来实现对电压的控制,如上图,第一个脉冲为50%高电平、50%低电平,占空比为50%,第二个25%高电平、75%低电平,占空比为25%。

2、 PWM的实现

一般使用定时器,实现的流程为:

①编写定时器初始化函数,初始化定时器,设置定时器的THx、TLx的初始值

②编写中断服务函数,函数参数可以为占空比,在这个函数中实现PWM脉冲信号的周期设置与信号发生

 

定时器的设置可以观看我上一节的定时器原理及其应用。下面通过一个实际案例了解一下PWM的应用

二、程序案例

例子:通过按键S7实现对L1指示灯的4级控制,占空比分别为10%、50%、90%、0%

#include "reg52.h"

sbit L1=P0^0;//定义引脚
sbit S7=P3^0;

/*****************************************************************
*@Function:  SelectHC573    //
*@Description: 锁存器选择,这里只用到LED相关的锁存器    //
*@Input:无 //
*@Output:无 //
*@Return:无  //
*@Others:无  //
/*****************************************************************/
void SelectHC573()
{
	P2=P2&0x1f|0x80;
}

unsigned char count=0;
unsigned char PWM_duty=0;

/*****************************************************************
*@Function:InitTimer0  //
*@Description: 定时器0初始化 //
*@Input:无 //
*@Output: 无//
*@Return: 无 //
*@Others: 无 //
/*****************************************************************/
void InitTimer0()
{
	TMOD=0x01;//设置定时器模式 16位不可重装载模式
	TH0=(65536-100)/256;//设置定时器初始计数值,为100us
	TL0=(65536-100)%256;
	
	ET0=1;//使能定时器0中断
	EA=1;//使能总中断
}

/*****************************************************************
*@Function: ServiceTimer0     //
*@Description: 定时器中断服务函数    //
*@Input:无 //
*@Output:无 //
*@Return:无  //
*@Others: 无 //
/*****************************************************************/
void ServiceTimer0() interrupt 1
{
	TH0=(65535-100)/256;//重新设置定时器初始值
	TL0=(65535-100)%256;
	count++;//计数变量加1
	
//	if(count<=PWM_duty)
//	{
//		L1=0;
//	}else if(count<100)
//	{
//		L1=0;
//	}else if(count==100)
//	{
//		count=0;
//	}
	if(count==PWM_duty)//如果等于设置的占空比(100份占比多少份)
	{
		L1=1;//将L1灯开启
	}else if(count==100)//计数变量如果等于100,即100个100us后,为一个周期
	{
		L1=0;//关闭L1灯
		count=0;//计数变量置0,重新计数
	}
}

/*****************************************************************
*@Function: DelayK     //
*@Description:用于按键延时     //
*@Input:无 //
*@Output:无 //
*@Return:无  //
*@Others:无  //
/*****************************************************************/
void DelayK(unsigned char t)
{
	while(t--);
}

unsigned char stat=0;//设置状态变量

/*****************************************************************
*@Function:  ScanKeys    //
*@Description: 按键扫描S7    //
*@Input:无 //
*@Output:无 //
*@Return: 无 //
*@Others:无  //
/*****************************************************************/
void ScanKeys()
{
	if(S7==0)//若S7按下
	{
		DelayK(100);
		if(S7==0)
		{
			switch(stat)//switch实现S7四个状态,占空比分别为10%、50%、90%、0,实现对L1的亮度控制
			{
				case 0:
					L1=0;
					TR0=1;
					PWM_duty=10;
					stat=1;
				break;
				
				case 1:
					L1=0;
					TR0=1;
					PWM_duty=50;
					stat=2;
				break;
				
				case 2:
					L1=0;
					TR0=1;
					PWM_duty=90;
					stat=3;
				break;
				
				case 3:
					L1=1;
					TR0=0;
					stat=0;
				break;
			}
			while(S7==0);
		}
	}
}

void main()
{
	SelectHC573();
	L1=1;
	InitTimer0();
	while(1)
	{
		ScanKeys();
	}
}

感谢大家的观看

欢迎大家提出问题并指正~

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IC 1396

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值