📄 speed_control.c
字号:
#include "CGJ.H" // 包含项目头文件
#include <math.h> // 包含算术运算头文件
#include "control.h" // 包含控制任务所共有的头文件
#include "DataBuffer.h"
#define TEST FALSE // 不测试
/***********************************************************************************************
* 函数名称: SpeedTask()
* 功 能: 恒速
* 入口参数:无
* 出口参数: 无
* 调用模块: OSFlagPend() 等待事件标志组函数
* OSFlagAccept() 无等待获得事件标志组函数
* OSTaskDel() 删除任务函数
* OSTaskCreate() 建立任务函数
* count_parameter 计算各种参数函数
* OSTimeDly() 任务延时函数
* 全局变量: set_control_value 命令设置值
* power_set_value 功率设定值
* task_status 事件标志组变量
* dtzq 可控硅的导通周期
* 设计者: 饶阳胜
* 日 期: 05-6-20
* 说 明:
***********************************************************************************************/
#define INIT_PERIOD 0
#define ONE_PERIOD 1
#define TWO_PERIOD 2
FP32 real_time_speed_set_value;
void SpeedTask(void *pdata)
{
INT32U speed_control_time; // 恒速控制的调整时间
INT8U l, time, err; // 出错信息变量
BOOLEAN begin, over; // 指示任务开始和结束的布尔变量
OS_FLAGS flag; // 事件标志组变量
FP32 copy_speed_set_value; // 恒速值
FP32 copy_speed_real_value, Aver_Speed; // 当前速度值, 平均速度
INT32U OutPeriodCount; // IGBT 输出宽度
FP32 Delta;
FP32 FirstSpeed, CurrSpeed;
INT32U AccelTick;
while(1){
begin = FALSE; // 任务开始布尔变量初始化
while(1){
flag = OSFlagPend(task_status, // 调用等事件标志组函数
SPEED_FLAG, // 只接收和恒速控制相关的事件
OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
0,
&err);
switch(flag){
case SET_SPEED_VALUE:
OS_ENTER_CRITICAL(); // 访问全局变量前,关中断
speed_set_value = set_control_value; // 收到设定速度命令,存储
OS_EXIT_CRITICAL();
SendProgramRunStatus(SPEED_SET_SUCCESS);
break;
case START_CONTROL_SPEED: // 收到开始控制速度命令
if(speed_set_value >= 30){
OS_ENTER_CRITICAL();
OSTaskSuspend(WAIT_TASK_PRIO); // 挂起空闲状态下的任务
OSTaskSuspend(POWER_TASK_PRIO); // 挂起恒功率任务
OSTaskSuspend(FORCE_TASK_PRIO); // 挂起恒力任务
OSTaskSuspend(DEMA_TASK_PRIO); // 挂起标定任务
OSTaskSuspend(ROAD_SIMUL_TASK_PRIO); // 挂起道路模拟任务
OS_EXIT_CRITICAL();
begin = TRUE;
IGBT_SetPeriodCount(0);
SendProgramRunStatus(ENTER_SPEED_CONTROL);
}else{
SendProgramRunStatus(SPEED_SET_TOO_SMALL);
}
break;
default:
break;
}
if(begin == TRUE) break; // break while(1)
}// end while(1)
time = 0; // 控制计算速度频率的参数初始化
l = 0; // 控制向上位机发送数据的参数初始化
over = FALSE; // 任务结束布尔变量初始化
OS_ENTER_CRITICAL(); // 处理全局变量,关中断
sc_t1cr0 = T1TC; // 得到实时的T1TC值
sc_t1cr1 = T1TC; //
OS_EXIT_CRITICAL(); // 全局变量处理完成,开中断
OSTimeDly(TASK_DELAY_TIME * 4); // 将任务挂起几个节拍,
// 这样做,是为了在第一次计算时,得到正确的
// 速度值 ????????
FirstSpeed = 0;
CurrSpeed = 0;
AccelTick = 0;
Delta = -3;
speed_control_time = 0;
Aver_Speed = 0;
while(1){
flag = OSFlagAccept(task_status, // 调用无等待获得事件标志组中的事件标志函数
SPEED_FLAG,
OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME,
&err);
switch(flag){
case SET_SPEED_VALUE: // 收到设定功率命令,存储
if(set_control_value >= 30){
OS_ENTER_CRITICAL(); // 访问全局变量前,关中断
speed_set_value = set_control_value;
speed_control_time = 0;
OS_EXIT_CRITICAL();
SendProgramRunStatus(SPEED_SET_SUCCESS);
}else{
SendProgramRunStatus(SPEED_SET_TOO_SMALL);
}
break;
case STOP_CONTROL: // 收到停止控制命令
over = TRUE; // 结束布尔变量置有效
IGBT_SetPeriodCount(0);
IGBT_Disable(); // IGBT关闭输出
OSTaskResume(FORCE_TASK_PRIO); // 唤醒恒力任务
OSTaskResume(POWER_TASK_PRIO); // 唤醒恒功率任务
OSTaskResume(DEMA_TASK_PRIO); // 唤醒标定任务
OSTaskResume(ROAD_SIMUL_TASK_PRIO); // 唤醒道路模拟阻力任务
OSTaskResume(WAIT_TASK_PRIO); // 唤醒等待任务
SendProgramRunStatus(EXIT_SPEED_CONTROL);
OS_ENTER_CRITICAL();
task_status->OSFlagFlags = 0; // 在退出速度控制前,清除事件标志组
OS_EXIT_CRITICAL();
break;
default:
break;
}
if(over == TRUE) break; // 已收到结束命令,退出恒功率状态
copy_speed_real_value = parameter[SPEED]; // 得到上次的实时速度值,如果上次速度值大于
if(copy_speed_real_value > 10){
CountSpeed();
time = 0;
}else if(++time >= COUNT_SPEED_TIME){
time = 0;
CountSpeed(); // 计算速度
}
CountForce(); // 计算力和功率
copy_speed_real_value = parameter[SPEED];
copy_speed_set_value = speed_set_value;
if(Aver_Speed > (copy_speed_set_value + Delta)){
/* if(AccelControl == TRUE) {
if( parameter[JSD] > 0 ) {
Delta += copy_speed_set_value - Aver_Speed;
} else {
AccelControl = FALSE;
}
} */
// 公式:Y = K*(当前速度 - (控制速度 + Delta)) K为输出系数值,由试验得到!
// Delta为当前速度与控制速度的速度差,该值每几秒钟调整一次!
OutPeriodCount = (INT32U)(45 * (Aver_Speed - (copy_speed_set_value + Delta)));
IGBT_Enable(); // 处于控制状态,计算输出周期
IGBT_SetPeriodCount(OutPeriodCount); // IGBT输出秒钟调整一次,
if(++speed_control_time >= 600) {
Delta += copy_speed_set_value - Aver_Speed;
speed_control_time = 0;
}
}else{
speed_control_time = 0;
IGBT_SetPeriodCount(0);
IGBT_Disable();
}
InsertSpeedPoint(parameter[SPEED]);
InsertForcePoint(parameter[FORCE]);
if(++l == SEND_DELAY_TIME){ // 向上位机送出检测到的数据
l = 0; // 计数器清零
// OS_ENTER_CRITICAL();
parameter[SPEED] = GetAdverOfSpeed();
parameter[FORCE] = GetAdverOfForce();
parameter[POWER] = parameter[SPEED] * parameter[FORCE] / 360 / 10;
// 计算加速度
CurrSpeed = parameter[SPEED];
Aver_Speed = parameter[SPEED];
// OS_EXIT_CRITICAL();
// 向上位机送数据
SendRealParaToComputer();
}
if(++AccelTick == 100) {
AccelTick = 0;
if(CurrSpeed > 5) {
parameter[JSD] = (CurrSpeed - FirstSpeed) * 1000 / 3600;
}else {
parameter[JSD] = 0;
}
FirstSpeed = CurrSpeed;
}
OSTimeDly(TASK_DELAY_TIME); // 将任务挂起2个节拍
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -