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

📄 main.c

📁 此源码为商用的电力抄表系统的主机端源程序。通过电力载波模块
💻 C
字号:
/* //////////////////////////////////////////////////////////////////////////
// main.c  - source file for lme2200 AMR
// 
//   家电智能控制统一主机程序(根据UPLM2200 API协议设定)
// Copyright 2006, Leaguer MicroElectronics Co., Ltd
// www.leaguerme.com
//
//              软件修改说明在页底,敬请留意
//////////////////////////////////////////////////////////////////////////// */
#include <REG922.H>

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


#define uint unsigned int
#define uchar unsigned char

/*============================版本号========================================*/
#define	Version1       0x01	  //版本号1
#define	Version2       0x01	  //版本号2
/*=============================================================================*/

#define AMR_OS_C		0 //本协议的控制字在第一位
#define AMR_OS_L		5 //本协议的长度值在第五位 

#define S2400          40
#define S1200          50
#define  S600          80

uchar code ADSS[4]; 
uchar plc_frame[18]; 
uchar code mcu_pc[5]= {0xfe,0xfe,0xfe,0xfe,0x68};
uchar code tx_buf[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12};
uchar code master = 0;

extern idata uchar amr_frame[];  // AMR frame buffer
extern idata uchar wet;

uchar CRC;//电力网收到CRC的值 
extern bit timeout_40s;
extern bit delay_tx;
extern bit packet_recved;
extern bit packet_recving;
extern bit t1_enable;
bit reply;
bit adss_ok;
bit CRC_switch;//CRC开关					 
void proc_amr_frame(uchar frame[]);
void amr_send_frame(uchar buf[]);
void return_inf(uchar frame,uchar inf_buf[],uchar dat);
void uart_tx_mode(uchar i_buf[]);
void rx_return(bit y,uchar R_data[]);
int plc_send(uchar frame[]);
void return_data();
void adss_crc(uchar buf[]);//地址校验

//void w_flsh(uchar dat,uchar dat1);

/*=============================================================================*/
/*								  主程序									   */
/*=============================================================================*/
main() {

  uchar l; 
  uchar buf[2];        
  P0M1 = 0x80;	  // 这是为第二版电力载波的小模块,发射部分是安捷伦的810方案  -IO口的定义
  P0M2 = 0x41;
  P1M1 = 0x7c;
  P1M2 = 0x80; 

  Rxok   = 0; 
  timer0_init(242, 10);	// 1ms * 10 = 10ms
 // plc_init(SMOD_SYNC); 
  uart_init(); //<--------------串口初始化 
  //relay_init();
  wdt_init();//<----------------看门狗初始化
  clr_wdt();
  plc_power_on();

  for(l = 0;l < 18;l ++)
  plc_frame[l]  =  0;
  clr_wdt();  
  timeout_40s = 0;
  setup_t2(4000, timeout_t2); //原10S

  setup_t1(30, disable_t1); //定时LED为300ms
  plc_getframe(plc_frame);	//查收8300的数据
 
  FLASH_ReadNByte(0x1c00,buf, 2);
  if(buf[0]!= 0){
  write_reg(REG_WR_33, buf[0]);
  write_reg(REG_WR_3c, buf[1]);
  }
 // FLASH_ReadNByte(0x1b05,buf, 2);  
 // master_slave  = (bit)buf[0];
 

 while (1) {   // the forever loop
		
		  if (uart_recved()) {  // AMR frame recved from meter
		       disable_t2();//<-------------------------------关40秒定时 			  
			  if (recv_amr_frame())	{ //uart_sendblock(amr_frame,4);
			    clr_wdt(); 
               // uart_sendblock(amr_frame, amr_frame[5]+6); //串口送至PC  
			    proc_amr_frame(amr_frame);	//最多26个字节
		       clr_wdt(); 
			  }
			 }

		  if (packet_recving) {//收到电力线上的数据
		        disable_t2();//<-------------------------------关40秒定时  
			 while (!plc_recved()) { clr_wdt();}// wait until packet is recved
			   packet_recving = 0; // reset it	 			   
		       plc_getframe(plc_frame);// read packet data
		       clr_wdt();
			   setup_t4(40, timeout_t4);delay_tx = 1; /*-延迟返回初始化-不可小于35*/
               CRC = read_crc(); //取CRC的值    		   
			   if (CRC == 0) {     // check CRC21  			    
			   Rxok = 0; clr_wdt();	               
		       t1_enable = 1;
			   adss_crc(plc_frame);          //LED定时300ms
               if(adss_ok==1){;//地址校验)//地址是否对
			    adss_ok = 0;
			   amr_send_frame(plc_frame);	//数据发入串口 
			   while(delay_tx)clr_wdt(); /*-延迟返回------*/
               //Rx_Command_Reply(plc_frame[0]);//测试回复控制
               //if(reply){ 			   
			   //Remote_Replies(plc_frame);//测试回复
			   clr_wdt(); 
			   //}		          
		       }}
			   if(CRC_switch){ //CRC开关
			        rx_return(0,plc_frame);	//数据发入串口 
				   	clr_wdt(); /*-延迟返回------*/
			   }
              
			  setup_t2(4000, timeout_t2); //40S	 
			}

		  if (timeout_40s)// Auto thres adjustment
		     {  
		      thres_adjust();
		      packet_recved = 0; // reset it	  
			}
		
		    if(~t1_enable)Rxok   = 1;  
		      
		    clr_wdt();
		     plc_getframe(plc_frame);  
		    clr_wdt();
	}
}

/*=============================================================================*/
/*=============================================================================*/
 
// Process the received AMR message/cmd from meter
/*=============================================================================*/

void proc_amr_frame(uchar frame[])
{  
   uchar m_buf[2];
   uchar contror_me;//B7B6  控制字 
   uchar command;   //B5~B0 命令字
   contror_me = (frame[AMR_OS_C] & 0xc0)>>6; //B7B6  控制字 
   command    = frame[AMR_OS_C] & 0x3f; //B5~B0 命令字

   switch (contror_me){
         Rxok   = 0;
        
        case 0x00:{ uart_tx_mode(frame);}break;//发送到远方模块

  	    case 0x01:{//本地设置控制
 
              switch (command){
                      case 0x01:{if(frame[AMR_OS_L] == 0){m_buf[0] = Version1;m_buf[1] = Version2;return_inf(0x61,m_buf,2);}}break;//读版本号

                      case 0x02:{if(frame[AMR_OS_L] == 0){m_buf[0] = read_reg(REG_RD_F3);return_inf(0x62,m_buf,1);}}break;//读速率信息

                      case 0x03:{ 
                        if(frame[AMR_OS_L] == 1){  
                         switch (frame[AMR_OS_L + 1] ){

			              case 0x01:{ w_flsh(0x01,0x04);}break; //设置速率2400bps
					 					 
					      case 0x02:{ w_flsh(0x02,0x02);}break;  //设置速率1200bps

					      case 0x04:{ w_flsh(0x04,0x01);}break;  //设置速率 600bps						
				         }
                         m_buf[0] = read_reg(REG_RD_F3);return_inf(0x62,m_buf,1);}}break;//读速率信息     

                      case 0x04:{if(frame[AMR_OS_L] == 0)CRC_switch = 1;}break;//读设置接收数据CRC报出
              
                      case 0x05:{if(frame[AMR_OS_L] == 0)CRC_switch = 0;}break;//读设置接收数据CRC不报出
					  
                      case 0x06:{;}break;

					  case 0x07:{;}break;

					  case 0x08:{if(frame[AMR_OS_L] == 0)sync_sendchar(0x7e);}break;
              }
           }break;

         case 0x02:{ uart_tx_mode(frame);}break;//远程设置控制//发送到远方模块

         case 0x03:{;}break;
     	     
	}setup_t4(40, timeout_t4);delay_tx = 1;	 		
}
 /*=============================================================================*/
/*						   数据发送到PC									   */
/*=============================================================================*/

void amr_send_frame(uchar ibuf[])
{
 // idata uchar o_frame[26];
  uchar  i;
  uchar  En;

       En = ibuf[AMR_OS_L] + 11;  //串口返回	

	clr_wdt();
    // preamble
    for (i = 0; i < 5; i++) amr_frame[i] = mcu_pc[i];	//放入0xFE	68
     clr_wdt();  
	for (i = 0; i < ibuf[AMR_OS_L]+6; i++)amr_frame[5+i] = ibuf[i];  //从C开始存放	        

    amr_frame[En] = 0x16;  //多补16h    
    uart_sendblock(amr_frame, En+1); //串口送至PC
    clr_wdt(); 
}
/*=============================================================================* /
						   信息返回
/*=============================================================================*/

void return_inf(uchar frame,uchar inf_buf[],uchar dat)
{	
    uchar con;
    uchar buf[18];
	clr_wdt();
	buf[0] = frame;
    buf[1] = ADSS[0];
	buf[2] = ADSS[1];
	buf[3] = ADSS[2];
	buf[4] = ADSS[3];
    buf[AMR_OS_L] = dat;
    for(con = 0;con < buf[AMR_OS_L];con ++)     
	    buf[6+con] = inf_buf[con];	//放入状态信息

	amr_send_frame(buf);//串口返回PC

}
/*=============================================================================* /
						串口发到2200C
/*=============================================================================*/

