基于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的色调一致.
随机推荐
- 抽样方法(Sampling Method)
概率抽样方法: 1. 随机抽样(random sampling):从有限总体中简单随机抽样或从无限总体中随机抽样. 具体实现方式:a. 抽签法:b. 随机数字法 2. 分层抽样(stratified ...
- .NET 爬虫总结
前言 技术本身并无罪,罪恶本质在于人心,好比厨师手中的菜刀用来创造美味佳肴,而杀手手上的刀却用来创造无限的罪恶. 环境 win7 IIS 6.0 SQLserver2012 .NET 4.0 win ...
- C++中list的用法总结
list简介 list 也是顺序容器的一种.只是list 是一个双向链表.使用 list 需要包含头文件 list.双向链表的每个元素中都有一个指针指向后一个元素,也有一个指针指向前一个元素,如下图所 ...
- [题解向] Luogu2146[NOI2015]软件包管理器
#\(\mathcal{\color{red}{Description}}\) \(Link\) 一道\(zz\)的树剖题\(qwq\). #\(\mathcal{\color{red}{Soluti ...
- Guava 库
https://www.yiibai.com/guava https://wizardforcel.gitbooks.io/guava-tutorial/content/1.html com.goog ...
- ChannelEventRunnable handle RECEIVED operation error, channel is NettyChannel解决方法
[] 2019-11-23 16:17:40 [3673645] [c.a.d.r.t.d.ChannelEventRunnable]-[WARN] DubboServerHandler-10.20. ...
- Linux虚拟机:发布WebService接口出现异常,无法访问接口
Linux虚拟机:发布WebService接口出现异常,无法访问接口 今天在部署WebService工程的时候遇到的问题: 在Linux虚拟机上部署一个tomcat同时在tomcat下放置2个工程,其 ...
- linux命令(56):环境变量:/etc/profile、/etc/bashrc 、~/.profile、~/.bashrc
添加环境变量:https://www.cnblogs.com/lovychen/p/5583703.html 一.环境变量介绍: 在Linux系统中,环境变量按照其作用范围不同大致可以分为系统级环境变 ...
- nanopi的ds18b20温度传感器测试
参考(抄袭)资料在这里 先接线,3.3v,gnd,数据输出脚,我是PG11 vim /boot/armbianEnv.txt overlays=w1-gpio param_w1_pin=PG11 pa ...
- Centos7.6使用yum安装PHP7.2
Centos7.6使用yum安装PHP7.2 1.安装源 安装php72w,是需要配置额外的yum源地址的,否则会报错不能找到相关软件包. php高版本的yum源地址,有两部分,其中一部分是epel- ...