【FPGA+DSP系列】——proteus仿真DSP控制单相整流电路,4路PWM波控制晶闸管实验
【FPGA+DSP系列】——proteus仿真DSP控制单相整流电路,4路PWM波控制晶闸管实验
- 前言
- 一、软件实现
- 二、硬件电路搭建
- 1.电路搭建
- 2.波形观看
- 总结
前言
前面两节通过matlab中simulink摸清了晶闸管控制思路以及触发信号与电压信号之间的位置关系,不过当时触发信号是直接使用的触发脉冲产生器的器件进行操作的,这一节就来通过dsp控制晶闸管实现整流实验,一部分是来验证你dsp代码功能正确性,另一方面为没有实验环境来学习的学生提供一种学习思路吧。

这是上一节simulink里面实现的单相桥式整流电路,触发脉冲通过脉冲发生器产生,不涉及任何dsp代码,现在要通过dsp产生4路pwm信号,来驱动晶闸管在适当的时候打开,进而完成整流。
声明:实验驱动晶闸管虽然只是一个简单的脉冲信号,但是实际中还是需要将pwm信号转换电平,然后接入驱动板,生成大的驱动电流,进而完成对晶闸管的控制。
一、软件实现
软件主要就是实现4路PWM的输出,其中2路PWM信号控制一个通路中的两个管子,另外两路相对第一路相位延迟180°,控制负半周通路的两个管子。
DSP芯片:TMS320F28027 CCS:CCS12.1 proteus:8.17
epwm函数声明
/** epwm.h** Created on: 2025年9月28日* Author: DELL*/#ifndef APPS_EPWM_EPWM_H_
#define APPS_EPWM_EPWM_H_#include "F2802x_Device.h" // 统一为F2802x头文件
#include "F2802x_Examples.h" // 包含延时函数void EPWM2_Init(Uint16 tbprd, Uint16 phase_offset);
void EPWM1_Init(Uint16 tbprd);
void EPwm1A_SetCompare(Uint16 val);
void EPwm1B_SetCompare(Uint16 val);#endif /* APPS_EPWM_EPWM_H_ */
epwm初始化函数等编写
#include "epwm.h"void EPWM1_Init(Uint16 tbprd)
{EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWMSysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1EDIS;InitEPwm1Gpio();EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocksEDIS;// Setup Sync - EPWM1作为主定时器EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // 在计数器为零时产生同步信号EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 主定时器不需要相位使能EPwm1Regs.TBPHS.half.TBPHS = 0; // 主定时器相位为0EPwm1Regs.TBCTR = 0x0000; // Clear counterEPwm1Regs.TBPRD = tbprd;EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count upEPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4;EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV16;// Setup shadow register load on ZEROEPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;// Set Compare values - 10%占空比Uint16 duty_10percent = tbprd * 10 / 100; // 计算10%占空比对应的比较值EPwm1Regs.CMPA.half.CMPA = duty_10percent; // PWM1A 10%占空比EPwm1Regs.CMPB = duty_10percent; // PWM1B 10%占空比// Set actionsEPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Clear PWM1A on ZeroEPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM1A on event A, up countEPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // Clear PWM1B on ZeroEPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Set PWM1B on event B, up countEPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero eventEPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INTEPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
}void EPWM2_Init(Uint16 tbprd, Uint16 phase_offset)
{EALLOW;SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2EDIS;InitEPwm2Gpio();// EPWM2作为从定时器,接收EPWM1的同步信号EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // 同步输入模式,接收EPWM1的同步EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // 使能相位加载EPwm2Regs.TBPHS.half.TBPHS = phase_offset; // 设置120°相位延迟EPwm2Regs.TBCTR = 0x0000; // Clear counterEPwm2Regs.TBPRD = tbprd; // 周期与EPWM1相同EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count upEPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV4;EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV16;// Setup shadow register load on ZEROEPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;// Set Compare values - 10%占空比Uint16 duty_10percent = tbprd * 10 / 100; // 计算10%占空比对应的比较值EPwm2Regs.CMPA.half.CMPA = duty_10percent; // PWM2A 10%占空比EPwm2Regs.CMPB = duty_10percent; // PWM2B 10%占空比// Set actionsEPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // Clear PWM2A on ZeroEPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Set PWM2A on event A, up countEPwm2Regs.AQCTLB.bit.ZRO = AQ_SET; // Clear PWM2B on ZeroEPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Set PWM2B on event B, up countEPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero eventEPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INTEPwm2Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
}void EPwm1A_SetCompare(Uint16 val)
{EPwm1Regs.CMPA.half.CMPA = val;
}void EPwm1B_SetCompare(Uint16 val)
{EPwm1Regs.CMPB = val;
}void EPwm2A_SetCompare(Uint16 val)
{EPwm2Regs.CMPA.half.CMPA = val;
}void EPwm2B_SetCompare(Uint16 val)
{EPwm2Regs.CMPB = val;
}
主函数:
#include "F2802x_Device.h"
#include "DSP28x_Project.h"
#include "led.h"
#include "epwm.h"void main(void)
{InitSysCtrl();LED_init();// 停止所有定时器时钟同步EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;EDIS;Uint16 tbprd = 18749; // 50Hz PWM周期值// 计算180°相位延迟对应的计数值// 180° = 120/360 = 1/2周期Uint16 phase_offset_120deg = tbprd / 2; // 180°相位延迟// 初始化EPWM1(主定时器)EPWM1_Init(tbprd);// 初始化EPWM2(从定时器,延迟120°)EPWM2_Init(tbprd, phase_offset_120deg);// 启动所有定时器时钟同步EALLOW;SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;EDIS;while(1){// 占空比已经在初始化时设置为10%,无需在循环中重复设置// 如果需要动态改变占空比,可以在这里调用EPwmX_SetCompare函数DELAY_US(10);}
}
产生这4路PWM波,首先要考虑PWM的周期,怎么确定你产生PWM波的周期,看过PWM产生原理的都知道,他是一个基于计数器进行操作的外设,所以说这个计数器大小和计数器参考时钟就是决定你周期的关键因素。
该芯片的系统时钟60MHz,计数器最大到65535,很明显这个计数器满足不了产生50Hz的要求,因此你需要降低参考时钟,所以就要分频,分频的关键语句就是:

分别进行4分频和16分频,两个相乘就是最后的分频倍数,也就是64倍。
所以现在的参考时钟是:937.5KHz
所以计数器的大小应该设置为:937.5KHz/50Hz=18750
由于计数器从0开始,所以实际的周期数应该设置为18750-1,这个设置也可以在我们主函数看到。
然后就是占空比的设置,这个关键也是一个计数器,当到达这个计数器的时候切换电平而已,没什么理解难度。
最后就是不同路PWM波相位的设置,这个我们第一个PWM默认相位为0,第二路相对第一路延迟180°。

然后这只是简单的pwm控制,实际中还需要判断三相信号的过零点,进而确定第一路的触发位置,不过仿真就不管了,先来看看PWM的效果再说。
二、硬件电路搭建
1.电路搭建

芯片时钟设置60MHz,下载代码

2.波形观看
四路PWM波形

整流结果波形:

总结
本文介绍了使用DSP控制单相整流电路的实验方法。通过TMS320F28027芯片产生4路PWM信号,分别控制桥式整流电路中的4个晶闸管。其中两路PWM控制正半周通路,另两路延迟180°控制负半周通路。文章详细说明了EPWM模块的初始化设置,包括时钟配置、同步信号处理、占空比设置等关键参数。实验验证了DSP代码功能,并为无硬件环境的学习者提供了仿真方案。重点包括:1)EPWM初始化函数实现;2)主从定时器同步设置;3)10%占空比的PWM信号生成。该方案通过Proteus仿真,可有效学习DSP在电力电子控制中
