虫子 PWM 芯时代将崛起,码时代让位

举报
虫子VV 发表于 2022/04/21 14:14:16 2022/04/21
【摘要】 什么是脉宽调制 PWM SPWM 简介 用定时器和CPU模拟PWM输出 新建工程 设置一个定时器,定时10us 定时器中断服务函数里面,驱动 P2.1 脚输出 PWM ==我们把它占空比设置成百分之40 通过变量来操作== 使用STC15W系列的硬件PWM功能 1.P2.1口配置IO模式 ==(强推挽输出)(写法多种看自己)== ==P2M1 &= ~0x02;P2M0 |= 0...

什么是脉宽调制 PWM

中间动的线是电流线,==电流通断==,电流小就暗,电流大就亮。实际上准确的说是应该是==功率线==,因为==导通电压不变== 电流减少一半 功率自然就是一半

==PWM 脉宽调制,==实质上就是==电路的“导通”和“关断”的时间比改变==, 调整电压或者电流的大小。专业术语叫“占空比”。一般来说,导通和关断的速度要求很高。比如我们有些==开关电源==的工作模式,就是脉宽调制。通过调整变压器的变压时间,来保证输出电流功率足够。实现电压稳定。

PWM影响

==开关电路== 影响的是电流通断 电压要么是0 要么最大

==积分微分 运放电路== 输出结果就是影响电压

SPWM 简介

SPWM 是基于 PWM 规则,使输出波形成正弦波。在 PWM 周期固定的情况下,通过调整不同的脉宽,可以输出不同电压,最后看起来就是一个正弦波波形。

image-20211121174756398

用定时器和CPU模拟PWM输出

新建工程

这个自己建

设置一个定时器,定时10us

image-20211121193227954

void Timer0_Init()
{
//	AUXR &= 0x7f;
//	TMOD &= 0xf0;
//	TMOD |= 0x01;
//	TR0 = 1;
//	TH0 = 0xf8;
//    TL0 = 0x30;//定时1ms
	
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x02;		//设置定时器模式
	TL0 = 0xEC;		//设置定时初值
	TH0 = 0xEC;		//设置定时重载值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;        //定时器0开始计时	
	ET0 = 1;
}

定时器中断服务函数里面,驱动 P2.1 脚输出 PWM

image-20211121200739823

==我们把它占空比设置成百分之40 通过变量来操作==

image-20211121202138473

void Timer0_Routine() interrupt 1
{
//	//重装初值
//	TH0 = 0xf8;
//    TL0 = 0x30;//定时1ms
	static u8 count = 0;//count在[0,255]之间 
	if(count<102)
		P21 = 1;
	else
		P21 = 0;
	count++;
}

使用STC15W系列的硬件PWM功能

image-20211026163257407

1.P2.1口配置IO模式 ==(强推挽输出)(写法多种看自己)== ==P2M1 &= ~0x02;P2M0 |= 0x02;==

image-20211026161818309

image-20211026162702470

2.PWM 寄存器是后来居上的。每次都需要先使能 P_SW2 寄存器才能写值。写入之后再关闭 P_SW2 ==P_SW2 |= 0x80; P_SW2 &= ~0x80;==

image-20211122085230712

3.确定 PWM3 口的初始电平状态。PWMCFG ==PWMCFG = 0;==

image-20211027091310747

4 .设置 PWM3 时钟来源为系统时钟,不分频。PWMCKS ==PWMCKS = 0;==

image-20211027091940860

5.设置 PWM3 周期 1~32767, 为 1023 。 PWMCH(7bit) 、PWMCL(8bit) ==PWMCH = 0x03; PWMCL = 0xff;==

image-20211027102359843

image-20211027094750553

6 .设置 PWM3 输出管脚选择 P2.1 ,关闭 PWM3 的中断申请。(PWM3CR) ==PWM3CR = 0x00;==

image-20211027095816629

7 .最后,启动 PWM 计数模块, PWM3 输出脚为 PWM 信号。(PWMCR) ==PWMCR &= ~0x82;PWMCR |= 0x82;==

image-20211027100954444

void PWM_Init()//PWM初始化
{
		P2M1 = 0;
		P2M0 = 0x02;      //强推挽
		P_SW2 |= 0x80;    //允许访问XSFR		
		PWMCFG = 0;       //配置PWM的输出初始电平为低电平
		PWMCKS = 0;       //选择PWM的时钟为Fosc
		PWMCH = 0x03;     //设置PWM周期
		PWMCL = 0xff;     //设置PWM周期
		PWM3CR = 0x00;    //选择PWM3输出到P2.1,不能使能PWM2中断
		PWMCR &= ~0x82;   //使能PWM信号输出
		PWMCR |= 0x82;    //使能PWM信号输出
				
		P_SW2 &= ~0x80;   //关闭访问XSFR
}

8.主函数可以调用修改 PWM 的两次 IO 口的跳变时间 T1 和 T2 。来修改占空比。修改 PWM 的参数之前,必须关闭 PWM 的输出。否则可能会导致 PWM 电平颠倒

image-20211122092546338

image-20211122093153758

//PWM修改驱动
void PWM_Modify_Drive(u16 data1,u16 data2)
{
		P_SW2 |= 0x80;         //修改PWM之前需要使能P_SW2
		PWMCR &= 0x7f;		   //修改之前必须先关闭PWM使能
		PWMCFG = 0;            //配置PWM的输出初始电平为低电平
		PWM3T1 = data1;        //设置PWM3第一次反转的PWM计数
		PWM3T2 = data2;        //设置PWM3第二次反转的PWM计数
		PWMCR |= 0x80;         //修改之后重新允许PWM功能
		P_SW2 &= ~0x80;        //写入之后关闭P_SW2
}

完美的计数

image-20211122101250088

糟糕的线条

image-20211122101800828

再来一个测试组

image-20211122102216109

我们来实现一个呼吸灯的效果

PWM呼吸灯波形

image-20211122132635814

//PWM数据分配
void PWM_Allot()
{
	//设置一个PWM变量
	static xdata u16 PWM = 0;
	static xdata u8 count = 0;
	//呼吸灯是从零到最大,从最大到零,所以来个标志变量
	static bit PWM_flag = 0;
	count++;
	if(count > 250)
	{
		count = 0;
		if(!PWM_flag)
		{
			PWM++;
			if (PWM > 1020) 
			{
				PWM_flag = 1;					
			}			
		}
		if(PWM_flag)
		{
			PWM--;
			if(PWM<2)
			{
				PWM_flag = 0;		
			}
		}
		PWM_Modify_Drive(0,PWM);
	}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。