📄 main.c
字号:
** 式中,P为待测压力,单位为0.1KPa,D为ADC0测得的对于输入电压的数字量。如果P<0,则应将其置0。
**
** 设 计 者:罗 建 日 期:2008年02月03日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ADC0_ISR(void) interrupt INT_ADC0
{
AD0INT = FALSE; // 清除ADC0转换结束标志
gnADC0Res += ADC0; // 累加ADC0转换结果
gnCntADC0++; // ADC0连续转换ADC0_SAMPLE_NUMS次,完成后暂停转换(不响应中断)
if (gnCntADC0 == ADC0_SAMPLE_NUMS) // 通知主程序ADC0_SAMPLE_NUMS次ADC0转换已结束,可以进行数据处理
{
gnCntADC0 = 0;
AD0EN = FALSE;
gbADC0OK = TRUE;
}
}
/********************************************************************************************************
** 函数名称: UART1_ISR
** 功能描述: 串行口UART1中断服务程序。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块:无
** 其它说明:1、上位机通讯协议
** 1)波特率:19200bps;
** 2)数据位:8位;
** 3)停止位:1位;
** 4)奇偶校验:none;
** 5)协 议:none;
** 6)数据格式:从上位机接收或发送到上位机的数值均采用16进制数表示,一帧数据的长度及其格式由命令
** 决定。
** 上位机发送给仪表或仪表发送给上位机的每帧数据组成如下:
** (帧头)(命令)[参数地址索引] [参数值/测量值](校验核)
** a)帧头:由两个连续的0xFF组成,标识一帧数据的开始;
** b)命令:由一个字节组成,本版软件共实现三个命令,即0xF0(读测量值),0xF1(读参数值),
** 0xF2(修改参数值);
** c)参数分组号:由一个字节组成,仅读参数值命令和修改参数值命令有效,标识要读取或修改的参数
** 值所在的分组号,取值范围为:0~9;
** d)参数索引:由一个字节组成,仅读参数值命令和修改参数值命令有效,标识要读取或修改的参数的
** 索引,其值对应于TParamIndex类型,取值范围为:0~8;
** e)参数值:由两个字节组成,先发高字节,后发低字节,仅读参数值命令和修改参数值命令有效;
** 测量值:由五个字节组成,第1、2字节代表测试压力值,第3、4字节代表测试流量值,先发高字节,
** 后发低字节,第5个字节代表仪表状态(见下),仅读测量值命令有效;
** 仪表状态(一个字节):D7 D6 D5 D4 D3 D2 D1 D0
** 保留 保留 保留 保留 流量状态 压力状态 工作状态
** 流量状态(D3)定义: 0--流量正常(PASS);
** 1--流量过大或过小(FAIL)。
** 压力状态(D2)定义: 0--压力正常;
** 1--压力过高或过低(WARN)。
** 工作状态(D1D0)定义:00--空闲状态;
** 01--参数设置状态;
** 10--充气状态;
** 11--测试状态。
** f)校验核:由一个字节表示,其值为不包含帧头在内的所有字节的异或值。
** 设 计 者:罗 建 日 期:2008年02月02日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART1_ISR(void) interrupt INT_UART1
{
UINT8 i,nCrc;
if (SCON1&0x01) // 数据接收中断
{
SCON1 &= ~0x01; // 清除数据接收中断标志
if (!gbTxdOK1) // 上一次命令还没有处理完,放弃当前帧数据
return;
if (gbSyncTwoOK1) // 检查同步字节是否接收完毕
{
if (SBUF1 == 0xFF) // 同步字节已接收完毕,但仍接收到了0xFF,说明出现了最糟糕
return; // 的情况,即有3个0xFF,因此需将该字节舍弃。
gnRxdBuf1[gnRxdID1++] = SBUF1;
switch (gnRxdBuf1[0])
{
case CMD_GET_VALUE: // 读测量值命令
if (gnRxdID1 < 2) // 上位机发送的读测量数据帧共包含4个字节(0xFF,0xFF,0xF0,CRC)
return; // 仪表发送数据帧共包含7个字节(0xFF,0xFF,0xF0,DATAH,DATAL,STATE,CRC)
if (gnRxdBuf1[1] != gnRxdBuf1[0]) // 计算上位机发送的校验核是否正确,不正确则不响应
return;
else
break;
case CMD_GET_PARAM: // 读参数值命令
if (gnRxdID1 < 4) // 上位机发送的读参数值数据帧共包含6个字节(0xFF,0xFF,0xF1,GROUP_ID,PARAM_ID,CRC)
return;
nCrc = gnRxdBuf1[1]^gnRxdBuf1[0]; // 计算上位机发送的校验核是否正确,不正确则不响应
nCrc = nCrc ^ gnRxdBuf1[2];
if (gnRxdBuf1[3] != nCrc)
return;
else
break;
case CMD_SET_PARAM: // 修改参数值命令
if (gnRxdID1 < 6) // 上位机发送的修改参数值数据帧共包含8个字节(0xFF,0xFF,0xF2,GROUP_ID,PARAM_ID,DATAH,DATAL,CRC)
return;
nCrc = gnRxdBuf1[0]; // 计算上位机发送的校验核是否正确,不正确则不响应
for (i=1;i<5;i++)
nCrc = nCrc ^ gnRxdBuf1[i];
if (gnRxdBuf1[5] != nCrc)
return;
else
break;
}
SetRxd1OK(); // 重新初始化同步字节检测标志及串口接收缓冲区索引
gbRxdOK1 = TRUE; // 通知主程序UART1有接收到数据,可以进行处理了
gbTxdOK1 = FALSE;
}
else // 同步字节还未接收完毕,继续检测
{
if (SBUF1 == 0xFF) // 如果是同步字节,则设置相应的同步字节接收到标志
{
if (gbSyncOneOK1)
gbSyncTwoOK1 = TRUE;
else
gbSyncOneOK1 = TRUE;
}
else // 接收到的字节既非同步字节又非正常的测量数据,舍弃重来。
SetRxd1OK(); // 重新初始化同步字节检测标志及串口接收缓冲区索引
}
}
else // 数据发送中断
{
SCON1 &= ~0x02; // 清除数据发送中断标志
gnTxdID1++; // 准备发送下一个数据
if (gnTxdID1 < gnTxdNums1) // 发送缓冲区中的gnTxdNums1个数据
SBUF1 = gnTxdBuf1[gnTxdID1];
else // 数据全部发送完毕,可以继续接收上位机发送的命令
gbTxdOK1 = TRUE;
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: DeviceInit
** 功能描述: 片上系统外围设备初始化子程序。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:略
** 调用模块:略
** 其它说明:外部系统时钟启动过程建议为:
** 1)允许外部振荡器;
** 2)等待至少1ms;
** 3)查询XTLVLD是否由“0”=>“1”;
** 4)将系统时钟切换到外部振荡器。
**
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DeviceInit(void)
{
UINT16 i; // 延时计数器
// 系统时钟初始化
OSCXCN = 0x67; // 启动外部22.1184MHz晶体振荡器
for (i=0;i<3000;i++); // 等待XTLVLD消隐期(>1ms)
while ((OSCXCN & 0x80) == 0); // 等待外部晶振稳定
OSCICN = 0x08; // 选择外部振荡器作为系统时钟SYSCLK,同时禁止时钟丢失检测功能
// 数字量输入输出端口初始化
P0MDOUT = 0x11; // TX0、TX1作为推挽方式
P1MDOUT = 0x00; // (默认为漏极开路方式)
P2MDOUT = 0x00; // (默认为漏极开路方式)
XBR0 = XBR0_UART0EN + XBR0_SMB0EN; // 允许UART0、SMBus
XBR1 = XBR1_NONE; // 不允许任何外部设备
XBR2 = XBR2_XBARE + XBR2_UART1E; // 允许交叉开关、弱上位(默认)和UART1
// ADC和DAC(取默认值)转换初始化
AMX0CF = 0x00; // 配置AIN00-AIN07均为单端输入方式(默认)
AMX0SL = 0x00; // 选择AIN00通道进行AD转换(默认)
ADC0CF = 0x50; // ADC0转换时钟为2MHz,PGA增益为1
ADC0CN = 0x84; // 允许ADC0,正常跟踪模式,Timer3溢出启动ADC0转换,ADC0数据右对齐
DAC0 = 0x0000; // 默认DAC0输出为0
DAC0CN = 0x80; // 允许DAC0输出,写DAC0H时DAC0更新输出,DAC0H3-0保存高4位,DAC0L7-0保存低8位(默认)
// ADC和DAC参考电压初始化
REF0CN = 0x03; // ADC0电压基准取至VREF0,禁止温度传感器,内部偏压发生器和基准电压缓冲器打开
// 串口UART0和UART1初始化
SCON0 = 0x50; // UART0(接流量计)为8位可变波特率模式,允许接收
SCON1 = 0x50; // UART1(接计算机)为8位可变波特率模式,允许接收
// SMBus初始化
SMB0CN = 0x44; // 允许SMBUS, 应答返回AA(低电平)
SMB0CR = 0xE7; // SMBus速率设置,系统时钟为22.1184MHZ,100kHz=0x94,400kHz=0xE7
// 定时器初始化
CKCON = 0x30; // TIMER1、TIMER2时钟源为SYSCLK,TIMER4、TIMER0时钟源为SYSCLK/12
TMOD = 0x21; // TIMER1为8位自动重装载模式,TIMER0为16位定时器方式
TH1 = 0xDC; // TIMER1作为UART0和UART1的波特率发生器,波特率均为19200bps
TCON = 0x40; // 允许TIMER1定时
RCAP2H = 0x53; // TIMER2自动重装载值(定时2ms,初值=65536-22118400*0.002=21299=0x5333)
RCAP2L = 0x33;
TH2 = 0x53; // TIMER2计数寄存器初值(定时2ms)
TL2 = 0x33;
T2CON = 0x04; // TIMER2作为2ms定时器,16位自动重装载模式,允许定时
TMR3RLL = 0x9A; // TIMER3自动重装载值(定时1ms)
TMR3RLH = 0xA9;
TMR3L = 0x9A; // TIMER3计数寄存器初值(定时1ms)
TMR3H = 0xA9;
TMR3CN = 0x06; // TIMER3作为1ms定时器,控制ADC,使用SYSCLK,允许定时
// 中断初始化
EIE1 = 0x02; // 允许SMBus中断
EIE2 = 0x42; // 允许UART1和ADC0中断
IE = 0xB0; // 允许TIMER2、UART0中断,开总中断
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: SysInit
** 功能描述: ADC0转换结束中断服务程序。
** 输 入: 无
** 输 出: 无
** 全局变量: 略
** 全局常量:略
** 调用模块:略
** 设 计 者:罗建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SysInit(void)
{
UINT8 i;
UINT8 nReadBuf[4];
LoadGroup(); // 从EEPROM中载入全部参数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -