⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aircontroler.c

📁 通过数据通讯
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -