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 + -
显示快捷键?