DSPTMS320F28027的SPWM程序.docx
《DSPTMS320F28027的SPWM程序.docx》由会员分享,可在线阅读,更多相关《DSPTMS320F28027的SPWM程序.docx(12页珍藏版)》请在冰豆网上搜索。
![DSPTMS320F28027的SPWM程序.docx](https://file1.bdocx.com/fileroot1/2022-11/30/7e8956fc-0e20-4daf-bdb8-558f913b4a3a/7e8956fc-0e20-4daf-bdb8-558f913b4a3a1.gif)
DSPTMS320F28027的SPWM程序
课程名称:
电机的DSP控制课程设计
院系:
电子信息与电气工程学院
专业:
电气工程与自动化
班级:
F0903006
学号:
姓名:
上海交通大学
摘要
本报告主要内容是用TMS320C28027DSP芯片产生SPWM波,实现恒压频比控制。
产生SPWM的方法有三角波与正弦波比较法(单极性和双极性)、数字方法,和具体的实现。
此外,还有两个小任务。
一个是利用该芯片实现按键判断和LED显示,另一个是AD转换和LCD显示。
小任务的目的是熟悉实验板的操作,为SPWM波程序编写打下基础。
第一章
LED和按键
1.1程序功能
该程序的功能是分辨按键的输入,不同的按键实现不同的功能,然后再LED上显示效果。
程序运行后,初始值为0,通过1个键,按一下加1,通过另一个键,按1下减1;(按着不放,超过1秒,不断加1或减1,时间超过5秒,不断加10,或减10)。
通过四个按键设置两个数值,再按第五个按键计算两个数的乘积。
1.2程序实现思想
按键的识别利用的BC7281芯片的相关功能,该模块提供了一个接口,变量KEY变低时说明有按键按下,利用Read_7281(0x13)函数就可以读取按键的地址(在BC7281中的存放地址为0x13),实现对按键的判断。
长按的功能通过定时器来实现。
初始设定长按标志变量flag=0;在按下某个值时,如果flag=按键地址(1-4),重载定时器1预定标值,开启定时器1,中断周期为5秒;重载定时器2,开启定时器2,中断时间为1秒。
如果flag=5,那么加减10;如果flag为6,那么加减1;如果为其他,加减1,令flag=按键地址。
在中断函数内,flag=5或6,停止定时器。
1.3程序流程图
图1-1LED程序流程图
1.4程序评价
该程序完成了要求的任务,并且采用中断而不是用delay来确定按键时间,提高了效率。
第二章AD转换和LCD显示
2.1程序功能
根据输入的电压值,把AD的结果显示出来,当输入电压变化时,显示值也变化。
2.2程序实现思想
利用示例程序很容易调节ADC模块的采样频率,触发方式,采样精度等参数,LCD的显示通过接口函数很容易使用。
这里将采样结果同样用LED显示。
2.3程序评价
该程序很好的完成的既定的任务,在LCD和LED显示屏上都有稳定的显示,AD采样灵敏。
第三章SPWM的产生
3.1程序功能
生成6路PWM正弦波程序(变频器逆变需6路),PWM的开关频率为10KHz,其输出的正弦波频率为0~100Hz,根据AD的值变化,50Hz时输出100%电压,0~50Hz按V/f等于常数输出,死区时间取2us。
频率值显示在数码管上。
3.2程序实现思想
1、采用epwm模块的上下数模式,计数值为3000,计数周期为16.67ns;
2、改变比较寄存器里的数值改变中断时间,上数到比较值置高,下数到比较值置低,数到周期值置高,数到0置低;
3、每个epwm模块产生两路死区时间为2us的相互反向的pwm波;
4、计数到0出发中断,中断操作为更改比较值;
5、比较值利用等面积法计算出来,最低点设置为0,最高点设置为3000。
6、比较值存放在table[200]数组中,只存放半个周期的比较值,在50Hz以上的算法为
table[i]=sin((2*i+1)*pi/(2*SamNum))*1500;式3-1
其中SamNum为半周期比较的次数。
1500为计数器的半周期值,更新比较值时,正半周要加上1500,后半周不需要;对50Hz一下频率(大于25Hz),算法为
table[i]=(workfre_div*sin((2*i+1)*pi/(2*SamNum))*1500)/50;式3-2
其中workfre_div为正弦波频率,0~100Hz。
当大于25Hz时,SamNum为半周期比较次数,当小于25Hz时,其为25Hz时的比较次数。
7、更新比较值策略:
正半周比较值为相应表格中的数加上1500,后半周不加。
当正弦波频率低于25Hz时,利用200个点来产生比较值,在第i次更新时取table中第i*workfare_div/workfre个值,这样可以产生很低频率的正玄波。
8、相角控制方法:
用epwm2和epwm3模块产生相差120和240度相角的正弦波,让epwm2中断一周期比较次数的2/3次后开始工作,同理让epwm3中断一周期比较次数的4/3次后开始工作。
3.3程序流程图
图3-1SPWM波产生流程图
3.4程序评价
该程序完成了既定的任务,得到的波形在高于20Hz时谐波较少,波形与正弦波十分接近。
相位关系正确。
符合恒压频比控制策略。
死区时间2us,载波10KHz。
SPWM附录程序(部分)
voidmain(void)
{
//Step1.InitializeSystemControl:
//PLL,WatchDog,enablePeripheralClocks
//ThisexamplefunctionisfoundintheDSP2802x_SysCtrl.cfile.
InitSysCtrl();
//Step2.InitalizeGPIO:
//ThisexamplefunctionisfoundintheDSP2802x_Gpio.cfileand
//illustrateshowtosettheGPIOtoit'sdefaultstate.
//InitGpio();//Skippedforthisexample
//ForthiscasejustinitGPIOpinsforePWM1,ePWM2,ePWM3
//ThesefunctionsareintheDSP2802x_EPwm.cfile
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
//Step3.ClearallinterruptsandinitializePIEvectortable:
//DisableCPUinterrupts
DINT;
//InitializethePIEcontrolregisterstotheirdefaultstate.
//ThedefaultstateisallPIEinterruptsdisabledandflags
//arecleared.
//ThisfunctionisfoundintheDSP2802x_PieCtrl.cfile.
InitPieCtrl();
//DisableCPUinterruptsandclearallCPUinterruptflags:
IER=0x0000;
IFR=0x0000;
//InitializethePIEvectortablewithpointerstotheshellInterrupt
//ServiceRoutines(ISR).
//Thiswillpopulatetheentiretable,eveniftheinterrupt
//isnotusedinthisexample.Thisisusefulfordebugpurposes.
//TheshellISRroutinesarefoundinDSP2802x_DefaultIsr.c.
//ThisfunctionisfoundinDSP2802x_PieVect.c.
InitPieVectTable();
//Interruptsthatareusedinthisexamplearere-mappedto
//ISRfunctionsfoundwithinthisfile.
EALLOW;//ThisisneededtowritetoEALLOWprotectedregisters
PieVectTable.EPWM1_INT=&epwm1_isr;
PieVectTable.EPWM2_INT=&epwm2_isr;
PieVectTable.EPWM3_INT=&epwm3_isr;
EDIS;//ThisisneededtodisablewritetoEALLOWprotectedregisters
EALLOW;//ThisisneededtowritetoEALLOWprotectedregister
PieVectTable.ADCINT1=&adc_isr;
EDIS;//ThisisneededtodisablewritetoEALLOWprotectedregisters
//Step4.InitializealltheDevicePeripherals:
//ThisfunctionisfoundinDSP2802x_InitPeripherals.c
//InitPeripherals();//Notrequiredforthisexample
sintable(table);
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=0;
EDIS;
InitEPwm1Example();
InitEPwm2Example();
InitEPwm3Example();
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=1;
EDIS;
InitAdc();
ConfigAdc();
//Step5.Userspecificcode,enableinterrupts
//Initalizecounters:
EPwm1TimerIntCount=0;
EPwm2TimerIntCount=0;
EPwm3TimerIntCount=0;
//EnableCPUINT3whichisconnectedtoEPWM1-3INT:
PieCtrlRegs.PIEIER1.bit.INTx1=1;
IER|=M_INT3;
IER|=M_INT1;
//EnableEPWMINTninthePIE:
Group3interrupt1-3
PieCtrlRegs.PIEIER3.bit.INTx1=1;
PieCtrlRegs.PIEIER3.bit.INTx2=1;
PieCtrlRegs.PIEIER3.bit.INTx3=1;
//EnableglobalInterruptsandhigherpriorityreal-timedebugevents:
EINT;//EnableGlobalinterruptINTM
ERTM;//EnableGlobalrealtimeinterruptDBGM
///////////////////////////////////////////////////////////////////led
Dlay(40000);
EALLOW;//允许访问受保护的空间
Clk_Out;//设定连接CLKK(7281.3)的SCL为输出(时钟脉冲输出)
Dat_In;//设定连接DATT(7281.1)的SDA为输入(接收7281的反馈信号)
EDIS;//禁止访问受保护的空间
Setb_Clk;
Write_7281(0x12,0x84);//初始化BC728x
Write_7281(0x15,(0x70+0));//向最右边算起第8位写1
Write_7281(0x15,(0x60+0));//向最右边算起第7位写2
Write_7281(0x15,(0x50+0));//向最右边算起第6位写3
Write_7281(0x15,(0x40+0));//向最右边算起第5位写4
Write_7281(0x15,(0x30+0));//向最右边算起第4位写5
Write_7281(0x15,(0x20+0));//向最右边算起第3位写6
Write_7281(0x15,(0x10+0));//向最右边算起第2位写7
Write_7281(0x15,(0x00+0));//向最右边算起第1位写8
//Write_7281(0x18,0x0bf);//消除第8位Led的小数点,该小数点是
///////////////////////////////////////////////////////////////////////////led
//Step6.IDLEloop.Justsitandloopforever(optional):
for(;;)
{
workfre_temp=(Voltage0*100/3790+1);
if((workfre_temp>workfre_div)||(workfre_temp{
workfre_div=workfre_temp;
if(workfre_div<25)
workfre=25;
else
workfre=workfre_div;
DINT;
Write_7281(0x15,(0x20+workfre_div/100));//向最右边算起第3位写6
Write_7281(0x15,(0x10+(workfre_div/10)%10));//向最右边算起第2位写7
Write_7281(0x15,(0x00+workfre_div%10));//向最右边算起第1位写8
sintable(table);
EPwm1TimerIntCount=0;
EPwm2TimerIntCount=0;
EPwm3TimerIntCount=0;
EINT;//EnableGlobalinterruptINTM
ERTM;//EnableGlobalrealtimeinterruptDBGM
}
}
}
voidsintable(Uint16*table)
{
for(i=0;i<200;i++)
table[i]=0;
SamNum=LOADFRE/(2*workfre);
if(workfre<50)
{
for(i=0;i{
table[i]=(workfre_div*sin((2*i+1)*pi/(2*SamNum))*1500)/50;
}
}
else
{
for(i=0;i{
table[i]=sin((2*i+1)*pi/(2*SamNum))*1500;
}
}
SamNum=LOADFRE/(2*workfre_div);
phaseB=2*SamNum/3;
phaseC=4*SamNum/3;
}
interruptvoidepwm1_isr(void)
{
if(EPwm1TimerIntCount>=(2*SamNum))
{
EPwm1TimerIntCount=0;
EPwm1Regs.CMPA.half.CMPA=table[0]+1500;
}
else
{
if(EPwm1TimerIntCount{
EPwm1Regs.CMPA.half.CMPA=table[EPwm1TimerIntCount*workfre_div/workfre]+1500;
}
else
{
EPwm1Regs.CMPA.half.CMPA=1500-table[(EPwm1TimerIntCount-SamNum)*workfre_div/workfre];
}
}
//EPwm1Regs.CMPA.half.CMPA=EPWM_TIMER_TBPRD/2;
EPwm1TimerIntCount++;
//ClearINTflagforthistimer
EPwm1Regs.ETCLR.bit.INT=1;
//Acknowledgethisinterrupttoreceivemoreinterruptsfromgroup3
PieCtrlRegs.PIEACK.all=PIEACK_GROUP3;
}
interruptvoidepwm2_isr(void)
{
if(EPwm2TimerIntCount>(phaseB-1))
{
if(EPwm2TimerIntCount>=(2*SamNum+phaseB))
{
EPwm2TimerIntCount=phaseB;
EPwm2Regs.CMPA.half.CMPA=table[0]+1500;
}
else
{
if(EPwm2TimerIntCount<(SamNum+phaseB))
{
EPwm2Regs.CMPA.half.CMPA=table[(EPwm2TimerIntCount-phaseB)*workfre_div/workfre]+1500;
}
else
{
EPwm2Regs.CMPA.half.CMPA=1500-table[(EPwm2TimerIntCount-phaseB-SamNum)*workfre_div/workfre];
}
}
}
EPwm2TimerIntCount++;
//ClearINTflagforthistimer
EPwm2Regs.ETCLR.bit.INT=1;
//Acknowledgethisinterrupttoreceivemoreinterruptsfromgroup3
PieCtrlRegs.PIEACK.all=PIEACK_GROUP3;
}
interruptvoidepwm3_isr(void)
{
if(EPwm3TimerIntCount>(phaseC-1))
{
if(EPwm3TimerIntCount>=(2*SamNum+phaseC))
{
EPwm3TimerIntCount=phaseC;
EPwm3Regs.CMPA.half.CMPA=table[0]+1500;
}
else
{
if(EPwm3TimerIntCount<(SamNum+phaseC))
{
EPwm3Regs.CMPA.half.CMPA=table[(EPwm3TimerIntCount-phaseC)*workfre_div/workfre]+1500;
}
else
{
EPwm3Regs.CMPA.half.CMPA=1500-table[(EPwm3TimerIntCount-phaseC-SamNum)*workfre_div/workfre];
}
}
}
EPwm3TimerIntCount++;
//ClearINTflagforthistimer
EPwm3Regs.ETCLR.bit.INT=1;
//Acknowledgethisinterrupttoreceivemoreinterruptsfromgroup3
PieCtrlRegs.PIEACK.all=PIEACK_GROUP3;
}