- 网页设计
- 整站网页设计
- 网站模板设计
- 网站开发
- 综合门户网开发
- 企业网站开发
- 电子商务网站开发
- 资讯网站开发
- 团购网站开发
- 手机网站开发
- 宣传展示网站
- 网站功能开发
- 网站特效制作
- 应用软件开发
- 手机应用软件
- 计算机应用软件
- 软件美工
- 程序修改
- 仿网站开发
- 脚本插件
- 软件测试
- 网站改版
- 企业办公系统
- 软件汉化
- 软件界面皮肤
- 企业办公系统界面
- 应用移植
- Android开发
- IOS开发
- 应用汉化
- 安卓系统定制
- 网店装修
MPC82G516 仿FX1NPLC 源码 V3
MPC82G516 仿FX1NPLC 源码 V3
/*----------------------------------------------------------------------------------------------------*/
/* */
/* PLC 梯型图 解释型监控 C Code示范程序(用于 51单片机) */
/* */
/* 为防止 PLC 指令编码和 C 语言关键字混淆,特规定,在本监控程序中,所有 PLC 指令前面加下划线"_", */
/* 所有点(BIT型)前后各加下划线"_",所有点(WORD型)前加下划线"_",指令后面的数据用( )包含,数据 */
/* 中间用","分隔,以示和 C 语言关键字区分及适应于 C 语言书写方法。 */
/* 所有十进制常数去掉前导"K",所有十六进制常数去掉前导"H"再加前导数字"0x",以便适应于 C 语言常 */
/* 数书写方法。这些下划线和加减前导数字将由 PLC 梯型图反编译程序自动加入。 */
/* */
/* 说心里话,这种容量小、功能少的 PLC,用汇编是最佳选择,程序精练、执行效率高,比如散转指令,用 */
/* C语言的函数指针效率大打折扣,但考虑到方便大家今后程序的移植、更改、提高,使之能适应于 AVR,STM8, */
/* NEC,PIC,H8,STM32......等任何单片机,未使用 51单片机特有的 bit 操作指令,关键部位也未插入汇编, */
/* 等程序修改稳定后再修改相关指令,优化程序代码,提升执行速度,使之更适合 51单片机的使用。 */
/* */
/* 本程序支持混合编程,即在 PLC 指令编码中可任意插入 C 语言语句,符合 C 语言规范的汇编语言语句。 */
/* 可使用现有的调试软件仿真器设置断点,单步,多步,跟踪,连续,全速等手段调试 PLC 程序,修改和监控 */
/* PLC 点件状态和内容,使之更适合广大单片机爱好者使用。 */
/* */
/* 目前支持下列点(继续完善中): */
/* _X0_---_X57_,_Y0_---_S57_,_M0_---_M255_,_S0_---_S255_,_T0---_T31,_C0---_C31,_D0---_D31; */
/* */
/* 目前支持常数(继续完善中): */
/* K 范围:-32768---32767; H 范围:0---FFFFH; */
/* */
/* 目前支持特殊点数(继续完善中): */
/* _M8000_,_M8001_,_M8002_,_M8003_,_M8004_,_M8011_,_M8012_,_M8013_,_M8014_, */
/* _M8020_,_M8021_,_M8022_; */
/* */
/* 目前支持下列基本指令和扩展指令(继续完善中): */
/* _LD,_LDI,_AND,_ANI,_OR,_ORI,_INV,_OUT(_OUT_T,_OUT_C),_SET,_RST,_ANB,_ORB,_LDP,_LDF,_ANDP,_ANDF, */
/* _ORP,_ORF,_PLS,_PLF,_MPS,_MRD,_MPP,_NOP,END,_ADD,_SUB,_MUL,_DIV,_INC,_DEC,_WAND,_WOR,_WXOR, */
/* _NEG,_ALT,_MOV,_CML,_XCH,_BCD,_BIN,_CMP,_ZCP,_FMOV,_ROR,_ROL,_ZRST,_REF,_ASCI,_SWAP,_CJ,_CALL, */
/* _SRET,_FEND,_LD>=,_LD<=,_LD>,_LD<,_LD<>,_LD=,_AND>=,_AND<=,_AND>,_AND<,_AND<>,_AND=,_OR>=,_OR<=, */
/* _OR>,_OR<,_OR<>,_OR=; */
/* */
/* 由于 C语言无法识别下列符号,特用下列英文缩写表示: */
/* 大于等于(>=) _GE,小于等于(<=) _LE,大于(>) _GT,小于(<) _LT,不相等(<>) _NE,相等(=) _EQ; */
/* 即指令集:_LD>=,_LD<=,_LD>,_LD<,_LD<>,_LD=,_AND>=,_AND<=,_AND>,_AND<,_AND<>,_AND=, */
/* _OR>=,_OR<=,_OR>,_OR<,_OR<>,_OR=; */
/* 用下列指令书写方式替代。 */
/* _LD_GE,_LD_LE,_LD_GT,_LD_LT,_LD_NE,_LD_EQ,_AND_GE,_AND_LE,_AND_GT,_AND_LT,_AND_NE,_AND_EQ, */
/* _OR_GE,_OR_LE,_OR_GT,_OR_LT,_OR_NE,_OR_EQ; */
/* */
/* */
/* C P U : MPC82G516A(51系列)单片机 */
/* 晶 振: 11.0592MHz */
/* 作 者: 许意义 */
/* 版 本: V1.1.6 */
/* 日 期: 2009.10.10 */
/* 版 权: ourDEV.cn */
/* */
/*----------------------------------------------------------------------------------------------------*/
/* 历次修改记录: 详见 updata.txt */
/*----------------------------------------------------------------------------------------------------*/
#include "SYSTEM.h"
// 所有头文件 至 SYSTEM.H MJ.2009.(咨询特价)
//#include "PLC51x_TYPE.H"
//#include "PLC51x_SYS.H"
//#include "PLC51x.H"
//#include "PLC51x_FNC.H"
//bit RUN = 0;
volatile unsigned char PLCRunFlag=1; // PLC 停止[0]运行[1] 标志位 MJ.2009.(咨询特价)
unsigned int code TYPE_BCD[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, // LED显示器段码表
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; // 0123456789AbCdEF
/***************************************************************************************/
unsigned char Timer_5ms; // 5ms时基计数器,5ms Timer0中断计数
unsigned char Timer_10ms; // 10ms时基计数器,5ms Timer0中断计数
unsigned char Timer_100ms; // 100ms时基计数器,5ms Timer0中断计数
unsigned char Pulse_val_Sec; // 1s时基计数器
unsigned char Pulse_val_Min; // 1min时基计数器
bit Pulse_10ms ;
bit Pulse_100ms;
bit Pulse_Sec ;
bit Pulse_Min ;
/***************************************************************************************/
volatile unsigned char data ACC_BIT; // 位运算器及 7级中间过渡栈
volatile unsigned char data MPS_BIT; // 位件 8级堆栈
//-------------------------------------------------------------------------------------//
// 位件 D 内存分配 //
//-------------------------------------------------------------------------------------//
volatile TYPE_BIT_BYTE data rX[_X_BYTE] , rY[_Y_BYTE]; // 位件 X,Y 存储位
volatile TYPE_BIT_BYTE data rX1[_X_BYTE], rY1[_Y_BYTE]; // 位件 X,Y 存储位上一步备份
volatile TYPE_BIT_BYTE data rM8xxx[3]; // 位件 M8xxx 存储位
volatile TYPE_BIT_BYTE data rM8xxx1[3]; // 位件 M8xxx 存储位上一步备份
volatile TYPE_BIT_BYTE data rTF[_T_BYTE]; // T 得电失电标志位
volatile TYPE_BIT_BYTE data rCF[_C_BYTE]; // C 得电失电标志位
volatile TYPE_BIT_BYTE data rT[_T_BYTE] , rC[_C_BYTE]; // 位件 T,C 输出位
volatile TYPE_BIT_BYTE data rT1[_T_BYTE], rC1[_C_BYTE]; // 位件 T,C 输出位上一步备份
volatile TYPE_BIT_BYTE xdata rM[_M_BYTE]; // 位件 M 存储位
volatile TYPE_BIT_BYTE xdata rS[_S_BYTE]; // 位件 S 存储位
volatile TYPE_BIT_BYTE xdata rM1[_M_BYTE]; // 位件 M 存储位上一步备份
volatile TYPE_BIT_BYTE xdata rS1[_S_BYTE]; // 位件 S 存储位上一步备份
volatile signed int xdata _T[_T_num][2]; // 位件 T 内存分配
volatile signed int xdata _C[_C_num]; // 位件 C 内存分配
volatile signed int xdata _D[_D_num]; // 位件 D 内存分配
//-------------------------------------------------------------------------------------//
// 基本指令,扩展指令 子函数 //
//-------------------------------------------------------------------------------------//
volatile unsigned char xdata addr0T,addr1T,addr2T,addr3T,addr4T; // 数据位第一至第五位字地址/数据类型
volatile TYPE_BYTES_WORD xdata addr0x,addr1x,addr2x,addr3x,addr4x; // 数据位第一至第五位字地址/数据缓冲区
volatile TYPE_BYTES_WORD xdata order0; // 命令位地址缓冲区
volatile unsigned int ppp;
volatile unsigned char code *CODE_p;
#if DEBUG
unsigned char code CODE_START[PLCSTEP*4] = {0x0,0x24,0x8,0x0,0x0,0x88,0x0,0x28,0x0,0xd5,0x1,0x24,0x9,
0x0,0x1,0x88,0x1,0x28,0x0,0xe5,0xca,0x1,0x2,0x84,0x2,0xc8,0x2,0x28,0x1,0xd5,0xcb,0x1,0x2,0x84,0x3,
0xc8,0x3,0x28,0x1,0xe5,0x0f,0x0
};
/*
unsigned char code CODE_START[PLCSTEP*4] = {0x00,0x24,0x00,0xd5, // 模拟PLC运行代码
0x01,0x24,0x00,0xe5,0x02,0x24,0x01,0xd5,0x03,0x24,0x01,0xe5,0x04,0x24,0x02,0xd5,
0x05,0x24,0x02,0xe5,0x06,0x24,0x03,0xd5,0x07,0x24,0x03,0xe5,0x08,0x24,0x04,0xc5,
0x09,0x24,0xfd,0xff,0x05,0xc5,0x0a,0x24,0x06,0xc5,0x0b,0x24,0xfd,0xff,0x07,0xc5,
0x0f,0x00,0xff,0xff,0xff,0xff };
*/
/*
unsigned char code CODE_START[PLCSTEP*2] = {
0x0,0x2f,0x1,0x6,0xa,0x80,0x0,0x80,0x1,0x26,0x0,0xc5,0x0,0x25,0x2,0x6,0xa,0x80,0x0,0x80,0x2,0x26,
0x1,0xc5,0x1,0x25,0x3,0x6,0xa,0x80,0x0,0x80,0x3,0x26,0x2,0xc5,0x2,0x25,0x4,0x6,0xa,0x80,0x0,0x80,
0x4,0x26,0x3,0xc5,0x3,0x25,0x5,0x6,0xa,0x80,0x0,0x80,0x5,0x26,0x4,0xc5,0x4,0x25,0x6,0x6,0xa,0x80,
0x0,0x80,0x6,0x26,0x5,0xc5,0x5,0x25,0x7,0x6,0xa,0x80,0x0,0x80,0x7,0x26,0x6,0xc5,0x6,0x25,0x8,0x6,
0xa,0x80,0x0,0x80,0x8,0x26,0x7,0xc5,0x7,0x25,0x0,0x6,0xa,0x80,0x0,0x80,0x0,0x26,0xc,0x0,0x1,0x86,
0xc,0x0,0x2,0x86,0xc,0x0,0x3,0x86,0xc,0x0,0x4,0x86,0xc,0x0,0x5,0x86,0xc,0x0,0x6,0x86,0xc,0x0,0x7,
(咨询特价),0xc,0x0,0x8,0x86,0xc,0x0,0x9,0x86,0xc,0x0,0x0,0x86,0x0f,0x0
};
*/
#endif
//-----------------------------------------------------------------------------------------//
// 数组名称: BYTE_BIT //
// 数组类型: unsigned char code BYTE_BIT[8] //
// //
// 功能描述: BYTE 字节型 BIT 位表 //
// //
// 入口参数: BIT 位编号 //
// //
// 出口参数: 返回 BYTE 字节中 BIT 屏蔽位 //
// //
// //
// 作 者: 许意义 //
// 日 期: 2009年10月2日 //
// 备 注: //
//-----------------------------------------------------------------------------------------//
// 修 改 人: 卢明君 //
// 日 期: 2009年12月01日 //
// 备 注: 从 PLC51x_FNC.c 文件 改至 PLC51x.c 文件 ; 消除编译警告. //
//-----------------------------------------------------------------------------------------//
unsigned char code BYTE_BIT_s[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
unsigned char code BYTE_BIT_w[8]={0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80};
unsigned char code BYTE_BIT_e[8]={0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
//-----------------------------------------------------------------------------------------//
// 子函数名: void inc_CODE_p(void) //
// //
// 注 释: 指向 PLC 运行程序的当前指针 CODE_p 值加 1 //
// //
// 入口参数: 无 //
// 出口参数: 无 //
//-----------------------------------------------------------------------------------------//
//void inc_CODE_p(void)
//{ CODE_p++;
//}
//-------------------------------------------------------------------------------------//
// 10ms延时子程序 //
//-------------------------------------------------------------------------------------//
void Time_10ms(void)
{ volatile unsigned char i;
for(i=0; i<10; i++)
{ ; }
}
//-------------------------------------------------------------------------------------//
// 74HC166并入串出芯片输入键盘扫描程序 //
//-------------------------------------------------------------------------------------//
unsigned char Get_EX_BIT(void)
{ unsigned char i;
unsigned char EX_data = 0;
HC166_SL = 0; // HC166_Disable; 将并行口的数据锁存
Time_10ms();
HC166_CLK = 0; // CLK : 0->1
Time_10ms();
HC166_CLK = 1;
Time_10ms();
HC166_SL = 1; // HC166_Enable; 转为串行
Time_10ms();
for(i=0; i<8; i++)
{ EX_data <<= 1;
if (HC166_DATA == 1) // DATA : QH
{ EX_data |= 0x01; }
HC166_CLK = 0; // CLK : 0->1
Time_10ms();
HC166_CLK = 1;
}
return(EX_data);
}
//-------------------------------------------------------------------------------------//
// 74HC595串入并出芯片输出(16bit数据)LED显示扫描程序 //
//-------------------------------------------------------------------------------------//
void Out_EY_BIT(void)
{ static unsigned char con;
unsigned char i;
unsigned int Ia;
if (++con >=5) { con = 0; }
switch(con)
{ case 0: Ia =( Value & 0x000f);
Ia = TYPE_BCD[Ia];
Ia |= 0x0800;
if (Vc0 == 1) { Ia |= 0xff; }
else { if (Vb0 == 1) { Ia &= 0xff7f; }
}
break;
case 1: Ia =((Value >> 4) & 0x000f);
Ia = TYPE_BCD[Ia];
Ia |= 0x0400;
if (Vc1 == 1) { Ia |= 0xff; }
else { if (Vb1 == 1) { Ia &= 0xff7f; }
}
break;
case 2: Ia =((Value >> 8) & 0x000f);
Ia = TYPE_BCD[Ia];
Ia |= 0x0200;
if (Vc2 == 1) { Ia |= 0xff; }
else { if (Vb2 == 1) { Ia &= 0xff7f; }
}
break;
case 3: Ia =((Value >>12) & 0x000f);
Ia = TYPE_BCD[Ia];
Ia |= 0x0100;
if (Vc3 == 1) { Ia |= 0xff; }
else { if (Vb3 == 1) { Ia &= 0xff7f; }
}
break;
default:
Ia = (~((Va4 << 4) | (Va3 << 3) | (Va2 << 2) | (Va1 << 1) | Va0) & 0x00ff) | 0x1000;
break;
}
for (i = 16; i > 0; i--)
{ HC595_SCLK = 0; //拉低74HC595时钟
Time_10ms();
if ((Ia & 0x8000) == 0) //先送高bit位数据
{ HC595_SDATA = 0; }
else //送74HC595的数据
{ HC595_SDATA = 1; }
Time_10ms();
Ia <<= 1;
HC595_SCLK = 1; //拉高74HC595时钟
Time_10ms();
}
HC595_SDATA = 1; //释放数据总线
Time_10ms();
HC595_RCLK = 0; //锁存数据
Time_10ms();
HC595_RCLK = 1;
Time_10ms();
}
//-------------------------------------------------------------------------------------//
// 100ms 定时子函数 //
//-------------------------------------------------------------------------------------//
void _T100mS(void)
{ unsigned char i;
if (Timer_100ms != 0)
{ Timer_100ms--;
Pulse_val_Sec++;
if (Pulse_val_Sec == 5)
{ Pulse_Sec = ~Pulse_Sec;
}
if (Pulse_val_Sec == 10)
{ Pulse_Sec = ~Pulse_Sec;
Pulse_val_Min++;
Pulse_val_Sec = 0;
}
for (i=0; i<_T_num; i++ )
{ if ((rTF[i/8].BYTE & (1 << (i%8))) != 0)
{ if (_T[i][0] < _T[i][1]) { _T[i][0]++; }
}
}
}
}
//-------------------------------------------------------------------------------------//
// 1Set 定时子函数 //
//-------------------------------------------------------------------------------------//
void _T1Set(void)
{ if ((Pulse_val_Min == 30) && (Pulse_val_Sec == 0))
{ Pulse_Min = ~Pulse_Min;
}
if ((Pulse_val_Min == 60) && (Pulse_val_Sec == 0))
{ Pulse_Min = ~Pulse_Min;
Pulse_val_Min = 0;
}
}
//-------------------------------------------------------------------------------------//
// 5ms 定时中断 子函数,使用定时器 0 //
//-------------------------------------------------------------------------------------//
void timer0(void) interrupt 1 using 1
{ TH0 = (Value_T0_cons >> 8);
Pulse_10ms = ~Pulse_10ms;
if ((++Timer_5ms & 0x01) != 0) { Timer_10ms++; }
if (Timer_5ms == 10) { Pulse_100ms = ~Pulse_100ms; }
if (Timer_5ms == 20)
{ Pulse_100ms = ~Pulse_100ms;
Timer_100ms++;
Timer_5ms = 0;
}
if(UartRxTimerStartFlag) // 接收超时...50ms
{ if(UartWaitForCounter>=10)
{ UartWaitForCounter=0;
UartRxTimerStartFlag=0;
UartDataReadyFlag=1;
REN=0; // 禁止UART接收器
}
else UartWaitForCounter++;
}
}
//-------------------------------------------------------------------------------------//
// 初始化,输入输出,内存处理 子函数 //
//-------------------------------------------------------------------------------------//
void input_IO(void) // X输入,Y输出刷新
{ unsigned char i;
i = P2;
i = ((i << 1) & 0xaa) | ((i >> 1) & 0x55);
i = ((i << 2) & 0xcc) | ((i >> 2) & 0x33);
rX[0].BYTE = ~((P1 & 0x0f) | (i & 0xf0));
rX[1].BYTE = ~(i & 0x0f) & 0x0f;
rX[2].BYTE = ~Get_EX_BIT();
P0 = rY[0].BYTE;
Out_EY_BIT();
_M8011_ = Pulse_10ms;
_M8012_ = Pulse_100ms;
_M8013_ = Pulse_Sec;
_M8014_ = Pulse_Min;
}
void reset_IO(void) // I,O口初始化
{ P0M0 = 0x00;
P0M1 = 0xff;
P0 = 0x00;
P1 = 0xff;
P2 = 0xff;
P3 = 0xff;
Value = 0; // 变频显示器LED显示缓冲区
Va0 = 0; // 变频显示器F/R指示显示缓冲区
Va1 = 0; // 变频显示器 Hz指示显示缓冲区
Va2 = 0; // 变频显示器 V 指示显示缓冲区
Va3 = 0; // 变频显示器 A 指示显示缓冲区
Va4 = 0; // 变频显示器PLCRunFlag指示显示缓冲区
Vb0 = 0; // 变频显示器LED个位小数点显示缓冲区
Vb1 = 0; // 变频显示器LED十位小数点显示缓冲区
Vb2 = 0; // 变频显示器LED百位小数点显示缓冲区
Vb3 = 0; // 变频显示器LED千位小数点显示缓冲区
Vc0 = 0; // 变频显示器LED个位数熄灭标志
Vc1 = 0; // 变频显示器LED十位数熄灭标志
Vc2 = 0; // 变频显示器LED百位数熄灭标志
Vc3 = 0; // 变频显示器LED千位数熄灭标志
}
void reset_M8xxx(void) // PLCRunFlag 后输出一个扫描周期初始化
{ rM8xxx[0].BYTE = 0x09;
}
void reset_RAM(void)
{ unsigned char i;
for (i=0; i<_T_num; i++) { _T[i][0] = 0; }
for (i=0; i<_T_num; i++) { _T[i][1] = 0x7fff; }
for (i=0; i<_C_num; i++) { _C[i] = 0; }
for (i=0; i<_T_BYTE; i++) { rT[i].BYTE = 0; rT1[i].BYTE = 0; rTF[i].BYTE = 0; }
for (i=0; i<_C_BYTE; i++) { rC[i].BYTE = 0; rT1[i].BYTE = 0; rCF[i].BYTE = 0; }
for (i=0; i<_Y_BYTE; i++) { rY[i].BYTE = 0; rY1[i].BYTE = 0; }
for (i=0; i<_M_BYTE; i++) { rM[i].BYTE = 0; rM1[i].BYTE = 0; }
for (i=0; i<_S_BYTE; i++) { rS[i].BYTE = 0; rS1[i].BYTE = 0; }
for (i=0; i<_M8xxx_BYTE; i++) { rM8xxx[i].BYTE = 0; rM8xxx1[i].BYTE = 0; }
rM8xxx[0].BYTE = 0x05;
rM8xxx1[0].BYTE = 0x05;
Timer_5ms = 0; // 5ms时基计数器,5ms Timer0中断计数
Timer_10ms = 0; // 10ms时基计数器,5ms Timer0中断计数
Timer_100ms = 0; // 100ms时基计数器,5ms Timer0中断计数
Pulse_val_Sec = 0; // 1s时基计数器
Pulse_val_Min = 0; // 1min时基计数器
CODE_ERROR = 0;
input_IO();
for (i=0; i<_X_BYTE; i++) { rX1[i].BYTE = rX[i].BYTE; }
}
void reset_interrupt(void)
{ IP = 0x00;
IE = 0x00;
TCON = 0x00; // 定时器控制寄存器, 注意:TCON只需操作一次
TMOD = 0x01;
T0 = Value_T0_cons; // 装入5ms Timer0中断常数
PT0 = 1;
ET0 = 1;
TR0 = 1;
}
void mov_to_old(void)
{ unsigned char i;
for (i=0; i<_X_BYTE; i++) { rX1[i].BYTE = rX[i].BYTE; }
for (i=0; i<_Y_BYTE; i++) { rY1[i].BYTE = rY[i].BYTE; }
for (i=0; i<_M_BYTE; i++) { rM1[i].BYTE = rM[i].BYTE; }
for (i=0; i<_S_BYTE; i++) { rS1[i].BYTE = rS[i].BYTE; }
for (i=0; i<_T_BYTE; i++) { rT1[i].BYTE = rT[i].BYTE; }
for (i=0; i<_C_BYTE; i++) { rC1[i].BYTE = rC[i].BYTE; }
for (i=0; i<_M8xxx_BYTE; i++) { rM8xxx1[i].BYTE = rM8xxx[i].BYTE; }
for (i=0; i<_T_num; i++ )
{ if (_T[i][0] >= _T[i][1])
{ rT[((&_T[i][0]-&_T[0][0])/2)/8].BYTE |= 1<<(((&_T[i][0]-&_T[0][0])/2)%8);
}
else { rT[((&_T[i][0]-&_T[0][0])/2)/8].BYTE &= ~(1 << (((&_T[i][0]-&_T[0][0])/2)%8));
}
}
PS1_BIT = PS_BIT;
}
#if 0
//-------------------------------------------------------------------------------------//
// 延迟 函数 delay_ms(unsigned int time) //
//-------------------------------------------------------------------------------------//
void delay_ms(unsigned int time)
{
volatile unsigned int i;
volatile unsigned char j;
for (i=0; i<time; i++)
{ for(j=0;j<0xfe;j++);
for(j=0;j<0xfe;j++);
}
}
#endif
//-------------------------------------------------------------------------------------//
// 串口初始化 函数 UartInit(); //
//-------------------------------------------------------------------------------------//
void UartInit(void)
{
SCON = 0x50;
TR1=0; // 停止定时器
// TCON=0x00; // 定时器控制寄存器 注意:TCON只需操作一次
TMOD |= 0x20; // 定时器1
TL1 = -(SYSCLK/12/32/BAUD);
TH1 = TL1;
TR1=1; // 启动定时器1
UartReceiveCounter=0;
UartRxTimerStartFlag=0;
}
//-------------------------------------------------------------------------------------//
// PLC 入口 函数 main_PLC(); //
//-------------------------------------------------------------------------------------//
void main_PLC (void)
{
CODE_p = (unsigned char code *)CODE_START;
Pi = 0x01;
do{
orderL = *CODE_p;
CODE_p++;
orderH = *CODE_p;
CODE_p++;
ppp = order & 0xfff;
(*key_list[orderH >> 4])();
} while((CODE_p < CODE_END) && (CODE_p != CODE_START));
}
unsigned char code ArrPLCSoftwareVer[] ="V1.01.06";// PLC Software Version
unsigned char FX1NPLCSoftwareVerCheck(void)
{
unsigned int i;
unsigned int tempaddr;
unsigned char tempArray[8];
unsigned char code ArrSoftwareUpdate[] ="Software Update!rn0";
// 根据 PLC 软件版本号,自动恢复出厂设置. MJ.2009.(咨询特价)
tempaddr=PLCSoftwareVerAddr;
for(i=0;i<8;i++)
{
tempArray[i]=IAPFlashReadMode(tempaddr++); // Software Version
if(tempArray[i]!=ArrPLCSoftwareVer[i])
{
UartSendByte(ArrPLCSoftwareVer,8);
UartSendString(ArrSoftwareUpdate);
return 0;
}
}
return 1;
}
void PLCStateCheck(void)
{
unsigned char tPLCState;
tPLCState=IAPFlashReadMode(PLCStateRealAddr);
if(tPLCState==PLCStateRun)PLCRunFlag=1;
else if(tPLCState==PLCStateStop)PLCRunFlag=0;
else
{
while(1); // 错误处理
}
}
//-------------------------------------------------------------------------------------//
// 主程序入口 主函数 //
//-------------------------------------------------------------------------------------//
void main(void)
{
unsigned char reset_i=1;
unsigned int i;
unsigned char PLCVerPassFlag;
unsigned char code ArrPass[] ="PASS!rn0";
unsigned char code DefaultSet[] ="System in factory default.rn0";
unsigned char TimesBuf=0; // 检测 上升 or下降 沿.
reset_IO();
reset_RAM();
reset_interrupt();
UartInit();
EA = 1;
PLCVerPassFlag=FX1NPLCSoftwareVerCheck(); // 上电,核实 PLC 软件版本号
if(PLCVerPassFlag==0) // 恢复出厂设置.
{
ErasurePLC(ErasureALL); // 全部擦除 初始PLC程序为空
for(i=0;i<8;i++) // 更新软件版本号
{
IAPFlashProgremMode(PLCSoftwareVerAddr+i,ArrPLCSoftwareVer[i]);
}
IAPFlashProgremMode(PLCStateRealAddr,PLCStateRun); // 写入 PLC [运行/停止状态位]为[运行]
for(i=0;i<92;i++) // 写入 PLC 初始化代码 查询地址0x8000~0x805B.
{
IAPFlashProgremMode(CodeStartAddr+i,CodeStart[i]);
}
for(i=0;i<0x100;i++) // 写入 PLC 初始化代码 查询地址0x0E00~0x0EFF
{
IAPFlashProgremMode(SDataRegStartAddr+SDataRegOffset+i,SDataReg[i]);
}
UartSendString(DefaultSet);
}
else UartSendString(ArrPass);
Value=0;
CODE_scan();
while (1)
{
// =============================================================================
// [====]以下内容由 MJ.2009.12.23 凌晨加入.
// 目的:【(运行)按钮按下】时为【停止】, 用 PLC -- 遥控运行/停止 命令至 PLC 内的控制字遥控运行/停止比按钮优先。
// ---- 摘自[★ 简易PLC 梯型图 解释型监控 示范程序 测试版(51)----直接使用三菱FXGPWIN软件!]一贴,第【199楼】 oste
// 说明:
// 1.在[运行按钮]按下(由抬起至按下)★变化当次★,无论[运行/停止状态位]是运行还是停止,一律停止;
// 2.在[运行按钮]抬起(由按下至抬起)★变化当次★,无论[运行/停止状态位]是运行还是停止,一律运行;
// 无论执行 1 或者 2 ,而后可通过[FXGPWIN]软件修改[运行/停止状态位].是运行就运行.是停止就停止;
// 注意:
// 1.请在[编写梯形图软件]时,自行避开两个引脚同时为低的情况.
// 2.请在[编写梯形图软件]时,注意这两个引脚为低时的后果.
TimesBuf<<=0x01;
if((P1 & 0x03) == 0)
{
if(TimesBuf==0xfc) // 下降沿
{
if(PLCRunFlag==1)IAPFlashProgremMode(PLCStateRealAddr,PLCStateStop);
}
else TimesBuf&=~0x01;
}
else
{
if(TimesBuf==0x02) // 上升沿
{
if(PLCRunFlag==0)IAPFlashProgremMode(PLCStateRealAddr,PLCStateRun);
}
else TimesBuf |=0x01;
}
PLCStateCheck();
// [====]以上内容由 MJ.2009.12.23 凌晨加入.
// =============================================================================
FX1NComPortProcessing(); // PLC 下载通信处理
if(PLCRunFlag)
{
input_IO();
if (CODE_ERROR == 0)main_PLC();
else
{
if (Pulse_Sec != 0)P1 &= 0xfc; // PLC 程序出错报警,X0,X1灯闪烁。
else P1 |= 0x03;
}
_T100mS();
_T1Set();
mov_to_old();
if (reset_i != 0)
{
reset_i--;
reset_M8xxx();
}
}
}
}
//-------- main END ----------//
-
最近销售:0 掌柜:禾苗云盾旗舰店¥897 元