PWM移相以及占空比可变(上)

2024-02-29 19:30
文章标签 可变 pwm 占空比 移相

本文主要是介绍PWM移相以及占空比可变(上),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文以 STC8H 芯片为例,输出两路相位可调以及占空比可调的PWM(CH1  CH2)。

一、PWM输出原理

我们所使用的是 STC8H 高级定时器的输出比较模式。

1.1、普通PWM输出

图1.1.1

图1.1.2

上两图展示的是普通的PWM输出模式,该模式下可以自己设定ARR和CCR,其中CCR用于控制占空比。

1.2、输出比较模式

输出比较模式通俗来说 是CNT = CCR时  电平会翻转。例如 你配置了 向上计数,ARR=100, CCR=30,初始电平为高电平,那么 CNT从0计数到30时, CNT =CCR =30,此时高电平就会跳变到低电平,CNT继续在30的基础上计数,直到计数到100并溢出,此时CNT会置0并重新开始计数。

值得注意的是,PWM模式与翻转模式下所输出的波形频率是相差 2倍的,即 PWM输出频率为10HZ,那么输出比较模式下的输出频率只有5HZ。

这是因为   输出比较模式下不关心CNT比 CCR值大还是小,只关心CNT和CCR值什么时候相等,两个值相等时,就翻转输出电平。在PWM模式下,CNT值从0增加到ARR一个周期内输出电平有两次变化,而在输出比较模式下时CNT值从0增加到ARR一个周期内输出电平只有一次变化。所以输出比较模式下,定时器输出方波的频率为PWM模式下定时器输出方波频率的一半。(该段内容源自--生成两路PWM波相位差90°的方法)

 要想 输出比较模式 下输出的PWM波的频率与普通PWM模式下输出的频率相等,则需要对输出比较模式下输出的PWM频率进行2分频。该点后续详解。

二、相位差原理

本文可调节的相位差在 0-180°范围 

CH1为普通PWM输出,其自动重装值为 ARR1=100,CH2为输出比较模式,其自动重装值为ARR2

2.1、频率相等

要实现CH1与CH2的输出频率相等,最重要的是两者的ARR的设置。其设置应为

ARR2=ARR1 / 2,且 CH2的 CCR应设置为0或50。

这是因为   输出比较模式下不关心CNT比 CCR值大还是小,只关心CNT和CCR值什么时候相等,两个值相等时,就翻转输出电平。在PWM模式下,CNT值从0增加到ARR一个周期内输出电平有两次变化,而在输出比较模式下时CNT值从0增加到ARR一个周期内输出电平只有一次变化。

我们设置 CH2 的ARR2 的值为50,其目的就是是为了 让  输出比较模式PWM模式下的一个 ARR1周期内,有两次电平跳变,从而达到2分频的效果。而CCR设置为0或50,只是让电平在最大量程临界点电平跳变。可参考下图理解。

2.2、移相原理

 想要得到0-180°范围内的相位差,最重要的是懂得如何调节输出通道CH1与输出通道2 CH2的 CCR关系。

首先我们理解 ARR 从0 --100这个范围对应着角度值的 0-- 360°。那么 0点对应的是 0°,25对应的就是90°,50 对应的就是 180°,  75对应的就是270°。那么想要实现移相的角度,无非是确定 输出比较模式 输出的 电平翻转点。

以180°移相为例。

要实现图中 CH1与CH2波形相位差为180°,我们要思考的是图中1 , 2 ,3点的电平该如何翻转。

仔细思考其实就可以知道,1点电平应该跳转为低电平,2点电平应跳转为高电平,3点应跳转为低电平。效果如下图所示。改图就是实现了180°移相,且占空比不改变的效果。

那么90°相位差呢? 

电平翻转点应该就是在CCR=25 这个点位。如下图所示

确定了 翻转点位为 CCR=25,那么为何在 CCR=75的时候还要翻转多一次?

这是因为前文所说的,需要保持与PWM输出频率相等。至于为什么一定是75这个点而不是其他的点,这是因为 CNT=CCR1=25 时,电平翻转后,CNT是继续计数到 CCR1 = 75 电平翻转,CNT继续计数到 CCR1 =100 并溢出后置零重新计数的。而在75  --- 100这个过程,CNT是走过了25个计数值,而 CNT重新从0 到 CNT=25这个过程,也走过了25个计数值,那合起来就一共是走了50个计数值,这与我们 设定的 ARR2是一致的,保持了PWM 与 输出比较模式下的频率相等。

所以,在0-180°范围内 想要得到任意的相位差x,只需要计算出该相位差x对应的 ARR1的值并将该值设置为 输出比较的CCR2的值即可。

计算公式 CCR2 = ARR1 /(360°/x)  

三、代码

u8	PWMA_ISR_En;	//每个通道可以单独允许中断处理, bit4:通道4, bit3:通道3, bit2:通道2, bit1:通道1.u16		pwma1;		//PWMA1输出高电平时间
u16		pwma2;		//PWMA2输出高电平时间
u16   pwma2N;void PWMA_config(void)
{u8	ccer1;u8	ccer2;u8	ps;u8	eno;P_SW2 |= 0x80;		//SFR enable   PWMA_ENO    = 0;	// IO输出禁止PWMA_IER    = 0;	// 禁止中断PWMA_SR1    = 0;	// 清除状态PWMA_SR2    = 0;	// 清除状态PWMA_CR1    = 0;	// 清除控制寄存器PWMA_CR2    = 0;	// 清除控制寄存器ccer1 = 0;ccer2 = 0;ps    = 0;eno   = 0;PWMA_ISR_En = 0;PWMA_PSCR = 100;	// 预分频寄存器, PWM时钟 = 12MHz/(11+1)=1MHz, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).PWMA_DTR  = 12;	// 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,  //				0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
//	PWMA_ARR     = PWMA_DUTY-1;	// 自动重装载寄存器,  控制PWM周期PWMA_ARRH=((PWMA_DUTY-1) >> 8);PWMA_ARRL=((PWMA_DUTY-1) & 0xFF);PWMA_CCMR4 = 0x10;		// 通道模式配置, PWM模式1, 预装载允许
//	PWMA_CCR4  =pwma2; //PWMA_PHASE2+pwma2;	// 比较值, 控制占空比(高电平时钟数)ccer2 |= 0x50;			// 开启比较输出, 高电平有效ps    |= 0xC0;				// 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1, eno   |= 0xC0;			// IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1PPWMA_ISR_En |= 0x10;	// 使能中断PWMA_CCMR1 = 0x68;		// 通道模式配置, PWM模式1, 预装载允许PWMA_CCR1  = pwma1;	// 比较值, 控制占空比(高电平时钟数)ccer1 |= 0x05;			// 开启比较输出, 高电平有效ps    |= 0;				// 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1, eno   |= 0x03;			// IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
//	PWMA_ISR_En |= 0x02;	// 使能中断PWMA_CCER1  = ccer1;	// 捕获/比较使能寄存器1PWMA_CCER2  = ccer2;	// 捕获/比较使能寄存器2PWMA_PS     = ps;		// 选择IOPWMA_IER    = PWMA_ISR_En;	//设置允许通道1~4中断处理PWMA_BKR    = 0x80;		// 主输出使能 相当于总开关PWMA_CR1    = 0x81;		// 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)PWMA_EGR    = 0x01;		//产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值PWMA_ENO    = eno;		// 允许IO输出
}void PWMA_ISR(void) interrupt PWMA_VECTOR
{u8	sr1;
//	u8	sr2;sr1 = PWMA_SR1;	//为了快速, 中断标志用一个局部变量处理PWMA_SR1 = 0;	//清除中断标志
//	sr2 = PWMA_SR2;	//为了快速, 中断标志用一个局部变量处理PWMA_SR2 = 0;	//清除中断标志sr1 &= PWMA_ISR_En;	//每个通道可以单独允许中断处理if(sr1 & 0x10)	//通道4匹配中断标志{if(!P34)	//当前输出低电平, 预装载的是输出高电平的匹配值, 则准备好输出低电平的匹配值{PWMA_CCR4 = pwma2;
//	pwma2; //PWMA_PHASE2;	// 通道2匹配值, 匹配时输出低PWMA_CCMR4 = 0x10;				// 通道模式配置, 匹配模式2, 禁止预装载, 匹配时输出低}else	//当前输出高电平, 预装载的是输出低电平的匹配值, 则准备好输出高电平的匹配值{PWMA_CCR4 =PWMA_PHASE2 + pwma2N;	// 通道2匹配值, 匹配时输出高PWMA_CCMR4 = 0x20;			// 通道模式配置, 匹配模式1, 禁止预装载, 匹配时输出高}}
}void main(void)
{ P_SW2  = 0x80;Tick_Init();Io_Init();pwma1 =200;pwma2 =50;pwma2N =850;PWMA_config(); EA = 1;while (1) {}
}

这篇关于PWM移相以及占空比可变(上)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/759822

相关文章

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

STM32CubeMX 3 解锁PWM模块

今天在底层高手的指导下又学习了PWM模块的配置!汪! 首先打开上次配置好的文件,如下: 然后,我们要用TIM1来进行PWM 的设置: 然后,clock configuration 不用动 然后 双击自动弹出以下,窗口:

STM32F103调试DMA+PWM 实现占空比逐渐增加的软启效果

实现效果:DMA+PWM 实现PWM输出时,从低电平到输出占空比逐渐增加再到保持高电平的效果,达到控制 MOS 功率开关软启的效果。 1.配置时钟 2.TIM 的 PWM 功能配置 选择、配置 TIM 注意:选择 TIM 支持 DMA 控制输出 PWM 功能的通道,有的TIM通道支持PWM 但不支持PWM注意选择。 PWM参数设置 Counter Period :

C++11,可变参数模板,lambda表达式,包装器

可变参数模板 在C++11中模板也可以接收多个不定参数,就和int printf(const char *format, ...);函数一般模板也可以接收多个参数; // 可变参数模板template<class ...Args>void testArgs(Args... args){}int main(){testArgs(123, 'a', "abc",

s3c2440---PWM使用之蜂鸣器驱动移植

一、蜂鸣器驱动介绍 1.1.什么是蜂鸣器               蜂鸣器是一种简单的声响发生器,常用于电子产品中作为警示或提醒作用。其基本原理是通过交替改变直流电的电压方向来产生声音,一般使用交替电流产生声音会比较稳定。 1.2.蜂鸣器的类别 1.有源蜂鸣器 1)结构原理 有源蜂鸣器内部自带振荡源,只需接通电源即可发声。内部电路会自动产生一定频率的振荡信号,从而驱动蜂鸣器发声。

android光滑绘图可变宽度笔

要绘制代码 path 使用可变的描边宽度 public class FingerPaint extends GraphicsActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(new MyView(this

61、Python之函数高级:为函数添加方法,实现属性可变的装饰器

引言 今天文章的标题,初读起来可能有些拗口,什么叫“为函数添加方法”?但是,如果真正对“Python函数也是对象”这个理念有清晰的理解的话,其实,也是不难理解的,本质上就是给一个对象新增一个自定义方法。通过这样做,我们就可以实现在运行过程中,对装饰器的属性进行动态修改了。 本文的主要内容有: 1、函数对象添加自定义方法 2、属性可变的动态装饰器 函数对象添加自定义方法 其实,这一点

[C++11#46](三) 详解lambda | 可变参数模板 | emplace_back | 默认的移动构造

目录 一.lambda 1. 捕捉列表 2. 底层原理 二. 可变参数模板 1. 递归函数方式展开参数包 2. 数组接收方式展开参数包 3. 运用 4.emplace_back 5.移动构造和拷贝构造 强制生成 default 一.lambda 可调用类的对象 函数指针--少用 void(*ptr) (int x) 仿函数--构造类 重载 operator() 对象

C++ 模板基础知识——可变参数模板

目录 C++ 模板基础知识——可变参数模板1. 可变参函数模板1.1 基本含义1.2 利用 constexpr if 优化递归函数1.3 关于 constexpr if 的进一步理解1.4 重载 2. 折叠表达式2.1 一元左折(Unary Left Fold)2.2 一元右折(Unary Right Fold)2.3 二元左折(Binary Left Fold)2.4 二元右折(Binar

51单片机的pwm控制的智能台灯设计【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能  该系统由AT89C51/STC89C52单片机+LCD1602显示模块+DS1302时间模块+光敏传感器模块+人体红外模块+按键等模块构成。适用于智能台灯、PWM调节灯光亮度等相似项目。 可实现基本功能: 1、LCD1602实时显示北京时间、环境光照强度、手动/自动模式、台灯亮度等信息; 2、DS1302采集时间数据; 3、光敏传感器(电位器模拟)采集光照强度; 4、人