📄 ldfxmain.c
字号:
/*********************************************************************************************************
**锂电分选系统 软件设计:刘宝贵,硬件设计:刘宝贵 调试:刘宝贵
**本系统使用编译器为 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 + -