📄 user_interface.c
字号:
/**********************************************************************
* 程序说明
*
* 该文件包含所有的执行用户接口的代码,用户接口函数由慢速事件调用,每100mSec
* 执行一次。
* 按照操作状态的变化调用不同的显示屏幕,函数process_switches()采用去抖动按钮,
* 确定参数快速递增时按键按下的时间,并通过按钮使系统在不同的状态切换。
* 函数save_parameter()把参数从flash内存读到RAM,修改参数然后再把它写回内存。
* 函数process_parameters()对要存储的参数做比例或单位变换。
*
**********************************************************************/
#include "general.h"
#include "hardware.h"
#include "defs.h"
#include "extern_globals.h"
#ifdef DEVELOPMODE
/*********************************************************************/
// 串行数据传送的ASCII缓冲,数据存储再程序内存中,采用dsPIC的PSV特征获取数据。
struct parameter_data
{
char *line_msg; //屏幕上行1参数信息
char *quick_msg; //信息缩写
};
struct fault_data
{
char *fault_msg;
};
const struct fault_data fault_data [] =
{
{"Press S2 to continue ..."},
{"Failed to Start"},
{"Over Current"},
{"Over Voltage"},
{"Hardware Trip"},
{"Over Speed"},
{"Sensorless Lost"},
{"Motor Stalled"}
};
const unsigned char help_info[5][14]=
{
{0,25,32,41,50,50,50,50,50,50,50,50,50,50},
{26,27,28,29,33,34,35,36,37,38,39,42,50,50},
{2,3,4,5,6,7,8,9,10,30,31,40,43,44},
{1,11,12,17,18,19,20,21,22,23,24,50,50,50},
{13,14,15,16,50,50,50,50,50,50,50,50,50,50},
};
const struct parameter_data parameter_data [] =
{
// Line msg, Quick msg
{"DIRECTION ","DD"},//0
{"CONTROL MODE ","CM"},//1
{"Lock Pos.1 Time ","LP1T"},//2
{"Lock Pos.2 Time","LP2T"},//3
{"Lock Pos.1 Dem. ","LP1D"},//4
{"Lock Pos.2 Dem. ","LP2D"},//5
{"Ramp Start Speed","RSS"},//6
{"Ramp End Speed ","RES"},//7
{"Ramp Start Dem. ","RSD"},//8
{"Ramp End Dem. ","RED"},//9
{"Ramp Duration ","RD"},//10
{"Phase Adv. Enable Spd ","PAES"},//11
{"Phase Adv. Slope","PAS"},//12
{"Stall Time Limit","STL"},//13
{"Over Speed Limit","OSL"},//14
{"Over Volts Limit","OVL"},//15
{"Over Current Lim","OCL"},//16
{"Current P Gain ","CKP"},//17
{"Current I Gain ","CKI"},//18
{"Current D Gain ","CKD"},//19
{"Speed P Gain ","SKP"},//20
{"Speed I Gain ","SKI"},//21
{"Voltage Demand ","VD"},//22
{"Volts P Gain ","VKP"},//23
{"Volts I Gain ","VKI"},//24
{"No. Motor Poles ","MP"},//25
{"Current Scale X ","CSX"},//26
{"Current Scale / ","CSD"},//27
{"Volts Scale X ","VSX"},//28
{"Volts Scale / ","VSD"},//29
{"Tolerance Check ","TC"},//30
{"Auto Re-acquire ","ARA"},//31
{"Blanking Count ","BC"},//32
{"Zero X Level Thd","ZXL"},//33
{"Acquire Threshld","AT"},//34
{"Acquire Level Td","AL"},//35
{"Rotation Timeout","RT"},//36
{"Pot / for Duty ","PDD"},//37
{"Pot / for Currnt","PDC"},//38
{"Pot X for Speed ","PXS"},//39
{"Starting Control","SC"},//40
{"Windmilling Dem.","WD"},//41
{"Braking Ramp T ","BRT"},//42
{"Acquire Method ","AM"},//43
{"ZeroX Enable Spd","ZXES"},//44
};
const unsigned char ParaHeader[] =
{"\r\nParameter Description\tParameter Abbreviation\tParameter Value\r\n"};
const struct parameter_data HelpMsg_data [] =
{
{"For Motor Parameters\t","Use '?M'"},
{"For Starting Parameters\t", "Use '?S'"},
{"For Control Parameters\t", "Use '?C'"},
{"For Limit Parameters\t", "Use '?L'"},
{"For Board Parameters\t", "Use '?B'"},
};
const unsigned char ErrorMsg[] = {"\r\nIncorrect Command! Use '??' For command set.\r\n"};
const unsigned char MotorParaHeader[] = {"Motor Parameters:\r\n"};
const unsigned char LimitParaHeader[] = {"Limit Parameters:\r\n"};
const unsigned char StartingParaHeader[] = {"Starting Parameters:\r\n"};
const unsigned char BoardParaHeader[] = {"Board Parameters:\r\n"};
const unsigned char ControlParaHeader[] = {"Control Parameters:\r\n"};
const unsigned char RunMessage[] = {"\r\n\r\n Speed = 2200 r.p.m. DutyCycle = 72% Peak Current = 0245 mA \r\n"};
const unsigned char FaultMessage[] = {"\r\n\r\n Fault = Failed to Start \r\n"};
const unsigned char RunMsg1[] = {"Speed in rpm = "};
const unsigned char RunMsg2[] = {" % DutyCycle = "};
#endif
#ifndef DEVELOPMODE
volatile unsigned int user_parameters[64] __attribute__((aligned(64),far,section(".const,r")))=
#endif
#ifdef DEVELOPMODE
unsigned int user_parameters[45] =
#endif
{
//BACKWARDS,
FORWARDS,
CLOSED_VOLTS, //速度控制模式->参见defs.h
50, // 首次锁位置时间,单位10mSec(中等速率时间)
50, // 第二次锁位置时间,单位10mSec(中等速率时间)
50, // 锁定位置1所需的数值百分比
50, // 锁定位置2所需的数值百分比
100, // 加速的起始速度,单位RPM
2000, // 加速的终止速度,单位RPM
52, // 加速起始所需的数值百分比
68, // 加速终止所需的数值百分比
100, // 开始加速持续时间,单位10mSec(中等速率时间)
1500, // 开始速度相位超前(缺省1500)
25, // 缓升相位超前,单位RPMP,1/1000
100, // 失速时间极限,单位10mSec(中等速率时间)
3500, // 过速跳闸,单位RPM,缺省(3500)
500, // 过压跳闸,单位1/10 V
100, // 过流极限,单位1/10 A
900, // 电流环P增益
100, // 电流环I增益
0, // 电流环D增益
2500, // 速度环P增益
40, // 速度环I增益
490, // 制动刹车所需的电压,单位1/10 V
10000, // 电压环P增益
5000, // 电压环I增益
8, // 马达的级数
100, // 电流放大比例系数Ix
539, // 电流缩小比例系数I/
//239,
100, // 电压放大比例系数Vx
//10,
1305, // 电压缩小比例系数V/
//910,
90, // 跑飞检查公差百分比
1, // 如果跑飞自动获取
1, // 熄火时间长度用于过零检测
2, // 在过零检测前> 或 < VDC/2所需的采样数
12, // 用于上升沿检测的ADC值
6, // 上升沿检测完成之前VPH采样数
5, // 旋转时间到,单位10mSec(中等速率时间)
1, // 用于把读到的ADC值转成占空比的除数
8, // 用于把读到的ADC值转成I项所需的除数
3, // 用于把读到的ADC值转成所需的转速,单位rpm
1, // 1=采用电压控制, 0=采用电流控制
20, // 自转制动所需的数值百分比
1, // 加速制动持续时间,单位10mSec(中等速率时间)
0, // 获取位置采用的方法 1 (=0) 或者方法 2 (=1)
400}; // 采用方法 1 过零检测使能时的速度
// 电流放大、缩小比例系数用于把ADC读数转换为电流或电压:
// 如Vibus = 12.87V , 乘以比例系数100则结果为1287。
// 对于低电压模块:
// VX=100 V/=1305 则比例系数为 13.05 V/V
// 如果LK11&12开路,IX=100 I/=539 则比例系数为 5.39A/V
// 如果LK11&12短路,IX=10 I/=119 则比例系数为 11.9A/V
// 对于高电压模块:
// VX=10 V/910 则比例系数为 91.0 V/V
// 如果LK11&12开路,IX=100 I/=108 则比例系数为 1.08A/V
// 如果LK11&12短路,IX=100 I/=239 则比例系数为 2.39A/V
// 跑飞检查容许公差常设为不小于25%
/*********************************************************************/
#ifdef DEVELOPMODE
void GetMsgIndex(void);
void SendCRLF(void);
void SendErrorMsg(void);
void CheckHelp(void);
void SendHelpMsg(void);
void SendMsg(void);
void SendValue(unsigned int k);
void SaveValue(void);
void InitUart(void);
void SendHelpInfo(unsigned char Tab);
void SendMotorPara(void);
void SendLimitPara(void);
void SendControlPara(void);
void SendBoardPara(void);
void SendStartingPara(void);
void SendHeader(void);
void SendTab(void);
void SendRunMsg(void);
void SendFaultMsg(void);
void send_run(void);
void send_fault(void);
void serial_handler(void);
#endif
void process_switches(void);
void save_parameter(void);
void process_parameters(void);
void debounce_switches(void);
void uint_to_string(unsigned int, unsigned char *);
extern void erase_flash_row(unsigned int);
extern void program_flash(unsigned int, unsigned int);
struct interface_flags {
unsigned EDIT_PARAM : 1;
unsigned EDIT_MENU : 1;
unsigned PARAM_CHANGING : 1;
unsigned S4_RISING :1;
unsigned S5_RISING :1;
unsigned S6_RISING :1;
unsigned S7_RISING :1;
unsigned RUN_FRAME :1;
unsigned UNUSED : 8;
};
struct interface_flags interface_flags;
//键盘处理子程序
void process_switches(void)
{
static unsigned char initializing_timer=20;
static unsigned char previous_valid_switch_states=0xFF;
static unsigned char key_hold_timer=0;
static unsigned int param_increment=1;
if (initializing_timer==1) run_state=STANDBY;
if (initializing_timer) initializing_timer--;
if (((previous_valid_switch_states & 0x08)==FALSE) && (valid_switch_states & 0x08))
interface_flags.S7_RISING=TRUE;
else
interface_flags.S7_RISING=FALSE;
previous_valid_switch_states=valid_switch_states;
switch(run_state)
{
case INITIALIZING: break;
case STANDBY: if (interface_flags.S7_RISING)
{
DISABLE_INTERRUPTS;
control_flags2.ROTATION_CHECK=TRUE;
control_flags2.WINDMILLING=FALSE;
control_flags2.RETRY_FLAG=FALSE;
control_flags.LOCK1=FALSE;
control_flags.LOCK2=FALSE;
control_flags.RAMP=FALSE;
control_flags.SENSORLESS=FALSE;
control_flags.ACQUIRE2=FALSE;
control_flags.ACQUIRE1=FALSE;
control_flags.DIR=user_parameters[0];
ENABLE_INTERRUPTS;
run_state=STARTING;
interface_flags.EDIT_MENU=FALSE;
interface_flags.RUN_FRAME=0;
fault_count = 0;
}
if (interface_flags.S4_RISING)
interface_flags.EDIT_MENU=TRUE;
break;
case STARTING: if (interface_flags.S7_RISING)
{
DISABLE_FIRING;
control_flags.SENSORLESS=FALSE;
control_flags.ACQUIRE2=FALSE;
IEC0bits.T1IE=FALSE;
IEC0bits.T2IE=FALSE;
run_state=STANDBY;
}
break;
case RUNNING: if (interface_flags.S7_RISING)
{
DISABLE_FIRING;
control_flags.SENSORLESS=FALSE;
control_flags.ACQUIRE2=FALSE;
IEC0bits.T1IE=FALSE;
IEC0bits.T2IE=FALSE;
run_state=STANDBY;
}
if (interface_flags.S4_RISING)
interface_flags.RUN_FRAME= !interface_flags.RUN_FRAME;
break;
case FAULT: if (interface_flags.S7_RISING)
{
trip_state=NO_TRIP;
DISABLE_INTERRUPTS;
control_flags.LOCK1=FALSE;
control_flags.LOCK2=FALSE;
control_flags.RAMP=FALSE;
control_flags.SENSORLESS=FALSE;
control_flags.ACQUIRE1=FALSE;
control_flags.ACQUIRE2=FALSE;
IEC0bits.T1IE=FALSE;
IEC0bits.T2IE=FALSE;
ENABLE_INTERRUPTS;
period_measurement=1000;
//FAULT_RESET=TRUE;
//FAULT_RESET=FALSE;
run_state=STANDBY;
}
if (interface_flags.S4_RISING)
interface_flags.EDIT_MENU=TRUE;
break;
default: break;
}
return;
}
//参数处理子程序,
void process_parameters(void)
{
unsigned long ltemp,ltemp2;
switch (param)
{
case 0: control_flags.DIR=user_parameters[0];
break;
case 4: //用电压控制
if (user_parameters[40])
hold1_demand=(unsigned int)((unsigned long)user_parameters[4])*FULL_DUTY/100;
else //用电流控制
{
ltemp=((unsigned long)(current_trip-ibus_offset));
ltemp*=((unsigned long)user_parameters[4]);
hold1_demand=(unsigned int)(ltemp/100);
}
break;
case 5: //用电压控制
if (user_parameters[40])
hold2_demand=(unsigned int)((unsigned long)user_parameters[5])*FULL_DUTY/100;
else //用电流控制
{
ltemp=(unsigned long)(current_trip-ibus_offset);
ltemp*=((unsigned long)user_parameters[5]);
hold2_demand=(unsigned int)(ltemp/100);
}
break;
case 8: //用电压控制
if (user_parameters[40])
ramp_start_demand=(unsigned int)((unsigned long)user_parameters[8])*FULL_DUTY/100;
else //用电流控制
{
ltemp=(unsigned long)(current_trip-ibus_offset);
ltemp*=((unsigned long)user_parameters[8]);
ramp_start_demand=(unsigned int)(ltemp/100);
}
ramp_demand_delta=(signed int)(ramp_end_demand-ramp_start_demand);
break;
case 9: //用电压控制
if (user_parameters[40])
ramp_end_demand=(unsigned int)((unsigned long)user_parameters[9])*FULL_DUTY/100;
else //用电流控制
{
ltemp=(unsigned long)(current_trip-ibus_offset);
ltemp*=((unsigned long)user_parameters[9]);
ramp_end_demand=(unsigned int)(ltemp/100);
}
ramp_demand_delta=(signed int)(ramp_end_demand-ramp_start_demand);
break;
case 10: ramp_time=user_parameters[10];
break;
case 17: iloop_p_gain=(int)user_parameters[17];
break;
case 18: iloop_i_gain=(int)user_parameters[18];
break;
case 19: iloop_d_gain=(int)user_parameters[19];
break;
case 20: wloop_p_gain=(int)user_parameters[20];
break;
case 21: wloop_i_gain=(int)user_parameters[21];
break;
case 23: vloop_p_gain=(int)user_parameters[23];
break;
case 24: vloop_i_gain=(int)user_parameters[24];
break;
case 6:
case 7:
case 25:
case 44:
//计算步率
ltemp=((unsigned long)user_parameters[6]*(unsigned long)user_parameters[25])/20;
//保证ramp_start_rate不会超出最大值
if ((COUNTER_RATE/ltemp) > 65535)
{
ramp_start_rate=65535;
ramp_start_speed=COUNTER_RATE*20/(65535*(unsigned long)user_parameters[25]);
}
else
{
ramp_start_rate=(unsigned int)(COUNTER_RATE/ltemp);
ramp_start_speed=user_parameters[6];
}
ltemp=((unsigned long)user_parameters[7]*(unsigned long)user_parameters[25])/20;
//保证ramp_end_rate不会超出最大值
if ((COUNTER_RATE/ltemp) > 65535)
ramp_end_rate=65535;
else
ramp_end_rate=(unsigned int)(COUNTER_RATE/ltemp);
ramp_speed_delta=(int)(user_parameters[7]-user_parameters[6]);
//采用获取方法1时,过零检测使能,计算步率
ltemp=((unsigned long)user_parameters[44]*(unsigned long)user_parameters[25])/20;
if ((COUNTER_RATE/ltemp) > 65535)
acquire1_enable_rate=65535;
else
acquire1_enable_rate=(unsigned int)(COUNTER_RATE/ltemp);
break;
case 16:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -