|
在PLC编程中,使用的是梯形图以及助记符,梯形图简单直观,但是分析总体的或段的逻辑并系不方便,占用程序行数太多。助记符就如汇编,看的多了头会大起来。
其实,PLC编程过程中,可以用C语言来进行辅助开发,先用C语言把逻辑关系理顺,然后再转换成梯形图程序,这里当然是手工转换。
如下面这段程序(西门子的PLC)
![](http://cache.amobbs.com/bbs_upload782111/files_11/ourdev_550242.jpg)
(原文件名:snap.jpg)
写成C语言就是:
if(((IN_STOP==1)&&(SM0_5==1))||(STSRT_F==1))
O_LAMP=1;
if((IN_STOP==0)&&(IN_START==1)&&(IN_START_F==0))
START_F=1;
这样的程序可以在KeilC里面调试运行,检查好逻辑关系后再写成PLC语句。
下面是其中一段子程序,基本上与梯形图一一对应,已经在Keil中调试完毕:
#include<AT89X52.H>
// 输入信号量:
bit IN_Qk_AN01=0,IN_QK_AN02=0,IN_QK_AN03=0,IN_DL01=0,IN_DL02=0,IN_DL03=0,IN_JT01=0,IN_JT02=0,IN_JT03=0,IN_M_A=0,IN_UP_DOWN=0;
unsigned char THREE_CHANGE=0; // 三个档位选择
bit IN_QK_G1=0,IN_QK_G2=0,IN_QK_G3=0,IN_G1_FRONT=0,IN_G1_BACK=1,IN_G2_FRONT=0,IN_G2_BACK=1,IN_G3_FRONT=0,
IN_G3_BACK=1,IN_G4_UP=0,IN_G4_DOWN=1,IN_STOP=1,IN_START=0;
bit O_QK_G1,O_QK_G2,O_QK_G3,O_G1,O_G2,O_G3,O_G4,O_DL1,O_DL2,O_DL3,O_HX,O_LAMP;
bit G1_CHANGE=0; // 标志
bit G2_CHANGE=0;
bit G3_CHANGE=0;
bit G4_CHANGE=0;
bit G1_CHANGE01=0;
bit G2_CHANGE01=0;
bit G3_CHANGE01=0;
bit QK_G1_CHANGE=0;
bit QK_G2_CHANGE=0;
bit QK_G3_CHANGE=0;
bit QK_ALL_HE=0; // 三个钳口开闭信号标志
bit DL_ALL_UP=0; // 三个挡料板信号标志
// 自动模式 (1)
// 准备: 手动装夹工件--按钳口1~3夹紧按钮--按起动按钮 I3.6
// 钳口闭合后,传感器 IN_QK_G1=1;IN_QK_G2=1;IN_QK_G3=1;
main()
{
for(;;)
{
if((O_QK_G1==0)&&(IN_Qk_AN01==1))
O_QK_G1=1; // 手动放置插接管,按下QK1闭合按钮,钳口1闭合
if((O_QK_G2==0)&&(IN_QK_AN02==1))
O_QK_G2=1; // 手动放置插接管,按下QK1闭合按钮,钳口1闭合
if((O_QK_G3==0)&&(IN_QK_AN03==1))
O_QK_G3=1; // 手动放置插接管,按下QK3闭合按钮,钳口3闭合
// 讯号变化: IN_QK_G1=1;IN_QK_G2=1;IN_QK_G3=1
if(((IN_QK_G1==0)&&(IN_QK_G2==0)&&(IN_QK_G3==0))&&(O_HX==1)) // 任一钳口未闭合,
O_HX=0; // 进气阀切换为低压
/*****************/
// IN_STOP=0;
/*****************/
if((IN_STOP==0)&&(IN_QK_G1==1)&&(IN_QK_G2==1)&&(IN_QK_G3==1)&&(O_HX==0)) // 所有钳口闭合,
{
O_HX=1; QK_ALL_HE=1; O_DL1=1;O_DL2=1;O_DL3=1; // 置位钳口标识 ,切换为高压
} // 讯号变化 IN_DL01=1;IN_DL02=1;IN_DL03=1
if((IN_START==1)&&(DL_ALL_UP==0)&&(IN_DL01==1)&&(IN_DL02==1)&&(IN_DL03==1))
DL_ALL_UP=1; // 讯号变化: IN_START=1
if((DL_ALL_UP==1)&&((IN_DL01==0)||(IN_DL02==0)||(IN_DL03==0)))
DL_ALL_UP=0;
if((O_G4==0)&&(QK_ALL_HE==1)&&(IN_G4_DOWN==1)&&(G4_CHANGE==0)&&(DL_ALL_UP==1)) //
{
O_G4=1; // 讯号变化:IN_G4_DOWN=0; IN_G4_UP=1
}
if(((O_G1==0)&&(QK_ALL_HE==1)&&(IN_G1_BACK==1))&&(((IN_G4_UP==1)&&(G4_CHANGE==0)&&(G1_CHANGE==0)&&(DL_ALL_UP==1))
||((O_G1==0)&&(G4_CHANGE==1)&&(IN_G4_DOWN==1)&&(G1_CHANGE01==0)&&(DL_ALL_UP==1)))) // 如果G1在退回位,G4上位,或G4已经完成一个动作循环
{
O_G1=1; // 讯号变化:IN_G1_BACK=0;IN_G1_FRONT=1
// 延时0.5秒 以使气缸进位
}
if((O_G1==1)&&(IN_G1_FRONT==1)&&(((QK_ALL_HE==1)&&(IN_G4_UP==1)&&(G4_CHANGE==0))
||((O_G1==1)&&(QK_ALL_HE==0)&&(G4_CHANGE==1)&&(IN_G4_DOWN==1)&&(QK_G1_CHANGE==1))))
{
O_G1=0; // 讯号变化: IN_G1_BACK=1;IN_G1_FRONT=0
if(IN_G4_UP==1)
G1_CHANGE=1;
if(IN_G4_DOWN==1)
G1_CHANGE01=1;
// 置G1动作标识为1,以与原始状态的O_G1 "0" 状态相区别
}
if((O_G3==0)&&(IN_G1_BACK==1)&&(IN_G3_BACK==1)&&(((G1_CHANGE==1)&&(IN_G4_UP==1)&&(QK_ALL_HE==1)&&(G3_CHANGE==0)&&(DL_ALL_UP==1))
||((O_G3==0)&&(G1_CHANGE01==1)&&(IN_G4_DOWN==1)&&(QK_ALL_HE==0)&&(G3_CHANGE01==0)&&(DL_ALL_UP==1))))
O_G3=1; // 信号变化:IN_G3_BACK=0;IN_G3_FRONT=1
// 延时0.5秒,以使气缸进位
if((O_G3==1)&&(IN_G3_FRONT==1)&&(((QK_ALL_HE==1)&&(IN_G4_UP==1)&&(G1_CHANGE==1))
||((O_G3==1)&&(QK_ALL_HE==0)&&(G4_CHANGE==1)&&(IN_G4_DOWN==1)&&(QK_G3_CHANGE==1))))
{
O_G3=0; // 讯号变化:IN_G3_BACK=1;IN_G3_FRONT=0
if(IN_G4_UP==1)
G3_CHANGE=1;
if(IN_G4_DOWN==1)
G3_CHANGE01=1;
}
if((O_G2==0)&&(IN_G3_BACK==1)&&(IN_G2_BACK==1)&&(((G3_CHANGE==1)&&(IN_G4_UP==1)&&(QK_ALL_HE==1)&&(G2_CHANGE==0)&&(DL_ALL_UP==1))
||((O_G2==0)&&(G3_CHANGE01==1)&&(IN_G4_DOWN==1)&&(QK_ALL_HE==0)&&(QK_G3_CHANGE==1)&&(G2_CHANGE01==0)&&(DL_ALL_UP==1))))
O_G2=1; // 信号变化:IN_G2_BACK=0;IN_G2_FRONT=1
// 延时0.5秒,以使气缸进位
if((O_G2==1)&&(IN_G2_FRONT==1)&&(((G3_CHANGE==1)&&(IN_G4_UP==1)&&(QK_ALL_HE==1))
||((O_G2==1)&&(G3_CHANGE01==1)&&(IN_G4_DOWN==1)&&(QK_ALL_HE==0)&&(QK_G3_CHANGE==1))))
{
O_G2=0; // 信号变化:IN_G2_BACK=1; IN_G2_FRONT=0
if(IN_G4_UP==1)
G2_CHANGE=1;
if(IN_G4_DOWN==1)
G2_CHANGE01=1;
}
if((O_G4==1)&&(IN_G2_BACK==1)&&(G2_CHANGE==1)&&(IN_G4_UP==1)&&(QK_ALL_HE==1))
{
O_G4=0; // 信号变化:IN_G4_DOWN=1;IN_G4_UP=0
G4_CHANGE=1;
}
// G1进--见上
if((O_QK_G1==1)&&(QK_ALL_HE==1)&&(G4_CHANGE==1)&&(IN_G4_DOWN==1)&&(IN_G1_FRONT==1))
{
O_QK_G1=0; // 信号变化: IN_QK_G1=0 钳口1松开
// 延时0.5秒,以使钳口松开
QK_ALL_HE=0;
}
if((QK_G1_CHANGE==0)&&(IN_QK_G1==0)&&(G4_CHANGE==1)&&(IN_G4_DOWN==1)&&(IN_G1_FRONT==1))
QK_G1_CHANGE=1;
// G1 退--见上
// G3 进--见上
if((O_QK_G3==1)&&(QK_ALL_HE==0)&&(G4_CHANGE==1)&&(IN_G4_DOWN==1)&&(IN_G3_FRONT==1))
{
O_QK_G3=0; // 信号变化:IN_QK_G3=0
// 延时0.5秒
QK_G3_CHANGE=1;
}
// G3 退--见上
// G2 进--见上
// G2 退--见上
if((O_QK_G2==1)&&(G2_CHANGE01==1)&&(IN_G2_BACK==1))
{
O_QK_G2=0; // 讯号变化: IN_QK_G2=0
QK_G2_CHANGE=1;
}
if((IN_STOP==1)||((QK_G2_CHANGE==1)&&(IN_QK_G2==0))) // 插接完毕,复位所有标识
{
// 复位所有标志
G1_CHANGE=0; // 标志
G2_CHANGE=0;
G3_CHANGE=0;
G4_CHANGE=0;
G1_CHANGE01=0;
G2_CHANGE01=0;
G3_CHANGE01=0;
QK_G1_CHANGE=0;
QK_G2_CHANGE=0;
QK_G3_CHANGE=0;
// 输出复位
O_HX=0;
O_DL1=0;
O_DL2=0;
O_DL3=0;
}
if(IN_STOP==1) // 按下停止按钮,所有的动作元件复位
{
O_QK_G1=0,O_QK_G2=0,O_QK_G3=0,O_G1=0,O_G2=0,O_G3=0,O_G4=0,O_DL1=0,O_DL2=0,O_DL3=0,O_HX=0,O_LAMP=0;// 注:灯要设置为闪动指示
}
}
} |
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|