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

📄 plc.c

📁 此源码为商用的电力抄表系统的从机端源程序。通过电力载波模块
💻 C
字号:
/* //////////////////////////////////////////////////////////////////////////
// lme2200.c  - source file for lme2200 API
// 
// Copyright 2005, Leaguer MicroElectronics Co., Ltd
// www.leaguerme.com
//////////////////////////////////////////////////////////////////////////// */
#include <REG922.H>

#include "sart.h"
#include "plc.h"
#include "timer.h"
#include "wr_flash.h"
//#include "Beacon.h"

#define uint unsigned int
#define uchar unsigned char

// Maximum time to wait to get reply from the chip after sending read command in sync mode,
// in number of instructions
#define SYNC_WAIT 100       	

#define INC_THRES_EA  16
#define MAX_THRES_EA  0x80
#define MIN_THRES_EA  16
#define	DEC_THRES_EA  8
idata uchar cur_smod = SMOD_SYNC;	// default
idata uchar frame_sz = 18;

// !!!!!!!! EA, EB should be initially set to prevent receiving packets
//uchar code plc_setting[] = {0x30,0x00,0x32,0x05,0x33,0x01,0x34,0x02,0x35,0x12,0x36,0x08,0x37,0xBC,0x38,0x60,0x39,0x64,0x3a,0x68,0x3b,0x6c,0x3c,0x04,0x3e,0x00,0x3f,0x00};//28 byte 传输速率为2400
uchar code plc_setting[] = {0x30,0x00,0x32,0x10,0x33,0x01,0x34,0x02,0x35,0x12,0x36,0x08,0x37,0x3C,0x38,0x60,0x39,0x64,0x3a,0x68,0x3b,0x6c,0x3c,0x04,0x3e,0x00,0x3f,0x00};//28 byte 传输速率为1200
/*
  uchar code WtFIR[] = {0x77,0x0d,0xfb,0xe8,0xfe,0xeb,0x06,0xac,0x06,0x8c,0xfb,0xba,
                              0xf4,0xae,0xfd,0x64,0x0a,0x68,0x08,0xf3,0xfb,0x38,0xf8,0xf8,
                              0xfe,0x8e,0x00,0xa7,0xfc,0x04,0x04,0x76,0x11,0x2c,0x06,0x39,
                              0xe3,0x7f,0xde,0x1a,0x13,0xfc,0x3e,0x7d,0x13,0x19,0xbb,0x4a,
                              0xb7,0x00,0x22,0xae,0x6c,0x7f,0x21,0x3f,0x9d,0xcc,0x9b,0xe5,
                              0x27,0xff,0x7f};
*/
idata uchar thres_ea;
idata uchar wet;

bit packet_recved;
bit packet_recving;
bit timeout_40s;
bit timeout_1s;
bit timeout_1m;
extern bit reply;
//bit init_set;
bit rx_adj;
bit rx_stop;
bit delay_tx;
idata uchar thres_set;
void timeout_t2(void);

/////////////////////////////////////////////////////////////////
// Data sending & receiving functions
/*=============================================================================*/
// Send a single byte
void send_data(uchar c)
{
 sync_sendchar(c);
}

/*=============================================================================*/

// Send a data block of specified length
void send_block(uchar block[], uint len)
{
  uchar i;

  for (i = 0; i < len; i++)   send_data(block[i]);

}
/*=============================================================================*/
// Register write & read operations

// Write register
void write_reg(uchar op, uchar val)
{
  uchar buf[2];

  buf[0] = op;
  buf[1] = val;
  send_block(buf, 2);
 
}
/*=============================================================================*/

// Read register. Return -1 if error,
// otherwise, the result is in the lower byte of the returned value
int read_reg(uchar op)
{
  uchar i;

 // ET0 = 0;

  send_data(op);  // send the read command
   
 /* if (cur_smod == SMOD_ASYNC) {

  //  ET0 = 1;

    return -1; // not supported
  }*/

  // sync mode
  i = 0;
  while (i++ < SYNC_WAIT) {
    if (sync_data_ready()) break;
  }

  if (!sync_data_ready()) {

   // ET0 = 1;

    return -1;  // time out
  }

  i = sync_getchar();

 // ET0 = 1;
 
  return  i;  

}
/*=============================================================================*/

// Read from buffer (multiple bytes)
int read_buffer(uchar op, uchar buf[], uint len)
{
  uint i;

 // ET0 = 0;

  //rx_clear();
  send_data(op);  // send the read command
   
  if (cur_smod == SMOD_ASYNC) {
  // async mode

   // ET0 = 1;
    return -1;
  }

  // sync mode
  i = 0;
  while (i++ < SYNC_WAIT) {
    if (sync_data_ready()) break;
  }

  if (!sync_data_ready()) {

   // ET0 = 1; 
    return -1;  // time out
  }

  i = sync_getblock(buf, len);
 // ET0 = 1;

  return i;  

}
/*=============================================================================*/
/*=============================================================================* /


// Send a command
void send_command(uchar cmd)
{
  send_data(cmd);
}

/*=============================================================================*/
// Register operations

/*
int set_sync_err(char val)
{
  ET0 = 0;
  write_reg(REG_WR_SYNC_ERR, val);
  ET0 = 1;

  // Verify
  if (read_reg(REG_RD_SYNC_ERR) != (int)val)
    return -1;

  return 0;

}

*/
/*=============================================================================*/

int set_thres_ea(uchar val)
{
 // ET0 = 0;
  write_reg(REG_WR_EA, val);  
 // ET0 = 1;

  // Verify
  if (read_reg(REG_RD_EA) != (uint)val)
    return -1;
}

/*=============================================================================*/


int set_thres_eb(uchar val)
{
 // ET0 = 0;
  write_reg(REG_WR_EB, val);
 // ET0 = 1;

  // Verify
  if (read_reg(REG_RD_EB) != (uint)val)
    return -1;
}

/*=============================================================================*/

int read_crc()
{
  return (read_reg(REG_RD_STATUS) & 0x01); 
}
/*=============================================================================*/

/*
int read_rssi(char rssi[])
{
  int val;

  val = read_reg(REG_RD_EA);
  if (val < 0) return -1;
  rssi[0] = (char)val;

  val = read_reg(REG_RD_EB);
  if (val < 0) return -1;
  rssi[1] = (char)val;

  return 0;
}
*/
/*=============================================================================*/

int write_txbuffer(uchar buffer[])
{
  send_data(BUF_WR_TXBUF);
  send_block(buffer, frame_sz);

  return 0;
}

/*=============================================================================*/

/*
int read_txbuffer(char buffer[])
{
 	return read_buffer(BUF_RD_TXBUF, buffer, frame_sz);
}
*//*
int read_rxbuffer(uchar buffer[])
{
	return read_buffer(BUF_RD_RXBUF, buffer, frame_sz);
}
/**/

/*=============================================================================* /

void send()
{
 // ET0 = 0;
  send_command(CMD_TRANSMIT);
 // ET0 = 1;
}

/*
int plc_reset()
{
  send_command(CMD_RESET);

  return 1;

}
*/
/*=============================================================================*/

//////////////////////////////////////////////////////////////////////
// High-level API function

/* this function must be called before using any PLC API functions.
   smod = SMOD_ASYNC or SMOD_SYNC, must be consistant with the hardware
   smod pin connection.

int plc_init(uint smod)
{
   cur_smod = smod;
 
   if (cur_smod == SMOD_ASYNC)
     uart_init();

   return 0;

}  */
/*=============================================================================*/

int plc_config(uchar buf[], uint len)
{
 // ET0 = 0;
  send_block(buf, len);
 // ET0 = 0;
  return 1;
}


/*=============================================================================* /
int plc_send(uchar frame[])
{
 // ET0 = 0;

  write_txbuffer(frame);
  send();  // send it!!

 // ET0 = 1;

  return 0;
}

/*=============================================================================*/
/*
int plc_resend()
{
  ET0 = 0;
  send();  // send current data in tx buffer
  ET0 = 1;

  return 0;
}
*/

/*=============================================================================*/

int plc_recved()
{
  return sync_recved();
}

/*=============================================================================*/

int plc_getframe(uchar *frame)
{
  uint res;

  res = read_buffer(BUF_RD_RXBUF, frame, frame_sz);
  
  if (res < 0) return -1;

  return frame_sz;

}

/* ================================================================* /
/* ================================================================*/

void thres_adjust(void)
{
  timeout_1s = 0;
  rx_adj = 0;
  rx_stop = 1;
  wet = 0;
  set_thres_eb(1);

  disable_t2();//<-------------------------------关40秒定时

 while(rx_stop){  //等待到上调 
     clr_wdt();
     if(timeout_40s){    //<---------------------------时间到下调	     
	    thres_ea -= DEC_THRES_EA + INC_THRES_EA;   //减8
	    if (thres_ea < MIN_THRES_EA) {thres_ea = MIN_THRES_EA; plc_power_on();} //最小16;
		timeout_40s = 0;
	    set_thres_ea(thres_ea);	
	    rx_adj = 0;
     }

    timeout_1s = 0;
    setup_t0(600, ist_count); //定时1s
    while(timeout_1s == 0){clr_wdt();}  
    if(wet > 4) {
        thres_ea +=  INC_THRES_EA;
        if (thres_ea > MAX_THRES_EA) thres_ea = MAX_THRES_EA;  //
        rx_adj = 1;     
        set_thres_ea(thres_ea);
    }
	if (wet == 4) {
        thres_ea +=  DEC_THRES_EA;
        if (thres_ea > MAX_THRES_EA){ thres_ea = MAX_THRES_EA; plc_power_on();} //
        rx_adj = 1;     
        set_thres_ea(thres_ea);
        rx_stop = 0;

    }
    else rx_stop = 0;//如果发现rx_busy不在闪,跳出
	wet = 0;
  }


  disable_t0(); //  关1秒定时 

  clr_wdt(); //重设看门狗

  thres_ea += INC_THRES_EA;
  if (thres_ea > MAX_THRES_EA) thres_ea = MAX_THRES_EA;
  set_thres_ea(thres_ea);
  // uart_sendchar(0xf0);
  // uart_sendchar(thres_ea);
  set_thres_eb(thres_ea>>1);
  wet = 0;
  setup_t2(4000, timeout_t2);
}

/*=============================================================================*/

									
void timeout_t3(void)
{
  disable_t3(); //t3_enable = 0;停计数100ms   

  // Test if RX_BUSY is still low 
  if (RX_BUSY){wet ++;} 

  else {
   // wet = 0; // recved, clear it
	packet_recved = 1;
	packet_recving = 1;
   }
}

/*=============================================================================*/
 
void RX_BUSY_ISR (void) interrupt 2		   //执行外部中断1
{
  // RX_BUSY is low, setup t3 and test RX_BUSY again when timeout.
  setup_t3(10, timeout_t3);    //设定100ms秒时间中断次数.
  packet_recving = 0;
  //wet ++;
}


/*=============================================================================*/
void ist_count()/*	   //计1秒中断次数   */
{  
  timeout_1s = 1;
  //disable_t0();
}

/*=============================================================================*/

void timeout_t2(void)
{
  timeout_40s = 1;
 // disable_t2();
}

/*=============================================================================*/

void timeout_t4(void)
{
  delay_tx = 0;
 disable_t4();
}
/*=============================================================================*/
/*=============================================================================*/

// Perform initialization of PLC modem after power on
void plc_power_on(void)
{
  uint i;
  clr_wdt();
  // Reset LME2200  
 // ET0 = 0;
  RST_PLC = 0;
  for (i = 0; i < 3000; i++) {;}
  clr_wdt();
  RST_PLC = 1;
  for (i = 0; i < 100; i++) {;} 
 // ET0 = 1;
  // Configure PLC 
  plc_config(plc_setting, sizeof(plc_setting));
  clr_wdt();
  //plc_config(WtFIR,sizeof(WtFIR));
  clr_wdt();
  // Initial threshold measurement & setting
  set_thres_eb(0);
  thres_set = 0;
  thres_ea = 0x05;

  while (thres_set < 4) {
    wet = 0; 
    timeout_1s = 0;  
    setup_t0(600, ist_count); //1.6s
    // wait for 1s
    while (timeout_1s == 0) { clr_wdt();}
    disable_t0();//关1S定时
	if	(wet > 4) {
	  thres_ea += INC_THRES_EA;
	  if (thres_ea > MAX_THRES_EA)  thres_ea = MAX_THRES_EA; 
      set_thres_ea(thres_ea);
	}
	else { thres_set++; }
  }

  thres_ea += INC_THRES_EA;
  if (thres_ea > MAX_THRES_EA) thres_ea = MAX_THRES_EA; 
  set_thres_ea(thres_ea);
  set_thres_eb(thres_ea>>1);
  clr_wdt();

  packet_recved = 0;
  packet_recving = 0;
  wet = 0;
}
/*=============================================================================*/
/*=============================================================================*/

void w_flsh(uchar dat,uchar dat1)
{
   uchar buf[2];

  write_reg(REG_WR_33, dat);
  write_reg(REG_WR_3c, dat1);
  buf[0] = dat;
  buf[1] = dat1;
  EA = 0; 
  FLASH_WriteNByte(0x1c00, buf, 2);
 // FLASH_WriteByte(0x1c05,dat);	//   (int code *)&plc_setting[5]
 // FLASH_WriteByte(0x1c06,dat1);//(int code *)&plc_setting[23]  
  EA = 1;
}

/*=============================================================================*/
//              家电智能控制统一程序(根据UPLM2200 API协议设定)
//           接收应答处理
/*=============================================================================* /
void Rx_Command_Reply(uchar comm)
{
    uchar Command;
    Command = comm & 0x3f;
   switch(Command){ //B5~B0 命令字
   
       case 0x01:{reply = 1;}break;

       case 0x02:{reply = 0;}break;
   }
}

/*=============================================================================*/
/*=============================================================================*/

void Remote_Replies(uchar buf[])//远程测试应答
{
    buf[0] = 0xa1;//B7B6 = 10;B5~B0 = 0x21h;
    while(delay_tx)clr_wdt(); /*-延迟返回------*/
	 write_txbuffer(buf);	//写入2200c
	 sync_sendchar(0x7e);
}

/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$<<<<<软件说明>>>>>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$* /
                              软件修改说明在main.c,敬请留意
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$<<<<<软件说明>>>>>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/


⌨️ 快捷键说明

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