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

📄 main.c

📁 一个采用C8051F020芯片实现的流量计控制系统源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************************************
**				                                RidenFlowForLED
**
**                                          版权所有 (c) 2007,罗建
**                                               保留所有权利
**
**                                                  V1.01
**
**
**-------------------------------------------------文件信息----------------------------------------------
**文   件   名: Main.C
**设   计   者: 罗建
**最后修改日期: 2008年03月01日
**描        述: 源程序。
**其        它:MCU采用C8051F020,外部晶振为22.1184MHz,采用两组共12个LED数码管显示测量数据和输入配置信息,
**              并控制电磁阀和比例阀调节充气及测试时的气体压力,以满足测试需要。
**所属项目概述:RIDEN FLOW流量计是用于测试气体流量的装置,其工作原理为:压缩空气经空气过滤器到达比例控制阀,
**              经比例控制阀调压稳定后,通过气路通断控制阀,到达气体流量计,然后进入产品。该装置功能就是测
**              量流过气体的质量流量。
**              各部件的作用如下:
**              1、比例控制阀:其作用是调节前端的高压气体以使其稳定在设置的压力值附近,为测试提供一个稳定的
**                 气源。
**              2、气路通断控制阀:在每一个测量周期内,此阀通断一次,即在测试检测过程中打开,测试完成后关闭,
**                 直到下一个测试开始。
**              3、气体流量计:用于测量流经该传感器的压缩空气的流量。
**基本技术参数:1、被测介质:            压缩空气,<0.8MPa;
**              2、气体流量范围:        0-99.99L/min;
**              3、流量精度:            0.01L/min;
**              4、采集及显示频率:      3Hz;
**              5、测试压力:            0-999.9KPa(自动调节,稳压);
**              6、测试压力精度:        0.1KPa;
**              7、充气时间:            0-999.9S;
**              8、测试时间:            0-999.9S;
**              9、校准系数:            3段;
**              10、通讯接口(To PC):  RS232。
**
**-----------------------------------------------历史版本信息--------------------------------------------
** 设计者: 罗建
** 版  本: V1.00
** 日 期: 2008年02月04日
** 描 述: 原始版本
**
**-----------------------------------------------当前版本修订--------------------------------------------
** 修改者: 罗建
** 版  本: V1.01
** 日 期: 2008年03月01日
** 描 述: 1)为了扩大流量的显示范围(0-150Ln/min和0-200Ln/min),将流量的小数点改为了1位(原来为2位),
**            但流量修正系数仍为2位小数点;
**         2)修改了流量分段修正系数的设置方法,当按下功能键持续时间在5秒以上时,调出流量分段修正参数供厂
**            家修改,此时,左边LED显示当前流量段的流量值,右边显示当前流量段的系数值,按一下设置键,左边
**            值允许修改(闪烁),再按一下保存左边修改的值,同时右边的值允许修改(闪烁),再按一下保存右边
**            修改的值;
**         3)增加了一个工作状态,即测试结束状态(显示“r”)。
**
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#include <c8051f020.h>                           // SFR declarations
#include <intrins.h>
#include <absacc.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 = 0x1F,XBR1 = 0x14,XBR2 = 0x44,P0MDOUT = 0x15,P1MDOUT = 0x01,P2MDOUT = 0x00,P3MDOUT = 0x80 */
// P0
sbit  UART0_TX    =  P0^0;                       // XBR0.2 = 1(UART0EN = 1),P0MDOUT.0 = 1,TX0作为推挽方式
sbit  UART0_RX    =  P0^1;
sbit  I2C_SDA     =  P0^2;                       // XBR0.0 = 1(SMB0EN = 1)
sbit  I2C_SCL     =  P0^3;
sbit  UART1_TX    =  P0^4;                       // XBR2.2 = 1(UART1EN = 1),P0MDOUT.4 = 1,TX1作为推挽方式
sbit  UART1_RX    =  P0^5;
// 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  DIS_RCK     =  P2^0;                       // P2MDOUT.0 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  DIS_SCK     =  P2^1;                       // P2MDOUT.1 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit  DIS_SER     =  P2^2;                       // P2MDOUT.2 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
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  KEY1        =  P2^6;                       // P2MDOUT.6 = 0,漏极开路方式,作为数字输入,默认为高电平,变低时表示有键按下
sbit  KEY2        =  P2^7;                       // P2MDOUT.7 = 1,漏极开路方式,作为数字输入,默认为高电平,变低时表示有键按下

// ------------------------------------------------------------------------------------------------------
/* 定义位变量 */
bit             gbReadyWarn=FALSE;               // 指示是否进入告警超时检测过程,0~否,1~是
bit             gbCanGetKey=TRUE;                // 指示是否可以再次检测按键,0~否,1~是
bit             gb100msOver=FALSE;               // 指示100ms定时间隔时间是否到,0~未到,1~已到
bit             gbLogoOver=FALSE;                // 指示LOGO画面显示时间是否到,0~未到,1~已到
bit             gbTestOver=FALSE;                // 指示当前是否已完成或退出了检测状态,0~非检测状态或检测过程未结束,1~检测完成(但未退出检测进程)
bit             gbSyncOneOK0=FALSE;              // 指示串口0数据帧的第一个同步字节是否接收完毕,0~未收到,1~收到
bit             gbSyncTwoOK0=FALSE;              // 指示串口0数据帧的第二个同步字节是否接收完毕,0~未收到,1~收到
bit             gbSyncOneOK1=FALSE;              // 指示串口1数据帧的第一个同步字节是否接收完毕,0~未收到,1~收到
bit             gbSyncTwoOK1=FALSE;              // 指示串口1数据帧的第二个同步字节是否接收完毕,0~未收到,1~收到
bit             gbStarted=FALSE;                 // 指示<启动键>是否按下,0~未按下,1~按下
bit             gbFilling=FALSE;                 // 指示当前是否工作于充气状态,0~否,1~是
bit             gbTesting=FALSE;                 // 指示当前是否工作于测试状态,0~否,1~是
bit             gbBufUsed=FALSE;                 // 指示LED段选缓冲区当前是否正在被非中断服务程序使用当中,0~未使用,1~正在使用
bit             gbParamSel=FALSE;                // 指示当前参数是否已处于待修改状态(闪烁),0~否,1~是
bit             gbCanFlash=FALSE;                // 该标志与gnCntFlash计数器配合实现闪烁间隔定时,0~不允许闪烁,1~允许闪烁
bit             gbParamSet=FALSE;                // 指示是否进入参数修改状态,0~否,1~是
bit             gbLeakOver=FALSE;                // 指示是否测量流量超出限制值,0~否,1~是
bit             gbPressOver=FALSE;               // 指示是否测量压力超出限制值,0~否,1~是
bit             gbADC0OK=FALSE;                  // 指示ADC0转换是否结束,0~否,1~是
bit             gbRxdOK0=FALSE;                  // 指示UART0串口一帧数据是否全部接收完毕,0~否,1~是
bit             gbRxdOK1=FALSE;                  // 指示UART1串口一帧数据是否全部接收完毕,0~否,1~是
bit             gbTxdOK1=TRUE;
bit             SM_BUSY=FALSE;                   // SMBUS总线忙碌标志位,0~空闲,1~忙碌
bit             gbAdjustOK=FALSE;                // 用于控制功能键的5秒钟持续按下延时(V1.01)
bit             gbFuncContinue=FALSE;            // 用于说明功能键是否持续按下,0~否,1~是

bit             gbPressStabled=FALSE;            // 指示当前压力是否进入设定的范围,0~否,1~是

/* 定义字节变量 */
VUINT8    data  gnWorkState=wsIdle;              // 仪表当前工作状态(0=空闲,1=参数设置,2=充气,3=测试)
VUINT8    data  gnKeyID=0;                       // 存放用户按键的键值,取值范围:0~8,0表示无按键
VUINT8    data  gnScanID=0;                      // 按键和LED扫描序号,取值范围:0~5,0表示LED1或Q1
VUINT8    xdata gnCursorID=0;                    // 代表当前光标位置,由左移键和右移键进行控制,取值0~4
VUINT8    data  gnGroupID=0;                     // 代表用户选择的参数分组索引,取值0~9,共10组
VUINT8    data  gnParamID;                       // 代表当前用户选择的参数在参数组中的序号,取值0~PARAMS_NUMS-1
VUINT8    data  gnCntFlash;                      // 代表当前光标闪烁的频率,实际频率=1/(gnCntFlash*0.1*2)Hz
VUINT8    data  gnCntADC0=0;                     // ADC0采集间隔时间计数器(为了降低LCD的刷新率)
VUINT8    xdata gnCntWarn=0;                     // 压力告警超时计数器
VUINT8    xdata gnCntLogo=0;                     // LOGO画面显示延时读数器
VUINT8    data  gnCntAdjust=0;                   // 压力调节时间计数器
VUINT8    data  gnCnt2ms=0;                      // 2ms定时计数器,用于实现100ms定时
VUINT8    data  gnCntGetKey=0;                   // 两次检测按键之间的时间间隔(实际间隔是该值乘以100ms
VUINT8    data  gnCntPressDis=0;
VUINT8    data  gnTxdID0=0;                      // 串口UART0发送缓冲区数组索引
VUINT8    data  gnTxdID1=0;                      // 串口UART1发送缓冲区数组索引
VUINT8    data  gnRxdID0=0;                      // 串口UART0接收缓冲区数组索引
VUINT8    data  gnRxdID1=0;                      // 串口UART1接收缓冲区数组索引
VUINT8    data  gnTxdNums0;                      // 串口UART0发送缓冲区数组中的数据个数,即要发送的数据个数
VUINT8    data  gnTxdNums1;                      // 串口UART1发送缓冲区数组中的数据个数,即要发送的数据个数
VUINT8    data  gnSlaAddrW;                      // 保存SMBUS设备从地址+WRITE位
VUINT8    data  gnSlaAddrR;                      // 保存SMBUS设备从地址+READ位
VUINT8    data  gnMemData;                       // 保存被收/发的数据字节
VUINT8    data  gnMemAddr;                       // 保存被收/发的数据地址
VUINT8    data  gnSendNums;                      // 保存被收/发的数据字节的数目
VUINT8    data  gnSendMode;                      // 读/写控制字,为1时表示读操作,为0时表示写操作
VUINT8    data  gnRxdBuf0[2];                    // 串口UART0接收缓冲区数组
VUINT8    xdata gnRxdBuf1[6];                    // 串口UART1接收缓冲区数组
VUINT8    xdata gnTxdBuf1[10];                   // 串口UART1发送缓冲区数组
VUINT8    data  gnDisBuf[2][6];                  // LED显示缓冲区,用于实现双缓冲操作
VUINT8    data  gnSegBuf[2][6];                  // 两组段选缓冲区在SEG_CODE段选码数组中的数字索引
VUINT8    data  gnFuncCnt=0;                     // 用于控制功能键的5秒钟持续按下延时(V1.01)
VUINT8    data  gnOldGroupID=0;                  // 用于当修改分段流量系数时,临时保存分组索引,在返回待机状态时恢复(V1.01)
VUINT8    data  gnSetID=1;                       // 指示当前正在修改的参数是左边6个LED上(0)还是右边6个LED上(1)

/* 定义字变量 */
VUINT16   data  gnPressGet=0;                    // 测得的气体压力(单位为0.1KPa)
VUINT16   data  gnLeakGet=0;                     // 测得的气体流量(单位为0.1L/min)
VUINT16   data  gnPressOut=0;                    // 输出到比例控制阀的压力信号值(单位为0.1KPa)
VUINT16   data  gnCurrTime=0;                    // 代表当前操作正在进行的时间
VUINT16   data  gnFillTime;                      // 用户设定的充气时间
VUINT16   data  gnTestTime;                      // 用户设定的测试时间
VUINT16   data  gnPressSet;                      // 用户设定的气体压力(单位为0.1KPa)
VUINT16   data  gnPressMax;                      // 用户设定的允许最大气体压力(单位为0.1KPa)
VUINT16   data  gnPressMin;                      // 用户设定的允许最小气体压力(单位为0.1KPa)
VUINT16   data  gnLeakMax;                       // 用户设定的允许最大气体流量(单位为0.1L/min)
VUINT16   data  gnLeakMin;                       // 用户设定的允许最小气体流量(单位为0.1L/min)
VUINT16   xdata gnLeakArea[GROUPS_OF_COEFS];     // 用户设定的10组分段修正流量最大值(单位为0.1L/min),实际只使用了3组
VUINT16   xdata gnLeakCoef[GROUPS_OF_COEFS];     // 用户设定的10组分段修正流量系数,实际只使用了3组

/* 定义双字变量 */
VUINT32   data  gnADC0Res=0;                     // ADC0的转换结果存储器定义及初始化

/************************************************
** 不带小数点的字符的LED段选码(共阳LED,段输出低
** 电平有效) 。在LED数码管上显示的数值直接参与计
** 算或保存到24C02中,或从24C02中读取到内存中,但
** 在送LED显示前,需将这些数值编码为可被LED正确识
** 别的代码,可以直接编码,也可从SEG_CODE[]数组中
** 选取对应的数字或符号编码。
************************************************/
UINT8 code SEG_CODE[] = 
{
  0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,    /* 0..9 */
  0x88,0x83,0xC6,0xA1,0x86,0x8E,                        /* A..F */
  0xFF,0x89,0x8B,0xCF,0xC7,0xAB,0xA3,0x8C,0x98,0xAF,    /*  ..r */
  0x92,0x87,0xE3,0x91,0xBF                              /* S..- */
};

/************************************************ 
** 不进行闪烁的LED位选码(共阳LED,位输出反相,低
** 电平有效)。扫描时,从低到高顺序进行。
************************************************/
//UINT8 code SCAN_CODE[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
UINT8 code SCAN_CODE[] = {0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE};

/************************************************
** 固定显示的字符数组的LED段选码在SEG_CODE数组中
** 的索引(共阳LED,段输出低电平有效)。为与实际的
** LED排序相一致,字符索引按反序排列。
************************************************/
UINT8 code FIX_CODE[][5] = 
{
  {0x14,0x14,0x13,0x0F,0x1E},                    // ID:0, -FiLL,即-FILL
  {0x1B,0x1A,0x0E,0x1B,0x1E},                    // ID:1, -tESt,即-TEST
  {0x1B,0x1A,0x19,0x17,0x1E},                    // ID:2, -PrSt,即-PRST
  {0x17,0x1C,0x19,0x17,0x1E},                    // ID:3, -PruP,即-PRUP
  {0x15,0x0D,0x19,0x17,0x1E},                    // ID:4, -Prdn,即-PRDN
  {0x17,0x1C,0x0E,0x14,0x1E},                    // ID:5, -LEuP,即-LEUP

⌨️ 快捷键说明

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