flowunit.c
来自「采用STC89C54RD实现的一个完整的流量计控制系统源代码」· C语言 代码 · 共 1,142 行 · 第 1/5 页
C
1,142 行
ES = FALSE; // 为防止读数时发生串口中断导致冲突,先禁用ES
nLeak = gnLeak; // 读取全局变量
ES = TRUE; // 恢复响应串口中断
if (gbStarted) // 在启动键按下后,流量显示值需要减去零点偏移值
nLeak = nLeak - gnLeakZero;
if (gbFilling) // 考虑到在充气阶段打开电磁阀可能会造成流量冲击,
{ // 因而在充气阶段不检测流量超限状态(2007-05-28)
gbPassed = TRUE;
gbLeakOver = FALSE;
}
else // 在非充气状态需要检测流量超限状态
{
gbPassed = ((nLeak > gnMaxLeak) || (nLeak < gnMinLeak) || gbDispOver) ? FALSE:TRUE; // 检查流量值是否超出了设定的区间范围
gbLeakOver = (nLeak > 5000) ? TRUE:FALSE;
}
gbBufUsed = TRUE;
if (gbLeakOver) // 如果大于50.00,则2#-LED显示 ouEr(OVER),且点亮FAIL灯
{
for (i=0;i<5;i++)
gnSegBuf[1][i] = FIX_CODE[PARAMS_NUMS][i];
gbBufUsed = FALSE;
return;
}
Decode(nLeak, gnSegBuf[1]); // 将流量测量值分解为独立的数字表示,以便于显示
HideInvalidZero(1); // 消隐gnSegBuf[1]中的无效0
gbBufUsed = FALSE;
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DisDone
** 功能描述: 在1#-LED和2#-LED上显示缓冲区中的数值,并根据需要加入小数点显示。
** 输 入: nLedID>>>>>LED位选码数组LedCode的索引(0~5,前5位对应于1#-LED和2#-LED,最后一位对应于3#、4#
** 和5#-LED)。
** 输 出: 无
** 全局变量: gbParamSel>>>>>>>>>指示当前是否工作在参数选择状态,0~不是,1~是;
** gbParamSet>>>>>>>>>指示当前是否工作在参数修改状态,0~不是,1~是;
** gbCanFlash>>>>>>>>>指示当前是否要执行闪烁操作(实际是消隐),0~不执行,1~执行;
** gnParamID>>>>>>>>>>代表参数组中当前选择的参数序号(从0开始编号,取值0~PARAMS_NUMS-1);
** gnSegBuf[][]>>>>>>>代表两组段选缓冲区在SEG_CODE段选码数组中的数字索引。
** 全局常量:SEG_CODE[]>>>>>>>>>不带小数点的字符的LED段选码(共阳LED,段输出低电平有效);
** LED_CODE[]>>>>>>>>>1#和2#LED的位选选通码(共阳LED,但因后级有反相,故输出低电平有效);
** ADD_DOT>>>>>>>>>>>>将该常量与要显示的LED内容相与,可在当前LED上显示小数点。
** 调用模块: Delay()>>>>>>>>>>>>延时一定的时间。
** 其它说明:LED的位选直接由P0口的Q1~Q6输出。
** 8位段选码数据的传送按先高位后低位的顺序进行(用左移实现),两个74HC595的数据同步传送。
** 另外,根据系统的工作状态来确定是否显示小数点及小数点的显示位置,具体判断如下:
** 1、工作状态==参数选择(gbParamSel=TRUE)
** 1)对于1#LED,显示参数名称,不显示小数点;
** 2)对于2#LED,显示参数值,要根据参数的类型来确定小数点的位置,即:
** a)对于参数:充气时间、测试时间、压力设定上限和压力设定下限(gnParamID=0~3),只保留一位小
** 数,因此只在nLedID=1时显示小数点;
** b)对于参数:流量设定上限和流量设定下限(gnParamID>3),只保留两位小数,因此只在nLedID=2
** 时显示小数点。
**
** 2、工作状态==待机或测试(gbParamSel=FALSE)
** 1)对于1#LED,显示压力测量值,显示一位小数,因此只在nLedID=1时显示小数点;
** 2)对于2#LED,显示流量测量值,显示两位小数,因此只在nLedID=2时显示小数点。
**
** 作 者: 罗建
** 日 期: 2007年02月09日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年03月10日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年03月23日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年03月25日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DisDone(void)
{
INT8U i;
INT8U nData1;
INT8U nData2;
INT8U nP0;
switch (gnLedID)
{
case 0: // 扫描LED数码管
case 1:
case 2:
case 3:
case 4:
nData1 = SEG_CODE[gnDisBuf[0][gnLedID]]; // 先暂存要显示的数据
if (gbCanFlash && gbParamSet && (gnCursorID == gnLedID))
nData2 = NOT_DIS;
else
nData2 = SEG_CODE[gnDisBuf[1][gnLedID]];
if (!gbLogo)
{
if (gbParamSel) // 当前处于参数选择(或参数修改)状态(2007.03.23)
{
if (((gnLedID == 1) && (gnParamID < pnMaxLeak)) || ((gnLedID == 2) && (gnParamID > pnMinPress)))
nData2 &= ADD_DOT;
}
else // 当前处于待机或测试状态
{
if (gnLedID == gnPressDot)
nData1 &= ADD_DOT; // 压力测量值为一位小数
if ((gnLedID == gnLeakDot) && !gbLeakOver)// 流量测量值为二位小数(2007.03.23)
nData2 &= ADD_DOT;
}
}
nP0 = P0 & 0xC0 | LED_CODE[gnLedID]; // 保持Q7和Q8不变
break;
case 5: // 扫描LED指示灯
nP0 = 0xDF;
nData1 = NOT_DIS;
nData2 = NOT_DIS;
if (gbStarted) // 用户按下了启动按扭,已进入测试状态
{
if (!gbFilling) // 非充气状态,根据测试结果显示3#和4#-LED指示灯
{
if (gbPassed) // 测试通过,PASS指示灯(含远程)亮
{
//nP0 &= 0xBF; // 打开远程PASS指示灯,关闭远程FAIL指示灯
nData1 = PASS; // 显示面板上的PASS指示灯,熄灭FAIL指示灯
}
else // 测试未通过,FAIL指示灯(含远程)亮
{
//nP0 &= 0x7F; // 关闭远程PASS指示灯,打开远程FAIL指示灯
nData1 = FAIL; // 显示面板上的FAIL指示灯,熄灭PASS指示灯
}
}
}
else // 参数选择或修改状态,不显示任何指示灯
{
if (!gbParamSel && gbWarned) // 待机状态,压力值超限,WARN指示灯亮
nData1 = WARN;
}
break;
}
RCK = FALSE; // 准备数据锁存时序
for (i=0;i<8;i++) // 将8位数据nData按先高后低顺序移至74HC595
{
SCK = FALSE; // 准备时钟移位时序
SER1 = (nData1 & 0x80)? 1:0; // 将nData1的最高位输出到SER1引脚上
SER2 = (nData2 & 0x80)? 1:0; // 将nData2的最高位输出到SER2引脚上
SCK = TRUE; // 将准备好的1位数据输出到U8和U9两个74HC595中
nData1 <<= 1; // 准备下一位要输出的数据位
nData2 <<= 1; // 准备下一位要输出的数据位
}
RCK = TRUE; // 将准备好的数据锁存到U8和U9两个74HC595中
P0 = nP0;
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: ReadKey
** 功能描述: 检测哪个键有按下。
** 输 入: nLedID>>>>>LED位选码数组LedCode的索引(0~5,前5位对应于1#-LED和2#-LED,最后一位对应于3#、4#
** 和5#-LED)。
** 输 出: 无
** 全局变量: gbCanGetKey>>>>>>>>指示当前是否可以读取按键,0~不可以,1~可以;
** gnKeyID>>>>>>>>>>>>存放用户按键的键值,取值范围:0~8,0表示无按键;
** gnGetKeyCnt>>>>>>>>按键检测间隔期间的倒计数,其值为0时允许再一次检测按键,以防止连续快速按键。
** 全局常量:无
** 调用模块: 无
** 其它说明:LED的位选直接由P0口的Q1~Q6输出。
** 8位段选码数据的传送按先高位后低位的顺序进行(用左移实现),两个74HC595的数据同步传送。
**
** 作 者: 罗建
** 日 期: 2007年02月24日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年03月25日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年05月08日,修正了远程停止键按下时不响应的错误。
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ReadKey(void)
{
if (!gbCanGetKey) // 检测用户按键情况
return;
switch (gnLedID)
{
case 0: // 扫描到LED数码管
case 1:
case 2:
case 3:
if (!KEY1)
gnKeyID = (gnLedID<<1) + 1;
else if (!KEY2)
gnKeyID = (gnLedID+1)<<1;
break;
case 5: // 检查远程启动与停止开关有否按下(外部键有最高优先级)
if (!START) // 远程启动键按下
gnKeyID = ktStartKey;
else if (!STOP) // 远程停止键按下
gnKeyID = ktStopKey; // 修正了原错误,2007-05-08
break;
}
if (gnKeyID != 0)
{
gnGetKeyCnt = KEY_WAIT; // 准备进行按键检测延时
gbCanGetKey = FALSE; // 暂停下一次键检测
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: FuncKeyDone
** 功能描述: 处理功能键,进入或退出参数选择工作状态。
** 输 入: 无
** 输 出: 无
** 全局变量: gbStarted>>>>>>>>>>指示当前启动键是否按下,0~否,1~是;
** gbLogo>>>>>>>>>>>>>仪表在上电时,该标志为TRUE,指示当前正在显示LOGO标志;
** gbParamSel>>>>>>>>>指示当前是否工作在参数选择状态,0~不是,1~是;
** gbParamSet>>>>>>>>>指示当前是否工作在参数修改状态,0~不是,1~是;
** gnParamID>>>>>>>>>>代表当前用户选择的参数在参数组中的序号,取值0~PARAMS_NUMS-1。
** 全局常量:无
** 调用模块: LoadParam()>>>>>>>>载入并显示指定参数的符号名称及参数值。
** 其它说明:本函数仅在启动按未按下情况下执行。如果功能键先前未按下,则进入参数选择工作状态,并调出第一个
** 参数名称及其值,同时关闭串口中断和INT1外部中断;如果功能键先前已经按下,则退出参数选择状态,
** 并且不保存用户可能已经修改的参数值,同时打开串口中断和INT1外部中断。
**
** 作 者: 罗建
** 日 期: 2007年02月09日
**-------------------------------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?