📄 main.#3
字号:
/********************************************************************************************************
** RidenFlowForLED
**
** 版权所有 (c) 2007,罗建
** 保留所有权利
**
** V1.0
**
**
**-------------------------------------------------文件信息----------------------------------------------
**文 件 名: Main.C
**设 计 者: 罗建
**最后修改日期: 2008年01月19日
**描 述: 源程序。
**其 它:MCU采用C8051F020,外部晶振为22.1184MHz,采用两组共12个LED数码管显示测量数据和输入配置信息,
** 并控制电磁阀和比例阀调节充气及测试时的气体压力,以满足测试需要。
**所属项目概述: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
** 日 期: 2008年01月19日
** 描 述: 原始版本
**
**-----------------------------------------------当前版本修订--------------------------------------------
** 修改者: 罗建
** 版 本: V1.00
** 日 期: 2008年01月19日
** 描 述: 原始版本。
**
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#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; /* 指示是否进入告警超时检测过程,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~是 */
bit gbLogo;
bit gbBufUsed;
bit gbParamSel;
bit gbCanFlash;
bit gbParamSet;
bit gbLeakOver;
/* 定义字节变量 */
INT8U data gnKeyID; /* 存放用户按键的键值,取值范围:0~8,0表示无按键 */
INT8U data gnScanID; /* 按键和LED扫描序号,取值范围:0~5,0表示LED1或Q1 */
INT8U data gnParamID; /* 代表当前用户选择的参数在参数组中的序号,取值0~PARAMS_NUMS-1 */
INT8U data gnCursorID; /* 代表当前光标位置,由左移键和右移键进行控制,取值0~4 */
INT8U data gnCntFlash; /* 代表当前光标闪烁的频率,实际频率=1/(gnCntFlash*0.01*2)Hz */
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 gnTxdID1; /* 串口UART1发送缓冲区数组索引 */
INT8U data gnRxdID0; /* 串口UART0接收缓冲区数组索引 */
INT8U data gnRxdID1; /* 串口UART1接收缓冲区数组索引 */
INT8U data gnTxdNums0; /* 串口UART0发送缓冲区数组中的数据个数,即要发送的数据个数 */
INT8U data gnTxdNums1; /* 串口UART1发送缓冲区数组中的数据个数,即要发送的数据个数 */
INT8U data gnT0OverCnt; /* 代表T0中断溢出的次数 */
INT8U xdata gnRxdBuf0[64]; /* 代表串口UART0接收缓冲区数组 */
INT8U xdata gnRxdBuf1[2]; /* 代表串口UART1接收缓冲区数组,高字节在前 */
INT8U xdata gnTxdBuf0[16]; /* 代表串口UART0发送缓冲区数组 */
INT8U xdata gnTxdBuf1[16]; /* 代表串口UART1发送缓冲区数组 */
INT8U data gnCnt2ms;
INT8U data gnLeakDot;
INT8U data gnGetKeyCnt;
INT8U data gnPressDot;
INT8U idata gnDisBuf[2][6];
INT8U idata gnSegBuf[2][6]; /* 代表两组段选缓冲区在SEG_CODE段选码数组中的数字索引 */
INT8 data SLAW; // 保存从地址+ WRITE 位
INT8 data SLAR; // 保存从地址+ READ 位
INT8 data gnEEData; // 保存被收/发的数据字节
INT8 data gnEEAddr; // 保存被收/发的数据地址
INT8 data nSendNums; // 保存被收/发的数据字节的数目
INT8U data nSendMode; // SENDMODE作读/写控制字
bit SM_BUSY=0; // 忙碌标志位
/* 定义字变量 */
INT16U data gnADC0Res=0; /* ADC0的转换结果(数字量) */
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 gnLeakMin =0; /* 用户通过触摸屏设定的允许最小气体流量(单位为0.01L/min) */
INT16U data gnCurrTime=0; /* 代表当前操作正在进行的时间 */
INT16U data gnFillTime=0; /* 用户通过触摸屏设定的充气时间 */
INT16U data gnTestTime=0; /* 用户通过触摸屏设定的测试时间 */
INT16U xdata gnLeakAreaMax[6]; /* 用户通过触摸屏设定的分段修正流量最大值(单位为0.01L/min) */
INT16U xdata gnLeakAreaCoef[6]; /* 用户通过触摸屏设定的分段修正流量系数 */
INT16U data gnPressOut=0; /* 输出到比例控制阀的压力信号值(单位为0.1KPa) */
/************************************************
** 不带小数点的字符的LED段选码(共阳LED,段输出低
** 电平有效) 。在LED数码管上显示的数值直接参与计
** 算或保存到24C02中,或从24C02中读取到内存中,但
** 在送LED显示前,需将这些数值编码为可被LED正确识
** 别的代码,可以直接编码,也可从SEG_CODE[]数组中
** 选取对应的数字或符号编码。
************************************************/
INT8U 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,位输出反相,低
** 电平有效)。扫描时,从低到高顺序进行。
************************************************/
INT8U code SCAN_CODE[] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
/************************************************
** 固定显示的字符数组的LED段选码在SEG_CODE数组中
** 的索引(共阳LED,段输出低电平有效)。为与实际的
** LED排序相一致,字符索引按反序排列。
************************************************/
INT8U code FIX_CODE[][5] =
{{0x14,0x14,0x13,0x0F,0x10}, /* ID:0, FiLL,即FILL */
{0x1B,0x1A,0x0E,0x1B,0x10}, /* ID:1, tESt,即TEST */
{0x17,0x1C,0x0E,0x19,0x17}, /* ID:2, PrEuP,即PREUP */
{0x15,0x0D,0x0E,0x19,0x17}, /* ID:3, PrEdn,即PREDN */
{0x17,0x1C,0x0A,0x0E,0x14}, /* ID:4, LEAuP,即LEAUP */
{0x15,0x0D,0x0A,0x0E,0x14}, /* ID:5, LEAdn,即LEADN */
{0x0F,0x0E,0x16,0x0C,0x14}, /* ID:6, LCoEF,即LEACO(2007.03.23) */
{0x19,0x0E,0x1C,0x16,0x10}, /* ID:7, ouEr,即OVER */
{0x15,0x0E,0x0D,0x13,0x19}, /* ID:8, ridEn,即RIDEN(2007.03.16) */
{0x00,0x05,0x0A,0x10,0x10} /* ID:9, A50,即A50 (2007.03.16)*/
};
/************************************************
** 为了加快Decode算法的计算速度,在存储器中生成一
** 个0~10000、按10倍递增的数组序列。
************************************************/
INT32U code TAB_COEF[] = {0, 10, 100, 1000, 10000};
// ------------------------------------------------------------------------------------------------------
/* 函数声明 */
void DeviceInit(void);
void SysInit(void);
void SetRxd0OK(void);
void SetRxd1OK(void);
void AdjustPress(void);
void DoneKey(void);
void DoneTest(void);
void DoneDisplay(void);
void DoneStartKey(void);
void DoneStopKey(void);
void DoneFuncKey(void);
void DoneSetKey(void);
void DoneUpKey(void);
void DoneDownKey(void);
void DoneLeftKey(void);
void DoneRightKey(void);
void EraseEEPROM(void);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -