单相逆变电源软件设计

这篇具有很好参考价值的文章主要介绍了单相逆变电源软件设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单相逆变电源软件设计

一、题目要求

1.题目

单相逆变程序,fpga开发,c语言,单片机
要求设计并制作输入为15V直流电压,输出为10V正弦交流电压的单相逆变电源。

2.系统总体框图

单相逆变程序,fpga开发,c语言,单片机软件思路:
FPGA:利用Matlab生成正弦及三角波查找表,在Quartus中使用rom查表产生正弦波与三角波,比较二者的大小,正弦波大于三角波为“1”,正弦波小于三角波为“0”(双极性调制),产生两路互补的SPWM波,经由逆变电路及滤波电路最终可以得到正弦交变电压,通过改变正弦波的幅值可以改变最终输出电压的大小。
单片机:接收频率设定并传给FPGA,显示当前状态,进行AD采样数字信号到具体值的转换,PID算法稳压。
AD采样:采用ADS8688进行采样,通过积分法 U r m s 2 = 1 T ∫ 0 T ∣ U ∣ 2 d t U_{rms}^2=\frac{1}{T}{\int_{0}^{T}}\left| U \right| ^ 2dt Urms2=T10TU2dt得到交流有效值。

二、控制核心及环境配置

tiva系列单片机:TM4C123GH6PM
Cyclone IVE 系列FPGA:EP4CE6E22C8
IDE:Code Composer Studio 以及 Quartus 17.0

1.CCS环境配置

Code Composer Studio配置:
单相逆变程序,fpga开发,c语言,单片机
单相逆变程序,fpga开发,c语言,单片机

2.Quartus环境配置

Quartus 17.0配置:
单相逆变程序,fpga开发,c语言,单片机
单相逆变程序,fpga开发,c语言,单片机

三、软件核心功能

1.产生SPWM波

方案一:单极性调制
单相逆变程序,fpga开发,c语言,单片机
方案二:双极性调制
单相逆变程序,fpga开发,c语言,单片机
这里我使用的是方案二,双极性调制产生正弦波。
首先利用Matlab产生正弦查找表以及三角波查找表。

产生正弦查找表的代码如下:

ADDR_WIDTH=12;
DATA_WIDTH=16;
depth=2^ADDR_WIDTH;
x=ceil(((2^DATA_WIDTH/2-1)*sin(0:pi*2/depth:2*pi)+2^DATA_WIDTH/2));
fid=fopen('sinrom1.mif','w');
fprintf(fid,'width=%d;\n',DATA_WIDTH);
fprintf(fid,'depth=%d;\n',depth);
fprintf(fid,'address_radix=uns;\n');
fprintf(fid,'data_radix=uns;\n');
fprintf(fid,'Content Begin\n');
for(k=1:depth)
    fprintf(fid,'%d:%d;\n',k-1,x(k));
end
fprintf(fid,'end;');

产生三角波查找表的代码如下:

ADDR_WIDTH=12;
DATA_WIDTH=16;
depth=2^ADDR_WIDTH;
x=ceil(2*(2^DATA_WIDTH/2-1)*sawtooth(0:pi*2/depth:2*pi)+2^DATA_WIDTH - 1);
y=ceil(-2*(2^DATA_WIDTH/2-1)*sawtooth(0:pi*2/depth:2*pi)+2^DATA_WIDTH - 1);
fid=fopen('trirom1.mif','w');
fprintf(fid,'width=%d;\n',DATA_WIDTH);
fprintf(fid,'depth=%d;\n',depth);
fprintf(fid,'address_radix=uns;\n');
fprintf(fid,'data_radix=uns;\n');
fprintf(fid,'Content Begin\n');
for(k=1:depth/2)
    fprintf(fid,'%d:%d;\n',k-1,x(k));
end
for(j=depth/2+1:depth)
    fprintf(fid,'%d:%d;\n',j-1,y(j));
end
fprintf(fid,'end;');

然后在Quartus中利用IP核生成rom查找表实例。
单相逆变程序,fpga开发,c语言,单片机
一路Next直到下图所示页面,如图所示选中Matlab生成的.mif文件作为查找表。
单相逆变程序,fpga开发,c语言,单片机
最后勾选生成实例文件即可。
单相逆变程序,fpga开发,c语言,单片机

