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

📄 3201.c

📁 基于PL3201芯片的单相复费率载波通信多功能电表应用程序
💻 C
📖 第 1 页 / 共 2 页
字号:

   if ( TH1!=0xF6 )
      TH1=0xF6;
   if ( TR1!=1 )
      TR1=1;          // 启动定时器1
      // 定时器0重置
   if ( TR0!=1 )
     TR0 = 1;        // 启动 T0 定时器

   // 中断设置重置
   if ( IE!=0x82 )
      IE=0x82;
   if ( IP!=2 )
      IP=2;
   if ( EIP!=1 )
      EIP=1; 	         // 外部中断2 为高级中断
}
/**************************************************************************************
 *
 * FUNCTION:    PLC_prog
 *
 * DESCRIPTION: 载波接收数据包后的处理函数
 *              1. 进行数据包的校验和合法性判断
 *              2. 点亮上传指示灯
 *              3. 进行数据包的向上转发
 *              4. 清com_buf[]
 *
 * PARAMETERS:  in:  PLC_Rxd_OK=1 ; R_T_buf_bak[]数据存入接收和数据
 *              out: none
 *
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void PLC_prog ( void )
{
     uchar data i;

     if ( EIE!=0X01 ) EIE=0X01;               // 先判断后再操作LXW2006-3-2 9:28
 
     RS_TLED=0;                          		// 串口发送指示灯亮
     PLC_Rxd_OK=0;                         	// 清载波接收好标志
     COM_State=0;
     COM_recv_pointer=0;                    // 停止串口接收

     txdbyte ( 'D' );
     txdbyte ( 'A' );
     txdbyte ( 'T' );                     	//发送协议命令字
     PLC_Rxd_tlen=PLC_Rxd_tlen+3;         	//加09.AF两个字节
     txdbyte ( PLC_Rxd_tlen );              //发送长度
     txdbyte ( 0x09 );
     txdbyte ( 0xaf );
     PLC_Rxd_tlen=PLC_Rxd_tlen-3;         	// 恢复数据体长度。
     for ( i=0;i<=PLC_Rxd_tlen;i++ )					// 
     {
         txdbyte ( R_T_buf_bak[i] );
         WDI=0x9a;													// not interrupt set the soft  dog
     }
      
     PLC_Rxd_state=0;
     PLC_Rxd_pointer=0;
     PLC_Rxd_tlen=0;
     RS_TLED=1;                          		// 发送完毕串口发送指示灯灭
     
     COM_State=8;

     if ( EIE!=0X01 ) EIE=0x01;           // 先判断后再操作lxw2006-3-2 9:30 ( A9H 使能INT2中断(EX2=1)
}
/**************************************************************************************
 *
 * FUNCTION:    COM_Re_prog
 *
 * DESCRIPTION: 接收串口数据包并做载波转发处理
 *              1. 点亮上传指示灯
*
 * PARAMETERS:  in:  RI=1
 *              out: none
 *
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void COM_Re_prog ( void )
{
  if ( RI )   // 有串口下发命令处理
  {
  	RI=0;
  	switch ( COM_State )
  	{
  		case 0:																 //接收初始态
  			if ( SBUF == 'S' ) 
  			{
  				RS_RLED=0;
  				COM_State=1; 
  				COM_recv_pointer=1;
  			}
  			else
  			{
  				COM_State=0; COM_recv_pointer=0;
  			}
  		break;
  		
  		case 1:																	//接收到第一字节准备接收第2个字节
  			if ( SBUF == 'N' )
  			{
  				COM_State=2; COM_recv_pointer=1;
  			}
  			else
  			{
  				COM_State=0; COM_recv_pointer=0;
  			}
  		break;
  		
  		case 2:
  			if ( SBUF == 'D' )
  				{ COM_State=3; COM_recv_pointer=1; }
  			else 
  				{ COM_State=0; COM_recv_pointer=0;}
  		break;
  		
  		case 3:																	//接收串口数据长度
  			if ( COM_recv_pointer == 1 ) 
  				{ 
  					COM_State=4; 
  					COM_recv_pointer=0; 
  					COM_recv_len=SBUF; 
  					if(COM_recv_len>100) 
  						COM_State=0;
  				}
  			else      
  				{ COM_State=0; COM_recv_pointer=0; }
  		break;  		
  		
  		case 4:																	//
  			COM_recv_buf[COM_recv_pointer]=SBUF;
  			COM_recv_pointer++;
  			COM_State=5;
  		break;  		
  		
  		case 5:
         COM_recv_buf[COM_recv_pointer]=SBUF;
         COM_recv_pointer++;
         if ( COM_recv_pointer>=COM_recv_len )
         {
         	  PLC_total_len=COM_recv_len;
         		COM_State=6;											//接收完成态
         		RS_RLED=1;  											// 串口接收指示灯灭lxw2006-3-14 15:44
         		for  ( COM_recv_pointer=0; COM_recv_pointer < PLC_total_len ; COM_recv_pointer++ )
         			R_T_buf_bak[ COM_recv_pointer ] = COM_recv_buf[ COM_recv_pointer ];
         		//备份串口的接收数据         	
         }          
  		break;
  		default: 
  			COM_State=0;
  			COM_recv_pointer=0;
  		break;
  	}
  }
}
/**************************************************************************************
 *
 * FUNCTION:    LED_flash3
 *
 * DESCRIPTION: 开机指示指示灯闪烁三次表示复费率
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void  LED_flash3 ( )
{
   uchar data i;
   uchar data j;
   uchar data k;
   uchar data h;


   for ( h=0;h<3;h++ )
   {
       FUNC_LED	= 0;
		   RS_RLED 	= 0;            		// 串口接收指示灯D2
			 PLC_TLED = 0;      		  		// 载波发送指示灯D3
			 PLC_RLED = 0;      		  		// 载波接收指示灯D4
			 RS_TLED 	= 0;            		// 串口发送指示灯D5
			 FUNC_LED	= 0;            		// 载波通讯方式,亮:3200模式;灭:3105模式D6

       for ( k=0;k<4;k++ )
       {
          for ( j=0;j<250;j++ )
          {
            WDT_RST=0xa1;            // 清看门狗
            for ( i=0;i<0xff;i++ );
          }
       }


		   FUNC_LED	= 1;
		   RS_RLED 	= 1;            		// 串口接收指示灯D2
			 PLC_TLED = 1;      		  		// 载波发送指示灯D3
			 PLC_RLED = 1;      		  		// 载波接收指示灯D4
			 RS_TLED 	= 1;            		// 串口发送指示灯D5
			 FUNC_LED	= 1;            		// 载波通讯方式,亮:3200模式;灭:3105模式D6

       for ( k=0;k<4;k++ )
       {
          for ( j=0;j<250;j++ )
          {
            WDT_RST=0xa1;           // 清看门狗
            for ( i=0;i<0xff;i++ );
          }
       }
   }
}
/**************************************************************************************
 *
 * FUNCTION:    PLC_rset
 *
 * DESCRIPTION: redundancy check  PLC set when no sending and receiving
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void PLC_rset()
{
  uchar s1;
	PSK_OUT=1;	
	if( function_now == 0 )						// 3200 check every 6 sec 
 	 {
  	  FUNC_LED=0;										// MEAN 3200 FUNCTION
	 	 	SSC_ADR=0x03;
	 	 	s1=SSC_DAT;
	 	 	if ( ( s1&0xf0 )!=0xc0 )
	 	 		set_PLC_3200 ();
	 }
	 else if ( function_now == 0xff )	//3105
   {
	 	 	FUNC_LED=1;										// MEAN 3105 FUNCTION
	 		SSC_ADR=0x03;
		 	s1=SSC_DAT;
		 	if ( ( s1&0xf0 )!=0xe0 )
	 	 	 set_PLC_3105 ();
   }
}
/////////////////////////////////////
// 主程序
/////////////////////////////////////
void main ( void )
{
   uchar data i;
   uchar data j;

   for ( i=0; i<5; i++ )		//wait for the stabilization of power
   {
      for ( j=0; j<0xff; j++ );
   }  

   for ( i=0; i<5; i++ )
   {
      for ( j=0; j<0xff; j++ );
   }
   
   LED_flash3();					//上电时所有led(除电源灯)闪亮3下
   
   for ( i=0; i<250;i++ )	//clear the buf of com 、PLC and their bak
   {
       COM_recv_buf[i]  =0x00;
       PLC_recv_buf[i]  =0x00;
       R_T_buf_bak[i]   =0x00;
   }
   
	 /***clear the state of com and the PLC **/
   COM_State=0;
   COM_recv_pointer=0;
   PLC_Rxd_OK=0;
   PLC_sending=0;
   PLC_Rxd_state=0;
   PLC_timer=0;
   PLC_Rxd_timer=0x00;
   PLC_Rxd_flag	=0;					// lxw2006-3-2
   
   /***turn off the led***************/   
   
   FUNC_LED	= 1;
   RS_RLED 	= 1;            // 串口接收指示灯D2
	 PLC_TLED = 1;      		  // 载波发送指示灯D3
	 PLC_RLED = 1;      		  // 载波接收指示灯D4
	 RS_TLED 	= 1;            // 串口发送指示灯D5
	 FUNC_LED	= 1;            // 载波通讯方式,亮:3200模式;灭:3105模式D6
	 
   function_now=0xff;			// defaut function 3105
   
     initsys ();						// init settings  
     txdbyte ( 'S' );
     txdbyte ( 't' );
     txdbyte ( 'a' );
     txdbyte ( 'r' );
     txdbyte ( 't' );
   while ( 1 )							//主循环
   {
       WDI=0x9a;            // 清看门狗       
       
       if(!(PLC_Rxd_timer||PLC_sending))	// no sending and receiving
       {
       	 PLC_rset();
       }

       Txd_p31=1; Rxd_p30=1;					// REDUNDANCY

       initsys_ref();                 // REDUNDANCY
       
       if ( PLC_Rxd_OK )							// 载波接收完毕
         PLC_prog ();                 // 载波接收处理

       if (RI)                        // 有串口下发命令
         COM_Re_prog ();              // 串口接收处理函数

       if ( COM_State == 6 )					// com receive data ok
       {                              // 设置载波发送起始数据
         COM_State=7;
         COM_recv_pointer=0;
         
         /*position the 09 af*/
         while  ( R_T_buf_bak[COM_recv_pointer] == 0xff ) 	
         	 COM_recv_pointer++;
         
         PLC_total_len=PLC_total_len-COM_recv_pointer;		// LENTH OF PLC SEND 
         
         for ( i=0;i<PLC_total_len;i++ )
         		R_T_buf_bak[i]=R_T_buf_bak[i+COM_recv_pointer];
         
         PLC_send_pointer=3;            	//          
         PLC_data=R_T_buf_bak[2];         // 送发送首字节         
         PLC_sending=1;            				// 置正在发送标志
         SSC_ADR=0x03;
         SSC_DAT= ( SSC_DAT|0x01 );       //设置3201为发送状态
		     SSC_BUF= PLC_data;     					//向载波发送缓冲区发送第一个字节。		     

         PLC_TLED=0;             					// 发送指示灯亮
         PLC_timer=30;         						// 载波发送过程延时控制1.5秒
       }

       if ( COM_State == 8)					// com receive data ok
       {                              // 设置载波发送起始数据
         COM_State=7;
         PLC_total_len=R_T_buf_bak[0]+1;
         PLC_send_pointer=1;            	//          
         PLC_data=R_T_buf_bak[0];         // 送发送首字节         
         PLC_sending=1;            				// 置正在发送标志
         SSC_ADR=0x03;
         SSC_DAT= ( SSC_DAT|0x01 );       //设置3201为发送状态
		     SSC_BUF= PLC_data;     					//向载波发送缓冲区发送第一个字节。		     

         PLC_TLED=0;             					// 发送指示灯亮
         PLC_timer=30;         						// 载波发送过程延时控制1.5秒
       }
 
       if ( COM_State == 7 )          		// 判断载波是否发送完; 发送完将 COM_State=0;
       {
          if ( PLC_sending == 0 )
          	COM_State=0;
 /* CLEAR THE FLAGE OF SENDING WHEN PLC SEND TIMER IS 0 */
          if ( PLC_timer == 0 )						// PLC sending finish
			   	{
			   		SSC_ADR=0x03;
			   		SSC_DAT= (SSC_DAT&0xFE);       // 设置3201为REC状态REDUNDANCY
			   		PLC_sending=0;
			   		PLC_TLED=1;
			   		COM_State=0;
			   	}
       }
    }
}

⌨️ 快捷键说明

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