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

📄 main.c

📁 一个采用C8051F020芯片实现的流量计控制系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
**           式中,P为待测压力,单位为0.1KPa,D为ADC0测得的对于输入电压的数字量。如果P<0,则应将其置0。
**
** 设 计 者:罗  建                                                              日  期:2008年02月03日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ADC0_ISR(void) interrupt INT_ADC0
{
  AD0INT = FALSE;                                // 清除ADC0转换结束标志
  gnADC0Res += ADC0;                             // 累加ADC0转换结果
  gnCntADC0++;                                   // ADC0连续转换ADC0_SAMPLE_NUMS次,完成后暂停转换(不响应中断)
  if (gnCntADC0 == ADC0_SAMPLE_NUMS)             // 通知主程序ADC0_SAMPLE_NUMS次ADC0转换已结束,可以进行数据处理
  {
    gnCntADC0 = 0;
    AD0EN = FALSE;
    gbADC0OK = TRUE;
  }
}

/********************************************************************************************************
** 函数名称: UART1_ISR
** 功能描述: 串行口UART1中断服务程序。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块:无
** 其它说明:1、上位机通讯协议
**           1)波特率:19200bps;
**           2)数据位:8位;
**           3)停止位:1位;
**           4)奇偶校验:none;
**           5)协  议:none;
**           6)数据格式:从上位机接收或发送到上位机的数值均采用16进制数表示,一帧数据的长度及其格式由命令
**             决定。
**             上位机发送给仪表或仪表发送给上位机的每帧数据组成如下:
**             (帧头)(命令)[参数地址索引] [参数值/测量值](校验核)
**             a)帧头:由两个连续的0xFF组成,标识一帧数据的开始;
**             b)命令:由一个字节组成,本版软件共实现三个命令,即0xF0(读测量值),0xF1(读参数值),
**                      0xF2(修改参数值);
**             c)参数分组号:由一个字节组成,仅读参数值命令和修改参数值命令有效,标识要读取或修改的参数
**                            值所在的分组号,取值范围为:0~9;
**             d)参数索引:由一个字节组成,仅读参数值命令和修改参数值命令有效,标识要读取或修改的参数的
**                          索引,其值对应于TParamIndex类型,取值范围为:0~8;
**             e)参数值:由两个字节组成,先发高字节,后发低字节,仅读参数值命令和修改参数值命令有效;
**                测量值:由五个字节组成,第1、2字节代表测试压力值,第3、4字节代表测试流量值,先发高字节,
**                        后发低字节,第5个字节代表仪表状态(见下),仅读测量值命令有效;
**                        仪表状态(一个字节):D7    D6    D5    D4    D3        D2        D1    D0
**                                              保留  保留  保留  保留  流量状态  压力状态  工作状态
**                        流量状态(D3)定义:   0--流量正常(PASS);
**                                               1--流量过大或过小(FAIL)。
**                        压力状态(D2)定义:   0--压力正常;
**                                               1--压力过高或过低(WARN)。
**                        工作状态(D1D0)定义:00--空闲状态;
**                                              01--参数设置状态;
**                                              10--充气状态;
**                                              11--测试状态。
**             f)校验核:由一个字节表示,其值为不包含帧头在内的所有字节的异或值。
** 设 计 者:罗  建                                                              日  期:2008年02月02日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART1_ISR(void) interrupt INT_UART1
{
  UINT8  i,nCrc;

  if (SCON1&0x01)                                // 数据接收中断
  {
    SCON1 &= ~0x01;                              // 清除数据接收中断标志
    if (!gbTxdOK1)                               // 上一次命令还没有处理完,放弃当前帧数据
      return;
    if (gbSyncTwoOK1)                            // 检查同步字节是否接收完毕
	{
      if (SBUF1 == 0xFF)                         // 同步字节已接收完毕,但仍接收到了0xFF,说明出现了最糟糕
	    return;                                  // 的情况,即有3个0xFF,因此需将该字节舍弃。
      gnRxdBuf1[gnRxdID1++] = SBUF1;
      switch (gnRxdBuf1[0])
      {
        case CMD_GET_VALUE:                      // 读测量值命令
          if (gnRxdID1 < 2)                      // 上位机发送的读测量数据帧共包含4个字节(0xFF,0xFF,0xF0,CRC)
            return;                              // 仪表发送数据帧共包含7个字节(0xFF,0xFF,0xF0,DATAH,DATAL,STATE,CRC)
          if (gnRxdBuf1[1] != gnRxdBuf1[0])      // 计算上位机发送的校验核是否正确,不正确则不响应
            return;
          else
            break;
        case CMD_GET_PARAM:                      // 读参数值命令
          if (gnRxdID1 < 4)                      // 上位机发送的读参数值数据帧共包含6个字节(0xFF,0xFF,0xF1,GROUP_ID,PARAM_ID,CRC)
            return;
          nCrc = gnRxdBuf1[1]^gnRxdBuf1[0];      // 计算上位机发送的校验核是否正确,不正确则不响应
          nCrc = nCrc ^ gnRxdBuf1[2];
          if (gnRxdBuf1[3] != nCrc)         
            return;
          else
            break;
        case CMD_SET_PARAM:                      // 修改参数值命令
          if (gnRxdID1 < 6)                      // 上位机发送的修改参数值数据帧共包含8个字节(0xFF,0xFF,0xF2,GROUP_ID,PARAM_ID,DATAH,DATAL,CRC)
            return;
          nCrc = gnRxdBuf1[0];                   // 计算上位机发送的校验核是否正确,不正确则不响应
          for (i=1;i<5;i++)
            nCrc = nCrc ^ gnRxdBuf1[i];
          if (gnRxdBuf1[5] != nCrc)
            return;
          else
            break;
      }
      SetRxd1OK();                               // 重新初始化同步字节检测标志及串口接收缓冲区索引
      gbRxdOK1 = TRUE;                           // 通知主程序UART1有接收到数据,可以进行处理了
      gbTxdOK1 = FALSE;
    }
    else                                         // 同步字节还未接收完毕,继续检测
    {
      if (SBUF1 == 0xFF)                         // 如果是同步字节,则设置相应的同步字节接收到标志
      {
        if (gbSyncOneOK1)
          gbSyncTwoOK1 = TRUE;
        else
          gbSyncOneOK1 = TRUE;
      }
      else                                       // 接收到的字节既非同步字节又非正常的测量数据,舍弃重来。
        SetRxd1OK();                             // 重新初始化同步字节检测标志及串口接收缓冲区索引
    }
  }
  else                                           // 数据发送中断
  {
    SCON1 &= ~0x02;                              // 清除数据发送中断标志
    gnTxdID1++;                                  // 准备发送下一个数据
    if (gnTxdID1 < gnTxdNums1)                   // 发送缓冲区中的gnTxdNums1个数据
      SBUF1 = gnTxdBuf1[gnTxdID1];
    else                                         // 数据全部发送完毕,可以继续接收上位机发送的命令
      gbTxdOK1 = TRUE;
  }
}

// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DeviceInit
** 功能描述: 片上系统外围设备初始化子程序。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:略
** 调用模块:略
** 其它说明:外部系统时钟启动过程建议为:
**           1)允许外部振荡器;
**           2)等待至少1ms;
**           3)查询XTLVLD是否由“0”=>“1”;
**           4)将系统时钟切换到外部振荡器。
**
** 设 计 者:罗建                                                                日  期:2007年12月09日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DeviceInit(void)
{
  UINT16 i;                                      // 延时计数器

  // 系统时钟初始化
  OSCXCN = 0x67;                                 // 启动外部22.1184MHz晶体振荡器
  for (i=0;i<3000;i++);                          // 等待XTLVLD消隐期(>1ms)
  while ((OSCXCN & 0x80) == 0);                  // 等待外部晶振稳定
  OSCICN = 0x08;                                 // 选择外部振荡器作为系统时钟SYSCLK,同时禁止时钟丢失检测功能
  // 数字量输入输出端口初始化
  P0MDOUT = 0x11;                                // TX0、TX1作为推挽方式
  P1MDOUT = 0x00;                                // (默认为漏极开路方式)
  P2MDOUT = 0x00;                                // (默认为漏极开路方式)
  XBR0 = XBR0_UART0EN + XBR0_SMB0EN;             // 允许UART0、SMBus
  XBR1 = XBR1_NONE;                              // 不允许任何外部设备
  XBR2 = XBR2_XBARE + XBR2_UART1E;               // 允许交叉开关、弱上位(默认)和UART1
  // ADC和DAC(取默认值)转换初始化
  AMX0CF = 0x00;                                 // 配置AIN00-AIN07均为单端输入方式(默认)
  AMX0SL = 0x00;                                 // 选择AIN00通道进行AD转换(默认)
  ADC0CF = 0x50;                                 // ADC0转换时钟为2MHz,PGA增益为1
  ADC0CN = 0x84;                                 // 允许ADC0,正常跟踪模式,Timer3溢出启动ADC0转换,ADC0数据右对齐
  DAC0   = 0x0000;                               // 默认DAC0输出为0
  DAC0CN = 0x80;                                 // 允许DAC0输出,写DAC0H时DAC0更新输出,DAC0H3-0保存高4位,DAC0L7-0保存低8位(默认)
  // ADC和DAC参考电压初始化
  REF0CN = 0x03;                                 // ADC0电压基准取至VREF0,禁止温度传感器,内部偏压发生器和基准电压缓冲器打开
  // 串口UART0和UART1初始化
  SCON0     = 0x50;                              // UART0(接流量计)为8位可变波特率模式,允许接收
  SCON1     = 0x50;                              // UART1(接计算机)为8位可变波特率模式,允许接收
  // SMBus初始化
  SMB0CN    = 0x44;                              // 允许SMBUS, 应答返回AA(低电平)
  SMB0CR    = 0xE7;                              // SMBus速率设置,系统时钟为22.1184MHZ,100kHz=0x94,400kHz=0xE7
  // 定时器初始化
  CKCON     = 0x30;                              // TIMER1、TIMER2时钟源为SYSCLK,TIMER4、TIMER0时钟源为SYSCLK/12
  TMOD      = 0x21;                              // TIMER1为8位自动重装载模式,TIMER0为16位定时器方式
  TH1       = 0xDC;                              // TIMER1作为UART0和UART1的波特率发生器,波特率均为19200bps
  TCON      = 0x40;                              // 允许TIMER1定时
  RCAP2H    = 0x53;                              // TIMER2自动重装载值(定时2ms,初值=65536-22118400*0.002=21299=0x5333)
  RCAP2L    = 0x33;
  TH2       = 0x53;                              // TIMER2计数寄存器初值(定时2ms)
  TL2       = 0x33;
  T2CON     = 0x04;                              // TIMER2作为2ms定时器,16位自动重装载模式,允许定时
  TMR3RLL   = 0x9A;                              // TIMER3自动重装载值(定时1ms)
  TMR3RLH   = 0xA9;
  TMR3L     = 0x9A;                              // TIMER3计数寄存器初值(定时1ms)
  TMR3H     = 0xA9;
  TMR3CN    = 0x06;                              // TIMER3作为1ms定时器,控制ADC,使用SYSCLK,允许定时
  // 中断初始化
  EIE1      = 0x02;                              // 允许SMBus中断
  EIE2      = 0x42;                              // 允许UART1和ADC0中断
  IE        = 0xB0;                              // 允许TIMER2、UART0中断,开总中断
}

// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: SysInit
** 功能描述: ADC0转换结束中断服务程序。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:略
** 调用模块:略
** 设 计 者:罗建                                                                日  期:2007年12月09日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SysInit(void)
{
  UINT8  i;
  UINT8  nReadBuf[4];

  LoadGroup();                                             // 从EEPROM中载入全部参数

⌨️ 快捷键说明

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