void uart_tx_mode(uchar i_buf[])
{  
     uchar i,tom;
	uchar no_all = 0;
	uchar o_buf[18];
     tom = i_buf[AMR_OS_L] + 6;
     for (i = 0; i < tom; i++) //C, A,A,A,A,L, DATA
	   o_buf[i]	 = 	i_buf[i];//放入DATA数据

	 if(tom < 18){		  //不够18个数据后补0
	   no_all = 18 - tom;
	   for (i = 0; i < no_all; i++)
	   o_buf[tom+i]	 = 	0x00; 
	 }

	 if(i_buf[AMR_OS_L] > 18)i_buf[AMR_OS_L] = 18;//超过18个数只认18个数


	 write_txbuffer(o_buf);	//写入2200c
	 sync_sendchar(0x7e);
}
/*=============================================================================* /
						接收数据重组
/*=============================================================================*/

void rx_return(bit y,uchar R_data[])
{
 uchar i;
 uchar o_buf[26];
   if(y)
	 o_buf[0] = 0x40 + 0x04; //本地上传收到的CRC正确数据  B7B6 =bit-01,B5~B0 = 0x04h
   else
     o_buf[0] = 0x40 + 0x05; //本地上传收到的CRC错误数据  B7B6 =bit-01,B5~B0 = 0x05h

	o_buf[1] = ADSS[0];
	o_buf[2] = ADSS[1];
	o_buf[3] = ADSS[2];
	o_buf[4] = ADSS[3];

   o_buf[AMR_OS_L] = 0x12;  // L=18

   for (i = 0; i < 18; i++)
	   o_buf[6 + i]	 = 	R_data[i];

   amr_send_frame(o_buf);
}

/*=============================================================================*/
void adss_crc(uchar buf[])
{
 if((buf[1] == ADSS[0])&&(buf[2] == ADSS[1])&&(buf[3] == ADSS[2])&&(buf[4] == ADSS[3]))
    adss_ok = 1;
 else adss_ok = 0;
}
/*=============================================================================*/
/*=============================================================================* /

/*=============================================================================*/
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$<<<<<软件说明>>>>>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/
/*=============================================================================* /
   智能控制演示程序(根据UPLM2200 API协议设定)
软件说明:

   1.更新的版本,支持电力线和PC通讯协议,
   2.可读写FLASH作为地址掉电保存,写时通过串口发地址数据,掉电后地址在片内保存.
   3.当写FLASH时,RXOK会闪动,之后返回一帧数据.表示已写入FLASH,
   4.该程序设有看门狗,添加新组件时注意时间差.
   5.如无接表时,可返回一帧仿真数据< *\   /* >
   6.该串口的波特率为9600,偶校验,      -
   7.可通过PC或电力线上改变速率寄存器的值,并写入 FLASH  ~
   
更新项目表:
------------------------------------------------------------------------------------------
|更新人   |   模块组件       |       更新时间   |    更新内容
--------------------------------------------------------------------------------------
| liangfq |     全部         | 2006-02-17       |    程序设计第一版
|         |                  |                  |  
--------------------------------------------------------------------------------------
| liangfq |           |  | 
|         |                  |                  |
--------------------------------------------------------------------------------------
| liangfq |            |  | 
|         |                  |                  |
--------------------------------------------------------------------------------------
| liangfq |                  |                  |
|         |                  |                  |
--------------------------------------------------------------------------------------
| liangfq |                  |                  |
|         |                  |                  |
--------------------------------------------------------------------------------------
| liangfq |                  |                  |
|         |                  |                  |
--------------------------------------------------------------------------------------
| liangfq |                  |                  |
|         |                  |                  |
--------------------------------------------------------------------------------------
| liangfq |                  |                  |
|         |                  |                  |
--------------------------------------------------------------------------------------
| liangfq |                  |                  |
|         |                  |                  |
--------------------------------------------------------------------------------------

!!!!!!重复特别注意:写模块的地址必须从串口写入才有效!!!!!                  

!!!!!!重复特别注意:写模块的地址必须从串口写入才有效!!!!!
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
!!!!!!重复特别注意:写模块的地址必须从串口写入才有效!!!!!
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
!!!!!!重复特别注意:写模块的地址必须从串口写入才有效!!!!!
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
!!!!!!重复特别注意:写模块的地址必须从串口写入才有效!!!!!
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$<<<<<软件说明>>>>>$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/








         
















⌨️ 快捷键说明

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