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

📄 speed_control.c

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