三菱梯型图转STM32 C语言,移植完成,所以指令使用汇编实现,执行速度非常快。逻辑指令
//-------------------------------------------------------////基本指令,扩展指令 宏定义
//-------------------------------------------------------//
#define_START _START_();
#define_END _END_();
#define_NOP _NOP_();
#define_MPS _MPS_();
#define_MRD _MRD_();
#define_MPP _MPP_();
#define_LD_GE(a,b) _LD_GE_(a,b);
#define_LD_LE(a,b) _LD_LE_(a,b);
#define_LD_GT(a,b) _LD_GT_(a,b);
#define_LD_LT(a,b) _LD_LT_(a,b);
#define_LD_NE(a,b) _LD_NE_(a,b);
#define_LD_EQ(a,b) _LD_EQ_(a,b);
#define_AND_GE(a,b) _AND_GE_(a,b);
#define_AND_LE(a,b) _AND_LE_(a,b);
#define_AND_GT(a,b) _AND_GT_(a,b);
#define_AND_LT(a,b) _AND_LT_(a,b);
#define_AND_NE(a,b) _AND_NE_(a,b);
#define_AND_EQ(a,b) _AND_EQ_(a,b);
#define_OR_GE(a,b) _OR_GE_(a,b);
#define_OR_LE(a,b) _OR_LE_(a,b);
#define_OR_GT(a,b) _OR_GT_(a,b);
#define_OR_LT(a,b) _OR_LT_(a,b);
#define_OR_NE(a,b) _OR_NE_(a,b);
#define_OR_EQ(a,b) _OR_EQ_(a,b);
#define_ANB _ANB_();
#define_ORB _ORB_();
#define_INV _INV_();
#define_PLS(nl) _PLS_(nl);
#define_PLF(nl) _PLF_(nl);
#define_LD(n) _LD_(n);
#define_LDI(n) _LDI_(n);
#define_LDP(n) _LDP_(n);
#define_LDF(n) _LDF_(n);
#define_AND(n) _AND_(n);
#define_ANI(n) _ANI_(n);
#define_ANDP(n) _ANDP_(n);
#define_ANDF(n) _ANDF_(n);
#define_OR(n) _OR_(n);
#define_ORI(n) _ORI_(n);
#define_ORP(n) _ORP_(n);
#define_ORF(n) _ORF_(n);
#define_OUT(n) _OUT_(n);
#define_SET(n) _SET_(n);
#define_RST(n) _RST_(n);
#define_CPL(n) _CPL_(n);
#define_ADD(a,b,c) _FNC_ADD(a,b,&##c);
#define_SUB(a,b,c) _FNC_SUB(a,b,&##c);
#define_MUL(a,b,c) _FNC_MUL(a,b,&##c);
#define_DIV(a,b,c) _FNC_DIV(a,b,&##c);
#define_INC(a) _FNC_INC(&##a);
#define_DEC(a) _FNC_DEC(&##a);
#define_WAND(a,b,c) _FNC_WAND(a,b,&##c);
#define_WOR(a,b,c) _FNC_WOR(a,b,&##c);
#define_WXOR(a,b,c) _FNC_WXOR(a,b,&##c);
#define_NEG(a) _FNC_NEG(a,&##a);
#define_ALT(a) _FNC_ALT(a);
#define_MOV(a,b) _FNC_MOV(a,&##b);
#define_CML(a,b) _FNC_CML(a,&##b);
#define_XCH(a,b) _FNC_XCH(&##a,&##b);
#define_BCD(a,b) _FNC_BCD(a,&##b);
#define_BIN(a,b) _FNC_BIN(a,&##b);
#define_OUT_T(a,k) _OUT_T_(&a,k-1);
#define_OUT_C(a,k) _OUT_C_(&a,k-1);
#define_SET_T(a) _SET_T_(&a);
#define_RST_C(a) _RST_C_(&a);
/* 私有函数原型 -----------------------------------------------------*/
__asm void_START_(void);
__asm void_END_(void);
__asm void_NOP_(void);
__asm void_MPS_(void);
__asm void_MRD_(void);
__asm void_MPP_(void);
__asm void_ANB_(void);
__asm void_ORB_(void);
__asm void_INV_(void);
__asm void_PLS_(u32 nl);
__asm void_PLF_(u32 nl);
__asm void_LD_(u32 n);
__asm void_LDI_(u32 n);
__asm void_LDP_(u32 n);
__asm void_LDF_(u32 n);
__asm void_AND_(u32 n);
__asm void_ANI_( u32 n);
__asm void_ANDP_(u32 n);
__asm void_ANDF_(u32 n);
__asm void_OR_(u32 n);
__asm void_ORI_(u32 n);
__asm void_ORP_(u32 n);
__asm void_ORF_(u32 n);
__asm void_OUT_(u32 n);
__asm void_SET_(u32 n);
__asm void_RST_(u32 n);
__asm void_CPL_(u32 n);
__asm void_LD_GE_( s16 a,s16 b );
__asm void_LD_LE_( s16 a,s16 b );
__asm void_LD_GT_( s16 a,s16 b );
__asm void_LD_LT_( s16 a,s16 b );
__asm void_LD_NE_( s16 a,s16 b );
__asm void_LD_EQ_( s16 a,s16 b );
__asm void_AND_GE_( s16 a,s16 b );
__asm void_AND_LE_( s16 a,s16 b );
__asm void_AND_GT_( s16 a,s16 b );
__asm void_AND_LT_( s16 a,s16 b );
__asm void_AND_NE_( s16 a,s16 b );
__asm void_AND_EQ_( s16 a,s16 b );
__asm void_OR_GE_( s16 a,s16 b );
__asm void_OR_LE_( s16 a,s16 b );
__asm void_OR_GT_( s16 a,s16 b );
__asm void_OR_LT_( s16 a,s16 b );
__asm void_OR_NE_( s16 a,s16 b );
__asm void_OR_EQ_( s16 a,s16 b );
__asm void_FNC_ADD( s16 a, s16 b, s16* c );
__asm void_FNC_SUB( s16 a, s16 b, s16* c );
__asm void_FNC_MUL( s16 a, s16 b, s16* c );
__asm void_FNC_DIV( s16 a, s16 b, s16* c );
__asm void_FNC_INC( s16*a);
__asm void_FNC_DEC( s16*a);
__asm void_FNC_WAND( s16 a, s16 b, s16* c );
__asm void_FNC_WOR( s16 a, s16 b, s16* c );
__asm void_FNC_WXOR( s16 a, s16 b, s16* c );
__asm void_FNC_NEG( s16 a, s16*b);
__asm void_FNC_MOV( s16 a, s16*b);
__asm void_FNC_CML( s16 a, s16*b);
__asm void_FNC_XCH( s16*a, s16*b);
__asm void_FNC_BCD( s16 a, s16*b);
__asm void_FNC_BIN( s16 a, s16*b);
__asm u8 _FNC_ALT( u8 a);
__asm void _OUT_T_( s16* a, s16 k );
__asm void _OUT_C_( s16* a, s16 k );
__asm void _RST_T_( s16* a );
__asm void _RST_C_( s16* a );
//-------------------------------------------------------//
// Modbus数据区分配
//-------------------------------------------------------//
#define S_Size 1024 //S000-1023 (128 byte) ->0x000-3FF
#define X_Size 256 //X000-377 (32 byte) ->0x400-4FF
#define Y_Size 256 //Y000-377 (32 byte) ->0x500_5FF
#define T_Size 512 //C000-511 (64 byte) ->0x600-7FF
#define M_Size 1536 //M000-1536 (192 byte) ->0x800-DFF
#define C_Size 256 //C000-255 (32 byte) ->0xE00-EFF
#define M8_Size 256 //M8000-8255 (32 byte) ->0xF00-FFF
#define MH_Size 2560 //M1536-4095 ( 320 byte) ->0xB000-FFF
#define D_Size 2048 //
//===========================================================//
// 杂类指令
//===========================================================//
__asm void _START_(void)
{
//保护现场
PUSH {R3-R12}
// 备份栈指针
MOV R6,SP
// 上次值偏移地址
LDR R5, = 512*8*4
BX lr
}
__asm void _END_(void)
{
// 恢复栈指针
MOV SP,R6
// 恢复现场
POP {R3-R12}
BX lr
}
__asm void _NOP_(void)
{
BX lr
}
//=====================================//
// 栈指令xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//=====================================//
//=====================================//
// 块指令
//=====================================//
__asm void _ANB_( void )
{
//R1 出栈
POP {R1}
//R7 <= ( R7 | R1 )
AND R7,R1
BX lr
}
__asm void _ORB_( void )
{
//R1 出栈
POP {R1}
//R7 <= ( R7 | R1 )
ORR R7,R1
BX lr
}
//=====================================//
// 输出预处理指令
//=====================================//
__asm void _INV_( void )
{
// R7 <= !R7
EOR R7,R7,#1
BX lr
}
__asm void _PLS_( u32 nl )
{
// R7 <=(R7 ^ nl) & n
MOV R1,R7
LDR R2,
EOR R7,R2
AND R7,R1
BX lr
}
__asm void _PLF_( u32 nl )
{
// R7 <=(R7 ^ nl) & nl
LDR R1,
EOR R7,R1
AND R7,R1
BX lr
}
//=====================================//
// 接入指令
//=====================================//
__asm void _LD_( u32 n)
{
// R7 压栈
PUSH {R7}
// R7 <=n
LDR R7,
BX lr
}
__asm void _LDI_( u32 n)
{
// R7 压栈
PUSH {R7}
// R7 <=!R0
LDR R1,
EOR R7,R1,#1
BX lr
}
__asm void _LDP_( u32 n)
{
// R7 压栈
PUSH {R7}
// R7 <=(n ^ nl) & n
LDR R1,
LDR R7,
EOR R7,R1
AND R7,R1
BX lr
}
__asm void _LDF_( u32 n)
{
// R7 压栈
PUSH {R7}
// R7 <=(n ^ nl) & nl
LDR R7,
LDR R1,
EOR R7,R1
AND R7,R1
BX lr
}
//=====================================//
// 串联指令
//=====================================//
__asm void _AND_( u32 n)
{
//R7 <= ( R7 & n )
LDR R1,
AND R7, R1
BX lr
}
__asm void _ANI_( u32 n)
{
//R7 <= ( R7 & (!R0) )
LDR R1,
EOR R2,R1,#1
AND R7,R2
BX lr
}
__asm void _ANDP_( u32 n)
{
// R2 <=(n ^ nl) & n
LDR R1,
LDR R2,
EOR R2,R1
AND R2,R1
//R7 <= ( R7 & R2 )
AND R7,R2
BX lr
}
__asm void _ANDF_( u32 n)
{
// R2 <=(n ^ nl) & nl
LDR R2,
LDR R1,
EOR R2,R1
AND R2,R1
//R7 <= ( R7 & R2 )
AND R7,R2
BX lr
}
//=====================================//
// 并联指令
//=====================================//
__asm void _OR_( u32 n)
{
//R7 <= ( R7 | R0 )
LDR R1,
ORR R7,R1
BX lr
}
__asm void _ORI_( u32 n)
{
//R7 <= ( R7 | (!R0) )
LDR R1,
EOR R2,R1,#1
ORR R7,R2
BX lr
}
__asm void _ORP_( u32 n)
{
// R2 <=(n ^ nl) & n
LDR R1,
LDR R2,
EOR R2,R1
AND R2,R1
//R7 <= ( R7 & R2 )
ORR R7,R2
BX lr
}
__asm void _ORF_( u32 n)
{
// R2 <=(n ^ nl) & nl
LDR R2,
LDR R1,
EOR R2,R1
AND R2,R1
//R7 <= ( R7 & R2 )
ORR R7,R2
BX lr
}
//=====================================//
// 输出指令
//=====================================//
__asm void _OUT_( u32 n)
{
// 恢复栈指针
MOV SP,R6
//n <= R7
STR R7,
BX lr
}
__asm void _SET_( u32 n)
{
// 恢复栈指针
MOV SP,R6
//n <= ( R7 | n )
LDR R1,
ORR R1,R7
STR R1,
BX lr
}
__asm void _RST_( u32 n)
{
// 恢复栈指针
MOV SP,R6
//n <= ( R7 & (!n) )
LDR R1,
BIC R1,R7
STR R1,
BX lr
}
__asm void _CPL_( u32 n)
{
// 恢复栈指针
MOV SP,R6
//n <= ( R7 ^ n )
LDR R1,
EOR R1,R7
STR R1,
BX lr
}
//=====================================//
// 比较指令
//=====================================//
__asm void _LD_GE_( s16 a, s16 b )
{
// R7 压栈
PUSH {R7}
// R7 <=( a>=b )
CMP R0,R1
ITE GE
MOVGE R7,#1
MOVLT R7,#0
BX lr
}
__asm void _LD_LE_( s16 a, s16 b )
{
// R7 压栈
PUSH {R7}
// R7 <=( a<=b )
CMP R0,R1
ITE LE
MOVLE R7,#1
MOVGT R7,#0
BX lr
}
__asm void _LD_GT_( s16 a, s16 b )
{
// R7 压栈
PUSH {R7}
// R7 <=( a>b )
CMP R0,R1
ITE GT
MOVGT R7,#1
MOVLE R7,#0
BX lr
}
__asm void _LD_LT_( s16 a, s16 b )
{
// R7 压栈
PUSH {R7}
// R0 <=( a<b )
ITE LT
MOVLT R7,#1
MOVGE R7,#0
BX lr
}
__asm void _LD_NE_( s16 a, s16 b )
{
// R7 压栈
PUSH {R7}
// R7 <=( a==b )
CMP R0,R1
ITE NE
MOVNE R7,#1
MOVEQ R7,#0
BX lr
}
__asm void _LD_EQ_( s16 a, s16 b )
{
// R7 压栈
PUSH {R7}
// R7 <=( a!=b )
CMP R0,R1
ITE EQ
MOVEQ R7,#1
MOVNE R7,#0
BX lr
}
__asm void _AND_GE_( s16 a, s16 b )
{
// R7 &=( a>=b )
CMP R0,R1
ITE GE
ANDGE R7,#1
ANDLT R7,#0
BX lr
}
__asm void _AND_LE_( s16 a, s16 b )
{
// R7 &=( a<=b )
CMP R0,R1
ITE LE
ANDLE R7,#1
ANDGT R7,#0
BX lr
}
__asm void _AND_GT_( s16 a, s16 b )
{
// R7 &=( a>b )
CMP R0,R1
ITE GT
MOVGT R7,#1
MOVLE R7,#0
BX lr
}
__asm void _AND_LT_( s16 a, s16 b )
{
// R7 &=( a<b )
CMP R0,R1
ITE LT
MOVLT R7,#1
MOVGE R7,#0
BX lr
}
__asm void _AND_NE_( s16 a, s16 b )
{
// R7 &=( a==b )
CMP R0,R1
ITE NE
MOVNE R7,#1
MOVEQ R7,#0
BX lr
}
__asm void _AND_EQ_( s16 a, s16 b )
{
// R7 &=( a!=b )
CMP R0,R1
ITE EQ
MOVEQ R7,#1
MOVNE R7,#0
BX lr
}
__asm void _OR_GE_( s16 a, s16 b )
{
// R7 |=( a>=b )
CMP R0,R1
ITE GE
ORRGE R7,#1
ORRLT R7,#0
BX lr
}
__asm void _OR_LE_( s16 a, s16 b )
{
// R7 |=( a<=b )
CMP R0,R1
ITE LE
ORRLE R7,#1
ORRGT R7,#0
BX lr
}
__asm void _OR_GT_( s16 a, s16 b )
{
// R7 |=( a>b )
CMP R0,R1
ITE GT
MOVGT R7,#1
MOVLE R7,#0
BX lr
}
__asm void _OR_LT_( s16 a, s16 b )
{
// R7 |=( a<b )
CMP R0,R1
ITE LT
MOVLT R7,#1
MOVGE R7,#0
BX lr
}
__asm void _OR_NE_( s16 a, s16 b )
{
// R7 |=( a==b )
CMP R0,R1
ITE NE
MOVNE R7,#1
MOVEQ R7,#0
BX lr
}
__asm void _OR_EQ_( s16 a, s16 b )
{
// R7 |=( a!=b )
CMP R0,R1
ITE EQ
MOVEQ R7,#1
MOVNE R7,#0
BX lr
}
//=====================================//
// 运算指令指令
//=====================================//
__asm void _FNC_ADD(s16 a, s16 b, s16* c)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*c = a + b
TST R7,#1
ITT NE
ADDNE R0,R1
STRHNE R0,
BX lr
}
__asm void _FNC_SUB(s16 a, s16 b, s16* c)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*c = a - b
TST R7,#1
ITT NE
SUBNE R0,R1
STRHNE R0,
BX lr
}
__asm void _FNC_MUL(s16 a, s16 b, s16* c)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*c = a * b
TST R7,#1
ITT NE
MULNE R0,R1
STRHNE R0,
BX lr
}
__asm void _FNC_DIV(s16 a, s16 b, s16* c)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*c = a / b
TST R7,#1
ITT NE
SDIVNE R0,R1
STRHNE R0,
BX lr
}
__asm void _FNC_INC(s16* a)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*a = a++
TST R7,#1
ITTT NE
LDRHNE R1,
ADDNE R1,#1
STRHNE R1,
BX lr
}
__asm void _FNC_DEC(s16* a)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*a = a--
TST R7,#1
ITTT NE
LDRHNE R1,
SUBNE R1,#1
STRHNE R1,
BX lr
}
__asm void _FNC_WAND(s16 a, s16 b, s16* c)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*c = a & b
TST R7,#1
ITT NE
ANDNE R1,R0
STRHNE R1,
BX lr
}
__asm void _FNC_WOR(s16 a, s16 b, s16* c)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*c = a | b
TST R7,#1
ITT NE
ORRNE R1,R0
STRHNE R1,
BX lr
}
__asm void _FNC_WXOR(s16 a, s16 b, s16* c)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*c = a ^ b
TST R7,#1
ITT NE
EORNE R1,R0
STRHNE R1,
BX lr
}
__asm void _FNC_NEG(s16 a, s16* b)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*b = ~a +1
TST R7,#1
ITT NE
ANDNE R2,R0
STRHNE R2,
BX lr
}
__asm void _FNC_MOV(s16 a, s16* b)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*b = a
TST R7,#1
IT NE
STRHNE R0,
BX lr
}
__asm void _FNC_CML(s16 a, s16* b)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则*b = ~a;;
TST R7,#1
ITT NE
MVNNE R2,R0
STRHNE R2,
BX lr
}
__asm void _FNC_XCH(s16* a, s16* b)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则
TST R7,#1
ITTTT NE
LDRHNE R2,
LDRHNE R3,
STRHNE R3,
STRHNE R2,
BX lr
}
__asm void _FNC_BCD(s16 a, s16* b)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则
TST R7,#1
ITTTT NE
LDRHNE R2,
LDRHNE R3,
STRHNE R3,
STRHNE R2,
BX lr
}
__asm void _FNC_BIN(s16 a, s16* b)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则
TST R7,#1
ITTTT NE
LDRHNE R2,
LDRHNE R3,
STRHNE R3,
STRHNE R2,
BX lr
}
__asm u8 _FNC_ALT(u8 a)
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则
TST R7,#1
ITT NE
MVNNE R0,R0
ANDNE R0,#1
BX lr
}
//=====================================//
// 定时器指令
//=====================================//
__asm void _OUT_T_( s16* a, s16 k )
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 0则TCnt =0 ,Tn =0
TST R7,#1
ITT EQ
MOVEQ R2,#0
BEQ _MOV_C_
// 检查R7 == 1
// *a >= K ?
LDRSH R2,
CMP R1,R2
ITT GE
MOVGE R2,#1 // Y, Tn =1
BGE _MOV_C_
ADDLT R2,#1 // N, TCnt计时
STRHLT R2,
BX lr
}
__asm void _OUT_C_( s16* a, s16 k )
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 0则返回
TST R7,#1
IT EQ
BXEQ lr
// 检查R7 == 1
// *a >= K ?
LDRSH R2,
CMP R2,R1
ITTEE GE
MOVGE R2,#1 // Y, Tn =1
BGE _MOV_C_
ADDLT R2,#1 // N,TCnt++
STRHLT R2,
BX lr
}
__asm void _RST_T_( s16* a )
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则TCnt =0
TST R7,#1
ITTE NE
MOVNE R2,#0
STRHNE R2,
BXEQ lr
}
__asm void _MOV_T_( s16* a)
{
// Tn =0
MOV32 R3, # ABS_ADR_TCnt
SUB R0,R3
LSL R0,#1
MOV32 R3, # ABS_ADR_T_BB
STRH R2,
BX lr
}
__asm void _RST_C_( s16* a )
{
// 恢复栈指针
MOV SP,R6
// 检查R7 == 1则CCnt =0
TST R7,#1
ITTE NE
MOVNE R2,#0
STRHNE R2,
BXEQ lr
}
__asm void _MOV_C_( s16* a)
{
//Cn =0
MOV32 R3, # ABS_ADR_CCnt
SUB R0,R3
LSL R0,#1
MOV32 R3, # ABS_ADR_C_BB
STRH R2,
BX lr
} 考虑到将来为了实现plc内部编译执行,已经将资源绝对定位,再将实现指令功能的汇编子程序定位,就可通过简单固定的几条汇编指令实现单步指令。只要研究下机器码中操作数的位置和存放方式,编写程序替换即可。下位plc编译执行的plc实现指日可待。 这个开发速度太慢了,稳定性也没法保证啊。 顶一下,希望早日成功,期待开源 不知能解决组和位元件吗? 组和位元件舒是指什么? 基本上大部分指令都可以实现。只是在汇编中调用C没有成功,所以对于一些特别复杂的指令,需要用C的复杂呀运算比如浮点,或pid什么的不好弄。但是即使不可以调用,也可以先执行一条汇编,执行一条C函数来变相替代。关键是要搞清楚调用的参数和返回值的传递办法,就是R0,R1,R2,就都可以搞定了。 mark mark 好东西,最近在研究ARM的C语言和汇编,研究下你的程序。 标记一下,楼主辛苦 Thanks for sharing! 这样的话,编程就很灵活了,就不知道能不能发脉冲! 最近在研究三菱PLC 顶一下!!! {:smile:}这一定要顶 真是很大的贡献,好! 一个好帖,顶 楼主的工作十分有用,但是公布的代码不全吧?能否全部公布出来? 牛牛 哈哈哈! 牛,源码呢!
页:
[1]