15分钟内具有纯正弦波的逆变器或“电力电子设备-所有人”

什么是电力电子? 毫无疑问-这就是整个世界! 现代且充满舒适感。 许多人认为电力电子设备是“神奇的”事物,但是却四处张望-我们周围几乎所有的东西都包含一个电源转换器:笔记本电脑电源,LED灯,UPS,各种稳压器,稳压器和频率计(IF) )在通风设备或电梯中等等。 大多数此类设备使我们的生活舒适安全。

由于多种原因,电力电子学的发展是电子学中最困难的领域之一-误差价格很高,而功率转换器的发展一直吸引着爱好者,DIY工人,不仅如此。 您确定要为项目构建功能强大的电源吗? 还是几千瓦的在线不间断电源不坏了? 还是车间里的一个变种人?

今天,我将谈论我的小型开放项目,或者说它的一部分,该项目将允许任何想要进入电力电子开发领域并同时存活的人。 为了说明这种可能性,我将展示如何在15分钟内组装一个正弦输出的12V DC至230V AC电压逆变器。 感兴趣吗? 走吧




项目原因


在最近几年中,电源转换器的开发已占我订单的90%左右,主要的人工成本主要用于软件开发和原型制作,电路设计+最终电路板追踪的总成本通常不超过10-15%。 这里的理解是,包括软件开发在内的原型制作过程需要以某种方式减少和优化。

至少有两种方法可以解决:例如从Texas Instrumets或Infineon购买现成的调试工具,但是它们通常是为特定任务量身定制的,成本在500美元到5,000美元之间,无法保证会有类似的订单,并且这种投资很可能很容易不会还清。
第二种选择是自己动手做,但是彻底做就和发射“ +1修订版铁”几乎一样,这将为客户带来额外的费用。 如果做得不够彻底,那么一切将照常流鼻涕,某些地方会掉下来,直到布局,组件和时序。
一段时间后,我提请注意最明显的解决方案。 它是如此简单和明显,以至于很长一段时间以来我一直在想为什么同一个TI或Infineon尚未做到这一点。 现在,我将介绍我的“启示”。

让我们看一些最流行的电源转换器拓扑:







现在再次仔细看。 我专门画了一些东西,但没有扎带,只是使关键部分更加清晰。 这些拓扑有什么共同点? 引起您注意的第一件事是一系列共同点:
  • 所有拓扑都包括主要组件-电容器,晶体管和电感(电感器或变压器)。 这是电力电子的三大鲸鱼;
  • 晶体管在所有相同的地方导通,形成所谓的“半桥”。 几乎所有的转换器拓扑都是从中构建的。
  • 在所有拓扑中,开启半桥+电容器耦合器的选项并不会改变。 电感的类型和接通半桥的选项正在改变。


由此可以得出结论,如果某个标准模块以半桥+电容器的形式耦合,则可以通过仅添加必要的电感器或变压器来构建任何转换器。 因此,简化原型的明显解决方案是创建这样的模块:


善与恶之间的斗争


不幸的是,每天的工作时间有限,平庸的懒惰决定了他们的状况。 我一年前就需要制作此模块,但是该实现始终以“我一定在下周末做到这一点”的口号进行转移

也许这个主意会留在架子上,如果不是两场比赛的话。 首先,一个月内有2个客户来找我,每个人都希望安装一个复杂且有趣的转换器,最重要的是,他们准备好支付高昂的费用。 尽管考虑到他来自欧洲,但对他们来说可能便宜了。)这两个项目对我来说都很有趣,例如,其中一个项目是“带电流隔离的三相电压调节器(原文如此!)”,也就是说,是三相PFC + 3个桥式转换器(移相)+同步整流器+三相逆变器。 所有这些都在SiC上并且非常紧凑。 通常,我接受了2个大订单,每个订单大约800个工时,为期6个月。 结果,我被“迫不得已”寻找优化方法。

其次, PCBway公司的人意外地给写信,许多人可能从他们那里订购了板子,并愿意合作。 他们非常积极地支持开放硬件项目,即CERN的首创-开源硬件。 合作很简单,双方都可以理解-他们向我提供了我的项目的免费板,我打开了它们,并将其放在他们的网站上,也已根据要求放在其他地方。 对我来说,这成为一种额外的动力,最重要的是,我的良心很清楚,因为 多年来,我一直在订购用于原型的电路板,为了批量生产,我将其告知朋友和合作伙伴。 现在,为此,我还有一个免费的板子供小项目使用,您可以经常在集线器上写)

然后破冰,决定不仅创建先前描述的模块,而且创建整套的电力电子开发人员,并将其开放给所有人使用。

项目结构


在本文的开头,我提到今天只告诉您一部分-这是半桥电源模块 。 仅凭它,您就可以通过简单地拧入控制电路来创建转换器,例如调试STM32-Discovery,Arduino,TMS320,TL494或您在那里拥有的任何设备。 完全不绑定任何平台或MK。

仅仅是这还不是整个项目,而是一部分))完成的电源转换器由什么组成? 首先,功率单元需要一个特定的控制模块才能工作,为了了解正在发生的事情,需要一个指示,并且要从安全距离了解正在发生的事情,还有一个接口,例如Modbus RTU或CAN。

结果,该项目的总体结构如下所示:



可能在将来,我还将编写一个程序来计算常规和平面变压器和扼流圈。 到目前为止。 草案中图表的不同部分已经实现并在两个项目中运行,在进行较小的修改后,还将在其上撰写文章,并且将提供源代码。

半桥电源模块


现在是时候仔细看看今天的英雄了。 该模块具有通用性,可让您使用Mosfet和IGBT晶体管(高达1200V的低压和高压开关)工作。

模块功能:
  • 控制(数字)电源的电隔离。 绝缘击穿电压3 kV;
  • 上下键是独立的,每个键都有自己的电隔离驱动器和电隔离dc / dc;
  • 应用了英飞凌的现代驱动程序-1EDC60I12AHXUMA1。 脉冲开/关电流为6A / 10A。 最大频率-1 MHz(稳定测试高达1.5 MHz);
  • 硬件电流保护:并联+运算放大器+比较器+光耦合器;
  • 最大电流为20A。 它不受键的限制,但受散热器的大小和铜多边形的厚度的限制。


该模块的第一个修订版出现在文章中,可以完全使用,但是将有第二个修订版,其中将消除纯粹的设计缺陷,并用更方便的连接器代替连接器。 完成文档后,他将Gerber扔进PCBway,6天后快递员敲了敲我的门,给了我这样的魅力:



一周后,这些终于从一家美丽的国内商店带来了配件。 结果,一切都挂载了:





在继续之前,让我们看一下模块的电路图。 您可以在此处下载它-PDF

没有什么复杂或神奇的。 通常的半桥:底部2个键,顶部2个键,一次可以焊接一次。 正如1ED家族上面所写的那样,驾驶员非常邪恶和不朽。 电源的任何地方都有指示,包括dc / dc输出上的+ 12V。 保护是在AND逻辑元件上实现的,如果超过电流,比较器将输出+ 3.3V,它们将照亮光耦合器,并将AND输入之一拉到地,这意味着log.0的建立和来自驱动器的PWM信号将消失。 具有3个输入的AND被专门使用,在下一个修订版中,我计划提供保护以防止散热器过热,并在那里启动错误信号。 所有资源都将在本文的结尾。

我们组装逆变器布局


我考虑了很长时间,以演示该模块的操作,这样它就不会变得很无聊,有用和困难,因此任何人都可以重复它。 因此,我停在了一个电压逆变器上,它们通常用于太阳能电池板,如果低压侧有气味,这并不可怕,但是在高压侧,当您打开电源时,请勿把手伸进去。

逆变器本身非常简单,顺便说一下,MAP Energy就是这样铆接的,这里甚至是该想法的商业实现示例。 逆变器的工作是从12V直流电压形成频率为50 Hz的正弦变量,因为正因为如此,才能使用50 Hz的常规变压器工作。 我使用某种苏维埃(如OSM),220V工厂绕组并用作次级,而初级〜8V用铜线绕制。 看起来像这样:



这个怪物只有400瓦! 根据感觉,变压器的重量约为5-7公斤,如果将其放在腿上,则绝对不会被带入军队。 实际上,这是带有“铁”变压器的逆变器的缺点,它们又大又重。 他们的优点是这些逆变器非常简单,不需要任何经验,当然它们很便宜。

现在,让我们连接模块和变压器。 实际上,用于开发人员的模块应该简单地表示为“黑匣子”,它具有2个PWM输入和3个电源输出:VCC,GND和半桥输出本身。



现在,从这些“黑匣子”中,我们绘制逆变器:



是的,只需要3个外部元件:一个变压器+ LC滤波器。 对于后者,我仅通过将模块和变压器之间的导线缠绕到Kool Mu材料制成的环上就制成了扼流圈,材料为R32,磁导率为60,电感约为10μH。 当然,应该计算节气门,但我们需要15分钟))通常,如果以400 W的功率驱动类似的东西,则需要一个R46尺寸的环(这是外径)。 电容-1-10 uF的薄膜,这就足够了。 实际上,您不能将电容器作为一种经济方式,因为变压器绕组的容量是健康的……一般来说,中文和MAP就是这样))电感器看起来像这样:



仍然需要在输出上施加测试负载,我有几个20 W的LED灯泡(别无其他选择),它们本身消耗的功率却是24W。 另外,变压器的开路电流约为1A。 带电池会吃掉5A左右。 结果,我们有了这样的立场:



此外,该布局分别使用Delta HR12-17电池,电压为12V,容量为17 A * h。 我们将通过STM32F469-Discovery调试板控制转换器。

代号


最初计划使用我的STM32VL-Disco进行控制,该STM32VL-Disco于2010年在展会上收到,但它恰好是在这种布局上,注定要在编写所有代码并启动布局后死掉。 我忘记了示波器探头和2个接地点,阿们。 结果,一切都在STM32F469NIH6上进行了重写,正是此调试在即,因此将有2个项目:F100和F469,都已选中。 该项目是针对TrueSTUDIO(ST的Eclipse版本)构建的。

鞋码
#include "main.h" /********************************************* Sinus table **********************************************************/ uint16_t sinData[240] = {0,13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,207,220,233,246,258,271,284,296,309,321,333,346,358,370, 382,394,406,418,430,442,453,465,477,488,500,511,522,533,544,555,566,577,587,598,608,619,629,639,649,659,669,678,688,697, 707,716,725,734,743,751,760,768,777,785,793,801,809,816,824,831,838,845,852,859,866,872,878,884,891,896,902,908,913,918, 923,928,933,938,942,946,951,955,958,962,965,969,972,975,978,980,983,985,987,989,991,993,994,995,996,997,998,999,999,999, 999,999,999,998,997,996,995,994,993,991,989,987,985,983,980,978,975,972,969,965,962,958,955,951,946,942,938,933,928,923, 918,913,908,902,896,891,884,878,872,866,859,852,845,838,831,824,816,809,801,793,785,777,768,760,751,743,734,725,716,707, 697,688,678,669,659,649,639,629,619,608,598,587,577,566,555,544,533,522,511,500,488,477,465,453,442,430,418,406,394,382, 370,358,346,333,321,309,296,284,271,258,246,233,220,207,195,182,169,156,143,130,117,104,91,78,65,52,39,26,13,0}; uint16_t sinStep; uint8_t sinStatus; /******************************************** Used functions ********************************************************/ void StartInitClock (void) { RCC->CR |= RCC_CR_HSEON; // Enable HSE while (!(RCC->CR & RCC_CR_HSERDY)); FLASH->ACR |= FLASH_ACR_LATENCY_5WS; RCC->PLLCFGR = 0x00; RCC->PLLCFGR |= RCC_PLLCFGR_PLLM_3; // Div for HSE = 8 RCC->PLLCFGR |= RCC_PLLCFGR_PLLN_4 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7; // PLL mult x240 RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC; // Source HSE RCC->CR |= RCC_CR_PLLON; while((RCC->CR & RCC_CR_PLLRDY) == 0){} RCC->CFGR &= ~RCC_CFGR_SW; RCC->CFGR |= RCC_CFGR_SW_PLL; // Select source SYSCLK = PLL while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1) {} // Wait till PLL is used RCC->CR |= RCC_CR_PLLSAION; while ((RCC->CR & RCC_CR_PLLSAIRDY) == 0) {} } void EnableOutputMCO (void) { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // Enable clock port A GPIOA->MODER &= ~GPIO_MODER_MODER8; GPIOA->MODER |= GPIO_MODER_MODER8_1; // Alternative PP GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8; // Very high speed RCC->CFGR |= RCC_CFGR_MCO1; // Source PLL RCC->CFGR &= ~RCC_CFGR_MCO1PRE; // Div = 1 } void InitIndicatorLED (void) { /* * LED1 - PG6 * LED2 - PD4 * LED3 - PD5 * LED4 - PK3 */ RCC->AHB1ENR |= RCC_AHB1ENR_GPIOGEN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOKEN; GPIOG->MODER &= ~GPIO_MODER_MODER6; GPIOG->MODER |= GPIO_MODER_MODER6_0; // Output PP GPIOD->MODER &= ~GPIO_MODER_MODER4; GPIOD->MODER |= GPIO_MODER_MODER4_0; // Output PP GPIOD->MODER &= ~GPIO_MODER_MODER5; GPIOD->MODER |= GPIO_MODER_MODER5_0; // Output PP GPIOK->MODER &= ~GPIO_MODER_MODER3; GPIOK->MODER |= GPIO_MODER_MODER3_0; // Output PP } void EnableIndicatorLED (void) { GPIOG->BSRR |= GPIO_BSRR_BR_6; GPIOD->BSRR |= GPIO_BSRR_BR_4; GPIOD->BSRR |= GPIO_BSRR_BR_5; GPIOK->BSRR |= GPIO_BSRR_BR_3; } void InitLowPWM (void) { /* * TIM1-CH1 - PA8 * TIM1-CH1N - PB13 */ RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; /*********** GPIO **********/ GPIOA->MODER &= ~GPIO_MODER_MODER8; GPIOA->MODER |= GPIO_MODER_MODER8_1; // Alternative output PP GPIOA->AFR[1] |= GPIO_AFRH_AFRH0_0; // Select TIM1-CH1 GPIOB->MODER &= ~GPIO_MODER_MODER13; GPIOB->MODER |= GPIO_MODER_MODER13_1; // Alternative output PP GPIOB->AFR[1] |= GPIO_AFRH_AFRH5_0; // Select TIM1-CH1N /*********** Timer *********/ TIM1->PSC = 2400-1; // div for clock: F = SYSCLK / [PSC + 1] TIM1->ARR = 1000; // count to 1000 TIM1->CR1 &= ~TIM_CR1_CKD; // div for dead-time: Tdts = 1/Fosc = 41.6 ns TIM1->CCR1 = 500; // duty cycle 50% TIM1->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1NE; // enable PWM complementary out to PB15 and to PA10 TIM1->CCER &= ~TIM_CCER_CC1NP; // active high level: 0 - high, 1 - low TIM1->CCMR1 &= ~TIM_CCMR1_OC1M; TIM1->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // positiv PWM1_CH3 and PWM1_CH3N TIM1->BDTR &= ~TIM_BDTR_DTG; // clear register TIM1->BDTR |= TIM_BDTR_DTG_2 | TIM_BDTR_DTG_1 | TIM_BDTR_DTG_0; // value dead-time: = 31*Tdts = 32*41,6ns = 1.29us TIM1->BDTR |= TIM_BDTR_MOE | TIM_BDTR_AOE; // enable generation output and dead-time TIM1->CR1 &= ~TIM_CR1_DIR; // count up: 0 - up, 1 - down TIM1->CR1 &= ~TIM_CR1_CMS; // aligned on the front signal: 00 - front; 01, 10, 11 - center TIM1->CR1 |= TIM_CR1_CEN; // start count } void InitSinusPWM (void) { /* * TIM3-CH1 - PB4 * TIM3-CH2 - PC7 */ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN; RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; /*********** GPIO **********/ GPIOB->MODER &= ~GPIO_MODER_MODER4; GPIOB->MODER |= GPIO_MODER_MODER4_1; // Alternative output PP GPIOB->AFR[0] |= GPIO_AFRL_AFRL4_1; // Select TIM3-CH1 GPIOC->MODER &= ~GPIO_MODER_MODER7; GPIOC->MODER |= GPIO_MODER_MODER7_1; // Alternative output PP GPIOC->AFR[0] |= GPIO_AFRL_AFRL7_1; // Select TIM3-CH2 /*********** Timer *********/ TIM3->PSC = 5-1; // div for clock: F = SYSCLK / [PSC + 1] TIM3->ARR = 1000; // count to 1000 TIM3->CCR1 = 0; // duty cycle 0% TIM3->CCR2 = 0; // duty cycle 0% TIM3->CCER |= TIM_CCER_CC1E; // enable PWM out to PA8 TIM3->CCER &= ~TIM_CCER_CC1P; // active high level: 0 - high, 1 - low TIM3->CCER |= TIM_CCER_CC2E; // enable PWM complementary out to PA9 TIM3->CCER &= ~TIM_CCER_CC1P; // active high level: 0 - high, 1 - low TIM3->CCMR1 &= ~(TIM_CCMR1_OC1M | TIM_CCMR1_OC2M); TIM3->CCMR1 |= TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2M_1; // positiv PWM1_CH1 and PWM1_CH2 TIM3->CR1 &= ~TIM_CR1_DIR; // count up: 0 - up, 1 - down TIM3->CR1 &= ~TIM_CR1_CMS; // aligned on the front signal: 00 - front; 01, 10, 11 - center TIM3->CR1 |= TIM_CR1_CEN; // start count } void InitStepSinus (void) { RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; // enable clock for basic TIM6 TIM6->PSC = 5-1; // div, frequency 24 kHz TIM6->ARR = 1000; // count to 1000 TIM6->DIER |= TIM_DIER_UIE; // enable interrupt for timer TIM6->CR1 |= TIM_CR1_CEN; // start count NVIC_EnableIRQ(TIM6_DAC_IRQn); // enable interrupt TIM6_DAC_IRQn } /************************************* Main code *********************************************/ int main (void) { StartInitClock(); // EnableOutputMCO(); InitIndicatorLED(); InitLowPWM(); InitSinusPWM(); InitStepSinus(); EnableIndicatorLED(); while(1) { } } /****************************** Interrupts ******************************************************/ void TIM6_DAC_IRQHandler (void) { TIM6->SR &= ~TIM_SR_UIF; if (sinStatus == 0) {TIM3->CCR1 = sinData[sinStep];} if (sinStatus == 1) {TIM3->CCR2 = sinData[sinStep];} sinStep++; if (sinStep >= 240) { sinStep = 0; sinStatus = sinStatus ? 0 : 1; } } 


总的来说,他在另一篇文章中详细详细地描述了如何生成正弦信号,如何编写代码等。 您可以在这里阅读。

你看过吗 要收集吗? 保留项目:


我们运行代码,用示波器武装自己,然后继续。 首先,我们检查驱动程序输入端是否存在信号,它应该像这样:



值得注意的是,我给出了两个在一个半桥(模块)上画正弦的信号,并在两个信号上画出了50 Hz。 此外,一个对角线是“红色+黄色”,另一个是“蓝色+绿色”。 如果您突然不明白,在上面的文章中,这是详细编写的。 现在,随着信号的到来,我们从实验室电源上同时接通了半桥+ 12V和GND。 电池无法立即显示,如果您在某个地方犯了错误,则可能会烧毁某些东西。 当正负混合在一起时,板上的保护可以避免过电流,但不能避免明显的侧边,但是实验室技术人员可以节省。 12V和1A足以进行测试。 我们将示波器的探头,地线连接到第一个半桥的输出,并将探头本身连接到另一个半桥的输出,应该有这样的图片:



您问的正弦值在哪里? 事实是,示波器的输入电阻很大,并且不构成负载,因此电流不会流过,也没有从那里获得正弦波的地方。 添加一个负载,我通过简单地串联9个元件,用10 Ohm的电阻制成了90 Ohm的负载。 我们将负载挂接到半桥的输出,并看到下图:



你有一样吗? 因此,是时候连接电感器,变压器,负载并尝试启动了。 啊! 您不能在没有负载的情况下打开此型号,因为在空闲状态下,输出最高可以达到350 ... 380V。 这样就不需要负载或OS。 我们将没有最后一篇,这是另一篇文章的主题,您可以像可选的一样简单地拧紧P-regulator,您已经有一个项目模板。

包容性


接通电源后,我们在输出端获得约230V的电压,输出肯定不稳定,并会浮动230V + -30V,以进行测试。在另一篇文章中,当我决定谈论P和PI控制器及其实现时,我们将最终确定布局。

现在,您可以享受工作的成果,如果有必要,可以将所有物品放在盒子里,甚至可以在农场或乡下使用,为自己提供照明和其他便利设施。



您可能已经注意到“咔嗒”声之间的延迟,即为Discovery供电和打开灯之间的时间-这是MK在初始化上花费的时间。 可以通过立即将一个数字写入寄存器而不是将寄存器条目分成几行来减少这种延迟。 我将其粉碎只是出于说明目的。 尽管这并不可怕,但是使用HAL代码时,延迟会延长3倍,并且人们会以某种方式忍受它))

直到我忘记了,项目的来源:



如果有任何特别的热点,还有待观察电路板上的温度如何。 5-6A当然还不够,但是如果存在直通电流或某些严重错误,则足以将板子变成水壶:



如您所见,最热的元件是用于电流隔离的dc / dc模块,功率为2瓦,可加热到34度,也是分流器。 转换器运行30分钟后,晶体管和散热器本身的环境温度))

谢谢和计划


我计划在不久的将来写出关于DSP板的信息,并从调试发现中而不是从“专用”模块中进行管理。 第2修订版的电路板是从同一PCBway过来的,我等待组件,然后立即写。

我希望您喜欢这篇文章和想法本身。 将来,在相同的模块上,我将展示如何组装chastotnik,mppt控制器或其他有趣的东西。 如果您有任何疑问,请随时在评论中或PM中询问,如果您突然没有完整的帐户,我将尽力回答所有问题。

现在要感谢PCBway ,他们支持开源引擎实际上是非常好的。 很快,硬件制造商甚至可能在开源项目的数量和质量方面赶上软件编写者。

Source: https://habr.com/ru/post/zh-CN428550/


All Articles