基于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的色调一致.
随机推荐
- 假设检验总结以及如何用python进行假设检验(scipy)
几种常见的假设检验总结如下: 假设检验名称 Z检验 t检验 χ2检验 F检验 原假设 H0: μ≥μ0 H0: μ≤μ0 H0: μ=μ0 (比较样本和总体均值) ...
- fiddler实现B/S端、APP抓包分析遇到的各种疑问
阅读本文前您需要先下载fiddler并成功安装,并且要有一丢丢测试和接口基础或者在学习fidder时遇到了问题,或许本文可以帮助到你 一.B/S端抓包 Fiddler设置 1. 官网下载fiddler ...
- 您使用的私钥格式错误,请检查RSA私钥配置,charset = utf-8 密钥集不存在
支付宝突然报异常 您使用的私钥格式错误,请检查RSA私钥配置,charset = utf-8 经排查:系统日志 System.Security.Cryptography.CryptographicEx ...
- proxmox之cloud-init
Cloud-Init支持 Cloud-Init是事实上的多分发包,它处理虚拟机实例的早期初始化.使用Cloud-Init,可以在虚拟机管理程序端配置网络设备和ssh密钥.当VM首次启动时,VM内的Cl ...
- Java常见集合的默认大小及扩容机制
在面试后台开发的过程中,集合是面试的热话题,不仅要知道各集合的区别用法,还要知道集合的扩容机制,今天我们就来谈下ArrayList 和 HashMap的默认大小以及扩容机制. 在 Java 7 中,查 ...
- sql脱库的几种方法
当发现sql注入之后,脱库的方法,有以下几种: (1)当目标主机支持外部连接时,使用Navicat 进行连接!当时目标主机不同,使用的Navicat种类不一样: mysql : Navicat f ...
- 利用python实现汉字转拼音
安装:pip install pypinyin import pypinyin # 不带声调的(style=pypinyin.NORMAL) def pinyin(word): s = '' for ...
- The Rise of Meta Learning
The Rise of Meta Learning 2019-10-18 06:48:37 This blog is from: https://towardsdatascience.com/the- ...
- SQLServer : 找中间日期
假设找 一个日期居于[ 2022-03-10, 2022-05-11 ]的正中间
- CefSharp中文帮助文档
https://github.com/cefsharp/CefSharp/wiki/CefSharp%E4%B8%AD%E6%96%87%E5%B8%AE%E5%8A%A9%E6%96%87%E6%A ...