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

📄 czx167-145-v2.2.c

📁 代码实现了载波抄读电能表
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************************************************/
/*
/*  Copyright (c) 2005,许继仪表股份有限公司
/*
/*  All Rights Reserved
/*
/*
/*
/*  文件名称:CZX165-145.C
/*
/*  文件标识:存档
/*
/*   摘    要:1、红外和载波通过485转发抄表控制程序
/*            2、该项目包括文件:CZX167-145.c ; pl3105.h
/*            3、CPU :PL3105
/*            4、该程序仅适用于符合标准645协议485电能表或多功能表的抄读
/*            5、载波信道CRC校验
/*
/*  功    能:0. 终端保存16个电表表号。
/*            1. 接收到红外通讯后转RS485抄表。
/*            2. 接收到载波通讯后转RS485抄表。
/*            3. 自动查表,抄读电表时,若该电表是终端所管理的电表,则该终端能够将表号自动保存
/*            4. 自动冻结功能,该终端能够根据设定的冻结时间将累计用电电量冻结 
/*             
/*  串口速率:1200BPS  偶校验
/*
/*  当前版本:2.02(发布)
/*  作    者:王振举
/*  完成日期:2006年07月04日
/*
/********************************************************************************************/

#include "PL3105.h"

#define uchar unsigned char
#define uint  unsigned int
//#include <INTRINS.H>

#define	 WR_24_COM  0xA2         /*24c04 读写命令字*/
#define  RD_24_COM  0xA3

//写24XX不同空间的地址指令
#define  WR_2402    0xA0         // 24空间0-2K 不受保护的低半部分
#define  WR_2404    0xA2         // 24空间2-4K 受保护的高半部分

#define  add_password        0x10             // 24空间0-2K
#define  add_password_bak    0x28             // 24空间0-2K
#define  add_terminal        0x00             // 24空间0-2K
#define  add_terminal_bak    0x18             // 24空间0-2K
#define  add_frozenday       0x08             // 24空间0-2K
#define  add_frozenday_bak   0x20             // 24空间0-2K
#define  first_Son_addr      0x00             // 24空间2-4K
#define  first_Son_addr_bak  0x80             // 24空间2-4K
/****** I/O 口设置 ********/

//sbit led     = P1^1;                     // 24保存指示灯
sbit  myled   = P0^4;                     //调试灯
sbit  wp24    = P2^0;
/////////////////////////////-----------------------------------
sbit  key     = P0^3;
sbit  RXD_TXD = P3^7;                   // 载波数据输入、输出口
/////////////////////////////------------------------------------
sbit S_Clk      = P2^1;                     // FM24C04的时钟口
sbit S_Dat      = P1^5;                     // FM24C04的数据口

//sbit  psk_out = P1^7;


// 位变量
uchar bdata pl_data;    //发送载波数据移位使用
sbit  pl_h = pl_data^7;
uchar bdata BIT_BIT;    //
sbit  r_x  = BIT_BIT^1;
sbit  r_d  = BIT_BIT^2; 
uchar bdata  Flag_Byte;                     // 位变量字节
sbit FM24_Bit=Flag_Byte^0;                         // FM24C04 的数据位(SDA)

//***载波通讯使用变量*****
uchar data pl_8;        //发送位数计数器

uchar data plret_l;     //载波发送复位计数器
uint  data   x_09af;    //接收同步头
uchar data   r_data;    //接收载波数据移位使用
uchar data   r_8;       //接收位数计数器
uchar data   r_len;     //载波接收字节计数器
uchar data   r_len1;    //载波要接收的数据长度(字节数)

/******* 全局变量设置 ******/
uchar data   Watchdog_Reset;        // 复位看门狗标志:为0x9A时,可以复位看门狗.
uchar data   Timer_RS_Answer;  		    // RS485应答时间
uchar data   Timer_HW;			    // 红外发射/接收定时器
uchar data   Timer_RS;  		    // 485发射/接收定时器
uchar data   Timer_Disp;                    // 显示时间间隔定时器(nx1S定时)
uchar data   Timer_Disp_Temp;               // 显示时间间隔定时器(1S定时)
uchar data   Disp_Pointer;                  // 显示内容指针
uchar data   ZJ_SEND;                       // 中继下发标志
uchar data   space_judge1;
uchar data   space_judge2;
uchar data   space_judge3;
uchar data   HW_Re_OK;		        // 红外接收状态标志: "OK"=接收正确,  "End"=接收数据处理完毕
uchar data   ZB_Re_OK;		        // 载波接收状态标志: "OK"=接收正确,  "ERR"=接收数据处理完毕
uchar data   RS_Re_OK;		        // 485接收状态标志:  "OK"=接收正确,  "ERR"=接收数据处理完毕
uchar data   HW_ZB;		            // 红外/载波状态标志:"HW"=红外接收 ;"ZB"=载波接收
uchar data   RS485_Txd_OK;		    // RS485发送状态标志: "OK"=数据准备好,  "End"=数据发送结束
uchar data   HW_State;		        // 红外接收过程标志
uchar data   ZB_Read_Time;	        // 载波读时间标志:
uchar data   RS485_Send_Sign;
uchar data   HW_Pointer;                    // 红外BUF数据指针
uchar data   HW_Data_Len;                   // 红外规约中数据部分的长度
uchar data   HW_Data_CRC;                   // 红外规约中的校验和
uchar data   RS485_Pointer;                 // RS485 BUF数据指针
uchar data   RS485_Data_Len;                // RS485 规约中数据部分的长度
uchar data   ZB_Txd_Len;                    // 载波发送数据长度
uchar data   ZB_Glob_Len;                   // 载波全局发送数据长度                                 
uchar xdata  Infrared_buf[30];              // Com0中断所接收的数据(红外数据)
uchar xdata  Carrier_buf[50];               // 载波中断所接收的数据(载波数据)
uchar xdata  RS485_buf[40];                 // Com1中断所接收的数据(RS485数据)
uchar xdata  Infrared_buf_bak[30];          // Com0中断所接收的数据(红外数据)备份
uchar xdata  Carrier_buf_bak[50];           // 载波中断所接收的数据(载波数据)备份
uchar xdata  RS485_buf_bak[30];             // Com1中断所接收的数据(RS485数据)备份
uchar xdata  Send_Infrared_buf[30];         // Com0中断所发射的数据(红外数据)
uchar xdata  Send_Carrier_buf[50];          // 载波中断所发射的数据(载波数据)
uchar xdata  Send_RS485_buf[30];            // Com1中断所发射的数据(RS485数据)
uchar xdata  Send_RS485_buf0[30];            // 读写电表所发射的数据(RS485数据)
uchar xdata  Add_buf[7];                    // 当前电表地址(通讯用)
uchar xdata  Read_buf[8];                   // 读取FM24时用的中间缓冲区
uchar xdata  Write_buf[8];                  // 写入FM24时用的中间缓冲区
uchar xdata  terminal_add[7];               // 终端表号
uchar xdata  addr_checked[7];               // 自动寻表时组帧用地址
uchar xdata  new_addr_checked[6];           // 载波接收到的新表地址
uchar xdata  new_meter_Txd;
uchar xdata  new_meter_flag;                // 载波通讯中发现新表的标志
uchar xdata  flag_byte_No;                  // 自动寻表时按地址的低位到高位的顺序依次查询,flag_byte_No是正在查询的字节次序
uchar xdata  Var_byte;                      // 自动寻表时,正在查询的字节的16进制数值
uchar xdata  on_frame_flag;                 // 启动自动寻表或判拆表组帧标志
uchar data   Meter_NO;                      // 判断查表过程数据指针
uchar data   no_ans_times;                  // 判拆表或自动找表数据帧发送后未接到应答的次数
uchar data   ans_times;                     // 查表数据帧下发后正确接收到应答的次数
uchar data   flag_no_RXD;                   // 启动485发送无应答处理标志
uchar data   j_f_meter_flag;                // 正在判拆表或自动找表标志
uchar xdata  find_meter_on;                 // 启动自动寻表标志
uchar xdata  judge_find_Txd;                // 判拆表或自动找表数据发送标志 
uchar xdata  HW_auto;                       // 红外修改表号不启动自动寻表
uchar xdata  ZJ_Add_buf[7];                 // 中继上传地址
uchar xdata  Son_Add_buf[16][7];            // 子表号的电表地址       //前16块表号为终端所管理的16块表,最后一块为终端地址
uchar xdata  Send_RS485_buf1[14];            // 自动查表或判拆表数据组帧缓冲区
uchar xdata  Send_RS485_buf2[14];            // 载波通讯中发现新表查寻时数据组帧缓冲区 
uchar xdata  ans_Add_buf[3][6];              // 自动寻表数据帧下发后接收到正确数据帧时电表地址暂存缓冲区
uchar xdata  Asc_buf[10]={0xED, 0x28, 0xB5, 0xB9, 0x78, 0xD9, 0xDD, 0xA8, 0xFD, 0xF9};
                     //    0x45, 0x7C, 0xF4, 0xD5, 0xD4, 0xFC};
                      //  0     1     2     3     4     5     6     7     8     9
                      //  L     H     P     E     F     R

void Infrared_Data_Send(uchar  Send_Len);
void HW_Answer_Success();
void HW_Answer_MeterNO(uchar  MeterNO);
uchar  Check_ZB_ZJ_ADD(uchar  Pos);
uchar  Compare_HW_ADD();
void Write_FM24_nByte(uchar WR_24,uchar byte_len,uchar  Add_FM24);
uchar Read_FM24_7Byte(uchar WR_24, uchar  Add_FM24);
uint cal_crc(uchar *ptr, uchar len);
void read_son_addr(uchar son_add_NO);
void frame_judge_meter(void);
void frame_find_meter(void);
void Rxd1_prog(void);
void RXD_judge_prog(void);
void Rxd_find_prog(void);
void write_addr_son(uchar k);
void no_ans_process(void);
void judge_next_byte(void);
void GB_Design_Prog(void);
void start_j_f_meter(void);
uchar  safe_where(void);
void frame_new_meter(void);
/**************************************************************************************
 *
 * FUNCTION:    timeint0
 *
 * DESCRIPTION: 定时器0中断程序,5ms 发生一次中断,
 *              对延时变量进行减1处理
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void  timeint0(void) interrupt 1
{
   if(Timer_Disp_Temp>0)    
      Timer_Disp_Temp--;
   else
   {
      Timer_Disp_Temp=100;

      if(Timer_Disp>0)
         Timer_Disp--;
      else
         Timer_Disp=0;
   }
   if(RS485_Send_Sign=='O')
   {
      if(Timer_RS_Answer>0)
          Timer_RS_Answer--;
      else if(RS485_Pointer==0)
      {
          RS485_Send_Sign=0;  
          if(judge_find_Txd=='E')
          {
              no_ans_times++;
              flag_no_RXD='O';
          }
      }
   }

   if(Timer_HW>0)
       Timer_HW--;
   else
       Timer_HW=0;

   if(Timer_RS>0)
       Timer_RS--;
   else
       Timer_RS=0;
   if(j_f_meter_flag!='O')
   {
       if(space_judge1>0)
       {
           if(space_judge2>0)
	       {
                if(space_judge3>0)
                   space_judge3--;
                else
	            {
                    space_judge2--;
		            space_judge3=250;
	            }
	       }
	       else
	       {
                space_judge1--;
		        space_judge2=250;	   
	       }
       }
       else
          start_j_f_meter();//启动判拆表及自动寻表
   }
   if(Watchdog_Reset==0x9a)
   {
      WDT_RST=0xa1;                         // 清看门狗
      Watchdog_Reset=0;
   }

   TH0=0xF8;                                // 置定时器计数   5ms 中断一次( 9.6/2 )
   TL0=0x30;

}


/**************************************************************************************
 *
 * FUNCTION:    Com0_int
 *
 * DESCRIPTION: COM0中断程序:    COM0(红外)中断产生时,按照顺序接收规约数据
 *
 *
 * PARAMETERS:  none
 *
 * RETURNED:    none
 *
 *************************************************************************************/
void  Com0_int(void) interrupt 4   using 3
{
   uchar i;
   if(RI!=0)
   {
      
      ES=0;                                               // 串口0中断禁止
      ET0=1;
      REN=1;
                                                          // 500mS未接收到下一字节则退出接收状态(恢复原始态)
      Timer_HW=100;

      if(HW_State==0)                                     // 初始状态接收
      {
         HW_Pointer=0;
         HW_Data_CRC=0;

         HW_Data_Len=0;

         Infrared_buf[HW_Pointer]=SBUF;
         HW_Data_CRC+=Infrared_buf[HW_Pointer];

         if(Infrared_buf[HW_Pointer]==0x68)
         {
            HW_State=1;
            HW_Pointer++;
         }
         else
         {
            HW_State=0;
            HW_Pointer=0;
            HW_Data_CRC=0;
         }
      }
      else if(HW_State==1)                                  // 已经接收到第一个0x68,开始接收地址部分
      {
         Infrared_buf[HW_Pointer]=SBUF;
         HW_Data_CRC+=Infrared_buf[HW_Pointer];

         if(HW_Pointer==6)
            HW_State=2;

         HW_Pointer++;
      }
      else if(HW_State==2)                                 // 已经接收完地址,开始接收第二个0x68
      {
         Infrared_buf[HW_Pointer]=SBUF;
         HW_Data_CRC+=Infrared_buf[HW_Pointer];

         if(Infrared_buf[HW_Pointer]==0x68)
         {
            HW_State=3;
            HW_Pointer++;
         }
         else
         {
            HW_State=0;
            HW_Pointer=0;
            HW_Data_CRC=0;
         }
      }
      else if(HW_State==3)                                 // 已经接收到第二个0x68,开始接收控制码
      {
         Infrared_buf[HW_Pointer]=SBUF;
         HW_Data_CRC+=Infrared_buf[HW_Pointer];

         HW_State=4;
         HW_Pointer++;
      }
      else if(HW_State==4)                                 // 已经接收到控制码,开始接收数据长度
      {
         Infrared_buf[HW_Pointer]=SBUF;
         HW_Data_Len=Infrared_buf[HW_Pointer];
         HW_Data_CRC+=Infrared_buf[HW_Pointer];

         if(HW_Data_Len>30)
         {
            HW_State=0;
            HW_Pointer=0;
            HW_Data_CRC=0;
         }
         else
         {
            HW_State=5;
            HW_Pointer++;
         }
      }
      else if(HW_State==5)                                 // 已经接收到数据长度字节,开始接收数据部分
      {
         Infrared_buf[HW_Pointer]=SBUF;
         HW_Data_CRC+=Infrared_buf[HW_Pointer];
         HW_Data_Len--;

         if(HW_Data_Len==0)
            HW_State=6;

         HW_Pointer++;
      }
      else if(HW_State==6)                                 // 已经接收完数据部分字节,开始接收校验和
      {
         Infrared_buf[HW_Pointer]=SBUF;

         if(Infrared_buf[HW_Pointer]==HW_Data_CRC)
         {

⌨️ 快捷键说明

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