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

📄 main.c

📁 C51模拟串口及C语言与汇编语言混合使用技术 有很高的参考价值
💻 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 + -