📄 main.#3
字号:
{
nRes *= gnLeakAreaCoef[i]; // 乘以系数(因触摸屏上的扩大了100倍)
nRes /= 100;
EA = FALSE;
gnLeakGet = nRes; // 返回流量值
EA = TRUE;
break;
}
}
}
}
else // 同步字节还未接收完毕,继续检测
{
if (SBUF0 == 0x7F) // 如果是同步字节,则设置相应的同步字节接收到标志
{
if (gbSyncOneOK0)
gbSyncTwoOK0 = TRUE;
else
gbSyncOneOK0 = TRUE;
}
else // 接收到的字节既非同步字节又非正常的测量数据,舍弃重来。
SetRxd0OK(); // 重新初始化同步字节检测标志和串口接收缓冲区索引
}
}
else
TI0 = FALSE; // 清除发送中断标志,允许下次接收数据
}
/********************************************************************************************************
** 函数名称: TIMER2_ISR
** 功能描述: TIMER2定时中断服务程序(2ms定时)。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void TIMER2_ISR(void) interrupt INT_TIMER2
{
INT8U i;
TF2 = FALSE;
if (gnScanID < 6) // 以下代码均为(2007.03.25)
{
KEY1 = LEVEL_HIGH; // 准备检测按键(KEY1或KEY2为低电平表示有键按下)
KEY2 = LEVEL_HIGH;
DoneDisplay(); // 显示当前扫描到的LED数码管及指示灯
//ReadKey(); // 读取按键
gnScanID++; // 准备扫描下一个按键和LED
}
else
{
gnScanID = 0; // 准备从头开始扫描
if (!gbBufUsed)
{
for (i=0;i<5;i++)
{
gnDisBuf[0][i] = gnSegBuf[0][i];
gnDisBuf[1][i] = gnSegBuf[1][i];
}
}
}
gnCnt2ms++;
if (gnCnt2ms >= 50) // 定时100ms
{
gbTimeOver = TRUE;
gnCnt10ms = 0;
}
}
void SMBUS_ISR (void) interrupt INT_I2C // 中断服务程序
{
switch (SMB0STA) // 根据中断状态码跳转,SMB0STA 是中断状态寄存器
{
case SMB_START: // 0x08, (MT & MR) 发送起始位
SMB0DAT = SLAW ; // 装入被访问的从芯片的写地址
STA = 0; // 人工清除 STA 位
SI = 0; // 清除中断标志位
break;
case SMB_RP_START: // 0x10,(MT & MR) 重复发送起始位
SMB0DAT = SLAR; // 装入被访问的从芯片的读地址
STA = 0; // 人工清除 STA 位
SI = 0; // 清除中断标志位
break;
case SMB_MTADDACK: // 0x18 ,(MT) 发送从地址 + W 后收到ACK
SMB0DAT = gnEEAddr;
SI = 0; // 清除中断标志位
break;
case SMB_MTADDNACK: // 0x20,(MT) 发送从地址 + W 后收到NACK
STO = 1;
STA = 1;
SI = 0; // 清除中断标志位
break;
case SMB_MTDBACK: // 0x28,(MT) 发送数据后收到ACK
switch (nSendMode) // 检查低1位
{
case 1:
nSendNums--;
if (nSendNums)
SMB0DAT = gnEEData;
else
{
STO = 1;
SM_BUSY = 0;
}
break;
case 0:
STO = 0;
STA = 1;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
SI = 0;
break;
case SMB_MTDBNACK: // 0x30
STO = 1;
STA = 1;
SI = 0; // 清除中断标志
break;
case SMB_MRADDACK: // 0x40
AA = 0;
SI = 0;
break;
case SMB_MRADDNACK: // 0x48
STO = 0;
STA = 1;
SI = 0;
break;
case SMB_MRDBNACK: // 0x58
gnEEData = SMB0DAT;
STO = 1;
SM_BUSY = 0;
AA = 1;
SI = 0;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: ADC0_ISR
** 功能描述: ADC0转换结束中断服务程序。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:略
** 调用模块: 略
** 其它说明:ADC0转换结果与工程量(气体压力)之间的转换原理如下:
** 由于电气比例阀ITV2000的信号输出与压力之间的对应关系为:1-5V对应于0-0.5MPa,假设1-5V信号经
** 2.5倍分压后(即0.4-2V)进入单片机,其对应的ADC0数字量(即mADC0Res变量的值)为:
** 0.4V===0.4*4096/VREF0,2V===2*4096/VREF0,
** 其中,4096为ADC0的转换位数(12位),VREF0为ADC0的参考电压(典型值为2.43V)。
** 将压力信号扩大10000倍,则0-0.5MPa对应数字0-5000(单位为0.1KPa)。为了便于计算,这里采用直线
** 方程来得到压力与电压数字量之间的关系:
** P1 = 0 = COEF0*0.4*4096/VREF0 + COEF1
** P2 = 5000 = COEF0*2*4096/VREF0 + COEF1
** 因VREF0可以测得,因此可以解上述方程组。为便于进行整数运算,将VREF0扩大1000倍,则上述方程组可
** 表述为:
** P1 = 0 = COEF0*400*4096/VREF0 + COEF1
** P2 = 5000 = COEF0*2000*4096/VREF0 + COEF1
** 解方程组得系数COEF0和COEF1分别为:
** COEF0 = VREF0*25/32768
** COEF1 = -1250
** 故压力方程为:
** P = D*VREF0*25/32768 - 1250
** 式中,P为待测压力,单位为0.1KPa,D为ADC0测得的对于输入电压的数字量。如果P<0,则应将其置0。
**
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ADC0_ISR(void) interrupt INT_ADC0
{
static INT8U nADC0Cnt=ADC0_SAMPLE_NUMS; // ADC0采样次数计数器定义及初始化
INT32U nPress;
AD0INT = FALSE; // 清除ADC0转换结束标志
gnADC0Res += ADC0; // 累加ADC0转换结果并取平均
gnADC0Res /= 2;
nADC0Cnt--; // ADC0连续转换ADC0_SAMPLE_NUMS次,完成后暂停转换(不响应中断)
if (nADC0Cnt == 0) // 同时将结果转换为工程量值(气体压力)
{
nADC0Cnt = ADC0_SAMPLE_NUMS;
AD0EN = FALSE;
nPress = gnADC0Res; // 转换为32位无符号数
nPress = nPress*VREF0*25/32768; // 进行工程量转换,如果值小于0,则认为是0
EA = FALSE;
if (nPress <= 1250)
gnPressGet = 0;
else
gnPressGet = nPress - 1250;
EA = TRUE;
}
}
/********************************************************************************************************
** 函数名称: UART1_ISR
** 功能描述: 串行口UART1中断服务程序。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块:无
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART1_ISR(void) interrupt INT_UART1
{
if (SCON1&0x01) // 数据接收中断
{
SCON1 &= ~0x01; // 清除数据接收中断标志
if (gbSyncTwoOK1) // 检查同步字节是否接收完毕
{
if (SBUF1 == 0xFF) // 同步字节已接收完毕,但仍接收到了0xFF,说明出现了最糟糕
return; // 的情况,即有3个0xFF,因此需将该字节舍弃。
gnRxdBuf1[gnRxdID1++] = SBUF1;
if (gnRxdID1 >= 2) // 检查命令字节是否接收完毕,接收完则根据命令决定要接收的数据个数
{
switch (gnRxdBuf1[1])
{
case 0x01: // 发送测量数据及开关状态至触摸屏命令(0xFF,0xFF,0x00,0x01,共4个字节)
SetRxd1OK(); // 重新初始化同步字节检测标志及串口接收缓冲区索引
gnTxdBuf1[0] = 0xFF;
gnTxdBuf1[1] = 0xFF;
gnTxdBuf1[2] = 0x01; // 准备发送命令的低8位字节
gnTxdBuf1[3] = 0x00; // 准备发送命令的高8位字节
gnTxdBuf1[4] = gnPressGet % 256;// 准备发送测试压力的低8位字节
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -