恭喜,你发布的帖子
发布于 2023-02-19 22:00:22
17楼
今天测试程序,采用定时中断进行流量累计的时候,数据一直对不上。经过测试发现自己多年犯了一个致命BUG,实在惭愧,贴出来跟大家探讨探讨。
定时中断一般不受扫描周期影响,一般建议中断程序短小精悍。因此本人,常在中断程序置位标志位,通过该标志位再调用处理子程序。比如中断程序(200MS)将M0.0写1,然后用M0.0在主程序调用流量处理以及累计子程序(执行一次,然后将M0.0复位)。
提出问题如下:
中断里执行该程序与主程序里执行该程序,有没有区别?测试如下:
1、200MS中断里,对VD484进行0.2S累计,同时置位M0.2。
2、主程序里面使用M0.2,调用子程序,对VD480,进行0.2S累计。
3、通过M5.0,触发复位清零并开始同步计时,同时使用T250进行计时比较。
结果如下图,单位为S
结果证明,定时中断时间累计与T250定时器数据基本相同,但是主程序调用子程序,时间为1642.9S,比前者少了近300S。问题就出在子程序与中断程序执行不同步,中转标志M0.2,可能被丢失了!如下图,M0.2只要在箭头区间被置位,程序执行网络7,则直接被复位,那么本次M0.2将是无效的。
也许有人说,M0.2放的太靠后了。可以把M0.2使用完成后直接复位掉。但是只要M0.2开始和结束之间有程序,则就有被丢失的风险,无非是这个程序越短,影响越小而已。
如何避免此问题呢?
1、直接在中断里处理程序。
2、类似M0.2的中转标志,可以使用上升沿调用子程序,然后延时多周期再复位。
爬了半天楼,还是有点云里雾里。
总结一下吧,
中断程序要放到OB1里处理,先决条件是中断间隔必须永远大于OB1扫描周期,
其次,编程如下图
楼主的第二点总结的并不正确,有没有上升沿,无所谓的,中断在指令之前本扫描周期立即处理,在指令之后的下一个扫描周期处理
请填写推广理由:
分享
只看
楼主