2022.4.26更新

若需商业合作可私聊留VX号,博主看到后会添加的。

--------------------------------------------------------------------------------------------------------------------------

最近在做单相逆变器,用篇文章来记录。

主电路采用H桥,使用IR2104半桥驱动内置630ns死区,上管采用自举电容浮地驱动

SPWM采用STM32F103C8T6产生两路互补的30K Hz 的SPWM。

LC滤波器的截止频率约为开关频率的1/10~1/5,我选的是30KHz的开关频率,则LC滤波器的截止频率约为3K,即截止频率越小越好。

电流检测采样ACS712,该芯片可以直接测DC电流和AC电流,缺点就是温漂较大,测量精度较小。适合于对精度要求不高的场合。

电压检测利用全桥整流,后经电压分压,稳压管是为了保护单片机AD转换输入口的电压,将其钳位在3V以下。

SPWM产生使用单片机查表产生。

正弦表值

正弦表计算时要注意ARR寄存器的最大值和最小值。

由于单片机的自动重装载寄存器ARR是无符号二进制,所以要将正弦表值在0.5ARR的偏置。

当占空比大于0.5输出为正,当占空比小于0.5输出为负。

PWM的开关频率要大于15KHz,我用的是30KHz

输出正弦波的频率

其中N是正弦波一周期内采样数,也即正弦表数组中数的总数。

通过定时器中断来更新比较寄存器CCR的值,以使PWM的脉宽按正弦规律变化。

如果需要调压,可以将正弦表值乘以一小于1.0的调压系数,需要注意的是单片机的正弦表是按单极性计算出来的,所以调压在程序上要分两步。

附上timer部分代码

/*
******************************************************************************
*Filename      :timer.c
*Programmer(s) :SueRocket
*Description   :Single phase inverter
******************************************************************************
*/#include "stm32f10x.h"
#include "timer.h"double K_Voltage = 1.0;  //调压系数const u32 spwm[600]={
0x4000,0x40AC,0x4157,0x4203,0x42AE,0x4359,0x4405,0x44B0,0x455B,0x4606,
0x46B0,0x475B,0x4805,0x48AF,0x4959,0x4A03,0x4AAC,0x4B55,0x4BFE,0x4CA6,
0x4D4E,0x4DF6,0x4E9D,0x4F44,0x4FEA,0x5090,0x5136,0x51DB,0x527F,0x5323,
0x53C7,0x546A,0x550C,0x55AE,0x564F,0x56EF,0x578F,0x582E,0x58CD,0x596A,
0x5A08,0x5AA4,0x5B40,0x5BDA,0x5C74,0x5D0E,0x5DA6,0x5E3E,0x5ED5,0x5F6A,
0x6000,0x6094,0x6127,0x61B9,0x624A,0x62DB,0x636A,0x63F9,0x6486,0x6512,
0x659E,0x6628,0x66B1,0x6739,0x67C0,0x6846,0x68CB,0x694F,0x69D1,0x6A52,
0x6AD2,0x6B51,0x6BCF,0x6C4B,0x6CC7,0x6D41,0x6DB9,0x6E31,0x6EA7,0x6F1B,
0x6F8F,0x7001,0x7072,0x70E1,0x714F,0x71BC,0x7227,0x7291,0x72FA,0x7361,
0x73C6,0x742A,0x748D,0x74EE,0x754E,0x75AC,0x7609,0x7664,0x76BD,0x7716,
0x776C,0x77C1,0x7815,0x7866,0x78B7,0x7905,0x7952,0x799E,0x79E8,0x7A30,
0x7A77,0x7ABC,0x7AFF,0x7B41,0x7B81,0x7BBF,0x7BFB,0x7C36,0x7C70,0x7CA7,
0x7CDD,0x7D11,0x7D44,0x7D74,0x7DA3,0x7DD1,0x7DFC,0x7E26,0x7E4E,0x7E74,
0x7E99,0x7EBC,0x7EDD,0x7EFC,0x7F1A,0x7F35,0x7F4F,0x7F67,0x7F7E,0x7F92,
0x7FA5,0x7FB6,0x7FC6,0x7FD3,0x7FDF,0x7FE9,0x7FF1,0x7FF7,0x7FFB,0x7FFE,
0x7FFF,0x7FFE,0x7FFB,0x7FF7,0x7FF1,0x7FE9,0x7FDF,0x7FD3,0x7FC6,0x7FB6,
0x7FA5,0x7F92,0x7F7E,0x7F67,0x7F4F,0x7F35,0x7F1A,0x7EFC,0x7EDD,0x7EBC,
0x7E99,0x7E74,0x7E4E,0x7E26,0x7DFC,0x7DD1,0x7DA3,0x7D74,0x7D44,0x7D11,
0x7CDD,0x7CA7,0x7C70,0x7C36,0x7BFB,0x7BBF,0x7B81,0x7B41,0x7AFF,0x7ABC,
0x7A77,0x7A30,0x79E8,0x799E,0x7952,0x7905,0x78B7,0x7866,0x7815,0x77C1,
0x776C,0x7716,0x76BD,0x7664,0x7609,0x75AC,0x754E,0x74EE,0x748D,0x742A,
0x73C6,0x7361,0x72FA,0x7291,0x7227,0x71BC,0x714F,0x70E1,0x7072,0x7001,
0x6F8F,0x6F1B,0x6EA7,0x6E31,0x6DB9,0x6D41,0x6CC7,0x6C4B,0x6BCF,0x6B51,
0x6AD2,0x6A52,0x69D1,0x694F,0x68CB,0x6846,0x67C0,0x6739,0x66B1,0x6628,
0x659E,0x6512,0x6486,0x63F9,0x636A,0x62DB,0x624A,0x61B9,0x6127,0x6094,
0x6000,0x5F6A,0x5ED5,0x5E3E,0x5DA6,0x5D0E,0x5C74,0x5BDA,0x5B40,0x5AA4,
0x5A08,0x596A,0x58CD,0x582E,0x578F,0x56EF,0x564F,0x55AE,0x550C,0x546A,
0x53C7,0x5323,0x527F,0x51DB,0x5136,0x5090,0x4FEA,0x4F44,0x4E9D,0x4DF6,
0x4D4E,0x4CA6,0x4BFE,0x4B55,0x4AAC,0x4A03,0x4959,0x48AF,0x4805,0x475B,
0x46B0,0x4606,0x455B,0x44B0,0x4405,0x4359,0x42AE,0x4203,0x4157,0x40AC,
0x4000,0x3F54,0x3EA9,0x3DFD,0x3D52,0x3CA7,0x3BFB,0x3B50,0x3AA5,0x39FA,
0x3950,0x38A5,0x37FB,0x3751,0x36A7,0x35FD,0x3554,0x34AB,0x3402,0x335A,
0x32B2,0x320A,0x3163,0x30BC,0x3016,0x2F70,0x2ECA,0x2E25,0x2D81,0x2CDD,
0x2C39,0x2B96,0x2AF4,0x2A52,0x29B1,0x2911,0x2871,0x27D2,0x2733,0x2696,
0x25F8,0x255C,0x24C0,0x2426,0x238C,0x22F2,0x225A,0x21C2,0x212B,0x2096,
0x2001,0x1F6C,0x1ED9,0x1E47,0x1DB6,0x1D25,0x1C96,0x1C07,0x1B7A,0x1AEE,
0x1A62,0x19D8,0x194F,0x18C7,0x1840,0x17BA,0x1735,0x16B1,0x162F,0x15AE,
0x152E,0x14AF,0x1431,0x13B5,0x1339,0x12BF,0x1247,0x11CF,0x1159,0x10E5,
0x1071,0x0FFF,0x0F8E,0x0F1F,0x0EB1,0x0E44,0x0DD9,0x0D6F,0x0D06,0x0C9F,
0x0C3A,0x0BD6,0x0B73,0x0B12,0x0AB2,0x0A54,0x09F7,0x099C,0x0943,0x08EA,
0x0894,0x083F,0x07EB,0x079A,0x0749,0x06FB,0x06AE,0x0662,0x0618,0x05D0,
0x0589,0x0544,0x0501,0x04BF,0x047F,0x0441,0x0405,0x03CA,0x0390,0x0359,
0x0323,0x02EF,0x02BC,0x028C,0x025D,0x022F,0x0204,0x01DA,0x01B2,0x018C,
0x0167,0x0144,0x0123,0x0104,0x00E6,0x00CB,0x00B1,0x0099,0x0082,0x006E,
0x005B,0x004A,0x003A,0x002D,0x0021,0x0017,0x000F,0x0009,0x0005,0x0002,
0x0001,0x0002,0x0005,0x0009,0x000F,0x0017,0x0021,0x002D,0x003A,0x004A,
0x005B,0x006E,0x0082,0x0099,0x00B1,0x00CB,0x00E6,0x0104,0x0123,0x0144,
0x0167,0x018C,0x01B2,0x01DA,0x0204,0x022F,0x025D,0x028C,0x02BC,0x02EF,
0x0323,0x0359,0x0390,0x03CA,0x0405,0x0441,0x047F,0x04BF,0x0501,0x0544,
0x0589,0x05D0,0x0618,0x0662,0x06AE,0x06FB,0x0749,0x079A,0x07EB,0x083F,
0x0894,0x08EA,0x0943,0x099C,0x09F7,0x0A54,0x0AB2,0x0B12,0x0B73,0x0BD6,
0x0C3A,0x0C9F,0x0D06,0x0D6F,0x0DD9,0x0E44,0x0EB1,0x0F1F,0x0F8E,0x0FFF,
0x1071,0x10E5,0x1159,0x11CF,0x1247,0x12BF,0x1339,0x13B5,0x1431,0x14AF,
0x152E,0x15AE,0x162F,0x16B1,0x1735,0x17BA,0x1840,0x18C7,0x194F,0x19D8,
0x1A62,0x1AEE,0x1B7A,0x1C07,0x1C96,0x1D25,0x1DB6,0x1E47,0x1ED9,0x1F6C,
0x2001,0x2096,0x212B,0x21C2,0x225A,0x22F2,0x238C,0x2426,0x24C0,0x255C,
0x25F8,0x2696,0x2733,0x27D2,0x2871,0x2911,0x29B1,0x2A52,0x2AF4,0x2B96,
0x2C39,0x2CDD,0x2D81,0x2E25,0x2ECA,0x2F70,0x3016,0x30BC,0x3163,0x320A,
0x32B2,0x335A,0x3402,0x34AB,0x3554,0x35FD,0x36A7,0x3751,0x37FB,0x38A5,
0x3950,0x39FA,0x3AA5,0x3B50,0x3BFB,0x3CA7,0x3D52,0x3DFD,0x3EA9,0x3F54,
};                                          //占空比为:(32767-spwm[i])/32767 = 1-(period*spwm[i])/period
u32 sinpwm;
static u16 i = 0;              //表示正弦波取样点u16 TimerPeriod   = 0;   //自动重装载值
u16 Channel1Pulse = 0;
extern float Period_percent;/********************************************************     定时器1产生4路互补的PWM波(频率=pfreq / (psc+1))*    channel1 ,channel2 -->A.8  A.9channel1N,channel2N-->B.13  B.14(互补)*     TimerPeriod   --> 自动重装载周期值*      ChannelxPulse --> 占空周期值******************************************************/
void TIM1_PWM_Init(u16 pfreq ,u16 psc)          //pfreq为不分频时的PWM频率,psc为预分频值
{  GPIO_InitTypeDef                  GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure;    TIM_OCInitTypeDef            TIM_OCInitStructure;           //输出通道配置TimerPeriod = (SystemCoreClock / pfreq) - 1;           //自动重装载周期值/* ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 */Channel1Pulse = (u16)((u32)(50  * (TimerPeriod - 1)) / 100 );  //占空比50%/* 使能TIM1,GPIOA,GPIOB,GPIOE */RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); /*channel1 ,channel2 -->A.8,A.9*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;GPIO_Init(GPIOB, &GPIO_InitStructure);/*  初始化TIM1  */TIM_TimeBaseStructure.TIM_Period            = TimerPeriod;       //设置重装载周期值  TIM_TimeBaseStructure.TIM_Prescaler         = psc;                    //设置预分频值 TIM_TimeBaseStructure.TIM_ClockDivision     = 0;                  //时钟分频因子,仅与输入捕获有关(定时器与滤波器的频率比)TIM_TimeBaseStructure.TIM_CounterMode       = TIM_CounterMode_Up;//TIM向上计数模式TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;                //重复溢出中断TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);                  //初始化定时器基本配置/* TIM_OCMode_PWM1模式 */     TIM_OCInitStructure.TIM_OCMode       = TIM_OCMode_PWM1;            //在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平TIM_OCInitStructure.TIM_OutputState  = TIM_OutputState_Enable;     //比较输出使能TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;    //PWM互补输出使能TIM_OCInitStructure.TIM_Pulse        = Channel1Pulse;           //占空比 = TIM_Pulse/TIM_Period;TIM_OCInitStructure.TIM_OCPolarity   = TIM_OCPolarity_High;      //有效电平为高电平TIM_OCInitStructure.TIM_OCNPolarity  = TIM_OCNPolarity_High;     //互补PWM极性TIM_OCInitStructure.TIM_OCIdleState  = TIM_OCIdleState_Reset;         //原 TIM_OCIdleState_Reset输出空闲状态TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;      //PWM互补输出空闲状态TIM_OC1Init(TIM1, &TIM_OCInitStructure);                           //根据指定的参数初始化外设TIM1 OCTIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);     //使能TIM3在CCR1上的预装载寄存器TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);      //使能TIM3在CCR2上的预装载寄存器TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE );                //使能指定的TIM2中断,允许更新中断(计数器溢出或软件初始化时)NVIC_InitStructure.NVIC_IRQChannel                   = TIM1_UP_IRQn;  //TIM1中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;          //主优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;          //从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;     //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);                                    //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器TIM_Cmd(TIM1, ENABLE);                       //使能TIM1TIM_CtrlPWMOutputs(TIM1,ENABLE);    //PWM输出使能
}//定时器1中断服务程序
void TIM1_UP_IRQHandler(void)
{if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)  //检查TIM1更新中断发生与否{   if(spwm[i]>16384){sinpwm = K_Voltage * (spwm[i]-16384);TIM_SetCompare1(TIM1,(u16)(Period_percent * (sinpwm + 16384) )) ;TIM_SetCompare2(TIM1,(u16)(Period_percent * (sinpwm + 16384) )) ;}else if(spwm[i]<=16384){sinpwm = K_Voltage * (16384 - spwm[i]);TIM_SetCompare1(TIM1,(u16)(Period_percent * (16384 - sinpwm) )) ; //修改TIM1通道1的PWM占空比,后者为捕获/比较寄存器1的值TIM_SetCompare2(TIM1,(u16)(Period_percent * (16384 - sinpwm) )) ;   //修改TIM1通道1的PWM占空比,后者为捕获/比较寄存器1的值}i++;if(i == 600)  //一周期采样600个点{i = 0;}TIM_ClearITPendingBit(TIM1, TIM_IT_Update);  //清除TIM1更新中断标志 }
}

