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

📄 power_control.c

📁 汽车测功机源肛码.单片机用的是LPC2104. 实现测速,对涡流机的控制,马达的控制.
💻 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 + -