CODESYS2.3部分功能块源代码算法移植C源代码共享希...

2020-02-11 08:54发布

本帖最后由 jiang887786 于 2015-1-16 11:54 编辑

   首先,我要说的是我读书少,表达意思不准确如有疑问请在下面的楼层提问。网上我没有搜索到类似的源代码,估计这是第一帖。由于功能块较多我不可能一次性全部发表&说明完整,可能以后我会陆续的发在下面的楼层。此功能块的原作者不知道是谁,呵呵。我只是根据IEC6113-3的标准ST语言改写成C语言。(当然,我不会C++,如果会的话我改成C++就完美了,c++在一个函数调用过程中可以一次性返回多个参数,就是类的公用部分参数吧?抱歉,书看的不多,也就不多说了。还是想啰嗦几句,哈哈。大神也可以指正我对c++的理解错误:比如c++里面有个函数(int)ACB_123){;;//许多语句…..},编译器编译时生成了(int)ACB_123)的机器码并且在单片机的某些flash存在,当其他函数调用(int)ACB_123)时编译器会分配相应的(int)ACB_123)里面使用的变量等等给系统使用,
当还有其他函数调用(int)(ACB_123)时编译器会分配相应的另一些(int)(ACB_123)里面使用的变量等等给系统使用,只是这些变量的地址不是上一次那个函数调用的变量地址了。而机器码还是原来的那部分机器码。就是你调用的再多次这个函数机器码只有这个机器码(节省flash看见相对于c来说。)而变量的地址不同了。从而返回的参数也不同了,这也是正确的结果。如果是c的话,你想在一个工程里面使用两个相同功能的函数的话,你只能吧一个函数复制成两个比如上面说的
                        (int)(ACB_123A){;;//许多语句…..}、
                        (int)(ACB_123B){;;//许多语句…..}、
                        (int)(ACB_123C){;;//许多语句…..}、
等等,只不过这三个(ACB_123函数内部的东西是一模一样的罢了)目前我就是这样做的,希望大神们给个高见解决我目前的窘态。哈哈!关于C&C++我就懂这么多吧。不扯了,下面开始正文。尼玛,正文都不知道扯到哪里了,让我看看想想……)花了将近2个月的时间才改写完成,最初改写是按照C51改的,最后感觉c51排不上大用场,还是用CW5.1+MC9S12XD256调试输出吧。所以现在才把这些源代码发给大家使用,(也是我兑奖K64—L5的非卡奖品想莫大承诺的,打算有时间就共享这些代码)有需要的哥们儿就顶一下哦。谢谢支持。还有,如果我侵犯原著的版权,请回帖或者告知本坛删帖,谢谢合作!谢谢大家。这里我要说的是从开始的一个模拟量输入到最后的两个uint量输出,进而用这两个模拟量赋值给pwm占空比寄存器输出两个pwm去控制两个比例阀的过程,这个功能在工程机械控制方面用途很多很多有了这个过程,大家同行就可以举一反三了,当然是给新入门的鸟看的,老鸟就不用喷我了。呵呵。下面开始正文!
   
                word FB_RC( unsigned long int Input)
                {        /*新加的FB-RC函数*/
                static volatile word        prev;
                           //Input++;
                。。。。。。。。。。。
       
                return prev;}
                word FB_RC( unsigned long int Input)
函数,形参Input,unsigned long int类型。返回值word型,不用多说了,这个是内部函数,也是必须要使用的,RC充放电波形,这个大家都理解吧?对了为了防止非注册用户可以复制使用这些代码我将每个函数都打包上传附件吧,不然每人都直接复制走了,那么将给本坛增加负担了。呵呵。 code.rar (2.49 KB, 下载次数: 57) 2015-1-15 12:50 上传 点击文件名下载附件
函数都在这个压缩文件里面
EPEC控制器CODESYS2.3编程软件说明.rar (1.18 MB, 下载次数: 72) 2015-1-16 11:53 上传 点击文件名下载附件   

                  word PL_MeanValue_Len50 /*循环渐进法求平均值*/
                (word         Input,byte        Par_Length,byte         Reset)
                {
                ,。。。。。。。。
                }
                这个是求平均值的函数,由于ADC的速度太快,求个平均值比较平滑稳定,后面貌似还有类似的功能块呢好像。word  Input形参这个是输入的要处理的模拟量值,byte Par_Length 这个是要取平均值的个数最大50 ,byte                 Reset这个是调用时使用使用这个功能,0不使用,1使用。看到没人家写这个函数时考虑的还不少啊!哈哈。

                    byte DELAY_10MS(byte IN,word PT)
                {  static word PT_TEMP;
                static byte run_flag=0,time_inte=0/*这个变量本来是在定时器中断函数中的全局变量现在特地定义在这里了*/;
                if(((0==PT_TEMP)&run_flag&IN)|(IN&(0==PT)))
                {return 1;}
                if (IN&!run_flag)
                {PT_TEMP=PT;}

                if (IN&!time_inte)
                {run_flag=1;}
                if (!IN&!time_inte)
                {run_flag=0;
                PT_TEMP=0;        }
                if (time_inte&run_flag)
                {PT_TEMP--;
                time_inte=0;}/*定时器中断标志位全局变量bit类型,每次中断置一*/
                return ((0==PT_TEMP)&run_flag);}       
        这个是我自己写的用定时器的一个延时程序,不耗机器资源。貌似效果不咋滴,因为水平有限,自己没没怎么搞出一二来,还请高手指点一下最好。下面的一些函数也使用到这个延时了,其实不用也行,在主函数里面不用实时调用反        复循环的函数就行了。我用它就是判断时间到了就调用一次反复循环的函数,不到就跳过。不理解的可以回帖讨论。
                int JoyStick_Filter(word Joy_Input, word/*0~1023*/Par_Neg ,word Par_Pos,word Par_Zero ,word Par_Deadband /*0~100*/, int Par_Neg_Pro, int/*-100~100*/Par_Pos_Pro, word Par_Diff, byte                                 Par_Pos_Dir_Switch,byte Par_Neg_Dir_Switch, byte Par_Not_Use_Dir_Switch,byte Par_Dir_Switch_Judge_Time ,byte Enable)
                {
                。。。。。。。。。。。。
                }
        看到了吧,这个函数就调用了,byte DELAY_10MS(byte IN,word PT)、word FB_RC( unsigned long int Input)、还有word PL_MeanValue_Len5(word         Input,byte        Par_Length,byte         Reset),
        好,说形参(word Joy_Input, 手柄的AD模拟量0-1023,Par_Neg 手柄最小值标定,当小于最小值是此函数不输出,保护机器误动作,高吧?呵呵。word Par_Pos手柄最大值标定,当手柄值大于最大值是此函数不输出,保护机器误动        作,,word Par_Zero 手柄中间值一般是512,word Par_Deadband手柄死区,就是让他打多少手柄没有输出,防止手柄中位不是2.5伏偏差的, int Par_Neg_Pro这个值一般取0, int/*-100~100*/Par_Pos_Pro这个值一般取0,, word         Par_Diff改写c后这个值不使用了, byte Par_Pos_Dir_Switch改写c后这个值不使用了,byte Par_Neg_Dir_Switch改写c后这个值不使用了, byte Par_Not_Use_Dir_Switch改写c后这个值不使用了,byte Par_Dir_Switch_Judge_Time改写c        后这个值不使用了 ,byte Enable调用时使用使能使用此函数,非0使用,为零不使用。)这些代码都是不用考虑的,没有使用,if (0==Par_Not_Use_Dir_Switch)   {
                tb1= ((Joy_Input>Par_Pos) && (0==Par_Pos_Dir_Switch)) ;
                /*T1(IN=tb1,pt=Par_Dir_Switch_Judge_Time);
                Error_Pos_Dir_Switch=t1.Q;*/
       
                Error_Pos_Dir_Switch=DELAY_10MS(tb1,Par_Dir_Switch_Judge_Time);
       
                tb2= ((Joy_Input<Par_Neg) && (0==Par_Neg_Dir_Switch)) ;
                /*T2(IN=tb1,pt=Par_Dir_Switch_Judge_Time);
                Error_Neg_Dir_Switch=t2.Q;*/
                Error_Neg_Dir_Switch=DELAY_10MS(tb2,Par_Dir_Switch_Judge_Time);}
        这个函数的返回值是+10000到-10000,一般是0.5v-2.5v是0到-10000,2.5-4.5v是0到+10000输出,刚好一个手柄两个动作。后面的动作输出函数就是需要+10000到-10000的。


                word JoyStick_to_Current_Valve(        int        Input_Control,/*-10000~10000*/

                volatile word        Input_Up_Accel,/*每隔100ms增加的占空比,Input_Up_Accel/10000*(Input_up_max_DutyCycle-Input_up_min_DutyCycle)*/
                volatile word          Input_Up_Dccel,/*每个100ms减少的占空比,Input_Up_Dccel/10000*(Input_up_max_DutyCycle-Input_up_min_DutyCycle)*/
                volatile word         Input_Down_Accel,/*每隔100ms增加的占空比,Input_Down_Accel/10000*(Input_down_max_DutyCycle-Input_down_min_DutyCycle)*/
                volatile word        Input_Down_Dccel,/*每个100ms减少的占空比,Input_Down_Dccel/10000*(Input_down_max_DutyCycle-Input_down_min_DutyCycle)*/

                volatile word        Input_up_min_DutyCycle,/*0~10000*/
                volatile word        Input_up_max_DutyCycle,/*0~10000*/
                volatile word        Input_down_min_DutyCycle,/*0~10000*/
                volatile word        Input_down_max_DutyCycle/*0~10000*/)
                                        /*VAR*/
                {       
                        。。。。。。。。。。。
                }


        这个函数就是输入是+10000到-10000,输出两个uint变量的,然后去控制两个pwm占空比。在codesys可以返回两个uint。C语言里面不行,所以我改了最后返回值的地方,使用时要注意。说形参word JoyStick_to_Current_Valve(        int                Input_Control,/*-10000~10000*/正负10000输入形参,volatile word        Input_Up_Accel,/*每隔100ms增加的占空比,Input_Up_Accel/10000*(Input_up_max_DutyCycle-Input_up_min_DutyCycle)*/
                volatile word  Input_Up_Dccel,/*每个100ms减少的占空比,Input_Up_Dccel/10000*(Input_up_max_DutyCycle-Input_up_min_DutyCycle)*/
                volatile word         Input_Down_Accel,/*每隔100ms增加的占空比,Input_Down_Accel/10000*(Input_down_max_DutyCycle-Input_down_min_DutyCycle)*/
                volatile word        Input_Down_Dccel,/*每个100ms减少的占空比,Input_Down_Dccel/10000*(Input_down_max_DutyCycle-Input_down_min_DutyCycle)*/

                volatile word        Input_up_min_DutyCycle,/*0~10000*/up设置的最小占空比,亦即比例阀的起始电流
                volatile word        Input_up_max_DutyCycle,/*0~10000*/ up设置的最大占空比,亦即比例阀的最大电流

                volatile word        Input_down_min_DutyCycle,/*0~10000*/另一个动作,和上面的设置一样。
                volatile word        Input_down_max_DutyCycle/*0~10000*/)
        好了,到这里基本是一个完整的过程了,写了我半天,累啊。欢迎大家同行讨论,工程机械方面的问题。谢谢大家,谢谢amoBBS.
        编辑增加cede附件。
        编辑添加codesys2.3编程epec文件指导。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
55条回答
jiang887786
1楼-- · 2020-02-15 20:47
ali1019 发表于 2015-1-18 09:53
一直以為只能用PASCAL , 沒想到還能用C !!!

PASCAL不了解,显然它没有c流行好用,我感觉c++才和原来的ST语言很像。
hiberhe
2楼-- · 2020-02-16 00:20
 精彩回答 2  元偷偷看……
Juggernaut
3楼-- · 2020-02-16 03:26
楼主讲的很详细
ali1019
4楼-- · 2020-02-16 03:29
本帖最后由 ali1019 于 2015-1-18 14:41 编辑
jiang887786 发表于 2015-1-18 10:22
PASCAL不了解,显然它没有c流行好用,我感觉c++才和原来的ST语言很像。


我比較好奇的是 , LZ這樣的寫法如何通過編譯?
是不是在那裏可以設定?  

如 A = B ;  我的版本必須是這樣寫 A := B ;  才能編譯
目前我只會用CFC功能 , ST不會用
自己寫的FUNCTION_BLOCK , 在CFC功能中系統會自己封裝成模塊,非常容易使用.
ali1019
5楼-- · 2020-02-16 05:15
hiberhe 发表于 2015-1-18 07:33
现在国内EPEC的代理有2家,江苏杰瑞科技集团(江苏自动化研究所)也是一级代理(同时也有graf显示器等,以及 ...

MARK

為了一個展覽,臨時被迫接觸CODESYS, 結果就被深深吸引了,
目前只會用CFC大部分的功能 及Function Block 功能 , 其他通通不會更不用說底層了,
只可惜國內這一塊討論的並不多, 希望有機會向你請教.
jiang887786
6楼-- · 2020-02-16 06:41
ali1019 发表于 2015-1-18 14:39
我比較好奇的是 , LZ這樣的寫法如何通過編譯?
是不是在那裏可以設定?  

兄弟,我发的代码是c语言的,不是ST语言了。多多讨论。我懂得也不多,

一周热门 更多>