📄 main.c
字号:
//本程序为中心机程序,负责轮询室内分机和其它门口机
#include "Main.h"
void main()
{
EA = 0;
TMOD = 0x21;
SETTIME1;
PCON = 0;
SCON = 0x50; //MOV SCON,#f0H 11位启用RB8 TB8 ;MOV SCON,#50H 10位数据
T2CON = 0x00;
T2MOD = 0;
SETTIME2;
SETTIME0
Uart0_Over = 0; //Com0 超时时间(单位毫秒)
Uart1_Over = 0; //Com1 超时时间(单位毫秒)
CallTallOver = 0; //呼叫或通话超时时间(单位时秒)
TmpMs = 0; //临时时间(单位毫秒)
MsCount = 0; //毫秒计数器
tmpdata = 0;
com0_bAck = 0;
UART_RXD = 1; //收数据初始化为高
EX0 = 0; //INT0 控制位
ET0 = 1; //T0 控制位
ET2 = 1; //T2 控制位
ES = 1; //串口 控制位
PX0 = 1; //INT0 优先级
PT0 = 0; //T0 优先级
PT2 = 1; //T2 优先级
PS = 1; //串口 优先级
SM = 1; //用作停止位
IT0 = 1; //INT0 为负跳变触发方式 CLR IT0 低电平触发方式
TR0 = 1; //T0 开关
TR1 = 1; //T1 开关
TR2 = 0; //T2 开关
EA = 1; //总开关
//=======================================
rec_cmd0 = 0x00; //初始化Uart0接收命令
uart0_status = 2;
uart1_status = 3;
com0_bAck = 0;
com1_bAck = 0;
bUart0RecSnd = bRecieve;
CallTallOver = 0;
while(CallTallOver < 2);
//****************************************************
//向室内机发上电命令
/*
Uart0ToUart1Data[0] = 0; //室内机的第一个地址
Uart0ToUart1Data[1] = 0x89; //命令
Uart0ToUart1Data[2] = 1; //要应答
bUart0ToUart1 = 1; //Uart1要发送这条命令标志
*/
//******************************************************
WDT_CONTR=0x3c; //看门狗定时器初始化
while(true)
{
WDT_CONTR=0x3c; //喂狗
CommUart0(); //Uart0
CommUart1(); //Uart1
}
}
void CommUart0() //COM0处理程序
{
//uart0_status 01正在向上发送数据 02发送数据完毕 正在接收数据 03接收数据开始 04接收数据完毕 05校验错
//呼叫通话时间控制,呼叫或通话超时
if(uart0_status == 0x01) //向门口机回应数据 超时出错
{
if(Uart0_Over > OverMs)
{
Uart0_Over = 0; //正在等待数据
bUart0RecSnd = bRecieve;
rec_bHead0 =0;
}
return;
}else if(uart0_status ==0x02 && Uart0_Over > OverMs) //发送数据完成没有接收数据
{
Uart0_Over = 0; //正在等待数据
bUart0RecSnd = bRecieve;
rec_bHead0 = 0;
return;
}else if(uart0_status == 0x03 && Uart0_Over > OverMs) //正在接收数据,超时处理 长度错误
{
//数据复位
rec_cmd0 = 0x00; //清除收到的命令
uart0_status = 0x02; //状态复位
rec_bHead0 = 0x00; //从新接收数据
bUart0RecSnd = bRecieve;
return;
}else if(uart0_status ==0x05)//效验错误
{//数据复位
rec_cmd0=0x00;
uart0_status = 0x02;
rec_bHead0 = 0x00; //重新接收数据
bUart0RecSnd = bRecieve;
return;
}
if(uart0_status != 0x04) //没有收到数据或者没有收完数据
return;
bUart0RecSnd = bSend; //发送状态
//用上发命令和向门口机返回命令
if(rec_cmd0 == LAddr) //轮询本机命令
{
}else if(rec_cmd0 == 0xA1) //应答本机命令
{
//等待下一个数据包
bUart0Ask = false;
//不需要重发
bUart0ReSnd = false;
}else if(rec_cmd0==0xB7)
{
}else if (uart0_status==0x05) // 接收数据校验错
{
}else //接收完成
{
}
if (bTaskUart0) //Uart0本身有请求
{
SndUart0[0] = Uart0Data[0]; //数据长度
SndUart0[1] = Uart0Data[1]; //命令
SndUart0[2] = Uart0Data[2]; //本机地址
SndUart0[3] = Uart0Data[3]; //室内机地址
SndUart0[4] = Uart0Data[4]; //是否有后继数据
SndUart0[5] = 0xCC^SndUart0[0]^SndUart0[1]^SndUart0[2]^SndUart0[3]^SndUart0[4];
com0_bAck = Uart0Data[5]; //是否应答
bTaskUart0 = false;
bUart0ReSnd = true; //如果没有反回,要重发
Uart0Nums = 0;
} else if(bUart1ToUart0)
{
SndUart0[0] = Uart1ToUart0Data[0]; //数据长度
SndUart0[1] = Uart1ToUart0Data[1]; //命令
SndUart0[2] = Uart1ToUart0Data[2]; //本机地址
SndUart0[3] = Uart1ToUart0Data[3]; //室内机地址
SndUart0[4] = Uart1ToUart0Data[4]; //数据
SndUart0[SndUart0[0]] = 0xCC;
tmpdata = 0;
for(;tmpdata < SndUart0[0];tmpdata++)
SndUart0[SndUart0[0]]^=SndUart0[tmpdata];
com0_bAck = Uart1ToUart0Data[5]; //应答
bUart1ToUart0 = false;
bUart0ReSnd = true; //如果没有反回,要重发
Uart0Nums = 0;
} else if(!bUart0Ask)
{
rec_cmd0=0x00; //清除收到的命令
uart0_status = 0x02; //状态复位
rec_bHead0 = 0x00; //从新接收数据
bUart0RecSnd = bRecieve;
bUart0Ask = true;
Uart0_Over = 0;
return;
} else if(bUart0ReSnd) //重发
{
if(!Uart0Nums) //第二次重发
Uart0Nums = 1;
else
bUart0ReSnd = false; //第三次重发
}else
{
SndUart0[0] = 0x03; //数据长度
SndUart0[1] = 0xA1; //命令子节
SndUart0[2] = LAddr; //本机地址
SndUart0[3] = 0xCC^SndUart0[0]^SndUart0[1]^SndUart0[2];
com0_bAck = false; //不要应答
}
rec_cmd0 = 0x00;
//发送数据包长度
snd_len0 = SndUart0[0]+2;
snd0_start = SndUart0; //发送数据包开始地址,从长度开始
uart0_status = 0x01; //正在发送数据
SBUF = 0xCC; //开始发送数据
//发送开始计时
Uart0_Over = 0;
}
void CommUart1() //COM1 处理程序
{
//uart1_status 01正在向下发送数据 02发送数据完毕 正在接收数据 03接收数据完毕 04接收数据校验错
if (uart1_status != 0x03 && Uart1_Over < OverMs) //50 MS检查一次
return;
if( rec_cmd1==0xA1 && uart1_status==0x03) //住户应答
{
SendUserFail[prevAddr-1] = 0;
bUart1ReSnd = false; //不要重发
// case 0x00: //轮询命令
}else if(rec_cmd1==0x00)
{
//不应答 发送完毕
if(!com1_bAck && (uart1_status == 0x02 || uart1_status == 0x03)) //发下一条命令
{
}else if(com1_bAck && uart1_status != 0x03) //要应答
{
//接收数据超时
if(Uart1_Over > OverMs) //超时处理
{
SendUserFail[prevAddr-1]+=1;
}else
{
return;
}
}else if(uart1_status == 0x01 && Uart1_Over < OverMs) //不要应答,但还没有发送数据完成
{
return;
}
}else if (uart1_status==0x04) // 接收数据校验错
{
Uart1Data[1] = 0xF2; //命令
Uart1Data[2] = 0; //不应答
bTaskUart1 = 1;
}else if (Uart1_Over > OverMs && rec_cmd1 != 0x00) //超时没有应答或没有应答完
{
//复位命令
rec_cmd1 = 0x00;
return;
}
if(bUart1ReSnd)
{
if(!Uart1Nums) //第二次重发
Uart1Nums = 1;
else
bUart1ReSnd = false; //第三次重发
}else {
//正常轮询
SndUart1[0] = 2;
SndUart1[1] = 0x06; //命令子节
com1_bAck = true;
}
snd_len1 = SndUart1[0]; //发送数据包长度
SndUart1[snd_len1] = 0xCC;
tmpdata = 0;
for(;tmpdata < snd_len1;tmpdata++)
SndUart1[snd_len1]^=SndUart1[tmpdata];
snd_len1+=2;
//发送数据包长度
snd1_start = SndUart1; //发送数据包开始地址,从长度开始
uart1_status = 0x01; //正在发送数据
//INT0关闭,不然就出现接收数据的错误
EX0 = 0;
SM = 1; //用作发送停止位
SBUF1 = 0xCC; //开始发送数据
//发送开始计时
Uart1_Over = 0;
Sdatabit = 0x0A; //发送位数
TH2 = RCAP2H;
TL2 = RCAP2L;
RI2 = 0; //发送状态
rec_cmd1 = 0;
TR2 = 1; //开启发送定时器
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -