📄 main14.c
字号:
/********************************************************************************************************
** RidenFlow
**
** 版权所有 (c) 2007,罗建
** 保留所有权利
**
** V1.0
**
**
**-------------------------------------------------文件信息----------------------------------------------
**文 件 名: Main.C
**设 计 者: 罗建
**最后修改日期: 2007年11月24日
**描 述: 源程序。
**其 它: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.00
** 日 期: 2007年11月24日
** 描 述: 原始版本。
**
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
#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 = 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 SPI_SCK = P0^2; // XBR0.1 = 1(SPI0EN = 1),P0MDOUT.2 = 1,P0MDOUT.4 = 1,SPI_SCK和SPI_MOSI作为推挽方式
sbit SPI_MISO = P0^3;
sbit SPI_MOSI = P0^4;
sbit SPI_NSS = P0^5;
sbit I2C_SDA = P0^6; // XBR0.0 = 1(SMB0EN = 1)
sbit I2C_SCL = P0^7;
// P1
sbit UART1_TX = P1^0; // XBR2.2 = 1(UART1EN = 1),P1MDOUT.0 = 1,TX1作为推挽方式
sbit UART1_RX = P1^1;
sbit PCA0_CEX0 = P1^2; // XBR0.[5..3] = 011(PCA0ME = 011),CEX0、CEX1和CEX2连到三个端口上
sbit PCA0_CEX1 = P1^3;
sbit PCA0_CEX2 = P1^4;
sbit INT0_SCK = P1^5; // XBR1.2 = 1(INT0E = 1),P1MDOUT.5 = 0,漏极开路方式,并使INT0_SCK = 1将其配置为数字输入
sbit INT1_CS = P1^6; // XBR1.4 = 1(INT1E = 1),P1MDOUT.6 = 0,漏极开路方式,并使INT1_CS = 1将其配置为数字输入
sbit INT2_MOSI = P1^7; // GPIO,P1MDOUT.7 = 0,漏极开路方式,并使INT2_MOSI = 1将其配置为数字输入
// P2
sbit KEY_START = P2^0; // P2MDOUT.0 = 0,漏极开路方式,并使KEY_START = 1将其配置为数字输入
sbit KEY_STOP = P2^1; // P2MDOUT.1 = 0,漏极开路方式,并使KEY_STOP = 1将其配置为数字输入
sbit PORT_P22 = P2^2; // 保留
sbit PORT_P23 = P2^3; // 保留
sbit DRV_PASS = P2^4; // P2MDOUT.4 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit DRV_FAIL = P2^5; // P2MDOUT.5 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit DRV_WARN = P2^6; // P2MDOUT.6 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit DRV_VALVE = P2^7; // P2MDOUT.7 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
// P3
sbit LCD_RS = P3^0; // P3MDOUT.0 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit LCD_RW = P3^1; // P3MDOUT.1 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit LCD_E = P3^2; // P3MDOUT.2 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit LCD_CS1 = P3^3; // P3MDOUT.3 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit LCD_CS2 = P3^4; // P3MDOUT.4 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit LCD_LED = P3^5; // P3MDOUT.5 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit LCD_RST = P3^6; // P3MDOUT.6 = 0,漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
sbit SPI_CS = P3^7; // P3MDOUT.7 = 1,推挽方式,作为数字输出,高电平由内部弱上拉电阻确定
// P4
sfr LCD_DBX = 0x84; // P4,P74OUT = 0x00,P4口被配置为漏极开路方式,作为数字输出,高电平由外部上拉电阻确定
// ------------------------------------------------------------------------------------------------------
/* 定义位变量 */
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 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 idata gnLeakAreaMax[6]; /* 用户通过触摸屏设定的分段修正流量最大值(单位为0.01L/min) */
INT16U idata gnLeakAreaCoef[6]; /* 用户通过触摸屏设定的分段修正流量系数 */
INT16U data gnPressOut=0; /* 输出到比例控制阀的压力信号值(单位为0.1KPa) */
// ------------------------------------------------------------------------------------------------------
/* 函数声明 */
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(); // 初始化系统变量
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 = 0x15; // TX0、SPI_SCK和SPI_MOSI作为推挽方式
P1MDOUT = 0x01; // TX1作为推挽方式
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -