?? svpwm.c
字號:
/*******************************************************************************************
文件: SvPwm.c 空間矢量脈寬調(diào)制
標(biāo)題: 通過事件管理產(chǎn)生PWM
條件: 本程序需要DSP281x V1.00頭文件支持,另外需配置成"boot to H0"操作方式。
除了boot方式引腳配置外,無需其他硬件配置方式。
說明: 該程序設(shè)置EV定時器(TIMER1, TIMER2, TIMER3 and TIMER4),用于產(chǎn)生T1PWM,
T2PWM, T3PWM, T4PWM and PWM1-PWM12波形。可通過示波器觀察這些波形。
在以下幾個方面對TI提供的驅(qū)動源碼進行了硬件和軟件的增強:
(1) 增加了LED數(shù)碼管顯示的硬件接口。以便將EvPwm發(fā)生的次數(shù)反映在LED數(shù)碼管上。
(2) 在更新EvPwm時,增加了受GPIO A控制的16個Led發(fā)光二極管的閃爍顯示。
(3) 增加了320*240液晶屏及與之配套的軟件。
*******************************************************************************************/
#include "DSP281x_Device.h" // DSP281x 頭文件包含文件
#include "DSP281x_Examples.h" // DSP281x 示例包含文件
//**********************************************//
#include "float.h"
#include "math.h"
float ualfa[200],ubeta[200]; // 存儲電壓矢量Uout的(α,β)坐標(biāo)軸分量Ualfa,
// Ubeta的數(shù)組
Uint16 sector[200]; // 定義存儲扇區(qū)數(shù)的數(shù)組
#define PI2 2*3.1415926 // 定義2π的值
#define DETA PI2/200 // 定義相鄰兩個Uout之間的電度角的差值
#define INIA 3.1415926/180 // 定義Uout的初始電度角
//Uint16 TP=3000;
static int TP=3000; // 周期寄存器的值,其值(1200)等于SVPWM調(diào)制周期T的
// 一半,因為在該程序中2π電度角內(nèi)Uout的點數(shù)一
// 定,故改變此值可以改變輸出的三相正弦交流電壓的頻
//float KP=0.7; // 率
static float KP=0.7; // 定義Uout的標(biāo)么值,KP的值在0和1之間,改變此
// 值可以改變逆變橋輸出電壓的幅值
static int receive[5]; // 串口通訊數(shù)據(jù)接收數(shù)組
//static int transfer[7]; // 串口通訊數(shù)據(jù)發(fā)送數(shù)組
//Uint16 receive[5];
void calu();
void SECTOR();
void scib_fifo_init();
void interrupt uarttr();
interrupt void scibRxFifoIsr(void);
int anticlk[6]={0x1666,0x3666,0x2666,0x6666,0x4666,0x5666}; // 逆時針旋轉(zhuǎn)的6個基本矢量
//**********************************************//
// 本文件建立的函數(shù)原型聲明。
void init_eva(void); // EVA配置T1PWM, T2PWM, PWM1-PWM6 ,初始化定時器
void init_evb(void); // EVB配置T3PWM, T4PWM, PWM7-PWM12 ,初始化定時器
void delay(); // 延時函數(shù)
interrupt void adc_isr(void);
void OscillographTable(); // 制作示波器表格
void VoltageCurve();
void AdcResultCopy();
Uint16 *Xaddr=(Uint16 *)0x13f000;
Uint16 Xram_pointer=0;
// 本例的全局變量
// 外部函數(shù)聲明。由Bc7281.c 文件建立
void LedD_Display(void);
// 將模數(shù)轉(zhuǎn)換值以10進制形式,在Led第4,3,2,1位數(shù)碼管上進行顯示
void LedH_Display(void);
// 將模數(shù)轉(zhuǎn)換值以16進制兩個字節(jié)形式,在Led第8,7,6,5位數(shù)碼管上進行顯示
// 本例中的全局計數(shù)器
Uint16 count=0,i;
void main(void)
{
int i,k=0,cmp1,cmp2;
float x,y,z;
// 步驟1 系統(tǒng)控制初始化: 鎖相環(huán)(PLL),看門狗(WatchDog)及外設(shè)時鐘
// (PeripheralClocks)初始化。該函數(shù)在DSP281x_SysCtrl.c文件中建立。
InitSysCtrl();
// 步驟2.初始化GPIO:
// 這個函數(shù)例舉怎樣將GPIO設(shè)置成其默認狀態(tài),該函數(shù)由DSP281x_Gpio.c文件建立。
// InitGpio(); // 本例跳過這個函數(shù)
lcd_init();
clearscr1(); // 第一顯示緩沖區(qū)(0x0000-0x29ff)清零
clearscr2(); // 第二顯示緩沖區(qū)(0x2a00-0x53ff)清零
clearscr3(); // 第三顯示緩沖區(qū)(0x5400-0x7dff)清零
OscillographTable();
// 對于這個檢測僅初始化GPAMUX和GPBMUX
EALLOW; //允許訪問受保護的空間
GpioMuxRegs.GPAMUX.all = 0x00FF; // 使能EVA PWM 1-6 腳
GpioMuxRegs.GPBMUX.all = 0x00FF; // 使能EVB PWM 7-12 腳
EDIS; //禁止訪問受保護的空間
EALLOW; // 允許訪問受保護的寄存器
GpioMuxRegs.GPAMUX.all=0x0000; // 將A端口設(shè)置成IO方式
GpioMuxRegs.GPADIR.all=0xffff; // 將GPIO A所有15個端口配置成數(shù)字量輸出
EDIS; // 禁止訪問受保護的寄存器
GpioDataRegs.GPADAT.all=0xAAAA; // 間隔一個點亮LED發(fā)光二極管。
// 步驟3 關(guān)所有中斷并初始化PWM矢量表
DINT; // 關(guān)CPU中斷
InitPieCtrl(); // 初始化PIE控制寄存器為默認狀態(tài)。該狀態(tài)關(guān)所有PIE中斷并清除所
// 有標(biāo)識。該函數(shù)在DSP281x_PieCtrl.c文件中建立。
IER = 0x0000; // 關(guān)CPU中斷并清CPU中斷標(biāo)識。
IFR = 0x0000;
InitPieVectTable();
// 初始化PIE向量表,該向量表指出中斷服務(wù)程序(ISR)的構(gòu)架。即使在本范例中
// 沒有用到中斷,仍舊組裝整張表。它在程序調(diào)試時是很有用的。ISR程序構(gòu)架由
// DSP281x_DefaultIsr.c文件建立
// InitPieVectTable()函數(shù)由DSP281x_PieVect.c文件建立
//##################
// 本例用到的中斷重新映射到由本文件建立的ISR函數(shù)中。
//******************************************************************************************
// 關(guān)于 "PieVectTable.ADCINT = &adc_isr;" 指令的說明
// 1. adc_isr 是一個ADC模塊中斷服務(wù)程序(ISR)。
// 2. 這個中斷程序與中斷擴展(PIE)向量表第1組INT1第6個中斷向量ADCINT(ADC)對應(yīng)。
// 3. 為了使這個程序響應(yīng)對應(yīng)的中斷,還需作如下配置:
//
// PieCtrlRegs.PIECRTL.bit.ENPIE = 1;
// 使能PIE向量表。這條指令包含在上面調(diào)用的InitPieVectTable()函數(shù)中。
//
// IER |= M_INT1; // 使能PIE向量表第1組CPU INT1中斷
// PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // 使能PIE向量表第一組第6個ADCINT中斷
// EINT; // 允許可屏蔽中斷(清INTM位)
//
// 這幾條指令在本程序的后續(xù)指令中可以找到。這樣,在發(fā)生ADCINT中斷的情況下,將
// 執(zhí)行adc_isr()中斷服務(wù)程序。
// "PieVectTable.ADCINT = &adc_isr;" 指令實際上就是通知編譯器,在發(fā)生ADCINT
// 中斷的情況下,將執(zhí)行adc_isr()中斷服務(wù)程序。adc_isr頭上的"&"為取地址運算符。
//******************************************************************************************
EALLOW; // 允許訪問受保護的寄存器
PieVectTable.ADCINT = &adc_isr;
EDIS; // 禁止訪問受保護的寄存器
EALLOW;
PieVectTable.RXBINT = &scibRxFifoIsr;
EDIS;
// 步驟4. 初始化器件所有外圍設(shè)備:
//這個函數(shù)由DSP281x_InitPeripherals.c文件建立。
// InitPeripherals(); // 本例不需要
InitAdc(); // 初始化ADC模塊
PieCtrlRegs.PIEIER9.bit.INTx3=1; // 使能PIE 第9組 INT3(RXBINT)中斷
// Step 5. User specific code, enable interrupts:
// 步驟5. 用戶代碼,中斷使能:
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // 使能PIE向量表第一組第6個ADCINT中斷
IER |= (M_INT1 | M_INT9 ); // M_INT1=0x0001, 意為使能包含ADC轉(zhuǎn)換的第1組中斷
// M_INT9=0x0100, 意為使能包含SCI-B的第9組中斷
EINT; // 允許可屏蔽中斷(清INTM位)
ERTM; // ERTM指令在外圍設(shè)備頭文件(DSP281x_Device.h)中有定義:
// #define ERTM asm(" clrc DBGM")。即清除DBGM位,作用為使能全局實時中斷
//******************************************************************************************
// 關(guān)于輸入通道選擇序列控制寄存器注解:
//
// ADCCHSELSEQ1-ADCCHSELSEQ4 為4個16位ADC輸入通道選擇序列控制寄存器,從ADCCHSELSEQ1
// 最低位開始,每一個4位值CONVnn(0<=nn<15)可以選擇16個模擬輸入通道(A通道或是B通道)中
// 的任何一路。每一個ADCCHSELSEQn(1<=n<=4)管理4個固定的CONVnn,其對應(yīng)關(guān)系見下面注釋.
// 輸入通道選擇個數(shù)必須與ADC最大轉(zhuǎn)換通道(數(shù))寄存器(ADCMAXCONV)的配置相匹配.
//
// ADCCHSELSEQ1[3:0] =CONV00, ADCCHSELSEQ3[3:0] =CONV08,
// ADCCHSELSEQ1[7:4] =CONV01, ADCCHSELSEQ3[7:4] =CONV09,
// ADCCHSELSEQ1[11:8] =CONV02, ADCCHSELSEQ3[11:8] =CONV10,
// ADCCHSELSEQ1[15:12]=CONV03, ADCCHSELSEQ3[15:12]=CONV11,
// ADCCHSELSEQ2[3:0] =CONV04, ADCCHSELSEQ4[3:0] =CONV12,
// ADCCHSELSEQ2[7:4] =CONV05, ADCCHSELSEQ4[7:4] =CONV13,
// ADCCHSELSEQ2[11:8] =CONV06, ADCCHSELSEQ4[11:8] =CONV14,
// ADCCHSELSEQ2[15:12]=CONV07, ADCCHSELSEQ4[15:12]=CONV15,
//
// 注意:
// 每一個4位值CONVnn可以選擇ADC的16個模擬輸入通道中的任何一路。下面16個CONVnn
// 全部選擇ADCINA7引腳,第8通道。系統(tǒng)的每一次序列化(16次)采樣都針對同一個通道進行。
// 程序規(guī)定一個完整的采樣由16個序列化采樣組成,即在一個采樣點上完成256次采樣。256個
// 采樣數(shù)據(jù)通過模數(shù)轉(zhuǎn)換結(jié)果寄存器直接順序存入起始地址為0x0013f000的外存空間。
//
//******************************************************************************************
AdcRegs.ADCMAXCONV.all = 0x000f; // 配置SEQ1模式16通道
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0x7; // 選擇ADCINA7引腳,第8通道。
AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // 使能EVASOC 啟動SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // 使能SEQ1 中斷 (在每一個EOS時)
AdcRegs.ADCTRL3.bit.SMODE_SEL = 0; // 連續(xù)采樣方式配置
// SMODE_SEL: 采樣方式選擇位。
// 當(dāng)SMODE_SEL=0, 連續(xù)采樣方式; 當(dāng)SMODE_SEL=1, 并發(fā)采樣方式。
// 所謂連續(xù)采樣方式是指:一旦啟動轉(zhuǎn)換,則轉(zhuǎn)換按照當(dāng)前CONVxx決定的順序
// 進行,xx 4位值的最高位確定是A引腳還是B引腳,低3位確定A引腳或B引腳
// 的偏移量,采樣結(jié)果依次存入結(jié)果寄存器。在并發(fā)采樣方式下,xx 最高位
// 被舍棄,系統(tǒng)根據(jù)低3位的偏移量先進行對應(yīng)A引腳的采樣再進行對應(yīng)B引腳
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -