基于STM32F767两路互补SPWM波(HAL库)
SPWM波指的是占空比呈正弦规律变化的PWM波,生成方式是在定时器中断中调整PWM波的占空比。
对于互补的两路SPWM波,一路为低电平 ‘0’ 时,另一路为高电平 ‘1’,即两路是互补的。
对于STM32F7,使用高级定时器TIM1可以方便地生成互补SPWM波。步骤如下:
1、确定载波周期 Tc,也即是每个SPWM波的周期。对于逆变电路,常采用20kHz,也即 Tc = 50us;
2、确定基波周期 Tb,此处取50Hz,即 Tb = 20ms;
3、计算取点数N,Tb / Tc = 20ms/50us = 4000;半个周期内则为 N = 2000点;
4、计算占空比,Di = sin(i*pi / N), i = 1, 2, 3, ..., N;
5、确定最大最小占空比,例如最小占空比 Dmin = 0,最大占空比Dmax = 100%;
6、计算并修改定时器的比较值。将占空比为0%时,定时器的比较值设置为Cmin = 0;将占空比为100%时,定时器的比较值设为Cmax = 5399;则每中断一次,占空比的值设为 Cmax*Di,直接在中断里完成计算。
根据以上计算,可以修改最小占空比和最大占空比,也可以修改基波与载波频率。
以下是具体定时器配置与中断服务函数程序,基于STM32F767IGBT:
//使用高级定时器 1 完成
//Update--2019.6.3
//sin_k = TIM1_ARR / 200.0 * (float)(spwm_max_duty - spwm_min_duty ) ; //正弦波的比例系数,一个简单的数学代换
//sin_b = TIM1_ARR / 200.0 * (float)(spwm_max_duty + spwm_min_duty ) ; //正弦波的截距 #include "timer1.h"
#include "led.h"
#include "math.h" TIM_HandleTypeDef TIM1_Handler; //定时器句柄
TIM_OC_InitTypeDef TIM1_CH1Handler; //定时器3通道4句柄
TIM_BreakDeadTimeConfigTypeDef BreakDeadTime_Config; #define PWM_GPIO GPIOA
#define PWM_PIN1 GPIO_PIN_8
#define PWM_PIN2 GPIO_PIN_7 #define TIM1_ARR 5399 //SPWM波相关计算
//sin_points -- 一个周期内中断计算的正弦点数,20KHz载波,Tc = 50us,基波周期 Tb = 50us * sin_points
//Tb = 20Hz = 50ms = 50,000us, sin_points = 1000
//Tb = 100Hz = 10ms = 10,000us , sin_points = 200 //(-sin_k + sin_b ) / TIM1_ARR = spwm_min_duty %
//( sin_k + sin_b ) / TIM1_ARR = spwm_max_duty %,反解出 sin_k, sin_b
// sin_k = TIM1_ARR / 200.0 * (float)(spwm_max_duty - spwm_min_duty )
// sin_b = TIM1_ARR / 200.0 * (float)(spwm_max_duty + spwm_min_duty ) uint8_t spwm_min_duty = ; //SPWM波最小占空比
uint8_t spwm_max_duty = ; //SPWM波最大占空比 uint16_t count = ;
uint16_t sin_points = ;
uint16_t cc1_value; //比较寄存器 1的值,修改改变占空比 float sin_k,sin_b; //TIM1 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM1_PWM_Init(u16 arr,u16 psc)
{
//时钟配置
TIM1_Handler.Instance = TIM1; //定时器3
TIM1_Handler.Init.Prescaler = psc; //定时器分频
TIM1_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式
TIM1_Handler.Init.Period=arr; //自动重装载值
TIM1_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&TIM1_Handler); //初始化PWM,会调用HAL_TIM_PWM_Init(*) //PWM配置
TIM1_CH1Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1
TIM1_CH1Handler.Pulse=arr/; //设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50%
TIM1_CH1Handler.OCPolarity = TIM_OCPOLARITY_HIGH;//输出比较极性为高
TIM1_CH1Handler.OCNPolarity = TIM_OCPOLARITY_HIGH;
TIM1_CH1Handler.OCIdleState = TIM_OCIDLESTATE_SET;
TIM1_CH1Handler.OCNIdleState = TIM_OCIDLESTATE_SET;
HAL_TIM_PWM_ConfigChannel(&TIM1_Handler,&TIM1_CH1Handler,TIM_CHANNEL_1);//配置TIM1通道1 //死区时间配置
//https://blog.csdn.net/DZRYWYBL/article/details/82527889
BreakDeadTime_Config.OffStateRunMode = TIM_OSSR_DISABLE;
BreakDeadTime_Config.OffStateIDLEMode = TIM_OSSI_DISABLE;
BreakDeadTime_Config.LockLevel = TIM_LOCKLEVEL_OFF;
BreakDeadTime_Config.DeadTime = 0X00; //0x00~0xFF,当设置为0xFF时,50us周期,约有4.68us死区时间;0x0F约有100ns死区时间
BreakDeadTime_Config.BreakState = TIM_BREAK_DISABLE;
BreakDeadTime_Config.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
BreakDeadTime_Config.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
HAL_TIMEx_ConfigBreakDeadTime(&TIM1_Handler, &BreakDeadTime_Config); //中断配置
HAL_NVIC_SetPriority(TIM1_CC_IRQn,,); //设置中断优先级,抢占优先级1,子优先级3
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); //开启ITM3中断
//开启PWM并使能中断
HAL_TIM_PWM_Start_IT(&TIM1_Handler, TIM_CHANNEL_1); //开启PWM输出并使能中断
HAL_TIMEx_PWMN_Start(&TIM1_Handler, TIM_CHANNEL_1); //打开互补通道
} //定时器底层驱动,时钟使能,引脚配置
//此函数会被HAL_TIM_PWM_Init()调用
//htim:定时器句柄
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_TIM1_CLK_ENABLE(); //使能定时器3
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_Initure.Pin=PWM_PIN1 | PWM_PIN2; //PWM Pin
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推完输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
GPIO_Initure.Alternate=GPIO_AF1_TIM1; //PA8复用为TIM1_CH1
HAL_GPIO_Init(PWM_GPIO,&GPIO_Initure); } //设置TIM通道4的占空比
//compare:比较值
void TIM_SetTIM1Compare1(u32 compare)
{
TIM1->CCR1=compare;
} //定时器1中断服务函数
void TIM1_CC_IRQHandler(void) //注意名称与通用计时器不同,多了 CC
{
HAL_TIM_IRQHandler(&TIM1_Handler);
} //定时器1中断服务函数调用
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&TIM1_Handler))
{
count ++;
if(count == sin_points)
count = ; sin_k = TIM1_ARR / 200.0 * (float)(spwm_max_duty - spwm_min_duty ) ; //正弦波的比例系数,一个简单的数学代换//更正为相减
sin_b = TIM1_ARR / 200.0 * (float)(spwm_max_duty + spwm_min_duty ) ; //正弦波的截距//更正为相加
cc1_value = (uint16_t) (sin_k * sin( (double)count * 6.28318 / (double)sin_points) + sin_b); //正弦值计算,得到SPWM波占空比
TIM_SetTIM1Compare1(cc1_value);
}
}
主函数配置为
TIM1_PWM_Init(-,-); //216M / (5400 * 2 ) = 20K
基于STM32F767两路互补SPWM波(HAL库)的更多相关文章
- STM32高级定时器TIM1产生两路互补的PWM波(带死区)
测试环境:Keil 5.20.0.0 STM32F103RBT6 固件库版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011) 本文使用TIM1的通道1,通道2,产生两路1kh ...
- 【书籍连载】《STM32 HAL 库开发实战指南—基于F7》-第一章
从今天起,每天开始连载一章<STM32 HAL 库开发实战指南—基于F7>.欢迎各位阅读.点评.学习. 第1章 如何使用本书 1.1 本书的参考资料 本书参考资料为:<STM32 ...
- stm32电机控制之控制两路直流电机
小车使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制,这里电机使用PWM驱动,速度控制框图如下: 由以上框图可知,STM32通过定时器模块输出PWM波来控制两个直流电机的转动 ...
- STM32 ADC多通道转换DMA模式与非DMA模式两种方法(HAL库)
一.非DMA模式(转) 说明:这个是自己刚做的时候百度出来的,不是我自己做出来的,因为感觉有用就保存下来做学习用,原文链接:https://blog.csdn.net/qq_24815615/arti ...
- 125-FMC125-两路125Msps AD,两路160Msps DA FMC子卡模块
FMC125-两路125Msps AD,两路160Msps DA FMC子卡模块 1.板卡概述 该板卡可实现2路14bit 250Msps AD 和2路16bit 160MspsDA功能,FMC连接 ...
- 新建基于STM32F103ZET6的工程-HAL库版本
1.STM32F103ZET6简介 STM32F103ZET6的FLASH容量为512K,64K的SRAM.按照STM32芯片的容量产品划分,STM32F103ZET6属于大容量的芯片. 2.下载HA ...
- stm32电机控制之控制两路直流电机!看完你会了吗
手头上有一个差分驱动的小车,使用两个直流电机驱动,要实现小车的在给定速度下运动,完成直线行驶,转向,加速,刹车等复杂运动. 使用的电机是12v供电的直流电机,带编码器反馈,这样就可以采用闭环速度控制, ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- FPGA图像处理 两路sensor的色调不一致
怎么调?可以让两路sensor的色调一致.
随机推荐
- plotly-dash 简单使用(一)
plotly-dash 是一个很不错的dashboard 开发平台,基于python 编写,提供了很便捷的dashboard 开发模型 同时扩展上也比较灵活我们可以编写自己的组件. 以下是一个简单的项 ...
- ModuleNotFoundError: No module named 'suit'
ModuleNotFoundError: No module named 'suit' pip3. install suit
- Nexus OSS私服仓库的备份与迁移
背景 在上一篇博客 [Maven学习]Nexus OSS私服仓库的安装和配置 中,我们已经在机房搭建好了新的Nexus OSS私服仓库.下面是两个版本的Nexus OSS私服仓库的对比图. 老的Nex ...
- 运行虚拟机报错:CPU acceleration status: HAXM is not installed on this machine
运行虚拟机报错:CPU acceleration status: HAXM is not installed on this machine. 这是因为SDKmanage没有安装HAXM ,于是打开S ...
- C++ std::map 屏蔽排序
转载:https://blog.csdn.net/sendinn/article/details/96286849 最近在项目中用标准库中的关联性容器map,但知道map默认升序的,但在一个需求时又不 ...
- php-7.3.4 configure: error: Please reinstall the libzip distribution
php-7.3.4 configure: error: Please reinstall the libzip distribution # wget https://libzip.org/downl ...
- SNF快速开发平台2019-权限管理模型-平台服务(多平台\多组织\SAAS\多系统)
1.1 不同组织机构 通俗的讲,就是一个集团公司,划分几个区域,每个区域都有什么分公司,每个分公司都有哪些部门一样,哪些部门又有那些子部门等. 当然也可以是外贸公司的全球性客户.合作伙伴的分布情 ...
- SNF快速开发平台2019-角色、权限、账户的概念理解-非常全的理论讲解权限控制
组织模型 资源模型 操作模型 谁能够执行哪些操作 执行资源的范围 资源概念资源就是想要的到的最终物质,我们可以给每一个资源定义一个权限,也可以给某一类资源定义一个权限 权限概念权限是对资源 ...
- 如何解决Windows 10屏幕字体缩放模糊问题
https://www.ithome.com/html/win10/374911.htm 笔者前段时间买了一台小米笔记本Pro,除了有字体模糊的问题外,还是比较满意的.这台笔记本是15.6英寸,108 ...
- html5统计数据上报API:SendBeacon
公司为了精准的了解自己产品的用户使用情况,通常会对用户数据进行统计分析,获取pv.uv.页面留存率.访问设备等信息.与之相关的就是客户端的数据采集,然后上报的服务端.为了保证数据的准确性,就需要保证数 ...