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

📄 main.#2

📁 一个采用C8051F020+CH372实现的带USB功能的流量测控系统
💻 #2
📖 第 1 页 / 共 3 页
字号:
/********************************************************************************************************
**				                                  RidenFlow
**
**                                          版权所有 (c) 2008,罗建
**                                               保留所有权利
**
**                                                  V1.0
**
**
**-------------------------------------------------文件信息----------------------------------------------
**文   件   名: Main.C
**设   计   者: 罗建
**最后修改日期: 2008年05月31日
**描        述: 第五代Riden A50流量计源程序,继承自第三代软件,根据硬件的不同修改了部分代码。
**其        它:MCU采用C8051F020,外部晶振为22.1184MHz,采用台达3.8'LCD触摸屏显示测量数据和输入配置信息,
**              并控制电磁阀和比例阀,以实现气体压力和流量的控制。
**所属项目概述:RIDEN FLOW流量计是用于测试气体流量的装置,其工作原理为:压缩空气经空气过滤器到达比例控制阀,
**              经比例控制阀调压稳定后,通过气路通断控制阀,到达气体流量计,然后进入产品。该装置功能就是测
**              量流过气体的质量流量。
**              各部件的作用如下:
**              1、比例控制阀:其作用是调节前端的高压气体以使其稳定在设置的压力值附近,为测试提供一个稳定的
**                 气源。
**              2、气路通断控制阀:在每一个测量周期内,此阀通断一次,即在测试检测过程中打开,测试完成后关闭,
**                 直到下一个测试开始。
**              3、气体流量计:用于测量流经该传感器的压缩空气的流量。
**基本技术参数:1、被测介质:            压缩空气,<0.8MPa;
**              2、气体流量范围:        0-50L/min(超量程50% 显示 Out Range);
**              3、流量精度:            0.01L/min;
**              4、采集及显示频率:      3Hz;
**              5、测试压力:            0-50KPa(自动调节,稳压);
**              6、测试压力精度:        0.1KPa;
**              7、充气时间:            0-999.9S;
**              8、测试时间:            0-999.9S;
**              9、校准系数:            5段;
**              10、通讯接口(To PC):  RS232。
**
**-----------------------------------------------历史版本信息--------------------------------------------
** 设计者: 罗建
** 版  本: V1.00
** 日 期: 2007年11月24日
** 描 述: 原始版本
**
**-----------------------------------------------当前版本修订--------------------------------------------
** 修改者: 罗建
** 版  本: V1.01
** 日 期: 2008年05月31日
** 描 述: 在第三代流量计软件基础上针对硬件的变化作了适应性修改。
**
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <c8051f020.h>                      // SFR declarations
//#include <Intrins.h>
//#include <String.h>
#include "GlobeDef.h"

//-------------------------------------------------------------------------------------------------------
/* C8051F02x单片机的16位SFR定义 */
sfr16 DP          =  0x82;                  // data pointer
sfr16 TMR3RL      =  0x92;                  // Timer3 reload value
sfr16 TMR3        =  0x94;                  // Timer3 counter
sfr16 ADC0        =  0xbe;                  // ADC0 data
sfr16 ADC0GT      =  0xc4;                  // ADC0 greater than window
sfr16 ADC0LT      =  0xc6;                  // ADC0 less than window
sfr16 RCAP2       =  0xca;                  // Timer2 capture/reload
sfr16 T2          =  0xcc;                  // Timer2
sfr16 RCAP4       =  0xe4;                  // Timer4 capture/reload
sfr16 T4          =  0xf4;                  // Timer4
sfr16 DAC0        =  0xd2;                  // DAC0 data
sfr16 DAC1        =  0xd5;                  // DAC1 data

//-------------------------------------------------------------------------------------------------------
/* 本项目对C8051F02x单片机的引脚重定义,其中,XBR0 = 0x05,XBR1 = 0x04,XBR2 = 0x44,P0MDOUT = 0x91,
   P1MDOUT = 0x00,P2MDOUT = 0x00,P3MDOUT = 0x03, P74OUT = 0x00 */
// P0
sbit  UART0_TX    =  P0^0;                  // XBR0.2 = 1(UART0EN = 1),P0MDOUT.0 = 1,TX0作为推挽方式输出
sbit  UART0_RX    =  P0^1;                  //                          P0MDOUT.1 = 0, RX0作为漏极开路方式输入
sbit  I2C_SDA     =  P0^2;                  // XBR0.0 = 1(SMB0EN = 1), P0MDOUT.2 = 0, SDA作为漏极开路方式输入或输出
sbit  I2C_SCL     =  P0^3;                  //                         P0MDOUT.3 = 0, SCL作为漏极开路方式输入或输出
sbit  UART1_TX    =  P0^4;                  // XBR2.2 = 1(UART1EN = 1),P0MDOUT.4 = 1,TX1作为推挽方式输出
sbit  UART1_RX    =  P0^5;                  //                          P0MDOUT.5 = 0, RX1作为漏极开路方式输入
sbit  USB_INT     =  P0^6;                  // XBR1.2 = 1(INT0EN = 1), P0MDOUT.6 = 0, INT0作为漏极开路方式输入
sbit  USB_A0      =  P0^7;                  // P0MDOUT.7 = 1, 推挽方式, 数字输出
// P1
sbit  KEY_START   =  P1^0;                  // P1MDOUT.0 = 0,漏极开路方式,并使KEY_START = 1将其配置为数字输入
sbit  KEY_STOP    =  P1^1;                  // P1MDOUT.1 = 0,漏极开路方式,并使KEY_STOP = 1将其配置为数字输入
sbit  DRV_PASS    =  P1^2;                  // P1MDOUT.2 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  DRV_FAIL    =  P1^3;                  // P1MDOUT.3 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  DRV_WARN    =  P1^4;                  // P1MDOUT.4 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  DRV_VALVE   =  P1^5;                  // P1MDOUT.5 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定

// P2
sbit  KEY_RCK     =  P2^0;                  // P2MDOUT.0 = 0,漏极开路方式,并使KEY_RCK = 1将其配置为数字输入
sbit  KEY_SCK     =  P2^1;                  // P2MDOUT.1 = 0,漏极开路方式,并使KEY_SCK = 1将其配置为数字输入
sbit  KEY_SER     =  P2^2;                  // P2MDOUT.2 = 0,漏极开路方式,并使KEY_SER = 1将其配置为数字输入
sbit  LED_PASS    =  P2^3;                  // P2MDOUT.3 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  LED_FAIL    =  P2^4;                  // P2MDOUT.4 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  LED_WARN    =  P2^5;                  // P2MDOUT.5 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  KEY_IN1     =  P2^6;                  // P2MDOUT.6 = 0,漏极开路方式,并使KEY_IN1 = 1将其配置为数字输入
sbit  KEY_IN2     =  P2^7;                  // P2MDOUT.7 = 0,漏极开路方式,并使KEY_IN2 = 1将其配置为数字输入

// P3
sbit  USB_WR      =  P3^0;                  // P3MDOUT.0 = 1,推挽方式,作为数字输出
sbit  USB_RD      =  P3^1;                  // P3MDOUT.1 = 1,推挽方式,作为数字输出

// P4
sfr   USB_DATA    =  0x84;                  // P74OUT = 0x00,P4口被配置为漏极开路方式,使USB_DATA = 0xFF将其配置为数字输入(需要输出时再配置为推挽方式


// ------------------------------------------------------------------------------------------------------
/* 定义位变量 */
bit       gbReadyWarn;                           /* 指示是否进入告警超时检测过程,0~否,1~是 */
bit       gbCanGetKey;                           /* 指示是否可以再次检测按键,0~否,1~是 */
bit       gbTimeOver;                            /* 指示规定的定时间隔时间(100ms)时否到,0~未到,1~已到 */
bit       gbTestOver;                            /* 指示当前是否已完成或退出了检测状态,0~非检测状态或检测过程未结束,1~检测完成(但未退出检测进程) */
bit       gbSyncOneOK0;                          /* 指示串口0数据帧的第一个同步字节是否接收完毕,0~未收到,1~收到 */
bit       gbSyncTwoOK0;                          /* 指示串口0数据帧的第二个同步字节是否接收完毕,0~未收到,1~收到 */
bit       gbSyncOneOK1;                          /* 指示串口1数据帧的第一个同步字节是否接收完毕,0~未收到,1~收到 */
bit       gbSyncTwoOK1;                          /* 指示串口1数据帧的第二个同步字节是否接收完毕,0~未收到,1~收到 */
bit       gbStarted;                             /* 指示<启动键>是否按下,0~未按下,1~按下 */
bit       gbFilling;                             /* 指示当前是否工作于充气状态,0~否,1~是 */
bit       gbTesting;                             /* 指示当前是否工作于测试状态,0~否,1~是 */

/* 定义字节变量 */
INT8U     data  gnCntADC;                        /* ADC0采集间隔时间计数器(为了降低LCD的刷新率) */
INT8U     data  gnCntWarn;                       /* 压力告警超时计数器 */
INT8U     data  gnCntAdjust;                     /* 压力调节时间计数器 */
INT8U     data  gnCnt10ms;                       /* 10ms定时计数器,用于实现100ms定时 */
INT8U     data  gnCntGetKey;                     /* 两次检测按键之间的时间间隔(实际间隔是该值乘以100ms */
INT8U     data  gnTxdID0;                        /* 串口UART0发送缓冲区数组索引 */
INT8U     data  gnRxdID0;                        /* 串口UART0接收缓冲区数组索引 */
INT8U     data  gnRxdID1;                        /* 串口UART1接收缓冲区数组索引 */
INT8U     data  gnTxdNums0;                      /* 串口UART0发送缓冲区数组中的数据个数,即要发送的数据个数 */
INT8U     data  gnT0OverCnt;                     /* 代表T0中断溢出的次数 */
INT8U     idata gnRxdBuf0[64];                   /* 代表串口UART0接收缓冲区数组 */
INT8U     idata gnRxdBuf1[2];                    /* 代表串口UART1接收缓冲区数组,高字节在前 */
INT8U     idata gnTxdBuf0[16];                   /* 代表串口UART0发送缓冲区数组 */

/* 定义字变量 */

INT16U    data  gnPressGet=0;                    /* 测得的气体压力(单位为0.1KPa) */
INT16U    data  gnLeakGet=0;                     /* 测得的气体流量(单位为0.01L/min) */
INT16U    data  gnPressSet=0;                    /* 用户通过触摸屏设定的气体压力(单位为0.1KPa) */
INT16U    data  gnPressMax=0;                    /* 用户通过触摸屏设定的允许最大气体压力(单位为0.1KPa) */
INT16U    data  gnPressMin=0;                    /* 用户通过触摸屏设定的允许最小气体压力(单位为0.1KPa) */
INT16U    data  gnLeakMax =0;                    /* 用户通过触摸屏设定的允许最大气体流量(单位为0.01L/min) */
INT16U    data  gnCurrTime=0;                    /* 代表当前操作正在进行的时间 */
INT16U    data  gnFillTime=0;                    /* 用户通过触摸屏设定的充气时间 */
INT16U    data  gnTestTime=0;                    /* 用户通过触摸屏设定的测试时间 */
INT16U    idata gnLeakAreaMax[6];                /* 用户通过触摸屏设定的分段修正流量最大值(单位为0.01L/min) */
INT16U    idata gnLeakAreaCoef[6];               /* 用户通过触摸屏设定的分段修正流量系数 */
INT16U    data  gnPressOut=0;                    /* 输出到比例控制阀的压力信号值(单位为0.1KPa) */

INT32U    data  gnADC0Res=0;                     /* ADC0的转换结果(数字量) */
INT32U    data  gnLeakRes=0;
// ------------------------------------------------------------------------------------------------------
/* 函数声明 */
void DeviceInit(void);
void SysInit(void);
void SetRxd0OK(void);
void SetRxd1OK(void);
void AdjustPress(void);
void DoneKey(void);
void DoneTest(void);

// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: main
** 功能描述: 主程序。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:略
** 调用模块:略
** 设 计 者:罗建                                                                日  期:2007年12月09日
** 版    本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void main(void)
{
  WDTCN = 0xDE;                             // 禁止看门狗定时器
  WDTCN = 0xAD;
  DeviceInit();                             // 初始化片上系统外围设备   
  EIP2|=0x40;
  SysInit();                                // 初始化系统变量
  DRV_PASS = 0;
  DRV_FAIL = 0;
  DRV_WARN = 0;
  DRV_VALVE= 0;
  //DAC0L = 0xFF;
  //DAC0H = 0x07;

  while (TRUE)                              // 主程序循环
  {
    while (!gbTimeOver);                    // 检查定时间隔是否到(0.1秒)
    gbTimeOver = FALSE;                     // 准备重新延时
	if (gnCntADC-- == 0)
	{
	  gnCntADC = ADC_WAIT;
      AD0EN = TRUE;
    }
	// 检查压力是否超出设定的最大与最小值,是则警告  
    if ((gnPressGet > gnPressMax) || (gnPressGet < gnPressMin))
	{
	  if (!gbReadyWarn)                     // 当首次检测到压力超出设定值时,开始计时
	  {
	    gbReadyWarn = TRUE;
	    gnCntWarn = WARN_WAIT;
      }
      else if (gnCntWarn-- == 0)            // 当压力超出设定值的时间持续10秒后,输出报警指示
	  {
	    gbReadyWarn = FALSE;
        DRV_WARN = OPEN;        
	  }
    }
	else                                    // 压力在设定值区间内,不用报警
	{
	  gbReadyWarn = FALSE;
      gnCntWarn = 0;
      DRV_WARN = CLOSE;
    }
    AdjustPress();                          // 进行压力调节
    DoneKey();                              // 按键检测处理
    DoneTest();                             // 执行流量测试
  }
}

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

  // 系统时钟初始化
  OSCXCN = 0x67;                            // 启动外部22.1184MHz晶体振荡器
  for (i=0;i<3000;i++);                     // 等待XTLVLD消隐期(>1ms)
  while ((OSCXCN & 0x80) == 0);             // 等待外部晶振稳定
  OSCICN = 0x08;                            // 选择外部振荡器作为系统时钟SYSCLK,同时禁止时钟丢失检测功能

  // 数字量输入输出端口初始化
  P0MDOUT = 0x91;
  P1MDOUT = 0x00;
  P2MDOUT = 0x00;
  P3MDOUT = 0x03;
  P74OUT  = 0x00;
  XBR0 = 0x05;                              // 允许UART0、SMBus、UART1

⌨️ 快捷键说明

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