📄 zhu1126_96.c
字号:
//修改为各自的函数
//2003.7.24,9:56
//模拟数据上传,上层通信良好;下层通信没做
//修改串口波特率容错没做,(办法为5分钟没收到数据就重新设置波特率),
//修改波特率等待数据发完才开锁,才进行修改
//完成与AIDI模块的通信,能实时上AIDI模块的数据2003.7.31;10:59
#include"zhu_ini.h"
#include"zhu1126.h"
void Feed_watchdog() //喂狗
{
FeedDogFlag=0;
_nop_();
FeedDogFlag=1;
}
void Delay_nop0(uchar n)//n个nop延时
{
uchar data i;
for(i=0;i<n;i++)
{
_nop_();
}
}
uchar Read_ID() //读ID号
{
return(XBYTE[0x2000]);
}
void baud_select(uchar channel_s,uchar baud_s)//波特率选择
{
uchar data baud00,setmodem;
uint data dptr00;
switch(channel_s)
{
case 1:
dptr00=0xA000;
setmodem=0x36;
break;
case 2:
dptr00=0xA001;
setmodem=0x76;
break;
case 3:
dptr00=0xA002;
setmodem=0xB6;
break;
default:return;
}
switch(baud_s)
{
case 1:
baud00=96;
break; //1200
case 2:
baud00=48;
break; //2400
case 3:
baud00=24;
break; //4800
case 4:
baud00=12;
break; //9600
case 5:
baud00=6;
break; //19200
case 6:
baud00=3;
break; //38400
default:return;
}
XBYTE[0xA003]=setmodem; //计数器方式设置
XBYTE[dptr00]=baud00; //设置波特率
XBYTE[dptr00]=0; //高八位
}
void hex2asc0(uchar * asc2char,uchar chChar)
{
uchar data hByte,lByte;
hByte=( chChar & 0xF0 )>>4;
lByte=( chChar & 0x0F );
if(hByte>=0 && hByte<10)
{
*asc2char++ = hByte + 48;
}
else if (hByte>9 && hByte<16)
{
*asc2char++ = hByte + 55;
}
if(lByte>=0 && lByte<10)
{
*asc2char++ = lByte + 48;
}
else if (lByte>9 && lByte<16)
{
*asc2char++ = lByte + 55;
}
}
void hex2asc1(uchar * asc2char,uint chInt)
{
uchar data hhByte,hlByte,lhByte,llByte;
hhByte=( chInt & 0xF000 )>>12;
hlByte=( chInt & 0x0F00 )>>8;
lhByte=( chInt & 0x00F0 )>>4;
llByte=( chInt & 0x000F );
if(hhByte>=0 && hhByte<10)
{
*asc2char++ = hhByte + 48;
}
else if (hhByte>9 && hhByte<16)
{
*asc2char++ = hhByte + 55;
}
if(hlByte>=0 && hlByte<10)
{
*asc2char++ = hlByte + 48;
}
else if (hlByte>9 && hlByte<16)
{
*asc2char++ = hlByte + 55;
}
if(lhByte>=0 && lhByte<10)
{
*asc2char++ = lhByte + 48;
}
else if (lhByte>9 && lhByte<16)
{
*asc2char++ = lhByte + 55;
}
if(llByte>=0 && llByte<10)
{
*asc2char++ = llByte + 48;
}
else if (llByte>9 && llByte<16)
{
*asc2char++ = llByte + 55;
}
}
void InterruptInt0() interrupt 0 using 1 //外部中断0
{
uchar data state,ReceByte;
bit tempFlag0,tempFlag1;
tempFlag1 = RamRom_Convert;
tempFlag0 = RamIO_Convert; //保护地址状态
RamRom_Convert=1; //128RAM
RamIO_Convert=1; //切换RAM与端口
state=XBYTE[0x4001]; //port1c;
if( state & 2 ) //接收状态
{
ReceByte = XBYTE[0x4000];
if( ReceCount1 >= MaxRece1 )
{
ReceCount1 = 0; //接收计数器循环
}
else if( ReceByte != 13 ) //'\r'=13
{
ReceSbuf1[ReceCount1++]=ReceByte;
led2Flag=0; //正在接收点亮通信灯
}
else
{
ReceSbuf1[ReceCount1++]=ReceByte;
ReceEndFlag1=1; //收到一包数据
}
}
//数据接收
else if( (state & 1) && SendingFlag1 ) //发送状态
{
NoReceFlag = 0; //没有发送标准位置一(有发送)
bNeedSend1 = 0; //启动发送标志位清零
if ( SendCount1 >= MaxSend1 ) //关闭发送,越界不发送
{
SendingFlag1 = 0; //发完一包数据
#ifdef OpenEn
SendEn&=0xFD; //模拟开关不切换
#else
for(state=0;state<100;state++)
{
_nop_();
} //关闭发送中断使能,关闭模拟开关
SendEn&=0xF9; //D5:继电器控制位,D3:发送进外部中断,D2:模拟开关,D1:发送进外部中断0
#endif
XBYTE[0xE000]=SendEn;
}
else if( SendSbuf1[SendCount1] != 10 ) //'\n'=10
{
XBYTE[0x4000]=SendSbuf1[SendCount1++];
SendingFlag1=1; //正在发送数据
led2Flag=0; //正在发送点亮通信灯
}
else //
{
SendingFlag1 = 0; //发完一包数据
#ifdef OpenEn
SendEn&=0xFD; //模拟开关不切换
#else
for(state=0;state<100;state++)
{
_nop_();
} //关闭发送中断使能,关闭模拟开关
SendEn&=0xF9; //D5:继电器控制位,D3:发送进外部中断,D2:模拟开关,D1:发送进外部中断0
#endif
XBYTE[0xE000]=SendEn;
}
}
ledled=AddLed; //更换指示灯
RamRom_Convert= tempFlag1;
RamIO_Convert = tempFlag0; //恢复地址状态
}
void InterruptInt1() interrupt 2 using 1 //外部中断1
{
uchar data state,ReceByte;
bit tempFlag0,tempFlag1;
tempFlag1 = RamRom_Convert;
tempFlag0 = RamIO_Convert; //保护地址状态
RamRom_Convert=1; //128RAM
RamIO_Convert=1; //切换RAM与端口
state=XBYTE[0x6001]; //port1c;
if(state&2) //接收状态
{
ReceByte=XBYTE[0x6000];
if( ReceCount2 >= MaxRece2 )
{
ReceCount2 = 0; //接收计数器循环
}
else if( ReceByte != 13 ) //'\r'=13
{
ReceSbuf2[ReceCount2++] = ReceByte;
led2Flag = 0; //正在接收点亮通信灯
}
else
{
ReceSbuf2[ReceCount2++]=ReceByte;
ReceEndFlag2=1; //收到一包数据
}
}
else if( state & 1 &&SendingFlag2 ) //发送状态
{
NoReceFlag = 0; //没有发送标志位置一(有发送)
bNeedSend2 = 0; //启动发送标志位清零
if ( SendCount2 >= MaxSend2 )
{
SendCount2 = 0;
SendingFlag2=0; //发完一包数据
#ifdef OpenEn
SendEn&=0xDF; //继电器不切换
#else
for(state=0;state<100;state++)
{
_nop_();
_nop_();
} //关闭发送中断使能,关闭模拟开关
SendEn&=0xD7; //D5:继电器控制位,D3:发送进外部中断,D2:模拟开关,D1:发送进外部中断0
#endif
XBYTE[0xE000]=SendEn;
}
else if( SendSbuf2[SendCount2] != 10 ) //'\n'=10
{
XBYTE[0x6000]=SendSbuf2[SendCount2++];
SendingFlag2=1; //正在发送数据
led2Flag=0; //正在发送点亮通信灯
}
else //
{
SendingFlag2=0; //发完一包数据
#ifdef OpenEn
SendEn&=0xDF; //继电器不切换
#else
for(state=0;state<100;state++)
{
_nop_();
_nop_();
} //关闭发送中断使能,关闭模拟开关
SendEn&=0xD7; //D5:继电器控制位,D3:发送进外部中断,D2:模拟开关,D1:发送进外部中断0
#endif
XBYTE[0xE000]=SendEn;
}
}
ledled=AddLed; //更换指示灯
RamRom_Convert= tempFlag1;
RamIO_Convert = tempFlag0; //恢复地址状态
}
void InterruptT1() interrupt 3 using 2 //50ms定时1中断
{
static uchar xdata ledcount0;
static uchar xdata ledcount1;
static uchar xdata ledcount2;
static uchar xdata ledcount3;
bit tempFlag0,tempFlag1;
tempFlag1 = RamRom_Convert;
tempFlag0 = RamIO_Convert; //保护地址状态
RamRom_Convert=1; //128RAM
RamIO_Convert=1;//切换RAM与端口
TL1 = 0xFA;
TH1 = 0x3C;
if( lockFlagDn ) //要求延时,枷锁
{
if( DelayCount++>=DelayNms ) //延时N个50ms
{
DelayCount=0;
lockFlagDn=0;
} //延时时间解锁
}
else DelayCount=0;
if( ReceConFlag ) //收到控制命令闪
{
if(ledcount2++>4) //控制灯闪
{
led3Flag=!led3Flag;
ledcount2=0;
}
if(ledcount3++>15) //闪灯八次
{
ledcount3=1;
ReceConFlag=0;
}
}
else ledcount2=0;
if(ledcount0++>4) //运行灯闪
{
led1Flag=!led1Flag;
ledcount0=0;
}
if(ledcount1++>1) //通信灯灭
{
led2Flag=1;
ledcount1=0;
}
if(ZhengChCount++>1105*ZhengChJianGe) //曲线历史记录定时*20*60
{
ZhengChFlag = 1; //保存正常历史记录间隔为10分钟)
ZhengChCount = 0; //,测试为1分钟(768/6/24=5.3天
}
if( NoReceFlag == 1 ) //20分钟没收发送数据,保存20*60*10=12000
{ //256/2/24=5.3天,测试为2分钟
if ( ReBaudCount++ > 1105*DuanKaiJianGe )//56次就一分钟了
{
ReBaudCount = 0;
ReBaudFlag = 1; //保存断开历史记录
}
}
else ReBaudCount=0;
if(KuaiShFlag) //测试512坏,控制灯快闪
{
led3Flag=!led3Flag;
if(led3Kuai++>150)
{
led3Kuai=0;
KuaiShFlag=0;
led3Flag=1; //闪灯后灭
}
}
if(ManShFlag) //测试512好,控制灯慢闪
{
led3Man++;
if(led3Man%10==0)
{
led3Flag=!led3Flag;
if(led3Man>150)
{
led3Man=0;
ManShFlag=0;
led3Flag=1; //闪灯后灭
}
}
}
NoReceFlag = 1; //在外部中断函数里清零,定时器中断函数置一;
//不进外部中断发送状态,不发标准位就一直为一
ledled=AddLed;
RamRom_Convert= tempFlag1;
RamIO_Convert = tempFlag0; //恢复地址状态
}
void InterruptS() interrupt 4 using 3 //串口中断
{
uchar data ReceByte; //不对端口操作,不用保护端口状态
bit tempFlag0,tempFlag1;
tempFlag1 = RamRom_Convert;
tempFlag0 = RamIO_Convert; //保护地址状态
RamRom_Convert=1; //128RAM
RamIO_Convert=1; //切换RAM与端口
if( RI ) //接收状态
{
RI=0;
ReceByte=SBUF;
if ( ReceCount0 >= MaxRece0 ) //最大接收缓冲区
{
ReceCount0 = 0;
}
else if ( ReceByte != 0x0D )
{
ReceSbuf0[ReceCount0++]=ReceByte;
}
else
{
ReceSbuf0[ReceCount0++]=ReceByte;
ReceEndFlag0=1;
}
}
else //发送状态
{
TI=0;
if ( SendCount0 >= MaxSend0 ) //发送缓冲区要越界,结束发送
{
SendCount0 = 0; //发完一包数据
TB8=1; //发送完,以便下次发送地址
}
else if ( SendSbuf0[SendCount0] != 0x0A )
{
_nop_();
SBUF=SendSbuf0[SendCount0++];
TB8=0;
}
else
{ //发完一包数据
TB8=1; //发送完,以便下次发送地址
}
}
RamRom_Convert= tempFlag1;
RamIO_Convert = tempFlag0; //恢复地址状态
}
void Analyse0() //下行通信解析函数
{
uint i,ReceCheck,SumCheck;//,broadid;
uint length = 0;
ReceEndFlag0 = 0; //结束完标志位清零
lockFlagDn = 0; //开锁
for( i = 0;i < MaxRece0;i++ ) //计算包长度
{
if( ReceSbuf0[i] == '\r')
{
length = i + 1; //数据包长度
break;
}
}
if( length < 10) //无效数据包
{
ReceCount0=0; //串口0接收计数器清零
return;
}
SumCheck=CrcCheck( ReceSbuf0,length-5 );//crc读取
ReceCheck=4096 * toint(ReceSbuf0[length-5]) + 256*toint(ReceSbuf0[length-4]) + 16*toint(ReceSbuf0[length-3]) + toint(ReceSbuf0[length-2]);
if( SumCheck != ReceCheck) //crc校验
{
return;
}
ReceCheck = 4096*toint(ReceSbuf0[3]) + 256*toint(ReceSbuf0[4]) + 16*toint(ReceSbuf0[5]) + toint(ReceSbuf0[6]);
if(ReceCheck != length-12) //长度校验
{
return;
}
ReceCheck = 16 * toint(ReceSbuf0[1]) + toint(ReceSbuf0[2]);
if(ReceCheck != RTdataAns)
{
return; //非实时数据响应
}
switch( ReceSbuf0[0] ) //收到是那块从模块信息
{
case 0x1F://0: //AIDI有AIDI量
FalseTime0 = 0; //错误次数清零
memcpy( RealTimeData+6, ReceSbuf0+11, 44 ); //AI量
memcpy( RealTimeData+12+AIsum, ReceSbuf0+59, B00DI/2 ); //DI量
break;
case 0x1E://1: //电池板只有AI量
FalseTime1 = 0; //错误次数清零
memcpy( RealTimeData+50, ReceSbuf0+11, B11AI*4 ); //AI量
break;
case 0x1D://2: //电池板只有AI量
FalseTime2 = 0; //错误次数清零
memcpy( RealTimeData+178, ReceSbuf0+11, B22AI*4 ); //AI量
break;
case 0x1C://3: //IP板
FalseTime3 = 0; //错误次数清零
memcpy( RealTimeData+306, ReceSbuf0+11, B33AI*4 ); //AI量
memcpy( RealTimeData+12+AIsum+B00DI/2, ReceSbuf0+15+B33AI*4, B33DI/2 ); //DI量
break;
default :
break;
}
//2003.12.11;11:46 modify
RealTimeData[0]=0x38; //AI标号
RealTimeData[1]=0x30;
hex2asc1(RealTimeData+2,75+B33AI); //AI通道数
RealTimeData[AIsum+6]=0x38; //DI标号
RealTimeData[AIsum+7]=0x31;
hex2asc1(RealTimeData+AIsum+8,(8+B33DI)/4); //DI通道数,压缩
ReceCount0=0; //串口0接收计数器清零
}
void Analyse1()
{
uchar data j,i,data00;
uint data kk,TemLen,kk0;
uchar readID, state, length, ReceLen, typeCom,RTclock[6];
uint SumCheck, ReceCheck;
ReceEndFlag1 = 0;
if( ReceSbuf1[0] != 0x7E ) //没有数据包头
{
memset( ReceSbuf1, 0, 50 ); //串口1接收缓冲区清零
ReceCount1 = 0; //串口1接收计数器清零
return;
}
for( i = 0;i < MaxRece1;i++ ) //计算包长度
{
if( ReceSbuf1[i] == '\r')
{
length = i+1;
break;
}
}
if( length < 10 && length > 60 ) //无效数据包
{
memset( ReceSbuf1, 0, 40 ); //串口1接收缓冲区清零
ReceCount1 = 0; //串口1接收计数器清零
return;
}
readID = toint( ReceSbuf1[5] ) * 16 + toint( ReceSbuf1[6] );
if( readID != Read_ID() ) //采集箱的ID号校验
{
memset( ReceSbuf1, 0, 50 ); //串口1接收缓冲区清零
ReceCount1 = 0; //串口1接收计数器清零
return;
}
SendSbuf1[SendCount1++] = '\r'; //结束上次发送(最好发送)
SendSbuf1[SendCount1] = '\n'; //结束上次发送(结束发送)
state = 0; //返回状态
if( ReceSbuf1[0] != 0x7E ) state = 1; //起始符校验
if( ReceSbuf1[1] != VERh && ReceSbuf1[2] != VERl)
{ //版本号校验
state = 2;
}
/*
if( ReceSbuf2[18] >0x36 || ReceSbuf2[19] >0x36 || ReceSbuf2[21] >0x36 || ReceSbuf2[23] >0x36 || ReceSbuf2[25] >0x36)
{
state = 10; //日期时间错
return;
}*/
SumCheck=CrcCheck( ReceSbuf1+1,length-6 ); //计算CRC //接收CRC
ReceCheck=4096 * toint( ReceSbuf1[length-5] )+256 * toint( ReceSbuf1[length-4] )+16 * toint( ReceSbuf1[length-3] )+toint( ReceSbuf1[length-2] );
if( SumCheck != ReceCheck ) state=5; //crc校验
ReceLen = 0x10*toint( ReceSbuf1[13] ) + toint( ReceSbuf1[14] );
if(ReceLen != length-20) state=4; //数据块长度
typeCom = 16 * toint( ReceSbuf1[7] ) + toint( ReceSbuf1[8] );
TemLen = 0;
if(KaiJiShZhFlag) //开机时钟校正
{
for(i = 0;i < 12;) //更新时钟
{
RTclock[i/2]=16 * toint(ReceSbuf1[15+i]) + toint(ReceSbuf1[16+i]);
i+=2;
}
setup_write(); //设置实时时钟操作方式
clock_write(RTclock); //修改时钟命令
KaiJiShZhFlag=0;
}
switch( typeCom )
{
case ResetCom: //系统复位命令
typeCom = ResetAns;
TemLen = 20 + 12;
ResetAnsFlag = 1; //复位标志位置一
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -