📄 bldcsensor.c
字号:
/* ====================================================
System Name: BLDCSensor(BLDC有位置传感器)
====================================================*/
#include <bldcSensor.h>
void RstSystem(void);
void rtmon_init(void);
void interrupt c_int03();
void interrupt phantom(void);
void GetSpeed(void);
// Global variables used in this system
int SpeedRef = 0x669; // 转速设定300rpm (pu)
int CurrentSet = 0x096; //电流设定,上限;1/20
int VirtualTimer = 0;
int ILoopFlag = FALSE;
int SpeedLoopFlag = FALSE;
int DFuncDesired = 0x2fff; // Desired duty cycle (Q15)
long speedtime=0;
int speedcount;
/*-----------------------------电机转子位置输出表-------------------------------*/
//表电机控制器换向表,电路板输出为低电平导通,高电平截至
unsigned int ACTRX1[]={0X0FFF,0X0F3E,0X03FE,0X03EF,0X0FE3,0X0EF3,0X0E3F,0X0FFF}; //电动运行换向表:AB->AC->BC->BA->CA->CB->AB
unsigned int ACTRX[]={0X0FFF,0X0FFB,0X0FFB,0X0FBF,0X0FBF,0X0BFF,0X0BFF,0X0FFF}; //发电运行换向表
//自定义变量2007-6-2
unsigned int disp_refresh=0;
int runled=0x0ffff;
unsigned int COM=0x0ff00;
int keycounter=0;
int key=0; //6-7-2007添加,定义并初始化KEY变量
int HallValue;
int TabShift=0;
int duty;
// System settings
#define WAIT_STATES 0x00C0
//Instance the WATCHDOG Interface.
WATCHDOG wdog = WATCHDOG_DEFAULTS;
// Instance PID regulator to regulate the DC-bus current and speed
PID2 pid1_idc = PID2_DEFAULTS;
PID2 pid1_spd = PID2_DEFAULTS;
// Instance a PWM driver instance
PWMGEN pwm1 = PWMGEN_DEFAULTS;
// Create an instance of the ADC driver
ADCVALS adc1 = ADCVALS_DEFAULTS;
// Instance a Hall effect driver
HALL3 hall1 = HALL3_DEFAULTS;
// Instance a ramp controller to smoothly ramp the frequency
RMPCNTL rc1 = RMPCNTL_DEFAULTS;
// Instance a RAMP2 Module
RMP2 rmp2 = RMP2_DEFAULTS;
// Instance a MOD6 Module
//MOD6CNT mod1 = MOD6CNT_DEFAULTS;
// Instance a SPEED_PR Module
SPEED_MEAS_CAP speed1 = SPEED_MEAS_CAP_DEFAULTS;
/*-----------------------------------------------------------------------------
Instance the ISR checking variable
-----------------------------------------------------------------------------*/
int isr_ticker;
void main()
{
/*-----------------------------------------------------------------------------
Return system to a sane condition
-----------------------------------------------------------------------------*/
RstSystem();
// Initialize PWM module
pwm1.DutyFunc = DFuncDesired; // DutyFunc = Q15
pwm1.init(&pwm1); /* pwm driver initialization */
// Initialize ADC module
adc1.ChSelect = 0x6666; //母线电流通道AD06
adc1.init(&adc1);
// Initialize the SPEED_PR module (150 MHz, N = 1 event period/rev)
speed1.InputSelect = 0; //?
speed1.BaseRpm = 6000; //120*(BASE_FREQ/P);
speed1.SpeedScaler = 400; //(Uint32)(ISR_FREQUENCY/(1*BASE_FREQ*0.001));BASE_FREQ=100;ISR_FREQUENCY=40(K)
speed1.motorpairs= 23;
// Initialize RMPCNTL module
rc1.RampDelayMax = 0x00ff;
rc1.RampLowLimit = 0x8000; //_IQ(0);
rc1.RampHighLimit = 0x7FFF; //_IQ(1);
// Initialize Hall module
//hall1.DebounceAmount = 5;
//hall1.Revolutions = -10; //?
hall1.init(&hall1);
// Initialize RMP2 module
rmp2.Out = DFuncDesired;
rmp2.Ramp2Delay = 50;
rmp2.Ramp2Max = 0x7FF0;
rmp2.Ramp2Min = 0x000F;
// Initialize the PID2 module for dc-bus current
pid1_idc.k0_reg2 = 0x0200; //Q9,_IQ(1);
pid1_idc.k1_reg2 = 0x0e0; //Q13,_IQ(T/0.003);
pid1_idc.kc_reg2 = 0x0506; //Q13,_IQ(0.2);
pid1_idc.max_reg2 = 0x7fff; // Q15 D=100% ,_IQ(0.99);
pid1_idc.min_reg2 = 0x0000; //_IQ(0);
// Initialize the PID2 module for speed
pid1_spd.k0_reg2 = 0x0800; //_IQ(2);
pid1_spd.k1_reg2 = 0x40;//0x0740; //_IQ(T/0.1);()0.002
pid1_spd.kc_reg2 = 0x0506; //_IQ(0.2);
pid1_spd.max_reg2 = 0x7fff; //// Q15 D=100%;
pid1_spd.min_reg2 = 0; // _IQ(10%);
T2PR = SYSTEM_INT_PERIOD; /* Initialize period register ,time base from T2 underflow interrupt (i.e. period)*/
T2CNT = 0x0000;
T2CON = 0x9040; // Count up, x1, internal clk, disable compare, use own period
/*-----------------------------------------------------------------------------
Initialise the Real time monitor
-----------------------------------------------------------------------------*/
#if (REAL_TIME == TRUE)
rtmon_init(); /* Call the monitor init function */
#endif /* REAL_TIME==TRUE */
// Enable global Interrupts and higher priority real-time debug events:
asm(" CLRC INTM "); /* set off the system running */
/*-----------------------------------------------------------------------------
LCD显示程序
----------------------------------------------------------------------------*/
LCD_disp1();
// COM=PFDATDIR;
// PFDATDIR=COM;
// PFDATDIR=PFDATDIR|0x0020;
/*-------------------------------------------------------------------------*/
// IDLE loop. Just sit and loop forever:
while(1) /* Nothing running in the background at present */
{
/*------------------------运行灯闪烁------------------------*/
keycounter++;
disp_refresh++;
if(disp_refresh>=40000)//1s刷新一次LCD显示
{
disp_refresh=0;
// PFDATDIR=(PFDATDIR|0x2020)&((~runled)|0x0ffdf);
// COM=PFDATDIR;
Iref_disp(); //电流给定值显示
Ifb_disp(); //电流实际值显示
Vref_disp(); //转速给定值显示
Vfb_disp(); //转速实际值显示
fpwm_disp(); //PWM斩波频率显示
Dpwm_disp(); //PWM占空比显示
mod6_disp(); //换向的状态,0~5中的一个.St显示
Hmap_disp(); //换向表
prop_int();
// PFDATDIR=COM;
}
/*-------------6-7-2007--按键设定用s1来增加,s2来减少---------*/
if(keycounter>=400) //10ms处理一次按键
{ keycounter=0;
key=Keys1s8();
switch(key)
{
case 1: {SpeedRef = SpeedRef+56;break;} //设定+步长10RPM
case 2: {SpeedRef = SpeedRef-56;break;} //设定-步长10RPM
case 3: {pid1_spd.k0_reg2 = pid1_spd.k0_reg2+0x010;break;} //_IQ(2);
case 4: {pid1_spd.k0_reg2 = pid1_spd.k0_reg2-0x010;break;} //_IQ(2);
case 5: {pid1_spd.k1_reg2 = pid1_spd.k1_reg2+0x01;break;} //_IQ(2);
case 6: {pid1_spd.k1_reg2 = pid1_spd.k1_reg2-0x01;break;} //_IQ(2);
case 7: {duty = duty + 0x1000;break;}
case 8: {TabShift = TabShift+1;break;}
default:;
}
}
/*------------------------------------------------------------------------------*/
/************************************************************************
GetSpeed,通过使用每个机械周期内中的值确定电机的精确速度。
*************************************************************************/
/* if (HallValue == 3) // 如果位于区间1
{
HallValue = 0xFF; // 强制一个新值作为区间值
if (++speedcount == speed1.motorpairs) // 对于23对极电机,将此代码段执行23 个电周期(即1 个 机械周期)
{
//Timer3 = TMR3;// 读tmr3 的最新值
//TMR3 = 0;
//Count = 0;
GetSpeed();// 确定速度
}
}*/
} /* Main system background loop */
} /* End: main() */
void interrupt c_int03()
{
// asm(" CLRC XF ");
isr_ticker++;
/*-----------------------------------------------------------------------------*/
EVAIFRB=0x0ffff; /* Clear all EV1 Group A EV interrupt flags*/
// ------------------------------------------------------------------------------
// Call the ADC04U_DRV read function.
// ------------------------------------------------------------------------------
// adc1.read(&adc1);
// ------------------------------------------------------------------------------
// Connect inputs of the RMP module and call the Ramp control
// calculation function.
// ------------------------------------------------------------------------------
rc1.TargetValue = SpeedRef;
rc1.calc(&rc1);
// ------------------------------------------------------------------------------
// Connect inputs of the HALL module and call the Hall sensor
// read function.
// ------------------------------------------------------------------------------
hall1.read(&hall1);
// ------------------------------------------------------------------------------
// Connect inputs of the MOD6 module and call the Modulo 6 counter
// calculation function.
// ------------------------------------------------------------------------------
//mod1.TrigInput = hall1.CmtnTrigHall;
//mod1.Counter = hall1.HallMapPointer;
//mod1.calc(&mod1);
// ------------------------------------------------------------------------------
// Connect inputs of the RMP2 module and call the Ramp control 2
// calculation function.
// ------------------------------------------------------------------------------
rmp2.DesiredInput = DFuncDesired;
rmp2.calc(&rmp2);
// ------------------------------------------------------------------------------
// Connect inputs of the PID_REG3 module and call the PID speed controller
// calculation function.
// ------------------------------------------------------------------------------
pid1_spd.ref_reg2 = rc1.SetpointValue;
pid1_spd.fb_reg2 = (int)(speed1.Speed);
pid1_spd.calc(&pid1_spd);
// ------------------------------------------------------------------------------
// Set the speed closed loop flag once the speed is built up to a desired value.
// ------------------------------------------------------------------------------
if (rc1.EqualFlag == 0x7FFF) {
// SpeedLoopFlag = TRUE;
rc1.RampDelayMax = 300;
}
// ------------------------------------------------------------------------------
// Connect inputs of the PWM_DRV module and call the PWM signal generation
// update function.
// ------------------------------------------------------------------------------
// Switch from fixed duty-cycle or controlled Speed duty-cycle by SpeedLoopFlag variable
if (SpeedLoopFlag == FALSE)
pwm1.DutyFunc = (rmp2.Out+duty)&0x07fff; // fixed duty-cycle
else
pwm1.DutyFunc = pid1_spd.out_reg2; // controlled Speed duty-cycle
//pwm1.CmtnPointer = hall1.tab;
HallValue=hall1.tab;
ACTRB=ACTRX1[(hall1.tab+TabShift)&6];
pwm1.update(&pwm1);
// ------------------------------------------------------------------------------
// Connect inputs of the SPEED_PR module and call the speed calculation
// function.
// ------------------------------------------------------------------------------
if (HallValue == 3) {
HallValue = 0xFF; // 强制一个新值作为区间值
if (++speedcount == speed1.motorpairs) // 对于23对极电机,将此代码段执行23 个电周期(即1 个 机械周期)
{
speed1.TimeStamp = VirtualTimer;
// speed1.calc(&speed1);
}
// if (speed1.InputSelect == 0)
//{
speed1.OldTimeStamp = speed1.NewTimeStamp;
speed1.NewTimeStamp = speed1.TimeStamp;
speed1.EventPeriod = speed1.NewTimeStamp - speed1.OldTimeStamp;
if (speed1.EventPeriod < 0)
speed1.EventPeriod += 32767; // 0x7FFF = 32767
//}
speed1.calc(&speed1);
/* SpeedTemp = (speed1.SpeedScaler*speed1.BaseRpm)/(speed1.EventPeriod*speed1.motorpairs);
speed1.SpeedRpm =(int)SpeedTemp;
speed1.Speed = ((long)speed1.SpeedRpm<<15)/((long)speed1.BaseRpm);
*/
}
// ------------------------------------------------------------------------------
// Increase virtual timer and force 15 bit wrap around
// ------------------------------------------------------------------------------
VirtualTimer++;
VirtualTimer &= 0x7FFF;
speedtime++;
speedtime &= 0x7FFFFFFF;
// asm(" SETC XF ");//SCSR2中/BOOT EN.BOOT使能位,这一位反映XF引脚在复位时的状态,它可以被软件改变.XF=0硎臼鼓芤
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -