📄 power_control.c
字号:
#include "CGJ.H" // 包含项目头文件
#include "control.h" // 包含控制任务所共有的头文件
#include "DataBuffer.h" // 包含数据缓冲头文件
/****************************************************************************************************
* 函数名称: PowerTask()
* 功 能: 恒功率
* 入口参数: 无
* 出口参数: 无
* 调用模块: OSFlagPend() 等待事件标志组函数
* OSFlagAccept() 无等待获得事件标志组函数
* OSTaskDel() 删除任务函数
* OSTaskCreate() 建立任务函数
* CountSpeed() 计算速度函数
* CountForcePower() 计算力,功率函数
* OSTimeDly() 任务延时函数
* EnableForceOutput() 使能可控硅输出
* DisableForceOutput() 关闭可控硅输出
* 全局变量: set_control_value 命令设置值
* power_set_value 功率设定值
* task_status 事件标志组变量
* kzq 可控硅的空周期
* 设计者: 饶阳胜
* 日期: 05-6-19
* 说明:
****************************************************************************************************/
void PowerTask(void *pdata)
{
INT8U l, time, err; // 出错信息变量
BOOLEAN begin, over; // 指示任务开始和结束的布尔变量
OS_FLAGS flag; // 事件标志组变量
FP32 copy_speed_real_value;
FP32 PowerOut;
FP32 Aver_Speed;
FP32 real_force, set_force;
FP32 FirstSpeed, CurrSpeed;
INT32U AccelTick;
FirstSpeed = 0;
CurrSpeed = 0;
AccelTick = 0;
while(1){
begin = FALSE; // 任务开始布尔变量初始化
while(1){
flag = OSFlagPend(task_status, // 调用等事件标志组函数
POWER_FLAG,
OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
0,
&err);
switch(flag){
case SET_POWER_VALUE:
if(set_control_value >= 0.5){
power_set_value = set_control_value; // 收到设定功率命令,存储
CountSpeed();
OSTimeDly(COUNT_SPEED_TIME);
CountSpeed();
if(parameter[SPEED] < 1) {
AdjustDemaPoint();
}
SendProgramRunStatus(POWER_SET_SUCCESS);
}else{
SendProgramRunStatus(POWER_SET_VALUE_TOO_SMALL);
}
break;
case START_CONTROL_POWER: // 收到开始控制功率命令
if(power_set_value >= 0.5){
IGBT_SetPeriodCount(0);
PidValueReset();
OS_ENTER_CRITICAL();
OSTaskSuspend(WAIT_TASK_PRIO); // 挂起等待任务
OSTaskSuspend(SPEED_TASK_PRIO); // 挂起恒速任务
OSTaskSuspend(FORCE_TASK_PRIO); // 挂起恒力任务
OSTaskSuspend(DEMA_TASK_PRIO); // 挂起标定任务
OSTaskSuspend(ROAD_SIMUL_TASK_PRIO); // 挂起道路模拟任务
OS_EXIT_CRITICAL();
begin = TRUE;
SendProgramRunStatus(ENTER_POWER_CONTROL);
}else{
SendProgramRunStatus(POWER_SET_VALUE_TOO_SMALL);
}
break;
default:
break;
}
if(begin == TRUE) break;
}
time = 0; // 控制计算速度频率的参数清0
l = 0; // 控制向上位机发送数据的参数清0
over = FALSE; // 任务结束布尔变量初始化
PowerOut = 0;
OS_ENTER_CRITICAL(); // 处理全局变量,关中断
sc_t1cr0 = T1TC; // 得到实时的T1TC值
sc_t1cr1 = T1TC;
OS_EXIT_CRITICAL(); // 全局变量处理完成,开中断
/* 将任务挂起几个节拍,是为了在第一次计算时,得到正确的
速度值和市电频率周期 */
OSTimeDly(TASK_DELAY_TIME * 4);
while(1){
flag = OSFlagAccept(task_status, // 调用无等待获得事件标志组中的事件标志函数
POWER_FLAG,
OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
&err);
switch(flag){
case SET_POWER_VALUE: // 收到设定功率命令,存储
OS_ENTER_CRITICAL(); // 访问全局变量前,关中断
if(set_control_value >= 0.5){
power_set_value = set_control_value;
OS_EXIT_CRITICAL();
SendProgramRunStatus(POWER_SET_SUCCESS);
}else{
OS_EXIT_CRITICAL();
SendProgramRunStatus(POWER_SET_VALUE_TOO_SMALL);
}
break;
case STOP_CONTROL: // 收到停止控制命令
over = TRUE; // 结束布尔变量置有效
IGBT_SetPeriodCount(0);
IGBT_Disable();
OSTaskResume(FORCE_TASK_PRIO); // 唤醒恒力任务
OSTaskResume(SPEED_TASK_PRIO); // 唤醒恒数任务
OSTaskResume(DEMA_TASK_PRIO); // 唤醒标定任务
OSTaskResume(ROAD_SIMUL_TASK_PRIO); // 唤醒道路模拟阻力任务
OSTaskResume(WAIT_TASK_PRIO); // 唤醒等待任务
SendProgramRunStatus(EXIT_POWER_CONTROL);
OS_ENTER_CRITICAL();
task_status->OSFlagFlags = 0; // 在退出速度控制前,清除事件标志组
OS_EXIT_CRITICAL();
break;
default:
break;
}
if(over == TRUE) break; // 已收到结束命令,退出恒功率状态
copy_speed_real_value = parameter[SPEED]; // 得到上次的实时速度值,如果上次速度值大于
// 10Km/h,则每0.01秒计算一次速度,否则每0.1秒计算一次
if(copy_speed_real_value > 10){
CountSpeed();
time = 0;
}else if(++time >= COUNT_SPEED_TIME){
time = 0;
CountSpeed(); // 计算速度
}
CountForce();
// copy_power_real_value = parameter[SPEED] * parameter[FORCE] / 360.0 / 10.0;
// 采用恒扭矩的方法进行恒功率控制!
// set_force = power_set_value * 3600.0 / parameter[SPEED];
set_force = power_set_value * 3600.0 / Aver_Speed;
real_force = parameter[FORCE];
// 调整输出
if(Aver_Speed > 10){
// PowerOut = PidCalc(copy_power_real_value, copy_power_set_value);
PowerOut = PidCalc(real_force, set_force);
IGBT_Enable();
IGBT_SetPeriodCount((INT32U)PowerOut);
}else{
PowerOut = 0;
IGBT_SetPeriodCount(0);
IGBT_Disable();
PidValueReset();
}
InsertSpeedPoint(parameter[SPEED]); // 将当前速度值与力值插入缓冲区
InsertForcePoint(parameter[FORCE]); //
// 判断是否到了向上位机送数时间
if(++l == SEND_DELAY_TIME){ // 向上位机送出检测到的数据
l = 0; // 向上位机送数据计时器清0
OS_ENTER_CRITICAL();
// 对向上位机送出的数据进行平滑
parameter[SPEED] = GetAdverOfSpeed(); // 得到速度的平均值
parameter[FORCE] = GetAdverOfForce(); // 得到力的平均值
parameter[POWER] = parameter[SPEED] * parameter[FORCE] / 360.0 / 10.0;
// 计算加速度
CurrSpeed = parameter[SPEED];
Aver_Speed = parameter[SPEED];
OS_EXIT_CRITICAL();
SendRealParaToComputer();
}
if(++AccelTick == 100) {
AccelTick = 0;
OS_ENTER_CRITICAL();
if(CurrSpeed > 5) {
parameter[JSD] = (CurrSpeed - FirstSpeed) * 1000.0 / 3600.0;
}else {
parameter[JSD] = 0;
}
OS_EXIT_CRITICAL();
FirstSpeed = CurrSpeed;
}
OSTimeDly(TASK_DELAY_TIME); // 将任务挂起2个节拍
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -