📄 aircontroler.c
字号:
#include <reg52.h>
#include <intrins.h>
#include "AirControler.h"
/********************* Comm.c**********************/
void DisposeCommTimer() //延时结束(对方无应答)接收指针指向标头
{
if(ComTimer>0)
{
ComTimer--;
if(ComTimer==0) s=RECSTATUS_SYNC;
}
}
/*
控制字符代码
SYN 46H 同步
SOH 41H 标头同步
NAK 45H 否定信号
ACK 36H 确认
PACKFINISH 27H 数据包完成保存有结果包
PACKVOID 28H 无效数据包
PACKNORESULT 29H 无结果包返回
数据包格式:
SYN S0H DA PACKTYPE LENH LENL DATA CHK
数据包总长为 7+(LENH*0x100 + LENL)
数据包中各段的定义:
DA:目的地址,1字节长
PACKTYPE:包类型,1字节长,
D7:0-数据包 1-查询包
D4~D6:来源网络层次
D0~D3:预留
LENH,LENL:数据包的长度,2字节长高位在前(查询包取值为0)表示数据(询问)包中DATA段字符数量。
DATA:数据段,传输的信息段,规定为询问包为空。
CHK:校验码,1字节长,是从"SYN"段到"DATA"段的累加和(模256)。
通讯过程描述
1. 主机向从机发送数据包
2. 从机接受数据包后,若数据通过校验则返回ACK,否则返回NAK
3. 从机完成数据包的保存后,若不支持数据包包含的指令则返回PACKVOID,若发现当前数据包不需要返回
结果则返回PACKNORESULT(不需要发送查询包),否则返回PACKFINISH(需要发送查询包取结果)
4. 主机向从机发送查询包
5. 若无指令未执行完毕则返回LEN为0的空包,否则返回执行结果
6. 主机接受查询结果后,若数据通过校验则返回ACK,否则返回NAK
4.2 空调控制器
地址取值0x10
包类型 命令类型 是否有结果包 LEN Data(Hex)
指令 设置空调参数 无 9 0x0+ACPara[8]
设置控制器
是否可操作 无 2 0x1+OpType(0xFF-不可操作 其他-可操作)
查询参数是否改变 若有变化则有
结果包,否则无 1 0x80
取空调参数 有 2 0x90 + ParaIndex
复位 无 1 0xF0
结果 返回参数是否改变 \ 0x2 0x80+AcParaStatus
返回空调参数 \ 0x1+ 0x90 +Para[7]
参数说明
ACPara[8]:
ACPara[0]:当前小时
ACPara[1]:当前分钟
ACPara[2]:0~6位:闹铃小时
7位:是否启用闹铃 1启用
ACPara[3]:闹铃分钟
ACPara[4]:0~6位:设定温度
7位:光线暗时是否关闭LED显示 1启用
ACPara[5]:0~3位:设定风速 0-关闭 1-低速 2-中速 3-高速 4-自动
4~6:工作模式 0-工作 1-送风 2-除湿
7位:空调制冷制热模式 1制冷 0制热
ACPara[6]:楼层地址
ACPara[7]:房间地址
ParaIndex-参数序号
0-当前时间
1-闹铃时间与状态
2-设定温度
3-设定风速
4-楼层与房间地址
5-当前温度
6-当前亮度 返回Para[]长度为1
Para[0]--0~2位: 当前亮度 0~5光线等级 7 光线未知
AcParaStatus 为0xFF表示需要重新设置空调参数 其他-位为1表示相应的参数发生变化
0位-当前时间发生变化
1位-闹铃时间与状态发生变化
2位-设定温度发生变化
3位-设定风速发生变化
4位-楼层与房间地址发生变化
5位-当前温度发生变化
6位-当前亮度发生变化
*/
void DisposeCommData() //处理接收数据包
{
if(RecDataOK==SYS_ERROR) return;
RecDataOK=SYS_ERROR;
//数据包
if(PackType<0x80)
{
IsCommandOK = SYS_OK;
IsNeedResult = SYS_ERROR;
CommResultBuf[RESULT_LEN] = 0;
CommResultBuf[RESULT_COMMAND] = CommBuf[0];
switch(CommBuf[0])
{
case COMMAND_SETPARA: /* 设置空调参数,命令字0+ACPara[8] */
CurrTime[0]=CommBuf[1]; /* 小时 */
CurrTime[1]=CommBuf[2]; /* 分钟 */
// ClockStatus=CommBuf[3]&0x80; /*启用闹钟(第7位)*/
ClockStatus=(CommBuf[3]&0x80)==0;/*启用闹钟(第7位)*/
ClockTimer[0]=CommBuf[3]&0x7F; /* 闹钟小时 */
ClockTimer[1]=CommBuf[4]; /* 闹钟分钟*/
// IsCloseDisByLight = CommBuf[5]&0x80; /*光线暗时启用关闭LED显示 */
IsCloseDisByLight = (CommBuf[5]&0x80)==0; /*光线暗时启用关闭LED显示 */
SetTemp=CommBuf[5]&0x7F; /* 设定温度*/
IsAcToHot=(CommBuf[6]&0x80)!=0; /* 制冷/制热 */
// IsAcToHot=CommBuf[6]&0x80; /* 制冷1/制热0 */
FanSpeed=CommBuf[6]&0xF; /* 0关 1小 2中 3大 4自动 */
SetFanStatus();
RoomAddress[0]=CommBuf[7]; /* 楼层地址 */
RoomAddress[1]=CommBuf[8]; /* 房间地址 */
status=0;
if(status == 0xFF)
{
PARA_CURRTEMP=1;
PARA_CURRLIGHT=1;
}
SystemOldStatus=DIS_VOID;/*????????????????????????*/
break;
case COMMAND_SETSTATUS: /* 命令字1,设置空调器是否可操作 */
if(CommBuf[1]==0xFF) IsSystemLock=SYS_OK;
else IsSystemLock=SYS_ERROR;
break;
case COMMAND_QUERYSTATUS: /* 命令字0x80,查询参数是否改变 */
if(status)
{
CommResultBuf[RESULT_LEN]=2;
CommResultBuf[RESULT_BEGINDATA]=status;
IsNeedResult = SYS_OK;/*需要返回结果包*/
}
break;
case COMMAND_GETPARA: /* 命令字0x90,取空调参数 */
if(status == 0xFF) break;
CommResultBuf[RESULT_LEN]=3;
switch(CommBuf[1])
{
case 0://PARA_TIME
CommResultBuf[RESULT_BEGINDATA]=CurrTime[0];
CommResultBuf[RESULT_BEGINDATA + 1]=CurrTime[1];
break;
case 1://PARA_CLOCK
CommResultBuf[RESULT_BEGINDATA]=ClockTimer[0];
if(ClockStatus==SYS_OK) CommResultBuf[RESULT_BEGINDATA]|=0x80;
CommResultBuf[RESULT_BEGINDATA + 1]=ClockTimer[1];
break;
case 2://PARA_TEMP
CommResultBuf[RESULT_LEN]=2;
CommResultBuf[RESULT_BEGINDATA]=SetTemp;
break;
case 3://PARA_FAN
CommResultBuf[RESULT_LEN]=2;
CommResultBuf[RESULT_BEGINDATA]=FanSpeed&0xF;
if(IsAcToHot==SYS_ERROR) CommResultBuf[RESULT_BEGINDATA]|=0x80;
break;
case 4://PARA_ADD
CommResultBuf[RESULT_BEGINDATA]=RoomAddress[0];
CommResultBuf[RESULT_BEGINDATA + 1]=RoomAddress[1];
break;
case 5://PARA_CURRTEMP
CommResultBuf[RESULT_LEN]=2;
CommResultBuf[RESULT_BEGINDATA]=CurrTemp;
break;
case 6://PARA_CURRLIGHT
CommResultBuf[RESULT_LEN]=2;
CommResultBuf[RESULT_BEGINDATA]=CurrLight&0x7;
break;
}
switch(CommBuf[1])
{
case 0:status &= 0xfe;break;
case 1:status &= 0xfd;break;
case 2:status &= 0xfb;break;
case 3:status &= 0xf7;break;
case 4:status &= 0xef;break;
case 5:status &= 0xdf;break;
case 6:status &= 0xbf;break;
case 7:status &= 0x7f;break;
};
IsNeedResult = SYS_OK; /*需要返回结果包*/
break;
case COMMAND_RESET: /* 命令字0xf0,复位指令 */
IsNeedReset = SYS_OK;
break;
default:
IsCommandOK = SYS_ERROR;
break;
}
if(IsCommandOK == SYS_OK)
{
//不需要返回结果
if(IsNeedResult == SYS_ERROR) SendAData(PACKNORESULT);
else SendAData(PACKFINISH);
}
else SendAData(PACKVOID);
}
else // 发送数据包
{
SendPackToServer(0xFF,CommResultBuf[RESULT_LEN],&CommResultBuf[RESULT_COMMAND]);
CommResultBuf[RESULT_LEN]=0;
}
if(IsNeedReset == SYS_OK)
{
TR0=0; /* 停止定时器0喂狗 */
// RST();
}
//2005-04-01 包处理完毕才允许中断接收
RI=0;ES=1;
}
void SendAData(uchar LData)
{
// ENREC_COMM = SYS_ERROR; /*禁止接收*/
SBUF=LData;
ComTimerT=10;
while(TI==0 && ComTimerT>0);TI=0;
// ENREC_COMM = SYS_OK; /*允许接收*/
s2+=LData;
}
void SendPackToServer(uchar TargetAdd,uchar DataLen,uchar * LData)
{
uchar tmp,LError,i;
LError=0;
do
{
s2=0;
SendAData(SYNC); //标头(命令字)
SendAData(SOH); //标头同步
SendAData(TargetAdd); //发往地址
SendAData(0); //包类型
SendAData(0); //长度高字节
SendAData(DataLen); //数据字节数
for(i=0;i<DataLen;i++)
{
SendAData(LData[i]);
}
RI=0;
SendAData(s2);
ComTimer=100;
while(RI==0 && ComTimer>0);
if(ComTimer>0) {tmp=SBUF;RI=0;}
else tmp=0xff;
LError++;
}while(tmp!=ACK && LError<3); //失败则重发3次
}
/*****************************A/D.c********************************/
void GetADValue()
{
float x,y,z;
/************************** 计算温度 *******************************/
Temp_changed=SYS_ERROR; //温度未变化
x=uTEMP.TEMP;
y=uREF.REF;
// z=75.6-20*(x*(5-f0)/y+f0);
z=73.6-20*(x*(5-f0)/y+f0);
if(z>41)z=41;
if(z<-19)z=-19;
if(firstT==SYS_OK){firstT=SYS_ERROR;OldTemp=z;Temp=z;}
if(OldTemp-z < 1 && OldTemp-z>-1) /* 相邻2次采样超过1度认为是无效数据 */
{
OldTemp=z;
if((Temp>0 &&Temp>z) || (Temp<=0 &&Temp<z))Temp=(Temp*49+z)/50; /* 加权平均 */
else Temp=(Temp*99+z)/100;
z=CurrTemp-Temp;
if(z >= 0.8 || z<=-0.8)
{
if(Temp>=0)CurrTemp=Temp+0.5; //转换成整数
else CurrTemp=Temp-0.5;
Temp_changed=SYS_OK;
}
}
else OldTemp=z;
/************************** 计算照度 *******************************/
Light_changed=SYS_ERROR; /*光线AD未变化*/
x=uLIGHT.LIGHT;
z=7*x/y-0.5;
if(z<0)z=0;
if(z>7)z=7;
if(firstL==SYS_OK){firstL=SYS_ERROR;OldLight=Light=z;}
if(OldLight-z < 1 && OldLight-z > -1)
{
OldLight=z;
Light=(Light*49+z)/50; /* 加权平均 */
z=CurrLight-Light;
if(z >= 1 || z<=-1)
{
if(Light>=0)CurrLight=Light+0.5;
else CurrLight=Light-0.5;
Light_changed=SYS_OK;
}
}
else OldLight=z;
LOWLight(); /*判断是否调节显示亮度*/
AD_OK=SYS_ERROR;
}
void LOWLight() /*判断是否调节显示亮度*/
{
if(IsCloseDisByLight==SYS_OK) /*光线暗需要关显示*/
{
if(NoLightStatus==SYS_ERROR) /*未处于无光状态*/
{
if(CurrLight>=5) NoLightStatus=SYS_OK;/*当前光线很暗则置无光状态 */
}
else
{
// if(CurrLight<5||CurrLight==7) /*当前光线亮或当前光线未知则取消无光状态 */
// {
NoLightStatus=SYS_ERROR;
CloseDisStatus=SYS_ERROR;
// }
}
}
else
{
NoLightStatus=SYS_ERROR;
CloseDisStatus=SYS_ERROR;
}
}
/********************* delay.c**********************/
void Delay_MS(uint cnt)
{
uchar i;
do {
i = 4;
do {
Delay_us(250);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -