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

📄 bldcmcontrol.c

📁 2812例程以及 控制直流无刷电机程序
💻 C
字号:
// ==============================================================================
//  系统命名:BLDC31
//
//  文件名:BLDCMControl.C
//
//  描述:此框架程序用于实现对直流无刷电机(BLDC)进行控制
//
//  注:此系统默认的逆变器为ICETEK-MOTOR-E背板
// ==============================================================================

// 主程序使用的头文件声明
#include "target.h"		// 定义本系统使用的DSP型号

#include "DSP281x_Device.h"	// 电机驱动库头文件

#include "IQmathLib.h"		// 浮点运算库
#include "bldc3_1.h"		// 本系统使用的数字电机算法库内容
#include "parameter.h"		// 系统参数、电机参数
#include "build.h"			// 编译参数

#include "ICETEK-F2812-Ae.h"	// ICETEK-F2812-Ae板硬件定义

// 中断服务程序头定义
interrupt void MainISR(void);

// 全局变量
float32 T = 0.001/ISR_FREQUENCY;   // 采样频率,参看parameter.h
Uint32 VirtualTimer = 0;
Uint16 IsrTicker = 0;			// 中断计数
Uint16 BackTicker = 0;			// 主程序计数
volatile Uint16 EnableFlag = FALSE;		// 程序运行标志	
long lnADCValues;
int16 nADCValue,nADCValue1;
int16 DFuncDesired = 0;      // 占空比控制
int16 nNowStatus=0;
Uint16 uISRWork1=3000;

// 中断服务程序专用工作变量定义
Uint16 uISRWork;

// Instance a PWM driver instance
PWMGEN pwm1 = PWMGEN_DEFAULTS;

// 建立ADC驱动的一个实例
ADCVALS adc1 = ADCVALS_DEFAULTS;

void main(void)		// 主程序开始
{

// ******************************************
// F2812初始化
// ******************************************
// 初始化系统控制寄存器,锁相环,看门狗,时钟为默认状态
	InitSysCtrl();	// 详见DSP281x_SysCtrl.c

// 设置HISPCP预分频寄存器,通常设置成默认值
    EALLOW;   // 关闭保护,使受保护的寄存器可写
    SysCtrlRegs.HISPCP.all = 0x0000;     // SYSCLKOUT/1 
    EDIS;   // 打开保护 

// 清除并禁止所有CPU中断
	DINT;
	IER = 0x0000;
	IFR = 0x0000;

// 初始化Pie控制寄存器为默认状态
	InitPieCtrl();	// DSP281x_PieCtrl.c

// 初始化PIE中断向量表 Vector Table To a Known State:
	// 此函数设置中断向量表到DSP281x_DefaultIsr.c所指定位置
	InitPieVectTable();	// DSP281x_PieVect.c
	
// 设置: 用户定义的函数,修改向量表,使能中断
	
	LBDS=0x00;	//熄灭所有用户指示灯

// 初始化EVA定时器1/2: 设置相关寄存器
    EvaRegs.GPTCONA.all = 0;

    // 设置全局定时器2的周期
    EvaRegs.T2PR = SYSTEM_FREQUENCY*1000000*T;  // 预分频X1 (T2), ISR周期 = T x 1
    
    // 清除全局定时器2的计数/比较寄存器
    EvaRegs.T2CNT = 0x0000;
    EvaRegs.T2CMPR = 0x0000;     

   	// 等待程序运行标志变成TRUE
   	while ( EnableFlag==FALSE ) 
    { 
      	BackTicker++;	// 程序运行计数加1
    }

// 使能全局定时器的周期中断
    EvaRegs.EVAIMRB.bit.T2PINT = 1;
    EvaRegs.EVAIFRB.bit.T2PINT = 1;

    // 增计数,x1,内部时钟,禁止比较,使用自己的周期
    EvaRegs.T2CON.all = 0x9040;

// 指定T2PINT到中断服务程序MainISR
	EALLOW;	// This is needed to write to EALLOW protected registers
	PieVectTable.T2PINT = &MainISR;
	EDIS;   // This is needed to disable write to EALLOW protected registers

// 使能T2PINT
    PieCtrlRegs.PIEIER3.all = M_INT1;
	IER |= M_INT3;

// Initialize PWM module
    pwm1.PeriodMax = (SYSTEM_FREQUENCY/PWM_FREQUENCY)*1000;  // Asymmetric PWM
    pwm1.DutyFunc = 0;	                            
    pwm1.init(&pwm1);

// 初始化ADC模块
    adc1.ChSelect = 0x7777;	// 通道选择:采集ADCIN7的输入4次
	adc1.init(&adc1);

// 使能全局中断和实时DEBUG事件
	EINT;   // Enable Global interrupt INTM
	ERTM;	// Enable Global realtime interrupt DBGM

// 空闲循环
	for(;;)
	{
		BackTicker++;
	}
} 	

// 定时器2中断服务程序
interrupt void MainISR(void)
{
	IsrTicker++;	// 中断计数

	uISRWork=(IsrTicker%uISRWork1);		// 控制nNowStatus以一定频率变动
	if ( uISRWork==0 )
	{
		nNowStatus++; nNowStatus%=6;	// 取值在[0,5]顺序递增后折返
	}

	pwm1.CmtnPointer = nNowStatus;		// 设置当前输出状态
	pwm1.DutyFunc = DFuncDesired;		// 占空比
	pwm1.update(&pwm1);					// 更新PWM状态只为它可以启动ADC转换

	if ( VirtualTimer%4000==0 )	// 每秒回读10次ADC结果
	{
		adc1.read(&adc1);	// 读一次ADC转换值(采集ADCIN7四次)
		lnADCValues=adc1.Ch1Out;	
		lnADCValues+=adc1.Ch2Out;
		lnADCValues+=adc1.Ch3Out;
		lnADCValues+=adc1.Ch4Out;
		lnADCValues/=4;		// 累加4次结果求平均值
		nADCValue1=lnADCValues;	// 将模拟输入值转换成0-255之间的取值存储到变量nADCValue中
		nADCValue1/=100; 
		if ( nADCValue1>255 )	nADCValue1=255;
		else if ( nADCValue1<0 )	nADCValue1=0;
		nADCValue=nADCValue1;
		DFuncDesired=nADCValue*10+72;
	}

	if ( VirtualTimer%20000==0 )	// 指示灯DS1每秒闪烁1次
		LBDS^=1;

// ------------------------------------------------------------------------------
//    15 bit计数器
// ------------------------------------------------------------------------------
	VirtualTimer++;
	VirtualTimer &= 0x00007FFF;

// 中断出口:
// Enable more interrupts from this timer
	EvaRegs.EVAIMRB.bit.T2PINT = 1;
	
// Note: To be safe, use a mask value to write to the entire
	// EVAIFRB register.  Writing to one bit will cause a read-modify-write
	// operation that may have the result of writing 1's to clear 
	// bits other then those intended. 
    EvaRegs.EVAIFRB.all = BIT0;
	
// Acknowledge interrupt to recieve more interrupts from PIE group 3
	PieCtrlRegs.PIEACK.all |= PIEACK_GROUP3;
}

//===========================================================================
// No more.
//===========================================================================

⌨️ 快捷键说明

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