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

📄 ldfxmain.c

📁 一个分选系统的软件:用SmallRtos操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
                    OSWait(K_TMO,(50*OS_TICKS_PER_SEC)/1000);
//                    WorkStepInit(DISCHARGE);
                    SetupDA();
                    OSWait(K_TMO,(500*OS_TICKS_PER_SEC)/1000);
                    OSWait(K_TMO,(500*OS_TICKS_PER_SEC)/1000);
                    OSWait(K_TMO,(500*OS_TICKS_PER_SEC)/1000);
                    OSWait(K_TMO,(500*OS_TICKS_PER_SEC)/1000);
                    while(all_cell_over==0)//等所有电池放干或超时
                    {
                        if(DaParaChanged)
                        {
                            SetupDA();
                            DaParaChanged=0;
                        }
                        if(OSSemAccept(StopWorkStepSem)==OS_SEM_OK)//如果急停
                        {
                            CurrentWorkStep = SumWorkStep - 1;
                            break;
                        }
                        OSWait(K_TMO,(50*OS_TICKS_PER_SEC)/1000);
                        CellCheckFlag  = 0;
                        all_cell_over=1;
                        for(i=0;i<24;i++)
                        {
                            if(Cell[i].s == DISCHARGE && Cell[i].i > 100)//如果电池状态为放电并且电流大于10毫安
                            {
                                all_cell_over=0;
                            }
                            if(ReferenceU[i] > 26000 && DAIBuf[i] > 0 && Cell[i].u < WorkStep[CurrentWorkStep].limit)//电池放完,进行状态转换
                            {
                                OSSemPend(IICSem,0);//保存分容信息
                                EepromWriteWord(ReferenceUTimeIICBase + ((38000 - WorkStep[CurrentWorkStep].limit)/1000)*48 + i*2, Cell[i].t);
                                ReferenceU[i] = 26000;
                                EepromWriteWord(ReferenceUIICBase + i*2, ReferenceU[i]);
                                OSSemPost(IICSem);
                                DAIBuf[i] = 0;
                                DAUBuf[i] = 0;
                                Cell[i].t = 0;
                            }
                            if(DAIBuf[i] == 0 && DAUBuf[i] == 0 && Cell[i].t > 3)
                            {
                                Cell[i].s = CURRENTOVER;
                            }
                        }
                        if(WorkStep[CurrentWorkStep].t < Second)
                        {
                            ClearDA();
                            all_cell_over = 1;
                        }

                    }//while(all_cell_over==0)//等所有电池放干或超时
                    for(i=0;i<24;i++)
                    {
                        Cell[i].s = CURRENTOVER; 
                    }
                    OSWait(K_TMO,(1000*OS_TICKS_PER_SEC)/1000);//等待所有AD通道电流变为0
                    OSWait(K_TMO,(1000*OS_TICKS_PER_SEC)/1000);
                    OSWait(K_TMO,(1000*OS_TICKS_PER_SEC)/1000);
                }break;//case 3://放电
            }//switch(WorkStep[i].type)
        }//for(i=0;i<SumStep;i++)
    }//while(1)
}//void TaskWorkStep(void)
/*********************************************************************************************************
** 函数名称: TaskCalcCapa
** 功能描述: 容量积分,每秒钟处理一次,同时将每只电池当前状态持续时间加1,
             在放电过程中,将每只电池每隔100mV电压变化的时间存入F24C16
** 输 入:   无
** 输 出:   无
** 全局变量: Cell[i].c Cell[i].i
** 调用模块: OSWait
**
** 作 者: 刘宝贵
** 日 期: 2004年4月29日22:07
**-------------------------------------------------------------------------------------------------------
** 修改人: 刘宝贵
** 日 期: 2004年10月25日16:00
** 内  容:在电池放电过程中,电池电压每下降100mV记录一次到达这个电压值的时间
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void TaskCalcCapa(void)
{
    uint8 data   i;
    uint8 xdata count=0;
    uint8 xdata bhcount[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    while (1)
    {
        OSWait(K_SIG,0);//等一秒
        Address = P7 & 0x3F;//读本机地址
        //通信中断处理 begin
        CommCounter++;
        if(CommCounter>120 && CommCounter < 150 && CurrentWorkStep != 0)//如果通信断2分钟FMQ报警,报警时长30秒
        {
            ALARMLED = 1;//ON
            FMQ = 0;     //ON
        }
        else
        {
            FMQ = 1;     //OFF
        }
        if(CommCounter>420 && CurrentWorkStep != 0)//如果通信断7分钟,本机停止工步执行。
            OSSemPost(StopWorkStepSem);
        //通信中断处理 end
        //容量积算处理 begin
        for(i=0;i<24;i++)
        {
            OS_ENTER_CRITICAL();
            Cell[i].c+=Cell[i].i;
            Cell[i].t++;
            OS_EXIT_CRITICAL();
        }
        //容量积算处理 end
        //软件电压保护电流保护处理begin
        if(P7 < 64)//地址码最高位为硬件过压保护测试位1:电压DA给最大值,0:给正常值;
        {          //次高位为软件过压保护控制位1:不使能软件过压过流保护,0:使能软件过压过流保护
            for(i=0;i<24;i++)
            {
                if(Cell[i].u > 43000 ||Cell[i].u < 10000 || Cell[i].i > (1000 + WorkStep[CurrentWorkStep].i) )//如果过压欠压过流
                {
                    bhcount[i]++;
                    if(bhcount[i] > 5)//如果过压欠压过流5秒
                    {
                        ALARMLED = 1;//ON
                        DAUBuf[i] = 0;
                        DAIBuf[i] = 0;
                        Cell[i].s = CELLERROR;
                    }
                }
                else
                {
                    bhcount[i] = 0;
                }
            }
        }
        //软件电压保护电流保护处理end
        //为工步续接而做的现场信息保存到F24C16 begin
        OSSemPend(IICSem,0);
        EepromWriteWord(SecondIICBase , Second);
        EepromWriteByte(CurrentWorkStepIICBase,CurrentWorkStep);
        EepromWriteByte(CurrentWorkStepMaxIICBase,CurrentWorkStepMax);
        OSSemPost(IICSem);
        for(i=0;i<24;i++)
        {
            OSSemPend(IICSem,0);

            EepromWriteWord(Cell_CIICBase+i*4+0,(uint16)(Cell[i].c>>16));
            EepromWriteWord(Cell_CIICBase+i*4+2,(uint16)(Cell[i].c));

            EepromWriteWord(Cell_TIICBase + i*2, Cell[i].t);

            EepromWriteByte(Cell_SIICBase + i,   Cell[i].s);

            OSSemPost(IICSem);
        }//for(i=0;i<24;i++)
        //为工步续接而做的现场信息保存到F24C16 end
        //在电池放电过程中,电池电压每下降100mV记录一次到达这个电压值的时间 begin
        //最后一次数据的记录由工步处理任务记录
        if(count<255 && WorkStep[CurrentWorkStep].type == DISCHARGE)//如果上电超过5秒且电池状态为放电
            count++;
        if(count > 5 && WorkStep[CurrentWorkStep].type == DISCHARGE)//加上第二个条件可以提高效率
        {
            for(i=0;i<24;i++)
            {
                if(DAIBuf[i]>0 && Cell[i].s == DISCHARGE && ReferenceU[i] >= Cell[i].u && ReferenceU[i] >= 26000)
                {//如果电流大于0 且 电池状态为放电 且 电池电压比设定值低 且 设定值大于2.6V
                    OSSemPend(IICSem,0);
                    EepromWriteWord(ReferenceUTimeIICBase + ((38000 - ReferenceU[i])/1000)*48 + i*2, Cell[i].t);
                    ReferenceU[i]-=1000;
                    EepromWriteWord(ReferenceUIICBase + i*2, ReferenceU[i]);
                    OSSemPost(IICSem);
                }//if(Cell[i].s == DISCHARGE && referenceu[i] >= Cell[i].u)
            }//for(i=0;i<24;i++)
        }
        //在电池放电过程中,电池电压每下降100mV记录一次到达这个电压值的时间 end
    }//while (1)
}
/*********************************************************************************************************
** 函数名称: TaskCellCheck
** 功能描述: 电池对点报任务
** 输 入:   无
** 输 出:   无
** 全局变量: Cell[i].u CellCheckUHigh CellCheckULow
** 调用模块: OSWait
**
** 作 者: 刘宝贵
** 日 期: 2004年4月29日22:07
**-------------------------------------------------------------------------------------------------------
** 修改人: 
** 日 期: 
** 内  容:
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void TaskCellCheck(void)
{
    uint8 data i;
    uint8 xdata ledimg[24];
    CellCheckFlag = 0;
    while (1)
    {
        OSWait(K_TMO,(50*OS_TICKS_PER_SEC)/1000);
        if(CellCheckFlag)
        {
            for(i=0;i<24;i++)
            {
                if(CellCheckU[i] > CellCheckUHigh || CellCheckU[i] < CellCheckULow)
                    ledimg[i] = 0xFF;
                else
                    ledimg[i] = 0x00;
            }
            //以下程序用于控制电池电压不在设定范围内的点的指于灯闪烁
            da(0,0);
            da(0,1);
            if(ledimg[0] ==0xFF){i=P4;i&=0x01;if(i == 0x01) P4 &= 0xFE; else P4 |= 0x01;} else P4&=0xFE;
            if(ledimg[1] ==0xFF){i=P4;i&=0x02;if(i == 0x02) P4 &= 0xFD; else P4 |= 0x02;} else P4&=0xFD;
            if(ledimg[2] ==0xFF){i=P4;i&=0x04;if(i == 0x04) P4 &= 0xFB; else P4 |= 0x04;} else P4&=0xFB;
            if(ledimg[3] ==0xFF){i=P4;i&=0x08;if(i == 0x08) P4 &= 0xF7; else P4 |= 0x08;} else P4&=0xF7;
            if(ledimg[4] ==0xFF){i=P4;i&=0x10;if(i == 0x10) P4 &= 0xEF; else P4 |= 0x10;} else P4&=0xEF;
            if(ledimg[5] ==0xFF){i=P4;i&=0x20;if(i == 0x20) P4 &= 0xDF; else P4 |= 0x20;} else P4&=0xDF;
            if(ledimg[6] ==0xFF){i=P4;i&=0x40;if(i == 0x40) P4 &= 0xBF; else P4 |= 0x40;} else P4&=0xBF;
            if(ledimg[7] ==0xFF){i=P4;i&=0x80;if(i == 0x80) P4 &= 0x7F; else P4 |= 0x80;} else P4&=0x7F;

            if(ledimg[8] ==0xFF){i=P5;i&=0x01;if(i == 0x01) P5 &= 0xFE; else P5 |= 0x01;} else P5&=0xFE;
            if(ledimg[9] ==0xFF){i=P5;i&=0x02;if(i == 0x02) P5 &= 0xFD; else P5 |= 0x02;} else P5&=0xFD;
            if(ledimg[10]==0xFF){i=P5;i&=0x04;if(i == 0x04) P5 &= 0xFB; else P5 |= 0x04;} else P5&=0xFB;
            if(ledimg[11]==0xFF){i=P5;i&=0x08;if(i == 0x08) P5 &= 0xF7; else P5 |= 0x08;} else P5&=0xF7;

            if(ledimg[12]==0xFF){i=P1;i&=0x80;if(i == 0x80) P1 &= 0x7F; else P1 |= 0x80;} else P1&=0x7F;
            if(ledimg[13]==0xFF){i=P1;i&=0x40;if(i == 0x40) P1 &= 0xBF; else P1 |= 0x40;} else P1&=0xBF;
            if(ledimg[14]==0xFF){i=P1;i&=0x20;if(i == 0x20) P1 &= 0xDF; else P1 |= 0x20;} else P1&=0xDF;
            if(ledimg[15]==0xFF){i=P1;i&=0x10;if(i == 0x10) P1 &= 0xEF; else P1 |= 0x10;} else P1&=0xEF;
            if(ledimg[16]==0xFF){i=P1;i&=0x08;if(i == 0x08) P1 &= 0xF7; else P1 |= 0x08;} else P1&=0xF7;
            if(ledimg[17]==0xFF){i=P1;i&=0x04;if(i == 0x04) P1 &= 0xFB; else P1 |= 0x04;} else P1&=0xFB;
            if(ledimg[18]==0xFF){i=P1;i&=0x02;if(i == 0x02) P1 &= 0xFD; else P1 |= 0x02;} else P1&=0xFD;
            if(ledimg[19]==0xFF){i=P1;i&=0x01;if(i == 0x01) P1 &= 0xFE; else P1 |= 0x01;} else P1&=0xFE;

            if(ledimg[20]==0xFF){i=P2;i&=0x80;if(i == 0x80) P2 &= 0x7F; else P2 |= 0x80;} else P2&=0x7F;
            if(ledimg[21]==0xFF){i=P2;i&=0x40;if(i == 0x40) P2 &= 0xBF; else P2 |= 0x40;} else P2&=0xBF;
            if(ledimg[22]==0xFF){i=P2;i&=0x20;if(i == 0x20) P2 &= 0xDF; else P2 |= 0x20;} else P2&=0xDF;
            if(ledimg[23]==0xFF){i=P2;i&=0x10;if(i == 0x10) P2 &= 0xEF; else P2 |= 0x10;} else P2&=0xEF;
        }//if(CellCheckFlag)
    }//while (1)
}
/********************************************************************************************************/
void TaskF(void)
{
    while (1)
    {
        OSWait(K_TMO,(50*OS_TICKS_PER_SEC)/1000);
    }
}
/********************************************************************************************************/
void TaskG(void)
{
    while (1)
    {
        OSWait(K_TMO,(200*OS_TICKS_PER_SEC)/1000);
    }
}
/********************************************************************************************************/
void TaskH(void)
{
    while (1)
    {
        OSWait(K_TMO,(100*OS_TICKS_PER_SEC)/1000);
      	RUNLED =!RUNLED;
    }
}
/********************************************************************************************************/
void t2int(void) interrupt 5 
{
    TF2=0;
}
/*********************************************************************************************************
** 函数名称: UserTickTimer
** 功能描述: 本函数每个节拍在中断中执行一次,用于处理周期性的工作
** 输 入:   无
** 输 出:   无
** 全局变量: AdBuf Cell 
** 调用模块: midst OSWait da
**
** 作 者: 刘宝贵
** 日 期: 2004年4月28日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void UserTickTimer(void)            /* 系统定时中断中调用的用户函数                                */
{
    static uint8 data timer=0;
    static uint8 data da_channel=0;
    timer++;
    if(timer==200)//每秒钟所做处理。
    {
        timer=0;
        Second++;
        OSIntSendSignal(TaskCalcCapa_ID);
    }
    //以下是对DA通道的处理
    if(CurrentWorkStep!=0 && WorkStep[CurrentWorkStep].type > 1)//如果系统不处于停止或静止状态 0:停止 1:静止
    {
        da_channel++;
        if(da_channel==24) 
            da_channel=0;
        P4 &=0x00;
        P5 &=0xF0;
        P2 &=0x0F;
        P1 &=0x00;//所有DA_EN脚均为0,使所有398处于保持状态
        if(P7 < 0x80)//拔码开关最高位拔为1时用于测试过压保护是否有效
            da(DAUBuf[da_channel],0);
        else
            da(4095,0);
        da(DAIBuf[da_channel],1);
        switch(da_channel)
        {
            case   0: P4|= 0x01; break;
            case   1: P4|= 0x02; break;
            case   2: P4|= 0x04; break;
            case   3: P4|= 0x08; break;
            case   4: P4|= 0x10; break;
            case   5: P4|= 0x20; break;
            case   6: P4|= 0x40; break;
            case   7: P4|= 0x80; break;
    
            case   8: P5|= 0x01; break;
            case   9: P5|= 0x02; break;
            case  10: P5|= 0x04; break;
            case  11: P5|= 0x08; break;
    
            case  12: P1|= 0x80; break;
            case  13: P1|= 0x40; break;
            case  14: P1|= 0x20; break;
            case  15: P1|= 0x10; break;
            case  16: P1|= 0x08; break;
            case  17: P1|= 0x04; break;
            case  18: P1|= 0x02; break;
            case  19: P1|= 0x01; break;
    
            case  20: P2|= 0x80; break;
            case  21: P2|= 0x40; break;
            case  22: P2|= 0x20; break;
            case  23: P2|= 0x10; break;
        }//switch(da_channel)
    }//if(WorkStep[CurrentWorkStep].type > 1)//如果系统不处于停止或静止状态 0:停止 1:静止
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -