主程序区:
LD SM0.1 //首次扫描时调用一次
CALL SBR_1:SBR1
//
LD SM0.0 //一直调用
CALL SBR_0:SBR0
//--------------------------------------------------
子程序区:
子程序0(一直调用,计时用):
LD M0.0
AN T32
TON T32, VW0 //此寄存器的值即为可调的定时时间(0-10MS),我是通过屏来实现的
子程序1(首次扫描调用,初始化程序用):
LD SM0.0
R M0.0, 1
ATCH INT_0:INT0, 1 //在I0.0 的下降沿触发的中断事件
ATCH INT_1:INT1, 21 //定时器T32,CT = PT 中断时触发的中断事件
ENI
//----------------------------------------------------------
中断程序区:
中断0(在I0.0 的下降沿时触发):
LD SM0.0
S M0.0, 1 //检测到I0.0的下降沿,置位M0.0到子程序0开始计时
R Q0.1, 1 //并复位控制输出
中断1(定时器T32,CT = PT 中断时触发的中断事件):
LD SM0.0
S Q0.1, 1 //定时时间到,输出控制
R M0.0, 1 //并复位定时器执行条件(M0.0),为后面再次计时做准备
以上是小弟做的一个0-10MS可调定时器程序,是通过检测交流电的过零点(由I0.0输入),然后延时输出控制振机的振动强度用的(由Q0.1输出)
。但在测试过程中感觉还是有点问题,就是输出控制不是很准确。再说这还只是一个小程序,扫描周期是很短的,而实际项目的程序是很长的
,扫描周期应该会在10MS以外,这样输出控制的准确性就更难保证了。希望各位给能点意见,或是修改我上面的程序,或是干脆重写一个都行
,哪怕是给点思路,也非常感激!!
俺的联系方式:lyrun1120@163.com QQ:262823396
问题补充:
1、谢谢shine的回答!我上面程序用的是输入中断+时间到中断,输出控制也是在中断里面完成的,一直调用的那个子程序只是计时用。但感觉那个计时还是无法避开程序的扫描周期。你说的定时中断要怎么个用法呢?
我刚刚看到西门子系统手册上面有一句话:“对于1ms分辨率的定时器来说,定时器位和当前值的更新不与扫描周期同步。对于大于1ms的程序扫描周期,定时器位和当前值在一次扫描内刷新多次。”我对这句话的理解是:1ms定时器的刷新是按毫秒级来进行的,跟程序的扫描周期(大于1m)无关,那使1ms定时器得以计时的条件又是怎么刷新的,如本例中的M0.0 ?
2、非常感谢 yanxiao 的热心指点!小弟不才,不过我觉得你的这个思路应该是非常好的!我会认真地去验证这种做法的。现在的主要问题是,我PLC(226CN)的高速输出(Q0.0,Q0.1)已经被用来控制步进电机了,还有一个要补充的,就是我所要求的分辨率只要达到毫秒级就可以了,即1ms,2ms,3ms...10ms可调就行了,是用来触发可控硅输出的。
最佳答案
1、是不是触发可控硅之类用的?
2、用1ms分辨率的定时器,最大误差就做不到1ms以下。
3、可以利用PTO输出+高速计数器中断,来模拟定时功能。
当I0.1测到过零信号,中断进入服务程序,开启Q0.0的PTO,内反馈到高速计数器,设定高速计数中断。当高速计数达到目标值时中断,控制Q0.1输出(使用立即指令)。
如果PTO值允许输出100KHz(比如224XP),那么可以做到0.01ms的分辨率。至少20KHZ也可以达到0.05ms的分辨率。但是误差仍可达到数百us。因为中断是要等到当前的指令执行完后才响应的,而有的指令耗时比较长,达百us以上,可以查手册的附录参考。
提问者对于答案的评价:
非常谢谢yanxiao的精彩回答,还有shine。但分数只能给一个人,不好意思...
原创文章,作者:ximenziask,如若转载,请注明出处:https://www.zhaoplc.com/plc355862.html