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

📄 ldfxmain.c

📁 一个分选系统的软件:用SmallRtos操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************************************************
**锂电分选系统 软件设计:刘宝贵,硬件设计:刘宝贵 调试:刘宝贵
**本系统使用编译器为 keil c51.exe V7.06
**本系统使用汇编器为 keil A51.exe V7.07
**本系统使用联接器为 keil BL51.exe V5.03
**本系统使用Small RTOS51 V1.12.0
**如果等程序有问题或者是Bug请与作者联系
**与作者联系方法:邮箱:baoguiliu@163.com,baoguiliu@sohu.com 电话:0451-86649609
**
**
**VER1.0
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: ldfxmain.c
**创   建   人: 刘宝贵
**最后修改日期: 
**描        述: ldfxmain.c源代码。
**
**--------------历史版本信息----------------------------------------------------------------------------
** 修改人: 
** 版  本: 
** 日 期: 
** 描 述: 
**
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人: 
** 日 期:
** 描 述:
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

#include "config.h"
void config();
/*********************************************************************************************************
** 函数名称: main
** 功能描述: 主函数
** 输 入:   无
** 输 出:   无
** 全局变量: 
** 调用模块: OSStart() config()
**
** 作 者: 刘宝贵
** 日 期: 2004年5月23日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void main(void)
{
    config();//auto config
    ConfigMe();
    TR0 = 1;
    OSStart();
}
/*********************************************************************************************************
** 函数名称: TaskADDA
** 功能描述: AD DA
** 输 入:   无
** 输 出:   无
** 全局变量: AdBuf Cell 
** 调用模块: midst OSWait
**
** 作 者: 刘宝贵
** 日 期: 2004年4月28日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void TaskAD(void)
{
    uint8  data i,j;
    uint16 xdata u_ad_para[24],temp16a,temp16b;
    uint16 xdata i_ad_para[24];
    uint16 xdata ADIBuf[240];  //AD采样滤波所用的缓冲区
    uint16 xdata ADUBuf[240];  //AD采样滤波所用的缓冲区
    uint8  code adchannel[48]=
    {
        0x70,0x50,0x30,0x10,0x71,0x51,0x31,0x11,0x72,0x52,0x32,0x12,
//        0x73,0x53,0x33,0x13,0x74,0x54,0x34,0x14,0x75,0x55,0x35,0x15,
        0x15,0x35,0x55,0x75,0x14,0x34,0x54,0x74,0x13,0x33,0x53,0x73,
        0x60,0x40,0x20,0x00,0x61,0x41,0x21,0x01,0x62,0x42,0x22,0x02,
//        0x63,0x43,0x23,0x03,0x64,0x44,0x24,0x04,0x65,0x45,0x25,0x05,
        0x05,0x25,0x45,0x65,0x04,0x24,0x44,0x64,0x03,0x23,0x43,0x63,
    };//每一路模拟采样对应通道控制字:控制CD4051的A,B,C(高四位)和C8051F020片内的AD通道选择(低四位)
      //adchannel[0~~~23]对应U0~~U23    adchannel[24~~~48]对应I0~~I23
    for(i=0;i<240;i++)
    {
        ADIBuf[i]=0;
        ADUBuf[i]=0;
    }
    AdParaChanged = 1;
    i = 0;
    j = 0;
    while (1)
    {
        //以下是对AD通道的处理
        i++;
        if(i == 48)
        {
            if(AdParaChanged)
            {
                if(OSSemPend(IICSem,0)==OS_SEM_OK)
                {
                    for(i=0;i<24;i++)
                    {
                        do
                        {
                            temp16a = EepromReadWordA(CellParaIICBase+i*16+0*2);
                            temp16b = EepromReadWordA(CellParaIICBase+i*16+0*2);
                        }while(temp16a !=temp16b);
                        u_ad_para[i] = temp16a;
                        if(u_ad_para[i] > PARAMETER_MAX || u_ad_para[i] < PARAMETER_MIN)
                        {
                            u_ad_para[i] = 10000;
                            EepromWriteWordA(CellParaIICBase+i*16+0*2,10000);
                        }

                        do
                        {
                            temp16a = EepromReadWordA(CellParaIICBase+i*16+2*2);
                            temp16b = EepromReadWordA(CellParaIICBase+i*16+2*2);
                        }while(temp16a !=temp16b);
                        i_ad_para[i] = temp16a;
                        if(i_ad_para[i] > PARAMETER_MAX || i_ad_para[i] < PARAMETER_MIN)
                        {
                            i_ad_para[i] = 10000;
                            EepromWriteWordA(CellParaIICBase+i*16+2*2,10000);
                        }
                    }//for(i=0;i<24;i++)
                    OSSemPost(IICSem);
                }//if(OSSemPend(IICSem,0)==OS_SEM_OK)
                AdParaChanged = 0;
            }//if(AdParaChanged)
            j++;
            j%=9;
            for(i=0;i<24;i++)
            {
                uint32 xdata temp32;
                temp32    = midst(&ADUBuf[i*9],9);
                temp32   *= 50000;
                temp32   /= 12750;//4095*3
                temp32   *= u_ad_para[i];
                temp32   /=10000;
                OS_ENTER_CRITICAL();
                Cell[i].u = (uint16)temp32;
                OS_EXIT_CRITICAL();

                temp32    = midst(&ADIBuf[i*9],9);
                temp32   *=30380;
                temp32   /=12285;//4095*3
                temp32   *=i_ad_para[i];
                temp32   /=10000;
                OS_ENTER_CRITICAL();
                Cell[i].i = (uint16)(temp32);
                OS_EXIT_CRITICAL();
            }
            i=0;
        }
        AD_CS=(bit)(adchannel[i]<<1 & 0x80);
        AD_BS=(bit)(adchannel[i]<<2 & 0x80);
        AD_AS=(bit)(adchannel[i]<<3 & 0x80);
        AMX0SL=adchannel[i]&0x0f;//channel select 
        OSWait(K_TMO,(5*OS_TICKS_PER_SEC)/1000);
        AD0INT=0;
        AD0BUSY=1;
        do
        {
            OSWait(K_TMO,(5*OS_TICKS_PER_SEC)/1000);
        }while(AD0INT==0);
        if(i<24)
        {
            
            uint32 xdata temp32;
            ADUBuf[i*9+j]=ADC0H*256+ADC0L;
            temp32    =  ADUBuf[i*9+j];
            temp32   *= 5000;
            temp32   /= 455;
            temp32   *= u_ad_para[i];
            temp32   /=9310;
            OS_ENTER_CRITICAL();
            CellCheckU[i] = (uint16)temp32;
            OS_EXIT_CRITICAL();
        }
        else
            ADIBuf[(i-24)*9+j]=ADC0H*256+ADC0L;
    }
}
/*********************************************************************************************************
** 函数名称: TaskWorkStep
** 功能描述: 工步处理
** 输 入:   无
** 输 出:   无
** 全局变量: 
** 调用模块: ClearDA
**
** 作 者: 刘宝贵
** 日 期: 2004年4月28日
**-------------------------------------------------------------------------------------------------------
** 修改人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
void TaskWorkStep(void)
{
    uint8 i;
    OSSemCreate(IICSem,1);           //实现IIC总线的互斥
    OSSemCreate(StartWorkStepSem,0); //工步执行报文下发与工步执行同步
    OSSemCreate(StopWorkStepSem, 0); //工步停止报文下发与工步停止同步
    while (1)
    {
TaskWorkStepBegin:
        if(CurrentWorkStep == 0)//CurrentWorkStep==0表示停止
        {
            OSSemPend(StartWorkStepSem,0);
        }
        for(;CurrentWorkStep <= SumWorkStep; CurrentWorkStep++)
        {
            switch(WorkStep[CurrentWorkStep].type)
            {
                case 0://停止
                {
                    da(0,0);
                    da(0,1);
                    P4 |=0xFF;
                    P5 |=0x0F;
                    P2 |=0xF0;
                    P1 |=0xFF;//所有DA_EN脚均为1,使所有398处于采样状态,把所有DA清为0
                    JDQ = 1;
                    CurrentWorkStep = 0;
                    WorkStepInit(STOP);                    
                    goto TaskWorkStepBegin;
                }break;
                case 1://静置
                {
                    da(0,0);
                    da(0,1);
                    P4 |=0xFF;
                    P5 |=0x0F;
                    P2 |=0xF0;
                    P1 |=0xFF;//所有DA_EN脚均为1,使所有398处于采样状态,把所有DA清为0
                    JDQ = 0;
                    WorkStepInit(HALT);
                    while(WorkStep[CurrentWorkStep].t > Second)
                    {
                        if(OSSemAccept(StopWorkStepSem)==OS_SEM_OK)//如果急停
                        {
                            CurrentWorkStep = SumWorkStep - 1;
                            break;
                        }
                        OSWait(K_TMO,(50*OS_TICKS_PER_SEC)/1000);
                        CellCheckFlag  = 0;
                    }
                }break;
                case 2://充电
                {
                    bit all_cell_full=0;
                    WorkStepInit(CHARGE);
                    ClearDA();//
                    OSWait(K_TMO,(450*OS_TICKS_PER_SEC)/1000);
                    JDQ = 0;
                    OSWait(K_TMO,(50*OS_TICKS_PER_SEC)/1000);
                    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_full==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_full=1;
                        for(i=0;i<24;i++)
                        {
                            if(Cell[i].s == CHARGE)
                            {
                                all_cell_full=0;
                            }
                            if(Cell[i].i < WorkStep[CurrentWorkStep].limit)
                            {
                                //DAIBuf[i] = 0;//先充完的继续恒压充等时间到或所有都充完
                                Cell[i].s = CURRENTOVER;//当前工步完成
                                Cell[i].t = 0;
                            }
                        }
                        if(WorkStep[CurrentWorkStep].t < Second)
                        {
                            ClearDA();
                            all_cell_full = 1;
                        }
                    }//while(all_cell_full==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 2://充电
                case 3://放电
                {
                    bit all_cell_over = 0;
                    bit change_flag   = 1;
                    //以下部分等程序用于确定是不清空平台电压数据
                    for(i=0;i<24;i++)
                    {
                        if(Cell[i].s == DISCHARGE)//如果电池状态为放电说明是掉电续接所以不清空平台时间数据
                        {
                            change_flag = 0;
                            break;
                        }
                    }
                    //以上部分等程序用于确定是不清空平台电压数据
                    WorkStepInit(DISCHARGE);
                    //以下部分等程序用于清空平台数据
                    if(change_flag)
                    {
                        for(i=0;i<156;i++)//清空平台电压时间数据
                        {
                            OSSemPend(IICSem,0);
                            EepromWriteWord(ReferenceUTimeIICBase + i*2, 0);
                            EepromWriteWord(ReferenceUTimeIICBase + 312 + i*2, 0);
                            OSSemPost(IICSem);
                        }
                        for(i=0;i<24;i++)//清空平台电压数据
                        {
                            ReferenceU[i]=38000;
                            OSSemPend(IICSem,0);
                            EepromWriteWord(ReferenceUIICBase + i*2, 38000);
                            OSSemPost(IICSem);
                        }
                    }
                    //以上部分等程序用于清空平台数据
                    ClearDA();
                    OSWait(K_TMO,(450*OS_TICKS_PER_SEC)/1000);
                    JDQ = 1;

⌨️ 快捷键说明

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