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

📄 main.#3

📁 一个采用C8051F020芯片实现的流量计控制系统源代码
💻 #3
📖 第 1 页 / 共 5 页
字号:
		  {
		    nRes *= gnLeakAreaCoef[i];           // 乘以系数(因触摸屏上的扩大了100倍)
            nRes /= 100;
            EA = FALSE;
            gnLeakGet = nRes;                    // 返回流量值
            EA = TRUE;
			break;
          }
        }
	  }
    }
	else                                         // 同步字节还未接收完毕,继续检测
	{
      if (SBUF0 == 0x7F)                         // 如果是同步字节,则设置相应的同步字节接收到标志
      {
	    if (gbSyncOneOK0)
		  gbSyncTwoOK0 = TRUE;
		else
		  gbSyncOneOK0 = TRUE;
	  }
	  else                                       // 接收到的字节既非同步字节又非正常的测量数据,舍弃重来。
		SetRxd0OK();                             // 重新初始化同步字节检测标志和串口接收缓冲区索引
	}
  }
  else
    TI0 = FALSE;                                 // 清除发送中断标志,允许下次接收数据    
}

/********************************************************************************************************
** 函数名称: TIMER2_ISR
** 功能描述: TIMER2定时中断服务程序(2ms定时)。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 设 计 者:罗建                                                                日  期:2007年12月09日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TIMER2_ISR(void) interrupt INT_TIMER2
{
  INT8U i;

  TF2 = FALSE;
  if (gnScanID < 6)                         // 以下代码均为(2007.03.25)
  {
    KEY1 = LEVEL_HIGH;                      // 准备检测按键(KEY1或KEY2为低电平表示有键按下)
    KEY2 = LEVEL_HIGH;
    DoneDisplay();                          // 显示当前扫描到的LED数码管及指示灯
    //ReadKey();                              // 读取按键
    gnScanID++;                             // 准备扫描下一个按键和LED
  }
  else
  {
    gnScanID = 0;                           // 准备从头开始扫描
    if (!gbBufUsed)
    {
      for (i=0;i<5;i++)
      {
        gnDisBuf[0][i] = gnSegBuf[0][i];
        gnDisBuf[1][i] = gnSegBuf[1][i];
      }
    }
  }
  gnCnt2ms++;
  if (gnCnt2ms >= 50)                       // 定时100ms
  {
    gbTimeOver = TRUE;
	gnCnt10ms = 0;
  }
}

void SMBUS_ISR (void) interrupt INT_I2C     // 中断服务程序
{
  switch (SMB0STA)                          // 根据中断状态码跳转,SMB0STA 是中断状态寄存器
  {
    case SMB_START:	                        // 0x08, (MT & MR) 发送起始位
      SMB0DAT = SLAW ;                      // 装入被访问的从芯片的写地址
      STA = 0;                              // 人工清除 STA 位
      SI = 0;                               // 清除中断标志位
      break;
    case SMB_RP_START:	                    // 0x10,(MT & MR) 重复发送起始位
      SMB0DAT = SLAR;                       // 装入被访问的从芯片的读地址
      STA = 0;                              // 人工清除 STA 位
      SI = 0;                               // 清除中断标志位
      break;
    case SMB_MTADDACK:                      // 0x18 ,(MT) 发送从地址 + W 后收到ACK
      SMB0DAT = gnEEAddr;
      SI = 0;                               // 清除中断标志位
      break;
    case SMB_MTADDNACK:     	            // 0x20,(MT) 发送从地址 + W 后收到NACK
      STO = 1;
      STA = 1;
      SI = 0;                               // 清除中断标志位
      break;
    case SMB_MTDBACK:		                // 0x28,(MT) 发送数据后收到ACK
      switch (nSendMode)                    // 检查低1位
      {
        case 1:
		  nSendNums--;
		  if (nSendNums)
			SMB0DAT = gnEEData;
		  else
          {
			STO = 1;
		    SM_BUSY = 0;
	      }
          break;             
        case 0:
		  STO = 0;
          STA = 1;
          break;            
        default:              
          STO = 1;
          SM_BUSY = 0;
          break;
      }
      SI = 0;
      break;
    case SMB_MTDBNACK:	                    // 0x30
      STO = 1;
      STA = 1;
      SI = 0;                               // 清除中断标志
      break;
    case SMB_MRADDACK:	                    // 0x40
      AA = 0;                        
      SI = 0;
      break;
   	case SMB_MRADDNACK:	                    // 0x48
      STO = 0;
      STA = 1;
      SI = 0;
      break;
    case SMB_MRDBNACK:	                    // 0x58
      gnEEData = SMB0DAT;
      STO = 1;
      SM_BUSY = 0;
      AA = 1;                          
      SI = 0;
      break;
    default:
      STO = 1;
      SM_BUSY = 0;
      break;
  }
}

// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: ADC0_ISR
** 功能描述: ADC0转换结束中断服务程序。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:略
** 调用模块: 略
** 其它说明:ADC0转换结果与工程量(气体压力)之间的转换原理如下:
**           由于电气比例阀ITV2000的信号输出与压力之间的对应关系为:1-5V对应于0-0.5MPa,假设1-5V信号经
**           2.5倍分压后(即0.4-2V)进入单片机,其对应的ADC0数字量(即mADC0Res变量的值)为:
**               0.4V===0.4*4096/VREF0,2V===2*4096/VREF0,
**           其中,4096为ADC0的转换位数(12位),VREF0为ADC0的参考电压(典型值为2.43V)。
**           将压力信号扩大10000倍,则0-0.5MPa对应数字0-5000(单位为0.1KPa)。为了便于计算,这里采用直线
**           方程来得到压力与电压数字量之间的关系:
**               P1 = 0 = COEF0*0.4*4096/VREF0 + COEF1
**               P2 = 5000 = COEF0*2*4096/VREF0 + COEF1
**           因VREF0可以测得,因此可以解上述方程组。为便于进行整数运算,将VREF0扩大1000倍,则上述方程组可
**           表述为:
**               P1 = 0 = COEF0*400*4096/VREF0 + COEF1
**               P2 = 5000 = COEF0*2000*4096/VREF0 + COEF1
**           解方程组得系数COEF0和COEF1分别为:
**               COEF0 = VREF0*25/32768
**               COEF1 = -1250
**           故压力方程为:
**               P = D*VREF0*25/32768 - 1250
**           式中,P为待测压力,单位为0.1KPa,D为ADC0测得的对于输入电压的数字量。如果P<0,则应将其置0。
**
** 设 计 者:罗建                                                                日  期:2007年12月09日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ADC0_ISR(void) interrupt INT_ADC0
{
  static INT8U nADC0Cnt=ADC0_SAMPLE_NUMS;   // ADC0采样次数计数器定义及初始化
  INT32U nPress;

  AD0INT = FALSE;                           // 清除ADC0转换结束标志
  gnADC0Res += ADC0;                        // 累加ADC0转换结果并取平均
  gnADC0Res /= 2;
  nADC0Cnt--;                               // ADC0连续转换ADC0_SAMPLE_NUMS次,完成后暂停转换(不响应中断)
  if (nADC0Cnt == 0)                        // 同时将结果转换为工程量值(气体压力)
  {
    nADC0Cnt = ADC0_SAMPLE_NUMS;
	AD0EN = FALSE;
    nPress = gnADC0Res;                     // 转换为32位无符号数
    nPress = nPress*VREF0*25/32768;         // 进行工程量转换,如果值小于0,则认为是0
    EA = FALSE;
	if (nPress <= 1250)
	  gnPressGet = 0;
    else
	  gnPressGet = nPress - 1250;
    EA = TRUE;
  }
}

/********************************************************************************************************
** 函数名称: UART1_ISR
** 功能描述: 串行口UART1中断服务程序。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块:无
** 设 计 者:罗建                                                                日  期:2007年12月09日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART1_ISR(void) interrupt INT_UART1
{
  if (SCON1&0x01)                           // 数据接收中断
  {
    SCON1 &= ~0x01;                         // 清除数据接收中断标志
    if (gbSyncTwoOK1)                       // 检查同步字节是否接收完毕
	{
      if (SBUF1 == 0xFF)                    // 同步字节已接收完毕,但仍接收到了0xFF,说明出现了最糟糕
	    return;                             // 的情况,即有3个0xFF,因此需将该字节舍弃。
      gnRxdBuf1[gnRxdID1++] = SBUF1;
      if (gnRxdID1 >= 2)                    // 检查命令字节是否接收完毕,接收完则根据命令决定要接收的数据个数
	  {
	    switch (gnRxdBuf1[1])
		{
		  case 0x01:                        // 发送测量数据及开关状态至触摸屏命令(0xFF,0xFF,0x00,0x01,共4个字节)
			SetRxd1OK();                    // 重新初始化同步字节检测标志及串口接收缓冲区索引
            gnTxdBuf1[0] = 0xFF;
			gnTxdBuf1[1] = 0xFF;
			gnTxdBuf1[2] = 0x01;            // 准备发送命令的低8位字节
            gnTxdBuf1[3] = 0x00;            // 准备发送命令的高8位字节
            gnTxdBuf1[4] = gnPressGet % 256;// 准备发送测试压力的低8位字节

⌨️ 快捷键说明

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