📄 main.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 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 + -