单相逆变器及基于STM32 SPWM生成代码相关推荐

  1. 基于scratch-blocks进行生成代码

    最近研究了下scratch图形化编程,发现可以生成一些自己想要的代码,挺有意思.自己做了下生成lua代码为例的demo.现在开源来玩玩. 地址如下 GitHub - zhangweihong/scra ...

  2. 基于GPT-4免费生成代码的工具!小游戏,管理系统都能生成!

    Cursor支持Python.Java.C++.JavaScript.C#等等,可AI生成代码,功能非常强大!这篇教程将教你如何下载安装,带你玩转Cursor 目录 话不多说,先看能力: 只需要三步, ...

  3. stm32 电机库生成代码出错原因 stm32 cuble生成代码出错原因

    原因1 第一个原因比较简单,是新手比较容易犯错的,就算路径中有汉语的问题 原因2 第二个原因就很隐蔽了,而且目前全网也很少有帖子谈及到第二个原因就是你的java环境(注意:stm32cubemx运行在 ...

  4. C语言 | 基于STM32的IIC代码实现(源代码)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 /*************** ...

  5. 高频隔离型光伏离网单相逆变器的控制算法的C代码+仿真模型

    高频隔离型光伏离网单相逆变器的控制算法的C代码+仿真模型,DC70~150V输入,AC220V 50Hz输出: 主回路DC DC+DC AC,相较于传统的非隔离型光伏逆变器,前级DC DC不再采用bo ...

  6. 基于Stm32的4G模块实现内网透传通信(代码后附)

    基于Stm32的4G模块实现内网透传通信 一.内网透传即内网映射,内网IP端口映射外网连接访问过程的实现.内网透传通信实现过程又有以下几种区别: 1)路由器映射.适合自己本地路由有公网IP网络环境,用 ...

  7. 基于wsimport生成代码的客户端

    概述 wsimport是jdk自带的命令,可以根据wsdl文档生成客户端中间代码,基于生成的代码编写客户端,可以省很多麻烦. wsimport命令 wsimport的用法 wsimport [opti ...

  8. sql自动生成工具_可自动生成代码,5款基于AI的开发工具

    如今,对机器学习潜力感兴趣的程序员都在讨论,如何使用人工智能和基于人工智能的软件开发工具构建应用程序.例如PyTorch和TensorFlow之类的解决方案. 除此之外,机器学习技术正以另一种有趣的方 ...

  9. pyqt漂亮gui界面模板_一种基于模板的C代码自动生成方法

    在做C代码项目的时候,我们期望做到代码的高复用,高复用意味着代码的高配置性,即通过简单的配置修改达到复用代码的目的.如果代码高复用,支持灵活的配置,那么完全可以在上边做一个更简单的配置工具,用来修改代 ...

最新文章

  1. HTML4.0 / XHTML 1.0 Reference Manual
  2. linux命令 pushd和popd
  3. 同步服务老是报错_悬而未决:MYSQL配置好主从同步后没有报错,但数据一直没有同步过来是什么原因? | 学步园...
  4. 为什么不应该使用(长期存在的)功能分支
  5. linux下spi有哪些函数,linux下怎么快速的使用 SPI 驱动。
  6. 蓝桥杯历届试题----矩阵翻硬币
  7. EL表达式---自定义函数(转)
  8. kafka报错:Error writing out kafka.log:type=Log,name=LogStartOffset,topic=xx EofException
  9. scal的函数定义(day01)
  10. 0011-绝对值函数
  11. 388. Longest Absolute File Path
  12. unity双面显示shader
  13. 精译丨贝莱德掌舵人拉里 · 芬克:华尔街是什么
  14. mysql backup user_mysql备份常见命令
  15. WIN10系统——打开PB的帮助文档
  16. 计算广告学--笔记(1)
  17. SAP 财务-统驭科目
  18. 用Python走入史学经典《三国演义》中的社交网络
  19. 路由器自动连接服务器无响应,路由器服务器无响应怎么办
  20. 目标与计划:仰望星空且脚踏实地

热门文章

  1. LR(0)项目集规范族和分析表的构造
  2. 遨博协作机器人ROS开发 - 机械臂规划场景构建
  3. ad safe5.0.630.9901懂你版补丁包
  4. 华为机试—姓名的夫妻相
  5. 北斗民码伪码生成电路
  6. 台达PLC通讯程序,PLC采用台达,触摸屏采用中达电通触摸屏软件编辑
  7. 【DIY】使用STM32及PID算法实现一个磁悬浮玩具
  8. 计算机网络实验思科实验报告,计算机网络思科综合性实验报告
  9. freeline集成
  10. SSH服务器拒绝了密码,请再输入一次(解决方法)