生成正弦波和三角波后,比较生成互补的SPWM波,注意要设置死区!

生成SPWM波代码如下:

always @(posedge clk, negedge rst_n)
begin
	if(!rst_n)
	begin
		spwm1_tmp <= 0;
		spwm2_tmp <= 0;
		cnt1 <= 0;
		cnt2 <= 0;
	end
	else
	begin
		//spwm1
		if(sin_sig >= tri_sig)		//延后一段时间再拉高
		begin
			if(cnt1 >= dead)			//cnt1 == dead
			begin
				spwm1_tmp <= 1;
				cnt1 <= 0;
			end
			else if(spwm1_tmp != 1)	//spwm1还没被拉高,则计数
				cnt1 <= cnt1 + 1;
			else;	
		end
		else
			begin spwm1_tmp <= 0; end
			
		//spwm2	
		if(sin_sig >= tri_sig)
			begin spwm2_tmp <= 0; end
		else								//延后一段时间再拉高
		begin
			if(cnt2 >= dead)			//cnt == dead
			begin
				spwm2_tmp <= 1;
				cnt2 <= 0;
			end
			else if(spwm2_tmp != 1)	//spwm2还没被拉高,则计数
				cnt2 <= cnt2 + 1;
			else;	
		end
	end
end

2.PID算法调控输出电压

调控输出电压可以通过改变正弦波的调制度来实现。这里我使用ADS8688芯片进行交流采样,计算获取交流电压的有效值(代码放在其他代码的压缩包中)。

PID调控代码如下:

void PID(void)
{
    double deltK;
    deltV[2] = Vset - Vrms;
    deltK = Kp * (deltV[2] - deltV[1]) + Ki * deltV[2] + Kd * (deltV[2] - 2 * deltV[1] - deltV[0]);
    deltV[0] = deltV[1];
    deltV[1] = deltV[2];
    K = K + (int)deltK;
    if(K > KMAX)
        K = KMAX;
    else;
    if(K < KMIN)
        K = KMIN;
    else;

}

让输出电压稳定的关键一在PID参数选取的适当,二在AD采样准确稳定。

3.顶层设计

Verilog顶层文件:

module DC_AC
(
input wire clk, 			// 50MHz
input wire rst_n,
input wire [7:0]ADDR,
input wire RD,WR,
input wire SDO,							// ADS8688 串行数字输出
//input wire [15:0] K,
//input wire [23:0] fs,

output wire spwm1_sig,
output wire spwm2_sig,
output wire irq,
output wire RST,								// ADS8688 复位信号
output wire CS,							// ADS8688 片选信号(低电平有效)
output wire SCLK,							// ADS8688 串行时钟
output wire SDI,							// ADS8688 串行数字输入
output wire alarm,


inout wire [15:0]DATA,
inout wire [3:0]KEY_H,KEY_V
);

wire cs0,cs1,cs2,cs3,cs4,cs5,cs6;
wire software_rst_n;
wire [7:0] rddat0;	//mcu读键盘值	CS0
wire [15:0] wrdat0;	
wire [15:0] wrdat1;	//K	CS5
wire [15:0] wrdat2;	
wire [15:0] wrdat3;	//fs	CS7
wire datacs0,datacs1;
wire [3:0]addr_ad;

wire [23:0] fc = 24'd17_000; 	//载波频率17k
wire [23:0] fs; 	//调制频率
wire [15:0] K;		//调制度
wire [15:0] sin_sig;
wire [15:0] tri_sig;
wire clk_50Hz;

wire [15:0] outRMS0;	//CS1
wire [15:0] outRMS1;	//CS2

assign fs = wrdat3;
assign K = wrdat1;

assign alarm = (K>500)?0:1;

Sin Sin_inst
(
	.clk(clk) ,	// input  clk_sig
	.rst_n(rst_n) ,	// input  rst_n_sig
	.fre(fs) ,	// input [23:0] fre_sig
	.sin_sig(sin_sig) 	// output [15:0] sin_sig_sig
);

Tripul Tripul_inst
(
	.clk(clk) ,	// input  clk_sig
	.rst_n(rst_n) ,	// input  rst_n_sig
	.fre(fc) ,	// input [23:0] fre_sig
	.tri_sig(tri_sig) 	// output [15:0] tri_sig_sig
);

SPWM SPWM_inst
(
	.clk(clk) ,	// input  clk_sig
	.rst_n(rst_n) ,	// input  rst_n_sig
	.sin_input(sin_sig) ,	// input [15:0] sin_input_sig
	.tri_sig(tri_sig) ,	// input [15:0] tri_sig_sig
	.K(K)	,
	.spwm1_sig(spwm1_sig) ,	// output  spwm1_sig_sig
	.spwm2_sig(spwm2_sig) 	// output  spwm2_sig_sig
);

clkdiv clkdiv_inst
(
	.clk(clk) ,	// input  clk_sig
	.rst_n(rst_n) ,	// input  rst_n_sig
	.div(32'd1_000_000) ,	// input [31:0] div_sig
	.clkout(clk_50Hz) 	// output  clkout_sig
);

BUS BUS_inst
(
	.clk(clk) ,	// input  clk_sig
	.rst_n(rst_n) ,	// input  rst_n_sig
	.ADDR(ADDR) ,	// input [7:0] ADDR_sig
	.RD(RD) ,	// input  RD_sig
	.WR(WR) ,	// input  WR_sig
	.DATA(DATA) ,	// inout [7:0] DATA_sig
	.software_rst_n(software_rst_n) ,	// output  software_rst_n_sig
	.cs0(cs0) ,	// output  cs0_sig
	.cs1(cs1) ,	// output  cs1_sig
	.cs2(cs2) ,	// output  cs2_sig
	.cs3(cs3) ,	// output  cs3_sig
	.cs4(cs4) ,	// output  cs4_sig
	.cs5(cs4) ,	// output  cs5_sig
	.cs6(cs4) ,	// output  cs6_sig
	.rddat0(rddat0) ,	// input [7:0] rddat0_sig
	.rddat1(outRMS0) ,	// input [7:0] rddat1_sig
	.rddat2(outRMS1) ,	// input [7:0] rddat2_sig
//	.rddat3(rddat3) ,	// input [7:0] rddat3_sig
	.wrdat0(wrdat0) ,	// output [7:0] wrdat0_sig
	.wrdat1(wrdat1) ,	// output [7:0] wrdat1_sig
	.wrdat2(wrdat2) ,	// output [7:0] wrdat2_sig
	.wrdat3(wrdat3) ,	// output [7:0] wrdat3_sig
	.addr_ad(addr_ad)	,	//output reg [3:0]addr_ad
	.datacs0(datacs0)	,	//output reg datacs0
	.datacs1(datacs1)		//output reg datacs1
);

KEY KEY_inst
(
	.clk(clk) ,	// input  clk_sig
	.rst_n(rst_n) ,	// input  rst_n_sig
	.rddat(rddat0) ,	// output [7:0] rddat_sig
	.irq(irq) ,	// output  irq_sig
	.cs(cs0) ,	// input  cs_sig
	.KEY_H(KEY_H) ,	// inout [3:0] KEY_H_sig
	.KEY_V(KEY_V) 	// inout [3:0] KEY_V_sig
);

ads8688 ads8688_inst
(
	.clk_50M(clk) ,	// input  clk_50M_sig
	.rst_n(rst_n) ,	// input  rst_n_sig
	.addr(addr_ad) ,	// input [3:0] addr_sig
	.RD(RD) ,	// input  RD_sig
	.datacs0(datacs0) ,	// input  datacs0_sig
	.datacs1(datacs1) ,	// input  datacs1_sig
	.clk_50Hz(clk_50Hz) ,	// input  clk_50Hz_sig
	.RST(RST) ,	// output  RST_sig
	.CS(CS) ,	// output  CS_sig
	.SCLK(SCLK) ,	// output  SCLK_sig
	.SDI(SDI) ,	// output  SDI_sig
	.SDO(SDO) ,	// input  SDO_sig
	.outRMS0(outRMS0) ,	// output [15:0] outRMS0_sig
	.outRMS1(outRMS1) 	// output [15:0] outRMS1_sig
//	.Vc(Vc)
);
endmodule

CCS中的main函数:

#include "common.h"
#include "bus_fpga.h"
#include "LCD12864_rom_enable.h"
#include "blue.h"
#include <math.h>

/**
 * main.c
 * 1.7增加了附加功能:1、按键设置 2、过流保护灯亮 3、蜂鸣器
 */

const int FMIN = 1;
const int FMAX = 999;
const double FULL = 10.24;
const double Vset = 10;
const int KMAX = 990;
const int KMIN = 900;

char keydat;
int a;
int fs = 50;
int K = 900;    //K的精度为1/1000
double Vrms = 0;
double Irms = 0;
double deltV[3] = {0};
float Kp = 45;  //65 30 60; 38 35
float Ki = 10;  //27 16 24; 17
float Kd = -12; //-10; -25 -20 -25
double V_list[5] = {0};
double I_list[5] = {0};
double V_sum;
double I_sum;
unsigned int j;
int overFlag = 0;
int fs_tmp[3] = {-1,-1,-1};

void mcuInit(void);
void getKey(void);
void getAD(int cnt);
void overCurrent(void);
void keyResponse(void); //无用
void changeFreq(void);
void PID(void);
void showPID(void); //无用
void ctrlPID(void); //无用
double change_voltage(unsigned int AD_value,double FS);
void showStatus(void);
void WRFPGA(void);
int datalen(int data);
void __key_delay(void);

int main(void)
{
    mcuInit();
    initialize_uart();
	while(1)
	{
	    V_sum = 0;
	    I_sum = 0;
	    for(j=0;j<5;j++){   //采样5次取平均值


	    __key_delay();
	    getKey();
	    changeFreq();
//	    getStringFVT();
//      updateKey(&a);
	    getAD(j);
	    PID();
	    showStatus();
        WRFPGA();

        V_sum = V_sum + V_list[j];
        I_sum = I_sum + I_list[j];

	    }
	    Vrms = V_sum / 5 * 7.80435435;   // * 7.810155
	    Irms = I_sum / 5 * 0.47501069;

	    PID();

	    overCurrent();
	}

}

四、其他

1.FPGA生成固化文件

FPGA本身并没有存储程序的功能,需要依靠外部flash芯片来实现程序的固化。以下两种方法分别介绍了用AS口和JTAG口固化程序。
方法一:生成.pof文件
step1:从Assignments进入Device。
单相逆变程序,fpga开发,c语言,单片机
step2:选择Device and Options。
单相逆变程序,fpga开发,c语言,单片机
step3:按照下图更改选项,注意这里的Device要看你FPGA上的flash芯片型号。
单相逆变程序,fpga开发,c语言,单片机
step4:全编译一下即可得到.pof文件。第一次烧录需要 Add Device 和 Add File。
单相逆变程序,fpga开发,c语言,单片机

方法二:生成.jic文件
step1:在File里面找到Convert Programming Files。
单相逆变程序,fpga开发,c语言,单片机
step2:选择生成.jic文件,同时选择flash芯片型号。
单相逆变程序,fpga开发,c语言,单片机
step3:往下翻找到Flash Loader添加设备,添加对应FPGA型号。
单相逆变程序,fpga开发,c语言,单片机
单相逆变程序,fpga开发,c语言,单片机
step4:选择SOF Data,添加.sof文件。
单相逆变程序,fpga开发,c语言,单片机
单相逆变程序,fpga开发,c语言,单片机
step5:点击Generate再重新全编译一遍即可生成.jic文件,用JTAG口,在烧录时Add File中选中相应的.jic文件即可。
单相逆变程序,fpga开发,c语言,单片机
烧录后,FPGA重新上电即成功固化程序。

2.其他代码

见单相逆变电源程序压缩包。

总结

在用Tiva和FPGA进行开发的时候,要注意二者之间的通信问题,比如有时候通信通道会传一些不定值,可能换个通道就好了。在CCS中烧录程序时如果配置出错可能会导致程序无法烧录,务必要正确配置后再进行烧录,可以先了解一些配置的基础知识。文章来源地址https://www.toymoban.com/news/detail-625941.html

到了这里,关于单相逆变电源软件设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于UDQ的并网单相逆变器控制【同步参考系下单相并网全桥正弦PWM逆变器闭环控制】(Simulink)

      💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码实现 能源在

    2024年02月01日
    浏览(33)
  • 【Simulink】单相电压型全桥逆变电路仿真基础实验

    版本:matlab2019b 逆变,即直流变换成交流。 在全桥(H桥)逆变电路中: V1、V2、V3、V4 为 IGBT,VD1、VD2、VD3、VD4为二极管 当V1、V4导通,V2、V3截止时,负载电压uo为正; 当V1、V4截止,V2、V3导通时,负载电压uo为负。 改变两组开关(V1、V4为一组,V2、V3为一组)的切换频率,即可

    2024年02月05日
    浏览(22)
  • 关于博主单相逆变电路的元器件清单,这里列一个说明

    本文列出了单相逆变电路的元器件清单,想DIY的朋友可以试一试。 另外有一个调整的地方,就是原电路图上的继电器不要焊接,直接连接I+和I-一端,在实际测试过程中出现了继电器哪怕没有驱动信号也在闭合,可能与高频方面有关系,最后买了个继电器模块到输入端,直接

    2024年02月12日
    浏览(29)
  • FPGA选型--电源设计(详细讲解了电源设计过程)

    备注:本次设计以 XCZU28DR-2FFVG1517E 为例,其他系列的电源设计类似。 赛灵思 Zynq® UltraScale+™ RFSoC 支持 -2 和 -1 速度等级,其中 -2E 器件性能最高。-2LE 和 -1LI 器件可以 0.85V 或 0.72V 的 VCCINT 电 压工作,专为实现更低的最大静态功耗而设计。使用以 VCCINT = 0.85V 工作的 -2LE 和 -1

    2024年02月03日
    浏览(33)
  • Xilinx FPGA电源设计与注意事项

    1 引言 随着半导体和芯片技术的飞速发展,现在的FPGA集成了越来越多的可配置逻辑资源、各种各样的外部总线接口以及丰富的内部RAM资源,使其在国防、医疗、消费电子等领域得到了越来越广泛的应用。当采用FPGA进行设计电路时,大多数FPGA对上电的电源排序和上电时间是有

    2024年02月02日
    浏览(35)
  • 单相PWM整流从硬件到软件一条龙

    首先很想吐槽国内开源环境,实在是无语,大家都不愿意分享资源,都需要花钱,主要是花钱也不一定能找到你想要的东西。今年的电赛电源题,到现在了,我都还没看到CSDN上有能让我看懂的东西。所以我和同伴一起从零开始学习PWM整流,直到实现,我打算免费共享出来,能

    2024年02月16日
    浏览(31)
  • FPGA—基于Quartus软件设计全加器

    本篇博客主要是基于Quartus软件件完成一个1位全加器的设计,分别采用:1)原理图输入 以及 2)Verilog编程 这两种设计方法。开发板基于Intel DE2-115。 1、半加器 1、定义: 半加器是能够对两个一位的二进制数进行相加得到半加和以及半加进位的组合电路。 2、真值表: A,B表示

    2024年02月06日
    浏览(32)
  • 基于STM32 ARM+FPGA伺服控制系统(二)软件及FPGA设计

    完整的伺服系统所包含的模块比较多,因此无法逐一详细介绍,所以本章着重介绍 设计难度较高的 FPGA 部分并简单介绍 ARM 端的工作流程。 FPGA 部分主要有 FOC 算法、电流采样算法及编码器采样算法,是整个控制系统的基础,直接决定电机控制 效果的好坏。因为 FPGA 工作的特

    2024年02月16日
    浏览(34)
  • FPGA的电源供电

    目录 1、供电要求  2、PCB设计的电源和地叠层分布 3、退耦电容 电源供电看似微不足道,但对于特定的FPGA应用来说却并非如此。如果FPGA周围缺乏足够退耦,将会显著降低FPGA设计的可靠性。更为糟糕的是,大部分问题都不是那种可以容易复现且在实验环境下也很难发现的(尤其

    2024年02月06日
    浏览(26)
  • FPGA电源电流参数

    VCCINT VCCINT是FPGA芯片的内核电压,是用来给FPGA内部的逻辑门和触发器上的电压。即芯片的晶体管开关是有核心电压提供。当内部逻辑工作时钟速率越高,使用逻辑资源越多,则核心电压供电电流会更大,可高达几安,此时芯片必然会发烫,需要散热装置辅助散热 VCCIO VCCIO(有

    2024年02月03日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包