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

📄 rs485.c

📁 RS485的通讯源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

#include  "RS485.H"
#include  "FM25040\FM25040.H"

idata unsigned char buff[60];
/*********************************************************************************************************
** 函数名称: RS485
** 功能描述: 串行中断程序
** 输 入  : 无
** 输 出  : 无	
** 说  明  : 在1.6S内没有数据接收到,系统会自动复位
**********************************************************************************************************/
void RS485( void )  interrupt 4
{
   unsigned char read_byte,add_num;//buff[2],

   watch_dogs();          //喂狗

   if( RI == 1 )  //判断是否为接收中断
     {
	     RI = 0;		 
		 //--------------接收地址信息
		 buff[0] = SBUF;

		 watch_dogs();          //喂狗
		 while(RI == 0);
	     buff[1] = SBUF ;
	     RI = 0;
		 watch_dogs();          //喂狗

		 add_num = byte_read( Machine_address + 2 );	 //读取设定的机器号

		 if( (buff[0] == add_num) && (buff[1] == add_num) )        //读取机器号
		   {
			   SM2 = 0;			   
			   REN = 0;		 
		       CS485 = 0;                    //发送状态	
		       SBUF = 0xaa;                  //发送应答信号
		       while( TI == 0 );             //等待发送完毕
		       TI = 0;

		       CS485 = 1;                    //接收状态
		       REN = 1;

			   watch_dogs();          //喂狗
			   while(RI == 0);		  //等待接收功能号
		       RI = 0; 		   
	           read_byte = SBUF;

               watch_dogs();          //喂狗  
			   switch( read_byte )
			    {
			   	  case 0xC0 : Back_all_num(Input_bill);  break;   //回收礼品机部分参数
				  case 0xC1 : Back_all_Goods(Onece_one); break;   //回收礼品机的礼品参数
				  case 0xC2 : Set_all_num(Play_money);   break;   //设定礼品机的所有参数				  
				  case 0xC3 : Read_all_num(Play_money);  break;   //确定设定参数
				  case 0xD4 : send_exsit();              break;   //机器检测(发送D4,机器存在回AA)
				  case 0xD5 : send_number(coinin_add);   break;   //回收总投币数目
				  case 0xD6 : send_number(coinout_add);  break;	  //回收总退币数目
				  case 0xD7 : send_number(cai_add);      break;	  //回收退出彩票总数
				  case 0xD8 : send_number(sin_add);      break;	  //回收开分总数
				  case 0xD9 : send_number(sout_add);     break;	  //回收洗分总数
				  case 0xDA : send_number(in_money);     break;	  //回收IC的总投钱数
				  case 0xDB : send_number(back_money);   break;	  //回收IC的总退钱数
				  case 0xDC : send_number(clear_add);    break;	  //回收洗IC的总钱数
				  case 0xDD : send_Goods(goods_add);     break;	  //回收礼品退出礼品数 = 2 * 礼品样数
				  case 0xDE : set_machine(machine);      break;	  //设定工作参数
				  case 0xDF : set_goods(goods_comp);     break;	  //设定礼品兑换比例 
				  case 0xE0 : Back_Goods(goods_comp);	 break;   //返回设定的礼品值
				  case 0xE1 : Back_machine(machine);     break;   //返回设定的机器值				    
                  default   : send_wrong();
			    }
		   }
	 }
   SM2 = 1;               //恢复SM2
   watch_dogs();          //喂狗
}

/*********************************************************************************************************
** 函数名称: send_exsit
** 功能描述: 检测机器是否存在
** 输 入  : 无
** 输 出  : 无	
**********************************************************************************************************/
void send_exsit( void )
{
   REN = 0;
   CS485 = 0;                    //发送状态
   SBUF = 0xaa;                  //发送应答信号
   while( TI == 0 );             //等待发送完毕
   TI = 0;

   CS485 = 1; 
   REN = 1;
}

/*********************************************************************************************************
** 函数名称: send_wrong
** 功能描述: 发送的功能号错误
** 输 入  : 无
** 输 出  : 无	
**********************************************************************************************************/
void send_wrong( void )
{
   REN = 0;
   CS485 = 0;                    //发送状态
   SBUF = 0xFE;                  //发送应答信号
   while( TI == 0 );             //等待发送完毕
   TI = 0;

   CS485 = 1; 
   REN = 1;	
}

/*********************************************************************************************************
** 函数名称: send_number
** 功能描述: 发送需要回收的数据
** 输 入  : data_address
** 输 出  : 无	
**********************************************************************************************************/
void send_number( unsigned int data_address )
{
    unsigned char i,timers = 3;	// buff[7],
	unsigned int address ;
  
    REN = 0;
    CS485 = 0; 

    SBUF = 0xaa;           //发送应答信号
    while(TI==0);          //等待发送完毕
    TI=0;

	REN=1;			      //返回到接收状态
	CS485=1;
   	RI = 0;
	while( RI == 0 );
	RI = 0;
	
	if(SBUF == 0xaa)
	  { 
	 	address = data_address;
        buff[0] = 0x00;
	    buff[1] = 0x04;

	    watch_dogs();          //喂狗
	    for(i=0; i<4; i++)	   //读出数据
	       buff[i+2] = byte_read( address++ );

	    buff[ 6 ] = 0x00;
        for(i=0; i<4; i++)									  
	      buff[6] += buff[i+2];  //累加和
	    watch_dogs();          //喂狗

LOOP1:
        REN = 0; 
	    CS485 = 0;         //发送状态
		
	    for(i=0; i<7; i++)
	     {
           SBUF = buff[i];
		   while(TI==0);
		   TI=0;
		   watch_dogs();          //喂狗
	     }

       REN = 1;			  //返回到接收状态
	   CS485 = 1;
	   watch_dogs();          //喂狗
	   while(RI == 0);
	   RI = 0;
	   watch_dogs();          //喂狗

	   if( SBUF != 0xaa)
	    {
		  timers --;
		  if(timers )
		    goto LOOP1;
		  else
		    {
				REN=1;			  //返回到接收状态
			    CS485=1;
		 	}
	     }
	  }	 	
}

/*********************************************************************************************************
** 函数名称: send_number
** 功能描述: 发送的功能号错误
** 输 入  : data_address
** 输 出  : 无	
**********************************************************************************************************/
void send_Goods(unsigned int data_address)
{
    unsigned char i,timers = 3; //buff[ Goods * 2 + 3],
	unsigned char n = 0;   //设定礼品种类
	unsigned int address ;
	  
	REN = 0;
    CS485 = 0;
	
	n = byte_read(Goods_num)<<1;	 

    SBUF = 0xaa;           //发送应答信号
    while(TI==0);          //等待发送完毕
    TI=0;
   
    REN=1;			      //返回到接收状态
	CS485=1;
   	RI = 0;
	while( RI == 0  );
	RI = 0;

	if(SBUF == 0xaa)
	  {
		 address = data_address;	//数据的起始地址
         buff[0] = 0x00;
	     buff[1] = n ;

	     watch_dogs();          //喂狗
	     for(i=0; i<n; i++)	  //读出数据
	       buff[i+2] = byte_read( address++ );

	     buff[ n+2 ] = 0x00;
         for(i=0; i<n; i++)
	        buff[ n+2 ] += buff[i+2];  //累加和
	     watch_dogs();          //喂狗

LOOP2:
         REN = 0; 
	     CS485 = 0;   //发送状态
	     for(i=0; i<n+3; i++)
	       {
              SBUF = buff[i];
		      while(TI==0);
		      TI=0;
			  watch_dogs();          //喂狗
	       }

         REN = 1;			  //返回到接收状态
	     CS485 = 1;

	     watch_dogs();          //喂狗
	     while(RI == 0);
	     RI = 0;
	     watch_dogs();          //喂狗

	     if( SBUF != 0xaa)
	       {
		      timers --;
		      if(timers )
		        goto LOOP2;
		      else
		        {
			  	    REN=1;			  //返回到接收状态
			        CS485=1;
			     }
	       }
	  }	   	  
}

/*********************************************************************************************************
** 函数名称: set_machine
** 功能描述: 设定机器工作信息
** 输 入  : data_address
** 输 出  : 无	
**********************************************************************************************************/
void set_machine(unsigned int data_address)
{
   unsigned char i,timers = 3;  //buff[ 25 ],
   unsigned int Data_Long = 0;
   unsigned int address ;

   REN = 0;
   CS485 = 0; 

   SBUF = 0xaa;           //发送应答信号
   while(TI == 0);        //等待发送完毕
   TI = 0;

   watch_dogs();          //喂狗
LOOP3:
   CS485 = 1;             //接收状态
   REN = 1; 			     
   RI = 0;
   
   //----------------------得到要接收数据的个数
   watch_dogs();          //喂狗
   while(RI  == 0);
   buff[ 0 ] = SBUF ;
   RI = 0;

   watch_dogs();          //喂狗
   while(RI  == 0);
   buff[ 1 ] = SBUF ;
   RI = 0;

   watch_dogs();          //喂狗
   Data_Long = buff[0]*256 +buff[1];  

   for(i=0; i<=Data_Long; i++)
     {
	    while(RI==0);   
		buff[i+2] = SBUF;
		RI=0;
		watch_dogs();          //喂狗
	 }

   //------------------------数据验证
   buff[Data_Long+3] = 0x00;
   for(i=0; i< Data_Long; i++)
	  buff[Data_Long+3] += buff[i+2];

   watch_dogs();          //喂狗
   if(buff[Data_Long+3] == buff[ Data_Long+2 ])
     {														   
	    REN = 0;				//数据接收正确
		CS485 = 0; 
		SBUF = 0xaa;           //发送应答信号
		while(TI == 0);        //等待发送完毕
		TI = 0;
		
		//-------------------保存数据
		watch_dogs();          //喂狗
		address = data_address;
		for(i=0; i<=Data_Long; i++)
          {  
			 byte_write(address,buff[i+2]);
			 address++;
		   }

		watch_dogs();          //喂狗
		byte_write(0x00,0xaa); //数据写入,写标志位
   	    REN = 1;	   //回到接收状态
		CS485 = 1;	 
	 }
   else
     {
	 	REN = 0;	            //发送数据重发信号
		CS485 = 0; 

		watch_dogs();          //喂狗
		SBUF = 0xFB;           //发送应答信号,数据重发
        while(TI == 0);        //等待发送完毕
		TI = 0;

		timers -- ;
		if( timers )
		  goto LOOP3;
		REN = 1;	   //回到接收状态
		CS485 = 1; 
	 }
}

/*********************************************************************************************************
** 函数名称: set_goods
** 功能描述: 设定机器工作信息
** 输 入  : data_address
** 输 出  : 无	
**********************************************************************************************************/
void set_goods(unsigned int data_address)
{
   unsigned char i,timers = 3,temp = 0;//buff[Goods*2+4],
   unsigned int Data_Long = 0 ;
   unsigned int address ;

   REN = 0;
   CS485 = 0;
   
   SBUF = 0xaa;           //发送应答信号
   while(TI == 0);        //等待发送完毕
   TI = 0;

LOOP3:
   CS485 = 1;             //接收状态
   REN = 1; 			     
   RI = 0;
   watch_dogs();          //喂狗

   //----------------------得到要接收数据的个数
   while(RI  == 0);
   buff[ 0 ] = SBUF ;
   RI = 0;

   watch_dogs();          //喂狗
   while(RI  == 0);
   buff[ 1 ] = SBUF ;
   RI = 0;

   watch_dogs();          //喂狗
   Data_Long = buff[0]*256 +  buff[1];
   temp = ( Data_Long % 256) >>1 ;
   byte_write(Goods_num ,temp) ;  //保存礼品的路数

   for(i=0; i<=Data_Long; i++)	  //接到数据长度加1
     {
	    while(RI==0);    
		buff[i+2] = SBUF;
		RI=0;
		watch_dogs();          //喂狗
	 }

   //------------------------数据验证
   watch_dogs();          //喂狗
   buff[Data_Long+3] = 0x00;
   for(i=0; i<Data_Long; i++)
	  buff[Data_Long+3] += buff[i+2];

   watch_dogs();          //喂狗
   if(buff[Data_Long+3] == buff[ Data_Long+2 ])
     {
	    REN = 0;				//数据接收正确
		CS485 = 0; 
		SBUF = 0xaa;           //发送应答信号
		while(TI == 0);        //等待发送完毕
		TI = 0;
		
		//-------------------保存数据
		watch_dogs();          //喂狗
		address = data_address;
		for(i=0; i<Data_Long; i++)
          {  
			 byte_write(address,buff[i+2]);
			 address++;
		   }

		watch_dogs();          //喂狗
		byte_write(0x00,0xaa); //数据写入,写标志位
   	    REN = 1;	           //回到接收状态
		CS485 = 1;	 
	 }
   else
     {
	 	REN = 0;	            //发送数据重发信号
		CS485 = 0; 

		watch_dogs();          //喂狗
		SBUF = 0xFB;           //发送应答信号,数据重发
        while(TI == 0);        //等待发送完毕
		TI = 0;

		timers -- ;
		if( timers )
		  goto LOOP3;
		REN = 1;	   //回到接收状态
		CS485 = 1; 
	 }
}

/*********************************************************************************************************
** 函数名称: watch_dogs
** 功能描述: 喂狗
** 输 入  : 无
** 输 出  : 无	
**********************************************************************************************************/
void watch_dogs( void )
{
    WDI = 0;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	WDI = 1;
}  

⌨️ 快捷键说明

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