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

📄 main.c

📁 此源码为商用的电力抄表系统的从机端源程序。通过电力载波模块
💻 C
📖 第 1 页 / 共 2 页
字号:
/* //////////////////////////////////////////////////////////////////////////
// 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 ADDR[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;

//bit auto_tx;//上电发送控制	   extern 
//bit auto_tx;//自动控制与PC控制标示
//bit Rx_bit; //主机接收控制
//bit master_slave;  // 主从
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 switd_s;   //开关确认
bit switd_T1;  //开关-开标示
bit switd_T2;  //开关-关标示

bit reply; //数据返回
bit adss_ok;//本地址正确标示
bit public_addr; //公用地址标示
bit CRC_switch;//CRC开关
bit addr_wr;//写地址标示

sbit tai    = P0^4;//   灯开关控制端
sbit switd =  P0^5;  //双联开关
					 
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 write_addr (bit y,uchar frame[]);//写地址功能
void processing_unit(uchar frame[]);//数据接收处理
//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;
  reply  = 0;
  adss_ok = 0;
  public_addr = 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)|| public_addr){;//地址校验)//地址是否对
			   //rx_return(1,plc_frame);	//数据发入串口
               processing_unit(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(); /*-延迟返回------*/
			   }
              adss_ok = 0;public_addr = 0;//地址标示清零
			  setup_t2(4000, timeout_t2); //40S	 
			}

         /********************************************************/
         if(switd  == !switd_T1){    //switd - on
               switd_T1  = 1;
               if(switd_T1 == switd_T2){
                  switd_T2 = 0;
                  switd_s = 1; //开关确认 
               }
           }
         if(!switd  == !switd_T2){    //switd - off
               switd_T2  = 1;
               if(switd_T2 == switd_T1){
                  switd_T1 = 0;
                  switd_s = 1; //开关确认
               }
            }
          if(switd_s){
            switd_s = 0;
            addr_wr = ~addr_wr;  //写地址
            tai  = ~tai; //灯的开关
          }
         /********************************************************/

		  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;

                      case 0x3f:{write_addr (0,frame);}break;
              }
           }break;

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

         case 0x03:{;}break;
        
         
     	     

⌨️ 快捷键说明

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