📄 serialcom.c
字号:
/*========================================================/
/ /
/ Copyright (C), 2001-2005, Pangu Automation. Co., Ltd. /
/ FileName: SerialComm /
/ Author: Zheng M.D. /
/ Version: 1.0 /
/ Date: 2005.11.25 /
/ Description: pH计通信程序 /
/ Modify: /
/ /
/========================================================*/
#include <reg52.h>
#include "include\DataProces.h"
#include "include\serialcom.h"
#include "include\X5045.h"
#include "include\CS5529.h"
#include "include\time.h"
//extern uchar ChannelSType[3];
extern CALIPARAM idata pHCaliParam;
extern TRANSMISSION idata TransData;
extern short idata ChannelADCode[5][4];
//------------内部变量-----------------
unsigned char idata cCommBuffer[COMM_MAX];
unsigned char idata cUartLen;
bit bFlagWriteConfig;
bit bFlagDataConfig;
bit bCaling;
bit bDoubleCali;
bit bCalied;
short spH7AD;
short spH4AD;
/*************************************************
//函 数 名: cal_crc()
//功 能: CRC-16校验
//输入参数: *ptr(数据头指针),len(校验数据长度)
//返 回 值: crc(校验结果)
*************************************************/
static unsigned short cal_crc(unsigned char *ptr, unsigned char len)
{
unsigned char i, j, sdata, tmp;
unsigned short crc;
crc = 0xFFFF;
if(len == 0)
return crc;
for(i = 0; i < len; i++)
{
sdata = *(ptr + i);
for(j = 0; j < 8; j++)
{
tmp = crc % 2 + sdata % 2;
crc = crc / 2;
sdata = sdata / 2;
if(tmp == 1)
crc = crc^0xA001;
}
}
return crc;
}
/*************************************************
//函 数 名: UartReceive()
//功 能: 通讯接收
//输入参数: 无
//返 回 值: 0(接收失败),1(接收成功)
*************************************************/
static bit UartReceive(void)
{
unsigned char i;
RI = 0;
cCommBuffer[0] = SBUF;
//地址错误
if(cCommBuffer[0] != ADDRESS)
{
cUartLen = 0;
return 0;
}
//初始长度
cUartLen = 1;
//接收数据,
for(i = 0; i <= 100; i++)
{
//接收到的数据长度必须小于缓冲区长度
if(RI & cUartLen < COMM_MAX)
{
RI = 0;
i = 0;
cCommBuffer[cUartLen] = SBUF;
cUartLen ++;
}
//通讯等待延时
delay_us(2);
}
//判断接收数据长度
if(cUartLen > 5)
return 1;
else
return 0;
}
/*************************************************
//函 数 名: UartTransmit()
//功 能: 通讯发送
//输入参数: 无
//返 回 值: 0(发送失败),1(发送成功)
*************************************************/
static bit UartTransmit(void)
{
char i = 0;
TI = 0;
//停止接收数据
REN = 0;
//发送长度不对
if(cUartLen < 5)
return 0;
//发送首字节
SBUF = cCommBuffer[0];
i ++;
cUartLen --;
//发送到字节完成
while(cUartLen != 0)
{
//等待一个字节发送完成
while(TI)
{
TI = 0;
SBUF = cCommBuffer[i];
i++;
cUartLen --;
}
//通讯等待延时
delay_us(3);
}
return 1;
}
/*************************************************
//函 数 名: Do03Command()
//功 能: 执行03命令,从仪表寄存器读连续数据
//输入参数: 无
//返 回 值: 0(错误),1(成功)
*************************************************/
static bit Do03Command(void)
{
unsigned char pos, len, i;
unsigned short crc;
//数据偏移量
pos = cCommBuffer[3];
//数据长度
len = cCommBuffer[5];
//读取数据超出范围
if(len > 30)
{
cCommBuffer[0] = ADDRESS;
cCommBuffer[1] = 0x83; //出错码
cCommBuffer[2] = 0x02; //非法的寄存器
//CRC校验计算
crc = cal_crc(&cCommBuffer, 3);
cCommBuffer[3] = (unsigned char)(crc / 256);
cCommBuffer[4] = (unsigned char)(crc % 256);
//发送总字节数
cUartLen = 5;
return 0;
}
else
{
cCommBuffer[0] = ADDRESS; //地址
cCommBuffer[1] = 0x03; //命令
cCommBuffer[2] = len; //数据长度
//三个通道实时的百分量
if(pos == 0x32)
{
for(i = 0; i < 3; i++)
{
cCommBuffer[3 + 2 * i] = *(&TransData.pHPercent +i ) &0xff;
cCommBuffer[4 + 2 * i] = *(&TransData.pHPercent +i ) >> 8;
}
for(i = 0; i < len - 6; i ++)
{
cCommBuffer[i + 9] = 0;
}
//__RUN = ~__RUN;
}
//标定的码值
if((pos >= 0x42) && (pos < 0x80))
{
for(i = 0; i < len; i++)
{
cCommBuffer[3 + i] =*((unsigned char*)&pHCaliParam+pos - 0x42 + i);
}
}
//AD原码
if(pos >= 0x80)
{
for(i = 0; i < len; i++)
{
cCommBuffer[3 + i] = *((unsigned char*)ChannelADCode + pos - 0x80 + i );
}
//__RUN = ~__RUN;
}
//__RUN = ~__RUN;
//CRC校验计算
crc = cal_crc(&cCommBuffer, len + 3);
cCommBuffer[len + 3] = (unsigned char)(crc / 256);
cCommBuffer[len + 4] = (unsigned char)(crc % 256);
//FlashLed(2);
//发送总字节数
cUartLen = 3 + len + 2;
return 1;
}
}
/*************************************************
//函 数 名: Do10Command()
//功 能: 执行10命令,写连续数据到AD板存器
//输入参数: 无
//返 回 值: 0(错误),1(成功)
*************************************************/
static bit Do10Command(void)
{
unsigned char pos, len, i;
unsigned short crc;
unsigned char* ptr = (unsigned char*) &pHCaliParam;
//数据偏移量
pos = cCommBuffer[3];
//数据长度
len = cCommBuffer[6];
//上位机写标定码值
if((pos >= 0x42) && (pos < (0x42+sizeof(CALIPARAM))) && (len <= sizeof(CALIPARAM)))
{
//写入数据
for(i = 0; i < len; i ++)
{
*(ptr + i +pos - 0x42) = cCommBuffer[i + 7];
}
bFlagWriteConfig = 1;
}
//非法写入
else{
return 0;
}
//CRC校验计算
crc = cal_crc(&cCommBuffer, 6);
cCommBuffer[6] = (unsigned char)(crc / 256);
cCommBuffer[7] = (unsigned char)(crc % 256);
//发送总字节数
cUartLen = 8;
return 1;
}
/*************************************************
//函 数 名: Do20Command()
//功 能: 执行20命令,标定操作
//输入参数: 无
//返 回 值: 0(错误),1(成功)
************************************************
static bit Do20Command(void)
{
unsigned char cmd;
//float ftemp,ftemp2,ftemp3,ftemp4;
//short temp;
cmd=cCommBuffer[7];
switch(cmd)
{
case 0x10: //读电压值,标定开始后传送给主机mV信号
bCaling=1;
break;
case 0x11: //下传pH=7.00标准溶液在特定温度的pH值
spH7AD=ChannelADCode[0][0];
bDoubleCali=0;
bCalied=1;
break;
case 0x12: //读电压值,标定开始后传送给主机mV信号
bCaling=1;
break;
case 0x13: //下传pH=4.01标准溶液在特定温度的pH值
bDoubleCali=1;
spH4AD=ChannelADCode[0][0];
bCalied=1;
break;
case 0x08: //恢复出厂标定
if(pHCaliParam.Mode==MODE_ORP)
{
pHCaliParam.OrpOnlineUpper=pHCaliParam.OrpUpper;
pHCaliParam.OrpOnlineLower=pHCaliParam.OrpLower;
}
else
{
pHCaliParam.pHOnlineUpper=pHCaliParam.pHUpper;
pHCaliParam.pHOnlineLower=pHCaliParam.pHLower;
}
bFlagWriteConfig=1;
break;
case 0x00:
//结束标定
DoCali(); //计算标定结果
break;
}
__RUN = ~__RUN;
cUartLen=10;
return 1;
}*/
/*************************************************
//函 数 名: Do66Command()
//功 能: 执行66命令,标定命令
//输入参数: 无
//返 回 值: 0(错误),1(成功)
************************************************
static bit Do66Command(void)
{
unsigned char pos, len, i;
unsigned char* ptr;
unsigned short crc;
//数据首地址
ptr = (unsigned char*) &pHCaliParam;
//数据偏移量
pos = cCommBuffer[3];
//数据长度
len = cCommBuffer[6];
//读取数据超出范围
if((pos + len) > sizeof(CALIPARAM))
{
cCommBuffer[0] = ADDRESS;
cCommBuffer[1] = 0x83; //出错码
cCommBuffer[2] = 0x02; //非法的寄存器
//CRC校验计算
crc = cal_crc(&cCommBuffer, 3);
cCommBuffer[3] = (char)(crc / 256);
cCommBuffer[4] = (char)(crc % 256);
//发送总字节数
cUartLen = 5;
return 0;
}
else
{
//写入数据
for(i = 0; i < len; i ++)
{
*(ptr + pos + i) = cCommBuffer[i + 7];
}
//CRC校验计算
crc = cal_crc(&cCommBuffer, 6);
cCommBuffer[6] = (char)(crc / 256);
cCommBuffer[7] = (char)(crc % 256);
//发送总字节数
cUartLen = 8;
return 1;
}
}*/
/*************************************************
//函 数 名: InitUart0()
//功 能: 串口0初始化程序
//输入参数: 无
//返 回 值: 无
*************************************************/
static bit AnalyseData(void)
{
unsigned short crc;
//step 1 CRC校验检查
crc = 0x0100 * cCommBuffer[cUartLen - 2] + cCommBuffer[cUartLen - 1];
if(crc != cal_crc(cCommBuffer, cUartLen - 2))
{
return 0;
}
//step 2 Do Command
if(cCommBuffer[1] == 0x03) //从仪表寄存器读连续数据
{
if(Do03Command())
{
return 1;
}
}
else if(cCommBuffer[1] == 0x10) //写连续数据到仪表寄存器,并保存组态参数
{
if(Do10Command())
{
//保存组态参数标志,在主循环中完成
return 1;
}
}
else
return 0;
}
/*************************************************
//函 数 名: ResetReceive()
//功 能: 接收初始化程序
//输入参数: 无
//返 回 值: 无
*************************************************/
static void ResetReceive(void)
{
TI = 0;
RI = 0;
REN = 1;
}
/*************************************************
//函 数 名: InitUart0()
//功 能: 串口0初始化程序
//输入参数: 无
//返 回 值: 无
*************************************************/
void InitUart0(void)
{
SCON = 0x90; //MODE 2,固定波特率=Fosc/64,地址无效,允许接收
PCON = 0x00; // /64 PCON=0x80 /32
ES = 1; //通讯中断允许
}
/*************************************************
//函 数 名: uart0()
//功 能: 串口0通讯程序
//输入参数: 无
//返 回 值: 无
*************************************************/
void uart0(void) interrupt INTERRUPT_UART_0
{
//接收数据
if(!UartReceive())
{
//接收复位
ResetReceive();
return;
}
//进行数据处理和命令执行
if(!AnalyseData())
return;
//发送数据
UartTransmit();
//接收复位
ResetReceive();
return;
}
/*************************************************
//函 数 名: SaveCaliParam
//功 能: 保存标定参数
//输入参数: 无
//返 回 值: 无
*************************************************/
void SaveCaliParam(void)
{
if(bFlagWriteConfig)//如果写标定位为1则保存标定值
{
bFlagWriteConfig = 0;
PutCaliParam(); //存标定参数
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -