利用STC15输出两路互补SPWM波形

news2024/11/18 19:58:22

利用STC15输出两路互补SPWM波形


  • 🎞逻辑分析仪信号采集演示:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 🔖本案例使用的是IAP15W4K61S4验证。

  • 📍相关篇《STC15系列PWM相关功能寄存器介绍》

  • 📌相关开源PCB《【PCB开源分享】STC/IAP15W4K61S4开发板》

  • 🎈相关参考来源于STC官方资料。

📋STC15W4K32S4系列新增6通道高精度PWM (带死区控制的增强型PWM波形发生器)简介

STC15W4K32S4系列的单片机集成了一组(各自独立6路)增强型的PWM波形发生器。PWM波形发生器内部有一个15位的PWM计数器供6路PWM使用,用户可以设置每路PWM的初始电平。另外,PWM波形发生器为每路PWM又设计了两个用于控制波形翻转的计数器T1/T2,可以非常灵活的每路PWM的高低电平宽度,从而达到对PWM的占空比以及PWM的输出延迟进行控制的目的。由于6路PWM是各自独立的,且每路PWM的初始状态可以进行设定,所以用户可以将其中的任意两路配合起来使用,即可实现互补对称输出以及死区控制等特殊应用。

📑SPWM实现原理介绍

SPWM是使用PWM来获得正弦波输出效果的一种技术。像STCI5W4KxS4系列MCU内带6通道15位PWM,各路PWM周期 (频率) 相同,输出的占空比独立可调,并且输出始终保持同步,输出相位可设置。这些特性使得设计SPWM成为可能并且可方便设置死区时间,对于驱动桥式电路,死区时间至关重要。不过本MCU没有专门的死区控制寄存器,通讨查表法设置PWM占空比参数来达到。

在这里插入图片描述

内部15位的PWM计数器一旦运行,就会从0开始在每个PWM时钟到来时加1,其值线性上升,当计数到与15位的周期设置寄存器[PWMCHPWMCL]相等时(图中斜线A到B),内部PWM计数器归0,并产生中断,称为“归0中断”。本例周期设置为2400,内部计数器计到2400就归0,即2399,下一个时钟就归0.

STC15W4K32S4 PWM输出端口定义和切换

STC15W4K32S4系列增强型PWM输出端口定义如下:[PWM2:P3.7, PWM3:P2.1, PWM4:P2.2, PWM5:P2.3, PWM6:P1.6, PWM7:P1.7],每路PWM的输出端口都可使用特殊功能寄存器位CnPINSEL分别独立的切换到第二组:[PWM2_2:P2.7, PWM3_2:P4.5, PWM4_2:P4.4, PWM5_2:P4.2, PWM6_2:P0.7, PWM7_2:P0.6]。
所有与PWM相关的端口,在上电后均为高阻输入态,必须在程序中将这些口设置为双向口或强推挽模式才可正常输出波形。

🌼双路PWM产生互补或同相的SPWM示例程序代码

  • 🎉本示例程序来源于STC15实验箱中的案例。
  • ✨使用的是PWM3(P21)和PWM4(P22)两路。
  • 📢在使用STC-ISP烧录时,注意选择24MHz,不然波形频率就不对了。

当内部计数器的值与某个翻转寄存器的值相等时,就对对应的输出IO取反,本例中,PWM3从P2.1输出
并且PWM3输出的P2.1初始电平为0,PWM4输出的P2.2初始电平为1,则,当内部PWM计数器计到等于PWM4T1=53时,P2.2 由高输出低,计到等于PWM3T1=65时,P2.1由低输出高,计到等于PWM3T2-800时,P2.1由高输出低,计到等于PWM4T2-812时,P22由低输出高
两路输出是互补的,用于驱动一些MOSFET的半桥式驱动IC。可以看到这两路PWM的翻转时刻有一点差别,相差12个时钟,为什么要这样设计呢?这就是传说中的死区。为了方便说明,把这两路PWM放大如图2:

在这里插入图片描述

  • P22输出低电平后,再过12个时钟在24MHZ时,对应0.Sus),P2.1输出高电平。

  • P2.1输出低电平后,再过12个时钟在24MHZ时,对应0.5us),P2.2输出高电平。
    这个12个时钟就是死区时间,本例PWM时钟为IT模式,对应0.5ws。假设P2.1驱动的是半桥的下臂,P22驱动的是上臂,则P2.2输出低电平后,上臂开始关闭,经过05us,上臂关闭完毕,P2.1输出高电平,下臂打开。P2.1输出低电平后,下臂开始关闭,经过0.5us,下臂关闭完毕,P2.2输出高电平,上臂打开。这样,死区时间的设置,可以避免上下臂同时打开造成烧毁MOSFET。
    有人会说,一路输出关闭的同时,另一路大开,不会烧管子啊?
    错啦,MOSFET打开快,关闭慢相关知识请翻翻书),所以需要一段时间关闭
    P2.1或P2.2如果直接用示波器观察,会看到比我们的思绪还凌乱的波形,因为PWM一直在变化,但
    是通过RC (1K+1uF) 低通滤波再观察的话,就会看到两个反相的正弦波,神奇吧,呵呵!

  • RC低通滤波器,截止频率计算公式:
    在这里插入图片描述
    在这里插入图片描述

  • 经过RC低通滤波器后,使用示波器采集的2路波形:
    在这里插入图片描述
    在这里插入图片描述

本例伸用24MHz时钟,PWM时钟为1T模式,PWM周期2400,正收表幅度为2300,往上偏移60
个时钟方便过0中断重装数据)。正弦采样为200点,则输出正弦波频率 =240000002400/200=50HZ。


/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ---------------------*/
/* --- Web: www.GXWMCU.com -----------------------------------------*/
/* --- QQ:  800003751 ----------------------------------------------*/
/* If you want to use the program or the program referenced in the  */
/* article, please specify in which data and procedures from STC    */
/*------------------------------------------------------------------*/


#include	"config.h"
#include	"PWM.h"


/*************	功能说明	**************

演示使用2路PWM产生互补或同相的SPWM.

主时钟选择24MHZ, PWM时钟选择1T, PWM周期2400, 死区12个时钟(0.5us).正弦波表用200点. 

输出正弦波频率 = 24000000 / 2400 / 200 = 50 HZ.

本程序仅仅是一个SPWM的演示程序, 用户可以通过上面的计算方法修改PWM周期和正弦波的点数和幅度.

本程序输出频率固定, 如果需要变频, 请用户自己设计变频方案.

本程序从P2.1(PWM3)输出正相脉冲, 从P2.2(PWM4)输出反相脉冲(互补).

如果需要P2.2输出同相的, 请在初始化配置中"Start_IO_Level"项选择0(设置PWM输出端口的初始电平, 0或1).


工程文件:
delay.c
pwm.c
main.c

******************************************/

/*************	本地常量声明	**************/


/*************	本地变量声明	**************/


/*************	本地函数声明	**************/



/*************  外部函数和变量声明 *****************/



//========================================================================
// 函数: void	PWM_config(void)
// 描述: PWM配置函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-8-15
// 备注: 
//========================================================================
void	PWM_config(void)
{
	PWMx_InitDefine		PWMx_InitStructure;					//结构定义
	
	PWMx_InitStructure.PWMx_IO_Select       = PWM3_P21;		//PWM输出IO选择. PWM2_P37,PWM2_P27,PWM3_P21,PWM3_P45,PWM4_P22,PWM4_P44,PWM5_P23,PWM5_P42,PWM6_P16,PWM6_P07,PWM7_P17,PWM7_P06
	PWMx_InitStructure.Start_IO_Level       = 0;			//设置PWM输出端口的初始电平, 0或1
	PWMx_InitStructure.PWMx_Interrupt       = DISABLE;		//中断允许,   			ENABLE或DISABLE
	PWMx_InitStructure.FirstEdge_Interrupt  = DISABLE;		//第一个翻转中断允许,   ENABLE或DISABLE
	PWMx_InitStructure.SecondEdge_Interrupt = DISABLE;		//第二个翻转中断允许,   ENABLE或DISABLE
	PWMx_InitStructure.FirstEdge            = 65;			//第一个翻转计数, 1~32767
	PWMx_InitStructure.SecondEdge           = 1220;			//第二个翻转计数, 1~32767
	PWMx_Configuration(PWM3_ID, &PWMx_InitStructure);		//初始化PWM, 	PWM2_ID,PWM3_ID,PWM4_ID,PWM5_ID,PWM6_ID,PWM7_ID
	P21 = 0;
	P2n_push_pull(1<<1);									//IO初始化, 上电时为高阻

	PWMx_InitStructure.PWMx_IO_Select       = PWM4_P22;		//PWM输出IO选择. PWM2_P37,PWM2_P27,PWM3_P21,PWM3_P45,PWM4_P22,PWM4_P44,PWM5_P23,PWM5_P42,PWM6_P16,PWM6_P07,PWM7_P17,PWM7_P06
	PWMx_InitStructure.Start_IO_Level       = 1;			//设置PWM输出端口的初始电平, 0或1
	PWMx_InitStructure.PWMx_Interrupt       = DISABLE;		//中断允许,   			ENABLE或DISABLE
	PWMx_InitStructure.FirstEdge_Interrupt  = DISABLE;		//第一个翻转中断允许,   ENABLE或DISABLE
	PWMx_InitStructure.SecondEdge_Interrupt = DISABLE;		//第二个翻转中断允许,   ENABLE或DISABLE
	PWMx_InitStructure.FirstEdge            = 65-PWM_DeadZone;	//第一个翻转计数, 1~32767
	PWMx_InitStructure.SecondEdge           = 1220+PWM_DeadZone;//第二个翻转计数, 1~32767
	PWMx_Configuration(PWM4_ID, &PWMx_InitStructure);		//初始化PWM, 	PWM2_ID,PWM3_ID,PWM4_ID,PWM5_ID,PWM6_ID,PWM7_ID
	P22 = 1;
	P2n_push_pull(1<<2);									//IO初始化, 上电时为高阻

	PWM_SourceClk_Duty(PwmClk_1T, 2400);	//时钟源: PwmClk_1T,PwmClk_2T, ... PwmClk_16T, PwmClk_Timer2,   PWM周期: 1~32767
	
	PWMCR |= ENPWM;		// 使能PWM波形发生器,PWM计数器开始计数
//	PWMCR &= ~ECBI;		//禁止PWM计数器归零中断
	PWMCR |=  ECBI;		//允许PWM计数器归零中断

//	PWMFDCR = ENFD | FLTFLIO | FDIO;	//PWM失效中断控制,  ENFD | FLTFLIO | EFDI | FDCMP | FDIO
}


/**********************************************/
void main(void)
{
	
	PWM_config();	//初始化PWM

	EA = 1;			//允许全局中断

	while (1)
	{
		
	}
}


📚完整工程代码

链接: https://pan.baidu.com/s/1PlF8HmJgXOgMTSa48lodcg
提取码: 8h6k

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195085.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux(七)进程间通信

进程间是如何进行通信的&#xff1f; 通过前面的学习之后&#xff0c;我们知道进程间是具有独立性的&#xff0c;在操作系统的层面来看&#xff0c;进程就是一块pcb&#xff0c;是对运行中的程序动态运行过程的描述&#xff0c;在Linux角度下&#xff0c;进程就是一个task_stru…

2-2JVM-GC垃圾回收

GC垃圾回收 了解什么是垃圾回收掌握垃圾会回收的常见算法学习串行、并行、并发、G1垃圾收集器学习GC日志的可视化查看 1.什么是垃圾回收&#xff1f; 程序的运行必然需要申请内存资源&#xff0c;无效的对象资源如果不及时处理就会一直占有内存资源&#xff0c;最终将导致内…

YOLOv5/v7 Falsk Web 监测平台 | YOLOv5/v7 Falsk Web 部署

YOLOv7 Falsk Web 监测平台图片效果展示 YOLOv7 Falsk Web 监测平台视频效果展示 YOLOv7 Flask Web 检测平台 什么是Flask? 简介 Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开…

HTB_Jerry tomcat弱口令war包getshell

文章目录信息收集Tomcat war 包 getshell信息收集 扫描发现 8080 端口存在 tomcat 服务&#xff0c;访问 manage app 管理接口&#xff0c;需要输入账号密码 点击取消&#xff0c;看到默认账号密码&#xff0c;重新登录&#xff0c;登录成功&#xff0c;未修改 一般就是上传或…

JVM类加载

作用&#xff1a;负责从硬盘/网络中加载字节码信息&#xff0c;加载到内存中&#xff08;运行时数据区的方法区中&#xff09; 类加载过程&#xff1a; 加载 使用IO读取字节码文件&#xff0c;转换并存储 为每个类创建一个Class类的对象 存储在方法区中 链接&#xff08;…

Jackson注解使用分析

文章目录Jackson常用注解1. 常用注解汇总2. 注解使用分析JsonIncludeJsonAnyGetterJsonAnySetterJsonNamingJsonAutoDetectJacksonInjectJsonAliasJsonValueJsonMergeJsonRawValueJsonEnumDefaultValueJsonFilterJsonSerializeJsonDeserializeJacksonAnnotationJacksonAnnotati…

excel合并技巧:查找函数遇到合并单元格怎么应对

大家都在期盼奖金的到来&#xff0c;可是核算奖金的同事正在苦恼&#xff0c;因为以前用得好好的VLOOKUP函数突然不合适了&#xff0c;很多人的奖金计算出来都变成了乱码&#xff1a;使用VLOOKUP函数每个部门只有第一行正确&#xff0c;其他都是乱码。看到这个表&#xff0c;相…

【服务器数据恢复】raid5硬盘离线后热备盘未启用的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌X3850服务器&#xff0c;组建的raid5磁盘阵列&#xff0c;该raid5磁盘阵列包含4块成员盘和1块热备盘。 服务器故障&#xff1a; 服务器在运行过程中由于未知原因突然崩溃&#xff0c;用户方工程师检查后发现该故障服务器raid5阵列中2块磁…

Electron + Vue 开发环境搭建

1.安装nodejs&#xff0c;下载网址&#xff1a;https://nodejs.org/en/ 点击安装程序&#xff0c;一路next即可 安装完成之后打开cmd测试&#xff0c;输入node -v查看node版本&#xff0c;输入npm -v查看npm版本 安装完成后&#xff0c;.msi格式的安装包已经将node.exe添加到…

Excel连接openGauss数据库实操

目录 前言 一、通过excel 添加数据源访问openGauss 1、查看Excel版本 2、下载 ODBC驱动 3、安装ODBC驱动 4、添加ODBC数据源 5、在excel中添加数据源&#xff08;访问openGauss&#xff09; 二、通过excel 的VBA&#xff08;宏&#xff09;访问openGauss 1、宏权限设置…

2.1 java基础 day02 流程控制 创建类和对象 栈堆元空间

1流程控制 流程控制&#xff1a; 1.1.计算机在执行代码时对指令代码执行顺序的控制 1.2.Java 流程控制主要分三种&#xff1a; 顺序执行 分支执行 重复执行 1.3.顺序执行 按代码和语法出现的先后顺序执行 1.4.分支执行 根据判断条件执行分支逻辑 可选分支、必选分支&#…

活体识别6:小视科技开源的静默活体检测

说明 该项目为小视科技的静默活体检测项目。开源地址在 https://github.com/minivision-ai/Silent-Face-Anti-Spoofing。 由于不是论文衍生项目&#xff0c;所以只有一个公众号文章的介绍&#xff1a;https://mp.weixin.qq.com/s/IoWxF5cbi32Gya1O25DhRQ 方案详情 该方案是…

【安全】端口复用:远程遥控iptablesSSLH工具

目录 基础知识点 链的概念 表的概念 表链关系 远程遥控iptables进行端口复用 Ⅰ、利用ICMP做遥控开关 ①创建端口复用链 ②创建端口复用规则&#xff0c;将流量转发至 22 端口 ③开启开关&#xff0c;如果接收到一个长为 1139 的 ICMP 包&#xff0c;则将来源 IP 添加到…

使用Oracle VM VirtualBox安装Centos

1.下载安装Oracle VM VirtualBox 2.下载Centos 下载地址 旧版本 3.新建 选择镜像填写账户信息之后&#xff0c;我这边不知道什么原因&#xff0c;并不能完成所有工作&#xff0c;所以我一般不选择 4.选择镜像 5.安装 通过方向键和回车键选择 6.设置 选择中文 等待一些自动…

2023年“华数杯”国际大学生数学建模B题完整思路

2023华数杯如期开赛&#xff0c;本次比赛作为美赛的模拟赛&#xff0c;赛题和比赛时间都和美赛高度相似&#xff0c;因此大家 完全可以当作一次美赛之前的练习赛进行。美赛的发题时间与华数杯一致&#xff0c;都是早晨六点&#xff0c;现已经将机器翻译的初步翻译 结果进行了分…

c语言通讯录max——数据的持久化处理(详解)

用文件操作升级通讯录前言1.实现逻辑2.用哪种文件存储数据2. save_contact函数设计3. load_contact 函数设计5.代码总览contact.hcontact.ctext.c前言 在有关通讯录的上一篇博客中&#xff0c;作者用柔性数组实现了动态改变通讯录占用空间的功能&#xff0c;但是在最后还是留下…

【Go基础】Http编程

文章目录1. http协议1.1 请求方法1.2 URL1.3 协议版本1.4 请求头1.5 请求正文1.6 http response1.7 https2. go语言http标准库3. http router4. 请求校验5. http中间件6. GIN6.1 路由6.2 参数获取6.3 利用postman提交http请求6.4 生成response6.5 参数检验6.6 中间件6.7 会话7.…

互联网分层模型

互联网的逻辑实现被分为好几层。每一层都有自己的功能&#xff0c;就像建筑物一样&#xff0c;每一层都靠下一层支持。用户接触到的只是最上面的那一层&#xff0c;根本不会感觉到下面的几层。要理解互联网就需要自下而上理解每一层的实现的功能。如上图所示&#xff0c;互联网…

55.Isaac教程--Livox 激光雷达

Livox 激光雷达 ISAAC教程合集地址文章目录Livox 激光雷达支持的硬件和固件在桌面上设置和运行示例应用程序在机器人上设置和运行示例应用程序查看正在运行的应用程序将来Livox 激光雷达 Isaac SDK 支持使用 Livox LIDAR&#xff0c;包括兼容的驱动程序和示例应用程序。 支持的…

Android马甲包的那些事儿

制作Android马甲包最简单的方式就是使用 productFlavors 机制。本文就是在productFlavors机制的基础上制作的马甲包&#xff0c;每个马甲只需要在build.gradle文件中配置一下包名、各种key、签名文件配置启动页、logo、app名等资源配置服务器域名、微信分享回调Activity等代码此…