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

📄 main.c

📁 51单片机实现远程电源控制,串口接收电台命令,控制通断电,C语言编程
💻 C
字号:
#include <reg52.h>
#define MsgLen 11
sfr WDTC  = 0x8f;//看门狗寄存器定义
sfr XICON = 0xc0;//外部中断控制寄存器定义
sbit EX2 = XICON^2;//外部中断2使能位定义
sbit EX3 = XICON^6;//外部中断3使能位定义
unsigned char MSGBuf[MsgLen];//接收缓冲区
unsigned char RcvBuf;//接收寄存器
unsigned int Timer10Min= 0 ;//10分钟超时计数器
bit HasRcv=0;//接收标志
bit SendOver=0;//发送标志
bit T0out=0;//10分钟超时标志
bit Timer0Flag=0;//定时器0溢出标志
code unsigned char PowerOnREQ[] = {//开机命令数据包
     0x56,0x07,0x81,0x01,0xfe,0xdd,0x95,0xb0,0xb0,0xaf,0x04};
code unsigned char PowerOnCMP[] = {//开机成功数据包
     0x56,0x07,0x82,0xfe,0x01,0x7b,0x39,0xd0,0x0c,0x6e,0x03};
code unsigned char PowerOffREQ[] = {//关机命令数据包
     0x56,0x07,0x83,0x01,0xfe,0xb3,0x41,0x34,0xb3,0xba,0x03};
code unsigned char PowerOffCMP[] = {//关机成功数据包
     0x56,0x07,0x84,0xfe,0x01,0xc9,0x45,0x5d,0x08,0x53,0x03};
code unsigned char PowerError[]  = {//出错信息数据包
     0x56,0x07,0x85,0xfe,0x01,0xfe,0x2f,0x9f,0x09,0xb6,0x03};
sbit nPCTL = P1^0;//电源控制位,低有效
sbit nPOn1 = P2^0;//电源监测位1,低有效
sbit nPOn2 = P2^1;//电源监测位2,低有效


void InitCom(unsigned int BaudRate)//串口初始化
{
	unsigned char THTL;
	switch (BaudRate)
	{
		case 300: THTL = 64; break; //波特率300
		case 600: THTL = 160; break; //600
		case 1200: THTL = 208; break; //1200
		case 2400: THTL = 243; break; //2400
		case 4800: THTL = 244; break; //4800
		case 9600: THTL = 250; break; //9600
		case 19200: THTL = 253; break; //19200
		case 57600: THTL = 255; break; //57600
		default: THTL = 208;
	}
	SCON = 0x50; //串口方式1,允许接收
	TMOD = 0x21; //定时器1定时方式2, 定时器0定时方式1
	TCON = 0x40; //设定时器1开始计数
	TH1 = THTL;
	TL1 = THTL;
	PCON = 0x80; //波特率加倍控制,SMOD位
	RI = 0; //清收发中断标志
	TI = 0;
	TR1 = 1; //启动定时器1
}


void externelINT0() interrupt 0//外部中断0中断服务程序
 {
  EX0=0;//关中断
 }

void Timer0Int() interrupt 1//定时器0中断服务程序
 {
  Timer10Min++;//10分钟超时计数器递增
  Timer0Flag=1;//定时器0溢出标志置位
  if(Timer10Min>10000)//判断超时
  T0out = 1;  
 }

void externelINT1() interrupt 2//外部中断1中断服务程序
 {
  EX1 = 0;//关中断
 }

void Timer1Int() interrupt 3//定时器1中断服务程序
 {
  ET1 = 0;//关中断
 }

void SerialIO0() interrupt 4 {//串口中断
  
  if(RI)  {
   RI = 0 ;
   RcvBuf = SBUF;
   HasRcv = 1;
   Timer10Min= 0;
   } 
  else
   { 
    TI = 0;
	SendOver=1;
	}
  }

void Timer2Int() interrupt 5 {//定时器2中断服务程序
   
  ET2 = 0;//关中断
}

void externelINT2() interrupt 6//外部中断2中断服务程序
 {
  EX2 = 0;//关中断
 }

void externelINT3() interrupt 7//外部中断3中断服务程序
 {
  EX3 = 0;//关中断
 }

/*************FUNCTION**************/
/*        11.0592MHz               */
/*     延时(count)ms               */
/***********************************/
void dmsec(unsigned int count)//延时程序
{
	unsigned int i;
	while(count--)
	{
		for(i=0;i<125;i++)
		{
		}
	}
}

void rcvMsg()//接收数据包
{
unsigned int Num=1;
unsigned int Timeout=0;
while(Num<MsgLen && Timeout<3000) {
    if (HasRcv)
     { HasRcv = 0;	
       MSGBuf[Num]= RcvBuf;
	   Num++;
     }
      Timeout++;
      
	 }
 WDTC = 0xe5;  //喂狗
}

void sendMSG(unsigned char MSG[])//发送数据包
{
unsigned int i;

for(i = 0 ; i<MsgLen; i++ ) 
{
 SBUF = MSG[i];
 while(SendOver==0);
 SendOver=0;
// dmsec(1);
}
 WDTC = 0xe5;//喂狗
}

unsigned int checkMSG()//校验数据包
{
 unsigned int i;
 unsigned int flag1;
 unsigned int flag2;

 for(i = 1 ; i<MsgLen; i++ ) 
{
 if (MSGBuf[i] != PowerOnREQ[i] )
 { flag1= 0;
   break;
 }
 flag1 = 1;
}
 for(i = 1 ; i<MsgLen; i++ ) 
{
 if (MSGBuf[i] != PowerOffREQ[i] )
 { flag2= 0;
   break;
 }
 flag2 = 2;
}
  //WDTC = 0xe5;
  return(flag1 + flag2) ;
}

void main() {
  WDTC = 0xe5;//看门狗寄存器赋值
  IE = 0x00;
  XICON = 0x00;//关闭外部中断
  InitCom(19200);
  ES = 1;//使能串口中断
  ET0 = 1;//定时器0溢出中断使能
  TR0 = 1;//激活定时器0
  EA =1;//中断允许
  nPCTL =1;
  P2 = 0xff;
  HasRcv =0;
  SendOver=0;
  Timer10Min= 0;
  T0out= 0;

  while (1) {
    while (HasRcv == 0){//等待接收
	if (T0out== 1 && nPOn1 == 0 && nPOn2 == 0)//超时断电
	 {nPCTL = 1;
	  sendMSG(PowerOffCMP);
	 }
     if(Timer0Flag) //定时喂狗
	  { 
        WDTC = 0xe5;
	    Timer0Flag = 0;//清定时器0溢出标志
	  }
	}
    HasRcv = 0;//清接收标志
    if(RcvBuf == 0x56)//判断信头
    {
     MSGBuf[0]=RcvBuf;//
     rcvMsg();

    switch( checkMSG() )
	{
	 //case 0 : //数据包错误
	         //sendMSG(PowerError); 
		    // break;
	 case 1 : if (nPOn1 == 1 && nPOn2 == 1)//响应开机信令
             {nPCTL = 0;
	          T0out = 0;             
	          dmsec(100);
             }
	         if (nPOn1 == 0 && nPOn2 == 0) //判成功,发回复信令
             sendMSG(PowerOnCMP);
			 else  sendMSG(PowerError);
			 break;
	 case 2 :if (nPOn1 == 0 && nPOn2 == 0) 	//响应关机信令
             { nPCTL = 1;
	           dmsec(100);
             }
	         if (nPOn1 == 1 && nPOn2 == 1) //判成功,发回复信令
             sendMSG (PowerOffCMP) ;
			 else sendMSG(PowerError);
             break;
     default: ;//sendMSG(PowerError);
	}
   }
	
   }
  
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -