搜档网
当前位置:搜档网 › DSP_TMS320F28027的SPWM程序

DSP_TMS320F28027的SPWM程序

课程名称:电机的DSP控制课程设计

院系:电子信息与电气工程学院专业:电气工程与自动化

班级: F0903006

学号:

姓名:

上海交通大学

目录

摘要 (3)

第一章LED和按键 (4)

1.1 程序功能 (4)

1.2 程序实现思想 (4)

1.3 程序流程图 (5)

1.4 程序评价 (5)

第二章AD转换和LCD显示 (6)

2.1 程序功能 (6)

2.2 程序实现思想 (6)

2.3 程序评价 (6)

第三章SPWM的产生 (7)

3.1 程序功能 (7)

3.2 程序实现思想 (7)

3.3 程序流程图 (8)

3.4 程序评价 (9)

SPWM附录程序(部分) (10)

摘要

本报告主要内容是用TMS320C28027DSP芯片产生SPWM波,实现恒压频比控制。产生SPWM的方法有三角波与正弦波比较法(单极性和双极性)、数字方法,和具体的实现。此外,还有两个小任务。一个是利用该芯片实现按键判断和LED显示,另一个是AD转换和LCD显示。小任务的目的是熟悉实验板的操作,为SPWM波程序编写打下基础。

第一章L ED和按键

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-1 LED程序流程图

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-1 SPWM 波产生流程图

该程序完成了既定的任务,得到的波形在高于20Hz时谐波较少,波形与正弦波十分接近。相位关系正确。符合恒压频比控制策略。死区时间2us,载波10KHz。

SPWM附录程序(部分)

void main(void)

{

// Step 1. Initialize System Control:

// PLL, WatchDog, enable Peripheral Clocks

// This example function is found in the DSP2802x_SysCtrl.c file.

InitSysCtrl();

// Step 2. Initalize GPIO:

// This example function is found in the DSP2802x_Gpio.c file and // illustrates how to set the GPIO to it's default state.

// InitGpio(); // Skipped for this example

// For this case just init GPIO pins for ePWM1, ePWM2, ePWM3 // These functions are in the DSP2802x_EPwm.c file

InitEPwm1Gpio();

InitEPwm2Gpio();

InitEPwm3Gpio();

// Step 3. Clear all interrupts and initialize PIE vector table:

// Disable CPU interrupts

DINT;

// Initialize the PIE control registers to their default state.

// The default state is all PIE interrupts disabled and flags

// are cleared.

// This function is found in the DSP2802x_PieCtrl.c file.

InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:

IER = 0x0000;

IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt

// Service Routines (ISR).

// This will populate the entire table, even if the interrupt

// is not used in this example. This is useful for debug purposes.

// The shell ISR routines are found in DSP2802x_DefaultIsr.c.

// This function is found in DSP2802x_PieV ect.c.

InitPieVectTable();

// Interrupts that are used in this example are re-mapped to

// ISR functions found within this file.

EALLOW; // This is needed to write to EALLOW protected registers

PieV ectTable.EPWM1_INT = &epwm1_isr;

PieV ectTable.EPWM2_INT = &epwm2_isr;

PieV ectTable.EPWM3_INT = &epwm3_isr;

EDIS; // This is needed to disable write to EALLOW protected registers EALLOW; // This is needed to write to EALLOW protected register

PieV ectTable.ADCINT1 = &adc_isr;

EDIS; // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:

// This function is found in DSP2802x_InitPeripherals.c

// InitPeripherals(); // Not required for this example

sintable(table);

EALLOW;

SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;

EDIS;

InitEPwm1Example();

InitEPwm2Example();

InitEPwm3Example();

EALLOW;

SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;

EDIS;

InitAdc();

ConfigAdc();

// Step 5. User specific code, enable interrupts

// Initalize counters:

EPwm1TimerIntCount = 0;

EPwm2TimerIntCount = 0;

EPwm3TimerIntCount = 0;

// Enable CPU INT3 which is connected to EPWM1-3 INT: PieCtrlRegs.PIEIER1.bit.INTx1 = 1;

IER |= M_INT3;

IER |= M_INT1;

// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3 PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

PieCtrlRegs.PIEIER3.bit.INTx2 = 1;

PieCtrlRegs.PIEIER3.bit.INTx3 = 1;

// Enable global Interrupts and higher priority real-time debug events:

EINT; // Enable Global interrupt INTM

ERTM; // Enable Global realtime interrupt DBGM

///////////////////////////////////////////////////////////////////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

// Step 6. IDLE loop. Just sit and loop forever (optional):

for(;;)

workfre_temp=(V oltage0*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; // Enable Global interrupt INTM

ERTM; // Enable Global realtime interrupt DBGM

}

}

}

void sintable(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;

}

interrupt void epwm1_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++;

// Clear INT flag for this timer

EPwm1Regs.ETCLR.bit.INT = 1;

// Acknowledge this interrupt to receive more interrupts from group 3

PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

interrupt void epwm2_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/workfr e];

}

}

}

EPwm2TimerIntCount++;

// Clear INT flag for this timer

EPwm2Regs.ETCLR.bit.INT = 1;

// Acknowledge this interrupt to receive more interrupts from group 3

PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

interrupt void epwm3_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/workfr e];

}

}

}

EPwm3TimerIntCount++;

// Clear INT flag for this timer

EPwm3Regs.ETCLR.bit.INT = 1;

// Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

}

相关主题