📄 main14.c
字号:
** B = ~(A-1)
**
** 2、工程量(流量)转换问题
** 对于A50_V型,流量系数为128。为了不使用浮点数进行计算,且又希望保留2位小数精度,因此可采用将
** 串口接收值先乘以100,再除以128(用右移7位实现)的方法来实现。这样,如果接收到的数值为十进制
** 的+1234,则在流量模式中利用上述方法计算的流量值为9.64Ln/min,所得的测量精度为±0.01Ln/min,
** 可以满足使用要求。
**
** 3、显示与储存冲突防治
** 由于串口接收数据是随机的,且数据有多字节(至少为2字节),在显示过程中,如果主程序刚访问了第1
** 个字节,这时发生了串口中断,并且更新了要显示的数据,当串口中断返回时,主程序继续显示第2个字
** 节,这时显示结果将可能是不正确的。
** 为防止上述冲突现象的发生,可采用Win32 API中的“临界区”思想来实现,即在主程序中读取数据前,
** 先关闭串口中断允许标志ES,在读取完数据后再打开串口中断允许标志ES的方法。
**
** 设 计 者:罗建 日 期:2007年12月09日
** 修 改 者:罗建 日 期:2007年03月23日
** 修 改 者:罗建 日 期:2007年12月09日
** 历史版本:V1.00,原始版本
** V1.01,修改了流量计算方式
** 版 本:V1.02,适应C8051F020单片机的串口UART1
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART1_ISR(void) interrupt INT_UART1
{
//INT8U i;
INT32U nRes;
if (SCON1&0x01)
{
SCON1 &= ~0x01; // 清除接收中断标志,允许下次接收数据
if (gbSyncTwoOK1) // 检查同步字节是否接收完毕
{
if (SBUF1 == 0x7F) // 同步字节已接收完毕,但仍接收到了0x7F,说明出现了最糟糕
return; // 的情况,即有3个0x7F,因此需将该字节舍弃。
gnRxdBuf1[gnRxdID1++] = SBUF1;
if (gnRxdID1 == 2) // 检查字节是否接收完毕,接收完则为下次接收做好准备
{
SetRxd1OK(); // 重新初始化同步字节检测标志和串口接收缓冲区索引
if (gbStarted && gbTestOver) // 当测试进程结束,且用户尚未按下停止键时,不更新流量显示值
return;
nRes = gnRxdBuf1[0]; // 先计算测量值
nRes = nRes*256 + gnRxdBuf1[1];
if (gnRxdBuf1[0] & 0x80) // 如果测量值为负,则乘以-1转换为正数
nRes = 0;
//for (i=0;i<1;i++) // 对流量值采取分段线性修正,如果流量值不在设定的流量范围,
//{ // 则保持上一次采集计算的值不变,这样可防止强脉冲干扰
/*if (nRes < gnLeakAreaMax[i])*/
/*{*/
//nRes *= gnLeakAreaCoef[i] ;
//nRes /= 128;
EA=0;
gnLeakGet = nRes;
EA =1;
// break;
/*}*/
//}
}
}
else // 同步字节还未接收完毕,继续检测
{
if (SBUF1 == 0x7F) // 如果是同步字节,则设置相应的同步字节接收到标志
{
if (gbSyncOneOK1)
gbSyncTwoOK1 = TRUE;
else
gbSyncOneOK1 = TRUE;
}
else // 接收到的字节既非同步字节又非正常的测量数据,舍弃重来。
SetRxd1OK(); // 重新初始化同步字节检测标志和串口接收缓冲区索引
}
}
else
SCON1 &= ~0x02; // 清除发送中断标志,允许下次接收数据
}
/********************************************************************************************************
** 函数名称: TIMER2_ISR
** 功能描述: TIMER2定时中断服务程序。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TIMER2_ISR(void) interrupt INT_TIMER2
{
TF2 = FALSE;
gnCnt10ms++;
if (gnCnt10ms >= 10) // 定时100ms
{
gbTimeOver = TRUE;
gnCnt10ms = 0;
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: SetRxd0OK和SetRxd1OK
** 功能描述: UART0或UART1数据接收完毕,重新初始化同步字节检测标志及接收缓冲区索引。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SetRxd0OK(void)
{
gbSyncOneOK0 = FALSE;
gbSyncTwoOK0 = FALSE;
gnRxdID0 = 0;
}
void SetRxd1OK(void)
{
gbSyncOneOK1 = FALSE;
gbSyncTwoOK1 = FALSE;
gnRxdID1 = 0;
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: AdjustPress
** 功能描述: 判断当前测试压力值是否超过设定范围,是则调节。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void AdjustPress(void)
{
INT16 nErr;
// 仅当进入测试画面后才进行压力调节
if (gnCntAdjust-- != 0)
return;
gnCntAdjust = ADJUST_WAIT;
// 调节比例阀的输出,使其等于用户设定值
nErr = gnPressSet - gnPressGet; // 计算设定值与实测值之间的差值
if ((nErr > -20) && (nErr < 20));
return;
gnPressOut = gnPressOut + nErr;
DAC0L = gnPressOut % 256; // 最后将输出值通过DAC0输出给压力调节阀
DAC0H = gnPressOut / 256;
/*DAC0 = 0x0FFF;*/
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DoneKey
** 功能描述: 检测哪个键有按下,如有键按下则进行相应的处理。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DoneKey(void)
{
if (!gbCanGetKey) // 检测用户按键情况
{
if (gnCntGetKey-- == 0) // 实现按键检测延时
gbCanGetKey = TRUE;
}
else // 可以检测按键
{
if (!KEY_START) // 启动键按下
{
if (!gbStarted) // 仅在启动按键尚未按下时才响应启动键操作
{
gnCurrTime= gnFillTime; // 准备充气时间
DRV_PASS = CLOSE; // 先将PASS和FAIL指示灯关闭
DRV_FAIL = CLOSE;
DRV_VALVE = OPEN; // 打开控制阀
gbTestOver= FALSE; // 假定测试状态未结束
gbStarted = TRUE; // 进入启动测试状态
gbFilling = TRUE; // 进入充气时间倒计数状态
}
}
else if (!KEY_STOP) // 停止键按下
{
DRV_VALVE = CLOSE; // 关闭电磁阀
gbFilling = FALSE; // 退出充气时间倒计数状态
gbTesting = FALSE; // 退出测试时间倒计数状态
gbStarted = FALSE; // 退出启动测试状态
gbTestOver= FALSE; // 已经退出测试状态
DRV_PASS = CLOSE; // 关闭PASS和FAIL指示灯
DRV_FAIL = CLOSE;
}
gnCntGetKey = KEY_WAIT; // 准备进行按键检测延时
gbCanGetKey = FALSE; // 暂停下一次键检测
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DoneTest
** 功能描述: 执行充气和测试操作。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DoneTest(void)
{
if (gbFilling) // 如果正在执行充气操作,则对充气时间进行递减
{
if (--gnCurrTime == 0) // 如果充气时间减为全0,则进入测试状态
{
gbFilling = FALSE;
gbTesting = TRUE;
gnCurrTime = gnTestTime; // 准备测试时间
}
}
else if (gbTesting) // 如果正在执行测试操作,则对测试时间进行递减
{
if (--gnCurrTime == 0) // 如果测试时间减为全0,则测试结束,关闭电磁阀并保持当前显示状态不变
{
gbTesting = FALSE;
gbTestOver= TRUE; // 指示检测已完成
DRV_VALVE = CLOSE; // 关闭电磁阀
if ((gnLeakGet > gnLeakMax) || (gnLeakGet < gnLeakMin))
{ // 测试结束后,如果气体流量超过了设定的流量范围,则FAIL灯亮,否则PASS灯亮
DRV_FAIL = OPEN;
DRV_PASS = CLOSE;
}
else
{
DRV_PASS = OPEN;
DRV_FAIL = CLOSE;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -