⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svpwm.c

📁 基于f2812的svpwm程序
💻 C
字号:
/*******************************************************************************************
文件: 	SvPwm.c		空间矢量脉宽调制	

标题:	通过事件管理产生PWM	

条件:	本程序需要DSP281x V1.00头文件支持,另外需配置成"boot to H0"操作方式。	
		除了boot方式引脚配置外,无需其他硬件配置方式。

说明:	该程序设置EV定时器(TIMER1, TIMER2, TIMER3 and TIMER4),用于产生T1PWM, 
		T2PWM, T3PWM, T4PWM and PWM1-PWM12波形。可通过示波器观察这些波形。

		在以下几个方面对TI提供的驱动源码进行了硬件和软件的增强:
		(1) 增加了LED数码管显示的硬件接口。以便将EvPwm发生的次数反映在LED数码管上。	
		(2)	在更新EvPwm时,增加了受GPIO A控制的16个Led发光二极管的闪烁显示。
		(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的(α,β)坐标轴分量Ualfa,
									// Ubeta的数组
Uint16      sector[200];			// 定义存储扇区数的数组
#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调制周期T的
									// 一半,因为在该程序中2π电度角内Uout的点数一
									// 定,故改变此值可以改变输出的三相正弦交流电压的频
//float 		KP=0.7;									// 率
static float KP=0.7;				// 定义Uout的标么值,KP的值在0和1之间,改变此
									// 值可以改变逆变桥输出电压的幅值
static int   receive[5];			// 串口通讯数据接收数组
//static int   transfer[7];			// 串口通讯数据发送数组
//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};	// 逆时针旋转的6个基本矢量

		//**********************************************//

	// 本文件建立的函数原型声明。
void init_eva(void);			// EVA配置T1PWM, T2PWM, PWM1-PWM6 ,初始化定时器
void init_evb(void);			// EVB配置T3PWM, T4PWM, PWM7-PWM12 ,初始化定时器
void delay();					// 延时函数

interrupt void  adc_isr(void);

void OscillographTable();		// 制作示波器表格

void VoltageCurve();
void AdcResultCopy();

Uint16 *Xaddr=(Uint16 *)0x13f000;

Uint16 Xram_pointer=0;

// 本例的全局变量



	// 外部函数声明。由Bc7281.c 文件建立
void LedD_Display(void);
	// 将模数转换值以10进制形式,在Led第4,3,2,1位数码管上进行显示	
void LedH_Display(void);
	// 将模数转换值以16进制两个字节形式,在Led第8,7,6,5位数码管上进行显示

	// 本例中的全局计数器
Uint16 count=0,i;


void main(void)
{
	int i,k=0,cmp1,cmp2;
	float x,y,z;

		// 步骤1 系统控制初始化: 锁相环(PLL),看门狗(WatchDog)及外设时钟
		// (PeripheralClocks)初始化。该函数在DSP281x_SysCtrl.c文件中建立。
	InitSysCtrl();

		// 步骤2.初始化GPIO: 
		// 这个函数例举怎样将GPIO设置成其默认状态,该函数由DSP281x_Gpio.c文件建立。
// 	InitGpio();  	// 本例跳过这个函数 

	lcd_init();
	clearscr1();					// 第一显示缓冲区(0x0000-0x29ff)清零
	clearscr2();					// 第二显示缓冲区(0x2a00-0x53ff)清零
	clearscr3();					// 第三显示缓冲区(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端口设置成IO方式		 
    GpioMuxRegs.GPADIR.all=0xffff;		// 将GPIO A所有15个端口配置成数字量输出 
	EDIS;								// 禁止访问受保护的寄存器
    GpioDataRegs.GPADAT.all=0xAAAA;		// 间隔一个点亮LED发光二极管。

		// 步骤3 关所有中断并初始化PWM矢量表
   	DINT;			// 关CPU中断
   
   	InitPieCtrl();	// 初始化PIE控制寄存器为默认状态。该状态关所有PIE中断并清除所
   					// 有标识。该函数在DSP281x_PieCtrl.c文件中建立。

   	IER = 0x0000;	//	关CPU中断并清CPU中断标识。
   	IFR = 0x0000;

   	InitPieVectTable();
					// 初始化PIE向量表,该向量表指出中断服务程序(ISR)的构架。即使在本范例中
					// 没有用到中断,仍旧组装整张表。它在程序调试时是很有用的。ISR程序构架由
					// DSP281x_DefaultIsr.c文件建立
					// InitPieVectTable()函数由DSP281x_PieVect.c文件建立
   
//##################

		// 本例用到的中断重新映射到由本文件建立的ISR函数中。
//******************************************************************************************
//   			关于 "PieVectTable.ADCINT = &adc_isr;" 指令的说明   
//	1. adc_isr 是一个ADC模块中断服务程序(ISR)。
//	2. 这个中断程序与中断扩展(PIE)向量表第1组INT1第6个中断向量ADCINT(ADC)对应。
//	3. 为了使这个程序响应对应的中断,还需作如下配置: 
//	 
//		PieCtrlRegs.PIECRTL.bit.ENPIE = 1;  
// 		使能PIE向量表。这条指令包含在上面调用的InitPieVectTable()函数中。
//
//   	IER |= M_INT1;						// 使能PIE向量表第1组CPU INT1中断	
//   	PieCtrlRegs.PIEIER1.bit.INTx6 = 1;	// 使能PIE向量表第一组第6个ADCINT中断
//      EINT;         					    // 允许可屏蔽中断(清INTM位)
//
//   	这几条指令在本程序的后续指令中可以找到。这样,在发生ADCINT中断的情况下,将
//		执行adc_isr()中断服务程序。   	
//   	"PieVectTable.ADCINT = &adc_isr;" 指令实际上就是通知编译器,在发生ADCINT
//		中断的情况下,将执行adc_isr()中断服务程序。adc_isr头上的"&"为取地址运算符。
//******************************************************************************************
   	EALLOW;  							// 允许访问受保护的寄存器
   	PieVectTable.ADCINT = &adc_isr;
   	EDIS;    							// 禁止访问受保护的寄存器

	EALLOW; 
	PieVectTable.RXBINT = &scibRxFifoIsr;
   	EDIS; 
		// 步骤4. 初始化器件所有外围设备:
		//这个函数由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转换的第1组中断
										// M_INT9=0x0100, 意为使能包含SCI-B的第9组中断

	EINT;         					    // 允许可屏蔽中断(清INTM位)
	ERTM;   // ERTM指令在外围设备头文件(DSP281x_Device.h)中有定义: 
			// #define  ERTM   asm(" clrc DBGM")。即清除DBGM位,作用为使能全局实时中断

//******************************************************************************************
// 关于输入通道选择序列控制寄存器注解:
//
// 	ADCCHSELSEQ1-ADCCHSELSEQ4 为4个16位ADC输入通道选择序列控制寄存器,从ADCCHSELSEQ1
// 	最低位开始,每一个4位值CONVnn(0<=nn<15)可以选择16个模拟输入通道(A通道或是B通道)中
// 	的任何一路。每一个ADCCHSELSEQn(1<=n<=4)管理4个固定的CONVnn,其对应关系见下面注释.
// 	输入通道选择个数必须与ADC最大转换通道(数)寄存器(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通道。系统的每一次序列化(16次)采样都针对同一个通道进行。
//	程序规定一个完整的采样由16个序列化采样组成,即在一个采样点上完成256次采样。256个
//	采样数据通过模数转换结果寄存器直接顺序存入起始地址为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; 				// 连续采样方式配置			    
		// SMODE_SEL: 采样方式选择位。
		// 当SMODE_SEL=0, 连续采样方式; 当SMODE_SEL=1, 并发采样方式。
		// 所谓连续采样方式是指:一旦启动转换,则转换按照当前CONVxx决定的顺序
		// 进行,xx 4位值的最高位确定是A引脚还是B引脚,低3位确定A引脚或B引脚
		// 的偏移量,采样结果依次存入结果寄存器。在并发采样方式下,xx 最高位
		// 被舍弃,系统根据低3位的偏移量先进行对应A引脚的采样再进行对应B引脚

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -