750 lines
28 KiB
C
750 lines
28 KiB
C
/*----------------------------------------------------------------------------------------------------*/
|
||
/* */
|
||
/* PLC 梯型图(指令编码)转 51 C 程序示范程序 */
|
||
/* */
|
||
/* 为防止 PLC 指令编码和 C 语言关键字混淆,特规定,所有 PLC 指令前面加下划线"_",所有点(BIT型) */
|
||
/* 前后各加下划线"_",所有点(WORD型)前加下划线"_",指令后面的数据用( )包含,数据中间用","分隔, */
|
||
/* 以示和 C 语言关键字区分及适应于 C 语言书写方法。 */
|
||
/* 所有十进制常数去掉前导"K",所有十六进制常数去掉前导"H"再加前导数字"0x",以便适应于 C 语言常 */
|
||
/* 数书写方法。这些下划线和加减前导数字将由 PLC 梯型图反编译程序自动加入。 */
|
||
/* */
|
||
/* 由于考虑到今后程序的移植,使之能适应于 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,_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=; */
|
||
/* 用下列指令书写方式替代(由 PLC 梯型图反编译程序自动生成)。 */
|
||
/* _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; */
|
||
/* */
|
||
/* */
|
||
/* CPU : 51系列单片机 */
|
||
/* 晶振 : 11.0592MHz */
|
||
/* 作者 : 许意义 */
|
||
/* 版本 : V1.05 */
|
||
/* 日期 : 2009.7.7 */
|
||
/* 版权 : ourDEV.cn */
|
||
/* */
|
||
/*----------------------------------------------------------------------------------------------------*/
|
||
|
||
#include "REG_MPC82G516.H"
|
||
#include "INTRINS.H"
|
||
#include "PLC_TYPE.H"
|
||
|
||
/***************************************************************************************/
|
||
|
||
sbit HC166_CLK = P3^3; // HC166-7 脚: CLK 时钟
|
||
sbit HC166_DATA = P1^4; // HC166-13脚: QH 数据
|
||
sbit HC166_SL = P3^4; // HC166-15脚: SL 锁存
|
||
|
||
sbit HC595_SCLK = P3^3; // HC595-11脚: SCLK 时钟
|
||
sbit HC595_SDATA = P3^7; // HC595-14脚: SDATA 数据
|
||
sbit HC595_RCLK = P3^5; // HC595-12脚: RCLK 锁存
|
||
|
||
#define Value _D31 // 变频显示器LED显示缓冲区
|
||
#define Va0 _S251_ // 变频显示器F/R指示显示缓冲区
|
||
#define Va1 _S252_ // 变频显示器 Hz指示显示缓冲区
|
||
#define Va2 _S253_ // 变频显示器 V 指示显示缓冲区
|
||
#define Va3 _S254_ // 变频显示器 A 指示显示缓冲区
|
||
#define Va4 _S255_ // 变频显示器RUN指示显示缓冲区
|
||
#define Vb0 _S243_ // 变频显示器LED个位小数点显示缓冲区
|
||
#define Vb1 _S244_ // 变频显示器LED十位小数点显示缓冲区
|
||
#define Vb2 _S245_ // 变频显示器LED百位小数点显示缓冲区
|
||
#define Vb3 _S246_ // 变频显示器LED千位小数点显示缓冲区
|
||
#define Vc0 _S247_ // 变频显示器LED个位数熄灭标志
|
||
#define Vc1 _S248_ // 变频显示器LED十位数熄灭标志
|
||
#define Vc2 _S249_ // 变频显示器LED百位数熄灭标志
|
||
#define Vc3 _S250_ // 变频显示器LED千位数熄灭标志
|
||
// 变频显示器扩展键盘输入端口
|
||
// STOP/RESET -----> X20
|
||
// RUN -----> X21
|
||
// 下箭头 -----> X22
|
||
// JOG -----> X23
|
||
// 右移 -----> X24
|
||
// 上箭头 -----> X25
|
||
// ENTER/DATA -----> X26
|
||
// MENU/ESC -----> X27
|
||
|
||
unsigned int code TYPE_BCD[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, // LED显示器段码表
|
||
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; // 0123456789AbCdEF
|
||
|
||
#define _X_num 48 // 48个输入端口, 编号:X0-X57
|
||
#define _Y_num 48 // 48个输出端口, 编号:Y0-Y57
|
||
#define _M_num 256 // 256个中间M继电器,编号:M0-M255
|
||
#define _S_num 256 // 256个中间S继电器,编号:S0-S255
|
||
#define _T_num 32 // 32个定时器, 编号:T0-T31
|
||
#define _C_num 32 // 32个计数器, 编号:C0-C31
|
||
|
||
#define _X_BYTE (_X_num + 7) / 8 // 48个输入端口,所占内存字节数
|
||
#define _Y_BYTE (_Y_num + 7) / 8 // 48个输出端口,所占内存字节数
|
||
#define _M_BYTE (_M_num + 7) / 8 // 256个中间M继电器,所占内存字节数
|
||
#define _S_BYTE (_S_num + 7) / 8 // 256个中间S继电器,所占内存字节数
|
||
#define _T_BYTE (_T_num + 7) / 8 // 32个定时器,所占内存字节数
|
||
#define _C_BYTE (_C_num + 7) / 8 // 32个计数器,所占内存字节数
|
||
|
||
#define Value_T0_cons 0xEE00 // Timer0中断常数(8051_12T_11.0592MHz)
|
||
//#define Value_T0_cons 0x2800 // Timer0中断常数(8051_1T_11.0592MHz)
|
||
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时基计数器
|
||
#define Pulse_10ms _M8011_
|
||
#define Pulse_100ms _M8012_
|
||
#define Pulse_Sec _M8013_
|
||
#define Pulse_Min _M8014_
|
||
|
||
/***************************************************************************************/
|
||
|
||
typedef struct {
|
||
unsigned char BIT0: 1;
|
||
unsigned char BIT1: 1;
|
||
unsigned char BIT2: 1;
|
||
unsigned char BIT3: 1;
|
||
unsigned char BIT4: 1;
|
||
unsigned char BIT5: 1;
|
||
unsigned char BIT6: 1;
|
||
unsigned char BIT7: 1;
|
||
}TYPE_BIT; //定义一个只能按位域寻址的新变量类型
|
||
|
||
typedef union {
|
||
TYPE_BIT BIT; //可以按位域寻址
|
||
unsigned char BYTE; //可以按字节寻址
|
||
}TYPE_BIT_BYTE; //定义一个既能按位域寻址也可按字节寻址的新变量类型
|
||
|
||
unsigned char data ACC_BIT; // 位运算器及 7级中间过渡栈
|
||
unsigned char data MPS_BIT; // 位元件 8级堆栈
|
||
TYPE_BIT_BYTE data rX[_X_BYTE] , rY[_Y_BYTE]; // 位元件 X,Y 存储位
|
||
TYPE_BIT_BYTE data rX1[_X_BYTE], rY1[_Y_BYTE]; // 位元件 X,Y 存储位上一步备份
|
||
TYPE_BIT_BYTE data rM8xxx[3]; // 位元件 M8xxx 存储位
|
||
TYPE_BIT_BYTE data rTF[_T_BYTE]; // T 得电失电标志位
|
||
TYPE_BIT_BYTE data rCF[_C_BYTE]; // C 得电失电标志位
|
||
TYPE_BIT_BYTE data rT[_T_BYTE] , rC[_C_BYTE]; // 位元件 T,C 输出位
|
||
TYPE_BIT_BYTE data rT1[_T_BYTE], rC1[_C_BYTE]; // 位元件 T,C 输出位上一步备份
|
||
TYPE_BIT_BYTE idata rM[_M_BYTE]; // 位元件 M 存储位
|
||
TYPE_BIT_BYTE xdata rS[_S_BYTE]; // 位元件 S 存储位
|
||
TYPE_BIT_BYTE xdata rM1[_M_BYTE], rS1[_S_BYTE]; // 位元件 M,S 存储位上一步备份
|
||
unsigned int xdata _T[_T_num][2], _C[_C_num]; // 位元件 T,C 内存分配
|
||
|
||
void main_PLC(void); // PLC 入口 主函数
|
||
|
||
//-------------------------------------------------------------------------------------//
|
||
// 位元件 D 内存分配 //
|
||
//-------------------------------------------------------------------------------------//
|
||
signed int xdata _D0 , _D1 , _D2 , _D3 , _D4 , _D5 , _D6 , _D7 ;
|
||
signed int xdata _D8 , _D9 , _D10, _D11, _D12, _D13, _D14, _D15;
|
||
signed int xdata _D16, _D17, _D18, _D19, _D20, _D21, _D22, _D23;
|
||
signed int xdata _D24, _D25, _D26, _D27, _D28, _D29, _D30, _D31;
|
||
|
||
//-------------------------------------------------------------------------------------//
|
||
// 基本指令,扩展指令 子函数 //
|
||
//-------------------------------------------------------------------------------------//
|
||
|
||
#define _LD(a) _LDx(a);
|
||
#define _LDI(a) _LDIx(a);
|
||
#define _AND(a) _ANDx(a);
|
||
#define _ANI(a) _ANIx(a);
|
||
#define _OR(a) _ORx(a);
|
||
#define _ORI(a) _ORIx(a);
|
||
#define _INV _INVx();
|
||
#define _OUT(a) a = OUTx();
|
||
#define _OUT_T(a,k) if ((ACC_BIT & 0x01) != 0) \
|
||
{ if ((a##_F) == 0) { (a##_F) = 1; a=0; *((&##a)+1) = k; }} \
|
||
else { (a##_F) = 0; a=0; } // _Tx, _Tx_F, _TKx, K
|
||
#define _OUT_C(a,k) if ((ACC_BIT & 0x01) != 0) \
|
||
{ if ((a##_F) == 0) \
|
||
{ (a##_F) = 1; \
|
||
if (a < k) \
|
||
{ a++; \
|
||
if (a >= k) \
|
||
{ rC[(&a-&_C0)/8].BYTE |= 1<<((&a-&_C0)%8); } \
|
||
else { rC[(&a-&_C0)/8].BYTE &= ~(1 << ((&a-&_C0)%8)); } \
|
||
} \
|
||
} \
|
||
} \
|
||
else { (a##_F) = 0; } // _Tx, _Tx_F, _TKx, K
|
||
#define _SET(a) if ((ACC_BIT & 0x01) != 0) { a = 1; }
|
||
#define _RST(a) if ((ACC_BIT & 0x01) != 0) { a = 0; }
|
||
#define _RST_T(a) if ((ACC_BIT & 0x01) != 0) { a = 0; rT[(&a-&_T0)/8].BYTE &= ~(1 << ((&a-&_T0)%8)); }
|
||
#define _RST_C(a) if ((ACC_BIT & 0x01) != 0) { a = 0; rC[(&a-&_C0)/8].BYTE &= ~(1 << ((&a-&_C0)%8)); }
|
||
#define _ANB _ANBx();
|
||
#define _ORB _ORBx();
|
||
#define _LDP(a) _LDPx(a,a##old);
|
||
#define _LDF(a) _LDFx(a,a##old);
|
||
#define _ANDP(a) _ANDPx(a,a##old);
|
||
#define _ANDF(a) _ANDFx(a,a##old);
|
||
#define _ORP(a) _ORPx(a,a##old);
|
||
#define _ORF(a) _ORFx(a,a##old);
|
||
#define _PLS(a) if ((ACC_BIT & 0x01) != 0) { a = _PLSx(a,a##old); }
|
||
#define _PLF(a) if ((ACC_BIT & 0x01) != 0) { a = _PLFx(a,a##old); }
|
||
#define _MPS _MPSx();
|
||
#define _MRD _MRDx();
|
||
#define _MPP _MPPx();
|
||
#define _NOP _nop_();
|
||
#define _END _nop_();
|
||
#define _ADD(a,b,c) if ((ACC_BIT & 0x01) != 0) { _FNC_ADD(a,b,&##c); }
|
||
#define _SUB(a,b,c) if ((ACC_BIT & 0x01) != 0) { _FNC_SUB(a,b,&##c); }
|
||
#define _MUL(a,b,c) if ((ACC_BIT & 0x01) != 0) { _FNC_MUL(a,b,&##c); }
|
||
#define _DIV(a,b,c) if ((ACC_BIT & 0x01) != 0) { _FNC_DIV(a,b,&##c); }
|
||
#define _INC(a) if ((ACC_BIT & 0x01) != 0) { _FNC_INC(&##a); }
|
||
#define _DEC(a) if ((ACC_BIT & 0x01) != 0) { _FNC_DEC(&##a); }
|
||
#define _WAND(a,b,c) if ((ACC_BIT & 0x01) != 0) { _FNC_WAND(a,b,&##c); }
|
||
#define _WOR(a,b,c) if ((ACC_BIT & 0x01) != 0) { _FNC_WOR(a,b,&##c); }
|
||
#define _WXOR(a,b,c) if ((ACC_BIT & 0x01) != 0) { _FNC_WXOR(a,b,&##c); }
|
||
#define _NEG(a) if ((ACC_BIT & 0x01) != 0) { _FNC_NEG(a,&##a); }
|
||
#define _ALT(a) if ((ACC_BIT & 0x01) != 0) { a = _FNC_ALT(a); }
|
||
#define _MOV(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_MOV(a,&##b); }
|
||
#define _CML(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_CML(a,&##b); }
|
||
#define _XCH(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_XCH(&##a,&##b); }
|
||
#define _BCD(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_BCD(a,&##b); }
|
||
#define _BIN(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_BIN(a,&##b); }
|
||
#define _LD_GE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_LD_GE(a,b); }
|
||
#define _LD_LE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_LD_LE(a,b); }
|
||
#define _LD_GT(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_LD_GT(a,b); }
|
||
#define _LD_LT(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_LD_LT(a,b); }
|
||
#define _LD_NE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_LD_NE(a,b); }
|
||
#define _LD_EQ(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_LD_EQ(a,b); }
|
||
#define _AND_GE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_AND_GE(a,b); }
|
||
#define _AND_LE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_AND_LE(a,b); }
|
||
#define _AND_GT(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_AND_GT(a,b); }
|
||
#define _AND_LT(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_AND_LT(a,b); }
|
||
#define _AND_NE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_AND_NE(a,b); }
|
||
#define _AND_EQ(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_AND_EQ(a,b); }
|
||
#define _OR_GE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_OR_GE(a,b); }
|
||
#define _OR_LE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_OR_LE(a,b); }
|
||
#define _OR_GT(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_OR_GT(a,b); }
|
||
#define _OR_LT(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_OR_LT(a,b); }
|
||
#define _OR_NE(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_OR_NE(a,b); }
|
||
#define _OR_EQ(a,b) if ((ACC_BIT & 0x01) != 0) { _FNC_OR_EQ(a,b); }
|
||
|
||
void _LDx(unsigned char a)
|
||
{ ACC_BIT <<= 1;
|
||
ACC_BIT |= a;
|
||
}
|
||
|
||
void _LDIx(unsigned char a)
|
||
{ ACC_BIT <<= 1;
|
||
ACC_BIT |= (~a & 0x01);
|
||
}
|
||
|
||
void _ANDx(unsigned char a)
|
||
{ ACC_BIT &= a;
|
||
}
|
||
|
||
void _ANIx(unsigned char a)
|
||
{ ACC_BIT &= (~a & 0x01);
|
||
}
|
||
|
||
void _ORx(unsigned char a)
|
||
{ ACC_BIT |= a;
|
||
}
|
||
|
||
void _ORIx(unsigned char a)
|
||
{ ACC_BIT |= (~a & 0x01);
|
||
}
|
||
|
||
void _INVx(void)
|
||
{ ACC_BIT = (ACC_BIT & 0xfe) | (~ACC_BIT & 0x01);
|
||
}
|
||
|
||
char OUTx(void)
|
||
{ return(ACC_BIT & 0x01);
|
||
}
|
||
|
||
void _ANBx(void)
|
||
{ ACC_BIT = (ACC_BIT >> 1) & (ACC_BIT & 0x01);
|
||
}
|
||
|
||
void _ORBx(void)
|
||
{ ACC_BIT = (ACC_BIT >> 1) | (ACC_BIT & 0x01);
|
||
}
|
||
|
||
void _LDPx(unsigned char a, unsigned char b)
|
||
{ ACC_BIT <<= 1;
|
||
ACC_BIT |= ((a & ~b) & 0x01);
|
||
}
|
||
|
||
void _LDFx(unsigned char a, unsigned char b)
|
||
{ ACC_BIT <<= 1;
|
||
ACC_BIT |= ((~a & b) & 0x01);
|
||
}
|
||
|
||
void _ANDPx(unsigned char a, unsigned char b)
|
||
{ ACC_BIT &= ((a & ~b) & 0x01);
|
||
}
|
||
|
||
void _ANDFx(unsigned char a, unsigned char b)
|
||
{ ACC_BIT &= ((~a & b) & 0x01);
|
||
}
|
||
|
||
void _ORPx(unsigned char a, unsigned char b)
|
||
{ ACC_BIT |= ((a & ~b) & 0x01);
|
||
}
|
||
|
||
void _ORFx(unsigned char a, unsigned char b)
|
||
{ ACC_BIT |= ((~a & b) & 0x01);
|
||
}
|
||
|
||
unsigned char _PLSx(unsigned char a, unsigned char b)
|
||
{ return((a & ~b) & 0x01);
|
||
}
|
||
|
||
unsigned char _PLFx(unsigned char a, unsigned char b)
|
||
{ return((~a & b) & 0x01);
|
||
}
|
||
|
||
void _MPSx(void)
|
||
{ MPS_BIT = (MPS_BIT << 1) | (ACC_BIT & 0x01);
|
||
}
|
||
|
||
void _MRDx(void)
|
||
{ ACC_BIT = (ACC_BIT & 0xfe) | (MPS_BIT & 0x01);
|
||
}
|
||
|
||
void _MPPx(void)
|
||
{ ACC_BIT = (ACC_BIT & 0xfe) | (MPS_BIT & 0x01);
|
||
MPS_BIT >>= 1;
|
||
}
|
||
|
||
void _FNC_ADD(int a, int b, int* c)
|
||
{ *c = a + b;
|
||
}
|
||
|
||
void _FNC_SUB(int a, int b, int* c)
|
||
{ *c = a - b;
|
||
}
|
||
|
||
void _FNC_MUL(int a, int b, int* c)
|
||
{ *c = a * b;
|
||
}
|
||
|
||
void _FNC_DIV(int a, int b, int* c)
|
||
{ *c = a / b;
|
||
}
|
||
|
||
void _FNC_INC(int* a)
|
||
{ ++(*a);
|
||
}
|
||
|
||
void _FNC_DEC(int* a)
|
||
{ --(*a);
|
||
}
|
||
|
||
void _FNC_WAND(int a, int b, int* c)
|
||
{ *c = a & b;
|
||
}
|
||
|
||
void _FNC_WOR(int a, int b, int* c)
|
||
{ *c = a | b;
|
||
}
|
||
|
||
void _FNC_WXOR(int a, int b, int* c)
|
||
{ *c = a ^ b;
|
||
}
|
||
|
||
void _FNC_NEG(int a, int* b)
|
||
{ *b = ~a + 1;
|
||
}
|
||
|
||
unsigned char _FNC_ALT(unsigned char a)
|
||
{ return((~a) & 0x01);
|
||
}
|
||
|
||
void _FNC_MOV(int a, int* b)
|
||
{ *b = a;
|
||
}
|
||
|
||
void _FNC_CML(int a, int* b)
|
||
{ *b = ~a;
|
||
}
|
||
|
||
void _FNC_XCH(int* a, int* b)
|
||
{ int c;
|
||
c = *a;
|
||
*a = *b;
|
||
*b = c;
|
||
}
|
||
|
||
void _FNC_BCD(int a, int* b)
|
||
{ signed int Ia;
|
||
Ia = (a / 1000) << 12;
|
||
a %= 1000;
|
||
Ia |= (a / 100 ) << 8;
|
||
a %= 100;
|
||
Ia |= (a / 10 ) << 4;
|
||
a %= 10;
|
||
*b = Ia | a;
|
||
}
|
||
|
||
void _FNC_BIN(int a, int* b)
|
||
{ signed int Ia;
|
||
Ia = ((a >> 12) & 0x0f) * 1000;
|
||
Ia += ((a >> 8 ) & 0x0f) * 100;
|
||
Ia += ((a >> 4 ) & 0x0f) * 10;
|
||
Ia += a & 0x0f;
|
||
*b = Ia;
|
||
}
|
||
|
||
void _FNC_LD_GE(int a, int b)
|
||
{ ACC_BIT <<= 1;
|
||
if (a >= b) { ACC_BIT |= 0x01; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_LD_LE(int a, int b)
|
||
{ ACC_BIT <<= 1;
|
||
if (a <= b) { ACC_BIT |= 0x01; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_LD_GT(int a, int b)
|
||
{ ACC_BIT <<= 1;
|
||
if (a > b) { ACC_BIT |= 0x01; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_LD_LT(int a, int b)
|
||
{ ACC_BIT <<= 1;
|
||
if (a < b) { ACC_BIT |= 0x01; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_LD_NE(int a, int b)
|
||
{ ACC_BIT <<= 1;
|
||
if (a != b) { ACC_BIT |= 0x01; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_LD_EQ(int a, int b)
|
||
{ ACC_BIT <<= 1;
|
||
if (a == b) { ACC_BIT |= 0x01; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_AND_GE(int a, int b)
|
||
{ if (a >= b) { ; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_AND_LE(int a, int b)
|
||
{ if (a <= b) { ; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_AND_GT(int a, int b)
|
||
{ if (a > b) { ; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_AND_LT(int a, int b)
|
||
{ if (a < b) { ; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_AND_NE(int a, int b)
|
||
{ if (a != b) { ; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_AND_EQ(int a, int b)
|
||
{ if (a == b) { ; }
|
||
else { ACC_BIT &= 0xfe; }
|
||
}
|
||
|
||
void _FNC_OR_GE(int a, int b)
|
||
{ if (a >= b) { ACC_BIT |= 0x01; }
|
||
}
|
||
|
||
void _FNC_OR_LE(int a, int b)
|
||
{ if (a <= b) { ACC_BIT |= 0x01; }
|
||
}
|
||
|
||
void _FNC_OR_GT(int a, int b)
|
||
{ if (a > b) { ACC_BIT |= 0x01; }
|
||
}
|
||
|
||
void _FNC_OR_LT(int a, int b)
|
||
{ if (a < b) { ACC_BIT |= 0x01; }
|
||
}
|
||
|
||
void _FNC_OR_NE(int a, int b)
|
||
{ if (a != b) { ACC_BIT |= 0x01; }
|
||
}
|
||
|
||
void _FNC_OR_EQ(int a, int b)
|
||
{ if (a == b) { ACC_BIT |= 0x01; }
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------//
|
||
// 10ms延时子程序 //
|
||
//-------------------------------------------------------------------------------------//
|
||
|
||
void Time_10ms(void)
|
||
{ 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]++; }
|
||
}
|
||
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));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------//
|
||
// 1Set 定时子函数 //
|
||
//-------------------------------------------------------------------------------------//
|
||
|
||
void _T1Set(void)
|
||
{ if (Pulse_val_Min == 30)
|
||
{ Pulse_Min = ~Pulse_Min;
|
||
}
|
||
if (Pulse_val_Min == 60)
|
||
{ 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;
|
||
}
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------//
|
||
// 初始化,输入输出,内存处理 子函数 //
|
||
//-------------------------------------------------------------------------------------//
|
||
|
||
void reset_IO(void) // I,O口初始化
|
||
{ P0M1 = 0xff;
|
||
rM8xxx[0].BYTE = 0x05;
|
||
rM8xxx[1].BYTE = 0;
|
||
rM8xxx[2].BYTE = 0;
|
||
Value = 0; // 变频显示器LED显示缓冲区
|
||
Va0 = 0; // 变频显示器F/R指示显示缓冲区
|
||
Va1 = 0; // 变频显示器 Hz指示显示缓冲区
|
||
Va2 = 0; // 变频显示器 V 指示显示缓冲区
|
||
Va3 = 0; // 变频显示器 A 指示显示缓冲区
|
||
Va4 = 0; // 变频显示器RUN指示显示缓冲区
|
||
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_IO1(void) // RUN 后输出一个扫描周期初始化
|
||
{ 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<_C_num; i++) { _C[i] = 0; }
|
||
for (i=0; i<_T_BYTE; i++) { rT[i].BYTE = 0; }
|
||
for (i=0; i<_C_BYTE; i++) { rC[i].BYTE = 0; }
|
||
}
|
||
|
||
void reset_interrupt(void)
|
||
{ TMOD = 0x11;
|
||
T0 = Value_T0_cons; // 装入5ms Timer0中断常数
|
||
PT0 = 1;
|
||
ET0 = 1;
|
||
TR0 = 1;
|
||
EA = 1;
|
||
}
|
||
|
||
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();
|
||
}
|
||
|
||
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; }
|
||
}
|
||
|
||
//-------------------------------------------------------------------------------------//
|
||
// 主程序入口 主函数 //
|
||
//-------------------------------------------------------------------------------------//
|
||
|
||
void main(void)
|
||
{ unsigned char i=1;
|
||
reset_IO();
|
||
reset_RAM();
|
||
reset_interrupt();
|
||
while (1)
|
||
{
|
||
input_IO();
|
||
main_PLC();
|
||
_T100mS();
|
||
_T1Set();
|
||
mov_to_old();
|
||
if (i != 0)
|
||
{ i = 0; reset_IO1(); }
|
||
}
|
||
}
|
||
|
||
//-------- END -------//
|
||
|