axis_motion.c 103 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660
  1. //===================================修改记录=================================//
  2. //2020.05.12 11:48 LXZ
  3. // 1、取消speed_unit参数,所以参数外部自己需要知道倍率,内部只管真实频率
  4. // 2、增加了设置正反转与高速回零的参数设置
  5. // 3、回零增加信号管脚、滤波次数的设置项目
  6. // 4、增加了回零方式中断回零的实现
  7. //2020.05.14 00:18 LXZ
  8. // 1、增了设置软件限位点的接口,修改软件限位开启接口
  9. // 2、增加了若干对外的参数读写类型
  10. // 3、修改报警反馈方式为位标志
  11. //2020.05.18 15:14 LXZ
  12. // 1、增加设置编码器回零的接口
  13. // 2、去除对编码器管脚的参数设置,要求必须用接口去操作
  14. // 3、增加对编码器Z信号回零的功能代码
  15. // 4、增加了设置齿轮比的对应接口
  16. // 5、增加了设置与读取现实位置的参数对象
  17. // 6、增加了位置与脉冲单位转换接口
  18. // 7、增加了转速与频率单位转换接口
  19. // 8、对位置定位的相关的代码自动调用位置与脉冲单位转换
  20. // 9、增加方向读取对象
  21. //2020.05.21 18:05 LXZ
  22. // 1、修正加减速状态值的定义
  23. // 2、修正位置减停位置不够时变速标志位设置不正常的问题
  24. // 3、修正回零方式1的回零偏移量使用错误的问题
  25. // 4、修改多段速函数接口定义
  26. // 5、修正软件限位设置接口没有齿轮比转换的问题
  27. //2020.05.26 14:49
  28. // 1、axis_pp函数与axis_start_pp_task函数增加返回值来表示定向运动是否正常启动
  29. // 2、增加报警
  30. // 3、增加axis_clear_alarm来清除部分非实时报警
  31. // 4、统一一下报警接口名称
  32. //2020.06.10 15:49
  33. // 1、增加关闭限位使能时自动清除相关报警位
  34. // 2、PP定位过程增加防止尖顶的过程的限制
  35. //2020.06.13 11:21
  36. // 1、增加了加减速曲线2与加减速曲线3,需要手动设置加加速与最大加减速,加减时间无效化
  37. // 加减速曲线2与加减速曲线1曲线形状保持一致,但是依靠手动设置加加速,因此不需要设
  38. // 置加减速时间去匹配每个阶段的速度
  39. // 加减速曲线3同理,但是曲线3只有波形下半部分是S形,上半部分是直线,因此加速时间比
  40. // 加减速曲线2要少,结速部分确仍然能保证一定的平滑
  41. //2020.06.17 11:21
  42. // 1、在插补进给中添加死等代码来保证外围运算波动不会对其造成影响
  43. // 2、将预览版本的比例开关并入驱动,增加比例开关接口,
  44. // 当比例开关打开时,所有的位置相关移动与限位设置都会经过比例计算
  45. // 当开关关闭时,所有定位相关的接口与限位设置都以脉冲为单位,但是位置与脉冲的转换接口是可用的。
  46. // 3、修正软件限位报警自动清零功能。
  47. // 4、增加减速设置项目
  48. //2020.06.20 00:54
  49. // 1、修改齿轮比接口,增加一个放大比例参数
  50. // 2、定位接口平滑倍率改成宏定义,并加大
  51. // 3、修改了脉冲、位置转换计算方法,采用预比例计算方式,提升运算速度
  52. //2020.06.28 00:54
  53. // 1、根据侧孔钻应用定向修改了齿轮比设置接口,同时完全照搬转换代码
  54. // 2、全并侧孔钻增加速度转频率接口
  55. // 3、为了剥离硬件IO接口,修改原点获取硬件信号方式为指针地址加掩码的方式
  56. // 4、对应修改回零管脚的注册管脚接口
  57. //============================================================================//
  58. #include "axis_motion.h"
  59. #include "axis_motion_config.h"
  60. #include <string.h>
  61. #include "user_app.h"
  62. /**
  63. * 轴运动驱动是一个利用时间为单位进行步进加减速度的驱动库。由于采用了定时周期加减速度,因此可以避免步进电机与
  64. * 伺服电机因为脉冲周期问题导致加减速度不好控制以及不好确定加减脉冲的问题。另外可以通过引入多段加减速度来保证
  65. * 停止的时候与开始时候的顺滑度,保证不会因为中间段加减速度过大而过冲。
  66. *
  67. */
  68. /**
  69. * 轴使能
  70. *
  71. * @author LXZ (121919)
  72. *
  73. * @param axis
  74. */
  75. void axis_enable(axis_object_t *axis) {
  76. axis->outputs.enable = 1;
  77. AXIS_SET_EN(axis, 1);
  78. }
  79. /**
  80. * 轴禁止
  81. *
  82. * @author LXZ (121919)
  83. *
  84. * @param axis
  85. */
  86. void axis_disable(axis_object_t *axis) {
  87. axis->outputs.enable = 0;
  88. AXIS_SET_EN(axis, 0);
  89. }
  90. /**
  91. * 轴正转
  92. *
  93. * @author lxz
  94. *
  95. * @param axis
  96. */
  97. void axis_cw(axis_object_t *axis) {
  98. axis->outputs.dir = 1;
  99. axis->feed = 1;
  100. if (axis->inputs.dir_reverse) {
  101. AXIS_SET_DIR(axis, 0);
  102. }
  103. else {
  104. AXIS_SET_DIR(axis, 1);
  105. }
  106. }
  107. /**
  108. * 轴反转
  109. *
  110. * @author lxz
  111. *
  112. * @param axis
  113. */
  114. void axis_ccw(axis_object_t *axis) {
  115. axis->outputs.dir = 0;
  116. axis->feed = -1;
  117. if (axis->inputs.dir_reverse) {
  118. AXIS_SET_DIR(axis, 1);
  119. }
  120. else {
  121. AXIS_SET_DIR(axis, 0);
  122. }
  123. }
  124. #ifdef AXIS_USING_FLOAT
  125. /**
  126. * 以直线加减速的方式计算加减速表
  127. *
  128. * @author LXZ (021720)
  129. *
  130. * @param axis
  131. * @param target_speed
  132. */
  133. static void axis_mode0_calc_accdec(axis_object_t *axis, int target_speed) {
  134. int acc_steps = 0; //加速时间单位数
  135. int dec_steps = 0; //减速时间单位数
  136. float cur_max_accdec = 0; //当前最大加速度减速度
  137. float cur_speed = 0; //当前速度
  138. int index = 0;
  139. int clock = axis->clock;
  140. int start_speed = axis->start_speed;
  141. float clock_ratio = axis->clock / 1000000;
  142. //周期临时值
  143. int period;
  144. int reg_Value = 0;
  145. int last_reg_value = 0;
  146. period = axis->period;
  147. //限制加速度周期
  148. if (period < 1) period = 2;
  149. //限制最小加速度时间单位
  150. acc_steps = axis->acc_time / period;
  151. if (acc_steps < 10) {
  152. acc_steps = 10;
  153. }
  154. dec_steps = axis->dec_time / period;
  155. if (dec_steps < 10) {
  156. dec_steps = 10;
  157. }
  158. //转换倍率
  159. period *= 1000;
  160. //保证加减速尽量对齐,需要保证加减数是偶数,由于计算误差,加1能让结果更加逼近设置的时间
  161. acc_steps++;
  162. acc_steps >>= 1;
  163. dec_steps++;
  164. dec_steps >>= 1;
  165. //保证是偶次数加减数,能减少计算误差
  166. //if ((min_acc_step & 0x01) != 0)
  167. // min_acc_step++;
  168. //目标速度不能比开始速度小
  169. if (target_speed < start_speed) {
  170. target_speed = start_speed;
  171. }
  172. //计算加速度会达到的最大值
  173. cur_max_accdec = (float)(target_speed - axis->start_speed) / acc_steps;
  174. //保证至少1以上的加减速度
  175. if (cur_max_accdec < 1) {
  176. cur_max_accdec = 1;
  177. }
  178. //尽量保证最大加速度不会大于限制值
  179. if (cur_max_accdec > axis->max_acc) {
  180. cur_max_accdec = axis->max_acc;
  181. }
  182. cur_speed = start_speed;
  183. //S加速曲线加速表计算
  184. do {
  185. //计算速度
  186. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  187. reg_Value = (int)((clock) / cur_speed);
  188. //过滤器重复的加减速点
  189. #ifdef AXIS_IGNORE_REPEAT_STEP
  190. if (last_reg_value != reg_Value) {
  191. #endif
  192. last_reg_value = reg_Value;
  193. AXIS_ACC_REG_TABLE(axis)[index] = reg_Value;
  194. AXIS_ACC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  195. if (AXIS_ACC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  196. AXIS_ACC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  197. }
  198. #ifdef AXIS_USING_DEBUG
  199. axis->acc_speed_table[index] = (int)cur_speed;
  200. #endif
  201. index++;
  202. #ifdef AXIS_IGNORE_REPEAT_STEP
  203. }
  204. #endif
  205. cur_speed += cur_max_accdec;
  206. } while ((cur_speed < target_speed) && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  207. //保存表大小
  208. axis->acc_table_size = index;
  209. #ifdef AXIS_USING_ACC_TABLE_ONLY
  210. if (index > 0) {
  211. index -= 1;
  212. }
  213. axis->dec_table_size = index;
  214. #else
  215. cur_max_accdec = (target_speed - axis->start_speed) / dec_steps;
  216. //保证至少1以上的加减速度
  217. if (cur_max_accdec < 1) {
  218. cur_max_accdec = 1;
  219. }
  220. //计算加速度会达到的最大值
  221. if (cur_max_accdec > axis->max_acc) {
  222. cur_max_accdec = axis->max_acc;
  223. }
  224. dec_steps = (int)((target_speed - axis->start_speed) / cur_max_accdec);
  225. //开始减速表计算
  226. index = 0;
  227. last_reg_value = 0;
  228. cur_speed = start_speed;
  229. //S加速曲线减速表计算
  230. do {
  231. //计算速度
  232. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  233. reg_Value = (int)((clock) / cur_speed);
  234. //过滤器重复的加减速点
  235. #ifdef AXIS_IGNORE_REPEAT_STEP
  236. if (last_reg_value != reg_Value) {
  237. #endif
  238. last_reg_value = reg_Value;
  239. AXIS_DEC_REG_TABLE(axis)[index] = reg_Value;
  240. AXIS_DEC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  241. if (AXIS_DEC_NUMBER_TABLE(axis)[index] < axis->min_steps) AXIS_DEC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  242. #ifdef AXIS_USING_DEBUG
  243. axis->dec_speed_table[index] = (int)cur_speed;
  244. #endif
  245. index++;
  246. #ifdef AXIS_IGNORE_REPEAT_STEP
  247. }
  248. #endif
  249. cur_speed += cur_max_accdec;
  250. } while ((cur_speed < target_speed) && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  251. //保存减速表大小
  252. axis->dec_table_size = index;
  253. if (axis->dec_table_size > 0) {
  254. axis->dec_table_size -= 1;
  255. }
  256. #endif
  257. }
  258. /**
  259. * 以S曲线减速的方式计算加减速表
  260. *
  261. * @author LXZ (021720)
  262. *
  263. * @param axis 轴对象
  264. * @param target_speed 目标速度
  265. */
  266. static void axis_mode1_calc_accdec(axis_object_t *axis, int target_speed) {
  267. int acc_steps = 0; //加速时间单位数
  268. int dec_steps = 0; //减速时间单位数
  269. float cur_accdec = 0; //当前加减速度
  270. float cur_max_accdec = 0; //当前最大加速度减速度
  271. float cur_speed = 0; //当前速度
  272. float ddc_speed = 0; //减减速开始速度
  273. float cur_aacddc = 0; //当前加加速减减速
  274. float mid_speed = 0; //中间速度
  275. int index = 0;
  276. float clock = axis->clock;
  277. float clock_ratio = axis->clock / 1000000;
  278. int start_speed = axis->start_speed;
  279. //周期临时值
  280. int period;
  281. int reg_Value = 0;
  282. int last_reg_value = 0;
  283. period = axis->period;
  284. //限制加速度周期
  285. if (period < 1) period = 2;
  286. //限制最小加速度时间单位
  287. acc_steps = axis->acc_time / period;
  288. if (acc_steps < 10) {
  289. acc_steps = 10;
  290. }
  291. dec_steps = axis->dec_time / period;
  292. if (dec_steps < 10) {
  293. dec_steps = 10;
  294. }
  295. //转换倍率
  296. period *= 1000;
  297. //保证加减速尽量对齐,需要保证加减数是偶数,由于计算误差,加1能让结果更加逼近设置的时间
  298. acc_steps++;
  299. acc_steps >>= 1;
  300. dec_steps++;
  301. dec_steps >>= 1;
  302. //保证是偶次数加减数,能减少计算误差
  303. //if ((min_acc_step & 0x01) != 0)
  304. // min_acc_step++;
  305. //目标速度不能比开始速度小
  306. if (target_speed < start_speed) {
  307. target_speed = start_speed;
  308. }
  309. //S加速算法需要先计算出加加速
  310. //推导过程:
  311. //S加减速度分为加加速与减加速度两个过程,假定两个过程是对称的,那么总占用时间为加速时间t的一半
  312. //因此利用积分公式(dv = sadt, vm = (vd - v0) / 2 => a = vm / (2 * (t / 2))可以得到acc = (vd - v0) * 2 / t
  313. //其中a与acc表示加速度,vd表示目标速度,v0表示开始速度t表示加速时间一半
  314. //加加速度aac与加速度关系acc为acc = aac * (t / 2)
  315. //从而公式为aac = (vd - v0) * 4 / (t ^2)
  316. //其中acc表示加速度,aac表示加加速,vd为目标速度,v0为开始速度,t为总的加速时间,在这算法里它就是加速度步数
  317. //由于加速度步数要对称就必须保持偶数,加上一些计算偏差以及为了保证电机正常运算必须限制参数
  318. //因此实际上两个过程在实际上是很难对称的,这就造成了实际加速时间肯定会比设定的长,具体长多
  319. //跟最大加加速,最大中速度,最小脉冲数,计算偏差,最小加速度步数有关
  320. cur_aacddc = ((target_speed - axis->start_speed)) / (acc_steps * acc_steps);
  321. //保证至少1以上的加减速度
  322. if (cur_aacddc < 1) {
  323. cur_aacddc = 1;
  324. }
  325. //计算加速度会达到的最大值
  326. cur_max_accdec = cur_aacddc * acc_steps;
  327. if (cur_max_accdec > axis->max_acc) {
  328. cur_max_accdec = axis->max_acc;
  329. }
  330. //限制加加速度,加加速度过大会导致过冲
  331. if (cur_aacddc > axis->max_aac) {
  332. cur_aacddc = axis->max_aac;
  333. }
  334. //由于加加速比计算结果小,所以需要更多步去达到最高速,需要重新加速步
  335. acc_steps = (int)(cur_max_accdec / cur_aacddc);
  336. if (cur_aacddc == 0) cur_aacddc = 1;
  337. //开始计算加速表
  338. mid_speed = (target_speed + axis->start_speed) / 2;
  339. ddc_speed = target_speed - ((cur_aacddc * acc_steps * acc_steps) / 2);
  340. if (ddc_speed < mid_speed) {
  341. ddc_speed = mid_speed;
  342. }
  343. cur_speed = axis->start_speed;
  344. //S加速曲线加速表计算
  345. do {
  346. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  347. //否则会造成波形中间下移,导致减加速流程过长
  348. if (cur_speed >= mid_speed) {
  349. cur_accdec = cur_max_accdec;
  350. //保证只能进一次
  351. mid_speed *= 3;
  352. }
  353. if (cur_speed >= ddc_speed) { //减减速需要提前判断,尽量保证流程对称
  354. //减加速流程
  355. if (cur_accdec > cur_aacddc) {
  356. cur_accdec -= cur_aacddc;
  357. }
  358. else {
  359. //保证至少有这个加加速,让速度有机会达到目标速度
  360. cur_accdec = cur_aacddc;
  361. }
  362. }
  363. //计算速度
  364. cur_speed += cur_accdec;
  365. if (cur_speed > target_speed) cur_speed = target_speed;
  366. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  367. reg_Value = (int)((clock) / cur_speed);
  368. //过滤器重复的加减速点
  369. #ifdef AXIS_IGNORE_REPEAT_STEP
  370. if (last_reg_value != reg_Value) {
  371. #endif
  372. last_reg_value = reg_Value;
  373. AXIS_ACC_REG_TABLE(axis)[index] = reg_Value;
  374. AXIS_ACC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  375. if (AXIS_ACC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  376. AXIS_ACC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  377. }
  378. #ifdef AXIS_USING_DEBUG
  379. axis->acc_speed_table[index] = (int)cur_speed;
  380. #endif
  381. index++;
  382. #ifdef AXIS_IGNORE_REPEAT_STEP
  383. }
  384. #endif
  385. if (cur_speed < ddc_speed) { //还没到开始减速的速度
  386. //加加速流程
  387. cur_accdec += cur_aacddc;
  388. if (cur_accdec >= cur_max_accdec) {
  389. cur_accdec = cur_max_accdec;
  390. }
  391. }
  392. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  393. //保存表大小
  394. axis->acc_table_size = index;
  395. #ifdef AXIS_USING_ACC_TABLE_ONLY
  396. if (index > 0) {
  397. index -= 1;
  398. }
  399. axis->dec_table_size = index;
  400. #else
  401. if (dec_steps != acc_steps) {
  402. cur_aacddc = ((target_speed - axis->start_speed)) / (dec_steps * dec_steps);
  403. //保证至少1以上的加减速度
  404. if (cur_aacddc < 1) {
  405. cur_aacddc = 1;
  406. }
  407. //计算加速度会达到的最大值
  408. cur_max_accdec = cur_aacddc * dec_steps;
  409. if (cur_max_accdec > axis->max_acc) {
  410. cur_max_accdec = axis->max_acc;
  411. }
  412. //限制加加速度,加加速度过大会导致过冲
  413. if (cur_aacddc > axis->max_aac) {
  414. cur_aacddc = axis->max_aac;
  415. }
  416. //由于加加速比计算结果小,所以需要更多步去达到最高速,需要重新加速步
  417. dec_steps = (int)(cur_max_accdec / cur_aacddc);
  418. //curMaxAccDec = curAacDdc * decSteps;
  419. //if (cur_aacddc == 0) cur_aacddc = 1;
  420. }
  421. //如果减速时间一样,就不重复计算表了
  422. if (dec_steps == acc_steps) {
  423. int j = 0;
  424. while (j < index) {
  425. AXIS_DEC_REG_TABLE(axis)[j] = AXIS_ACC_REG_TABLE(axis)[j];
  426. AXIS_DEC_NUMBER_TABLE(axis)[j] = AXIS_ACC_NUMBER_TABLE(axis)[j];
  427. j++;
  428. }
  429. axis->dec_table_size = index;
  430. if (axis->dec_table_size > 0) {
  431. axis->dec_table_size -= 1;
  432. }
  433. return;
  434. }
  435. //开始减速表计算
  436. index = 0;
  437. last_reg_value = 0;
  438. mid_speed = (target_speed + axis->start_speed) / 2;
  439. ddc_speed = target_speed - ((cur_aacddc * dec_steps * dec_steps) / 2);
  440. if (ddc_speed < mid_speed) {
  441. ddc_speed = mid_speed;
  442. }
  443. cur_speed = axis->start_speed;
  444. //S加速曲线减速表计算
  445. do {
  446. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  447. //否则会造成波形中间下移,导致减加速流程过长
  448. if (cur_speed >= mid_speed) {
  449. cur_accdec = cur_max_accdec;
  450. //保证只可能进一次
  451. mid_speed *= 3;
  452. }
  453. if (cur_speed >= ddc_speed) { //减减速需要提前判断,尽量保证流程对称
  454. //减加速流程
  455. if (cur_accdec > cur_aacddc) {
  456. cur_accdec -= cur_aacddc;
  457. }
  458. else {
  459. //保证至少有这个加加速,让速度有机会达到目标速度
  460. cur_accdec = cur_aacddc;
  461. }
  462. }
  463. //计算速度
  464. cur_speed += cur_accdec;
  465. if (cur_speed > target_speed) cur_speed = target_speed;
  466. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  467. reg_Value = (int)((clock) / cur_speed);
  468. //过滤器重复的加减速点
  469. #ifdef AXIS_IGNORE_REPEAT_STEP
  470. if (last_reg_value != reg_Value) {
  471. #endif
  472. last_reg_value = reg_Value;
  473. AXIS_DEC_REG_TABLE(axis)[index] = reg_Value;
  474. AXIS_DEC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  475. if (AXIS_DEC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  476. AXIS_DEC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  477. }
  478. #ifdef AXIS_USING_DEBUG
  479. axis->dec_speed_table[index] = (int)cur_speed;
  480. #endif
  481. index++;
  482. #ifdef AXIS_IGNORE_REPEAT_STEP
  483. }
  484. #endif
  485. if (cur_speed < ddc_speed) { //还没到开始减速的速度
  486. //加加速流程
  487. cur_accdec += cur_aacddc;
  488. if (cur_accdec >= cur_max_accdec) {
  489. cur_accdec = cur_max_accdec;
  490. }
  491. }
  492. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  493. //保存减速表大小
  494. axis->dec_table_size = index;
  495. if (axis->dec_table_size > 0) {
  496. axis->dec_table_size -= 1;
  497. }
  498. #endif
  499. }
  500. /**
  501. * 以定加加速的S曲线方式计算加减速表
  502. *
  503. * @author LXZ (021720)
  504. *
  505. * @param axis 轴对象
  506. * @param target_speed 目标速度
  507. */
  508. static void axis_mode2_calc_accdec(axis_object_t *axis, int target_speed) {
  509. float cur_accdec = 0; //当前加减速度
  510. float cur_max_accdec = 0; //当前最大加速度减速度
  511. float cur_speed = 0; //当前速度
  512. float ddc_speed = 0; //减减速开始速度
  513. float cur_aacddc = 0; //当前加加速减减速
  514. float mid_speed = 0; //中间速度
  515. int index = 0;
  516. float clock = axis->clock;
  517. float clock_ratio = axis->clock / 1000000;
  518. int start_speed = axis->start_speed;
  519. //周期临时值
  520. int period;
  521. int reg_Value = 0;
  522. int last_reg_value = 0;
  523. period = axis->period;
  524. //限制加速度周期
  525. if (period < 1) period = 1;
  526. //转换倍率
  527. period *= 1000;
  528. //目标速度不能比开始速度小
  529. if (target_speed < start_speed) {
  530. target_speed = start_speed;
  531. }
  532. //开始计算加速表
  533. mid_speed = (target_speed + axis->start_speed) / 2;
  534. cur_speed = axis->start_speed;
  535. cur_aacddc = axis->max_aac;
  536. cur_max_accdec = axis->max_acc;
  537. cur_accdec = 0;
  538. ddc_speed = 0;
  539. //S加速曲线加速表计算
  540. do {
  541. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  542. //否则会造成波形中间下移,导致减加速流程过长
  543. if (cur_speed >= mid_speed) { //减减速需要提前判断,尽量保证流程对称
  544. //减加速流程
  545. if (ddc_speed != 0) { //ddc_speed是为了保证第一次开始减速的时候,加加速不掉下来,从而保证曲线中心至少在上方
  546. if (cur_accdec > cur_aacddc) {
  547. cur_accdec -= cur_aacddc;
  548. }
  549. else {
  550. //保证至少有这个加加速,让速度有机会达到目标速度
  551. cur_accdec = cur_aacddc;
  552. }
  553. }
  554. else {
  555. ddc_speed = mid_speed;
  556. }
  557. }
  558. //计算速度
  559. cur_speed += cur_accdec;
  560. if (cur_speed > target_speed) cur_speed = target_speed;
  561. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  562. reg_Value = (int)((clock) / cur_speed);
  563. //过滤器重复的加减速点
  564. #ifdef AXIS_IGNORE_REPEAT_STEP
  565. if (last_reg_value != reg_Value) {
  566. #endif
  567. last_reg_value = reg_Value;
  568. AXIS_ACC_REG_TABLE(axis)[index] = reg_Value;
  569. AXIS_ACC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  570. if (AXIS_ACC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  571. AXIS_ACC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  572. }
  573. #ifdef AXIS_USING_DEBUG
  574. axis->acc_speed_table[index] = cur_speed;
  575. #endif
  576. index++;
  577. #ifdef AXIS_IGNORE_REPEAT_STEP
  578. }
  579. #endif
  580. if (cur_speed < mid_speed) {
  581. //加加速流程
  582. cur_accdec += cur_aacddc;
  583. if (cur_accdec >= cur_max_accdec) {
  584. cur_accdec = cur_max_accdec;
  585. }
  586. }
  587. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  588. //保存表大小
  589. axis->acc_table_size = index;
  590. #ifdef AXIS_USING_ACC_TABLE_ONLY
  591. if (index > 0) {
  592. index -= 1;
  593. }
  594. axis->dec_table_size = index;
  595. #else
  596. //如果减速时间一样,就不重复计算表了
  597. if (axis->max_dec == axis->max_dec) {
  598. int j = 0;
  599. while (j < index) {
  600. AXIS_DEC_REG_TABLE(axis)[j] = AXIS_ACC_REG_TABLE(axis)[j];
  601. AXIS_DEC_NUMBER_TABLE(axis)[j] = AXIS_ACC_NUMBER_TABLE(axis)[j];
  602. j++;
  603. }
  604. axis->dec_table_size = index;
  605. if (axis->dec_table_size > 0) {
  606. axis->dec_table_size -= 1;
  607. }
  608. return;
  609. }
  610. //开始减速表计算
  611. index = 0;
  612. last_reg_value = 0;
  613. mid_speed = (target_speed + axis->start_speed) / 2;
  614. ddc_speed = 0;
  615. cur_accdec = 0;
  616. cur_max_accdec = axis->max_dec;
  617. cur_speed = axis->start_speed;
  618. //S加速曲线减速表计算
  619. do {
  620. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  621. //否则会造成波形中间下移,导致减加速流程过长
  622. if (cur_speed >= mid_speed) { //减减速需要提前判断,尽量保证流程对称
  623. //减加速流程
  624. if (ddc_speed != 0) {
  625. if (cur_accdec > cur_aacddc) {
  626. cur_accdec -= cur_aacddc;
  627. }
  628. else {
  629. //保证至少有这个加加速,让速度有机会达到目标速度
  630. cur_accdec = cur_aacddc;
  631. }
  632. }
  633. else {
  634. ddc_speed = mid_speed;
  635. }
  636. }
  637. //计算速度
  638. cur_speed += cur_accdec;
  639. if (cur_speed > target_speed) cur_speed = target_speed;
  640. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  641. reg_Value = (int)((clock) / cur_speed);
  642. //过滤器重复的加减速点
  643. #ifdef AXIS_IGNORE_REPEAT_STEP
  644. if (last_reg_value != reg_Value) {
  645. #endif
  646. last_reg_value = reg_Value;
  647. AXIS_DEC_REG_TABLE(axis)[index] = reg_Value;
  648. AXIS_DEC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  649. if (AXIS_DEC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  650. AXIS_DEC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  651. }
  652. #ifdef AXIS_USING_DEBUG
  653. axis->dec_speed_table[index] = cur_speed;
  654. #endif
  655. index++;
  656. #ifdef AXIS_IGNORE_REPEAT_STEP
  657. }
  658. #endif
  659. if (cur_speed < mid_speed) { //还没到开始减速的速度
  660. //加加速流程
  661. cur_accdec += cur_aacddc;
  662. if (cur_accdec >= cur_max_accdec) {
  663. cur_accdec = cur_max_accdec;
  664. }
  665. }
  666. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  667. //保存减速表大小
  668. axis->dec_table_size = index;
  669. if (axis->dec_table_size > 0) {
  670. axis->dec_table_size -= 1;
  671. }
  672. #endif
  673. }
  674. /**
  675. * 以定加加速的S曲线方式计算加减速表
  676. *
  677. * @author LXZ (021720)
  678. *
  679. * @param axis 轴对象
  680. * @param target_speed 目标速度
  681. */
  682. static void axis_mode3_calc_accdec(axis_object_t *axis, int target_speed) {
  683. float cur_accdec = 0; //当前加减速度
  684. float cur_max_accdec = 0; //当前最大加速度减速度
  685. float cur_speed = 0; //当前速度
  686. //float ddc_speed = 0; //减减速开始速度
  687. float cur_aacddc = 0; //当前加加速减减速
  688. //float mid_speed = 0; //中间速度
  689. int index = 0;
  690. float clock = axis->clock;
  691. float clock_ratio = axis->clock / 1000000;
  692. int start_speed = axis->start_speed;
  693. //周期临时值
  694. int period;
  695. int reg_Value = 0;
  696. int last_reg_value = 0;
  697. period = axis->period;
  698. //限制加速度周期
  699. if (period < 1) period = 1;
  700. //转换倍率
  701. period *= 1000;
  702. //目标速度不能比开始速度小
  703. if (target_speed < start_speed) {
  704. target_speed = start_speed;
  705. }
  706. //开始计算加速表
  707. //mid_speed = (target_speed + axis->start_speed) / 2;
  708. cur_speed = axis->start_speed;
  709. cur_aacddc = axis->max_aac;
  710. cur_max_accdec = axis->max_acc;
  711. cur_accdec = 0;
  712. //ddc_speed = 0;
  713. //S加速曲线加速表计算
  714. do {
  715. //变异的S曲线,没有上部
  716. cur_speed += cur_accdec;
  717. if (cur_speed > target_speed) cur_speed = target_speed;
  718. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  719. reg_Value = (int)((clock) / cur_speed);
  720. //过滤器重复的加减速点
  721. #ifdef AXIS_IGNORE_REPEAT_STEP
  722. if (last_reg_value != reg_Value) {
  723. #endif
  724. last_reg_value = reg_Value;
  725. AXIS_ACC_REG_TABLE(axis)[index] = reg_Value;
  726. AXIS_ACC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  727. if (AXIS_ACC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  728. AXIS_ACC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  729. }
  730. #ifdef AXIS_USING_DEBUG
  731. axis->acc_speed_table[index] = cur_speed;
  732. #endif
  733. index++;
  734. #ifdef AXIS_IGNORE_REPEAT_STEP
  735. }
  736. #endif
  737. //加加速流程
  738. cur_accdec += cur_aacddc;
  739. if (cur_accdec >= cur_max_accdec) {
  740. cur_accdec = cur_max_accdec;
  741. }
  742. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  743. //保存表大小
  744. axis->acc_table_size = index;
  745. #ifdef AXIS_USING_ACC_TABLE_ONLY
  746. if (index > 0) {
  747. index -= 1;
  748. }
  749. axis->dec_table_size = index;
  750. #else
  751. //如果减速时间一样,就不重复计算表了
  752. if (axis->max_dec == axis->max_dec) {
  753. int j = 0;
  754. while (j < index) {
  755. AXIS_DEC_REG_TABLE(axis)[j] = AXIS_ACC_REG_TABLE(axis)[j];
  756. AXIS_DEC_NUMBER_TABLE(axis)[j] = AXIS_ACC_NUMBER_TABLE(axis)[j];
  757. j++;
  758. }
  759. axis->dec_table_size = index;
  760. if (axis->dec_table_size > 0) {
  761. axis->dec_table_size -= 1;
  762. }
  763. return;
  764. }
  765. //开始减速表计算
  766. index = 0;
  767. last_reg_value = 0;
  768. //mid_speed = (target_speed + axis->start_speed) / 2;
  769. //ddc_speed = 0;
  770. cur_accdec = 0;
  771. cur_max_accdec = axis->max_dec;
  772. cur_speed = axis->start_speed;
  773. //S加速曲线减速表计算
  774. do {
  775. //变异的S曲线,上升不减速,
  776. cur_speed += cur_accdec;
  777. if (cur_speed > target_speed) cur_speed = target_speed;
  778. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  779. reg_Value = (int)((clock) / cur_speed);
  780. //过滤器重复的加减速点
  781. #ifdef AXIS_IGNORE_REPEAT_STEP
  782. if (last_reg_value != reg_Value) {
  783. #endif
  784. last_reg_value = reg_Value;
  785. AXIS_DEC_REG_TABLE(axis)[index] = reg_Value;
  786. AXIS_DEC_NUMBER_TABLE(axis)[index] = (int)((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value);
  787. if (AXIS_DEC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  788. AXIS_DEC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  789. }
  790. #ifdef AXIS_USING_DEBUG
  791. axis->dec_speed_table[index] = cur_speed;
  792. #endif
  793. index++;
  794. #ifdef AXIS_IGNORE_REPEAT_STEP
  795. }
  796. #endif
  797. //加加速流程
  798. cur_accdec += cur_aacddc;
  799. if (cur_accdec >= cur_max_accdec) {
  800. cur_accdec = cur_max_accdec;
  801. }
  802. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  803. //保存减速表大小
  804. axis->dec_table_size = index;
  805. if (axis->dec_table_size > 0) {
  806. axis->dec_table_size -= 1;
  807. }
  808. #endif
  809. }
  810. #else
  811. /**
  812. * 以直线加减速的方式计算加减速表
  813. *
  814. * @author LXZ (021720)
  815. *
  816. * @param axis
  817. * @param target_speed
  818. */
  819. static void axis_mode0_calc_accdec(axis_object_t *axis, int target_speed) {
  820. int acc_steps = 0; //加速时间单位数
  821. int dec_steps = 0; //减速时间单位数
  822. int cur_max_accdec = 0; //当前最大加速度减速度
  823. int cur_speed = 0; //当前速度
  824. int index = 0;
  825. int step = 0;
  826. int clock = axis->clock;
  827. int clock_ratio = axis->clock / 1000000;
  828. int start_speed = axis->start_speed;
  829. //周期临时值
  830. int period;
  831. int reg_Value = 0;
  832. int last_reg_value = 0;
  833. period = axis->period;
  834. //限制加速度周期
  835. if (period < 1) period = 2;
  836. //限制最小加速度时间单位
  837. acc_steps = axis->acc_time / period;
  838. if (acc_steps < 10) {
  839. acc_steps = 10;
  840. }
  841. dec_steps = axis->dec_time / period;
  842. if (dec_steps < 10) {
  843. dec_steps = 10;
  844. }
  845. //转换倍率
  846. period *= 1000;
  847. //保证加减速尽量对齐,需要保证加减数是偶数,由于计算误差,加1能让结果更加逼近设置的时间
  848. acc_steps++;
  849. acc_steps >>= 1;
  850. dec_steps++;
  851. dec_steps >>= 1;
  852. //保证是偶次数加减数,能减少计算误差
  853. //if ((min_acc_step & 0x01) != 0)
  854. // min_acc_step++;
  855. //目标速度不能比开始速度小
  856. if (target_speed < start_speed) {
  857. target_speed = start_speed;
  858. }
  859. //计算加速度会达到的最大值
  860. cur_max_accdec = (target_speed - axis->start_speed) / acc_steps;
  861. //保证至少1以上的加减速度
  862. if (cur_max_accdec < 1) {
  863. cur_max_accdec = 1;
  864. }
  865. //尽量保证最大加速度不会大于限制值
  866. if (cur_max_accdec > axis->max_acc) {
  867. cur_max_accdec = axis->max_acc;
  868. }
  869. acc_steps = (target_speed - axis->start_speed) / cur_max_accdec;
  870. //S加速曲线加速表计算
  871. do {
  872. //计算速度
  873. cur_speed = ((target_speed - start_speed) * step) / acc_steps + start_speed;
  874. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  875. reg_Value = ((clock) / cur_speed);
  876. //过滤器重复的加减速点
  877. #ifdef AXIS_IGNORE_REPEAT_STEP
  878. if (last_reg_value != reg_Value) {
  879. #endif
  880. last_reg_value = reg_Value;
  881. AXIS_ACC_REG_TABLE(axis)[index] = reg_Value;
  882. AXIS_ACC_NUMBER_TABLE(axis)[index] = ((period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value;
  883. if (AXIS_ACC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  884. AXIS_ACC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  885. }
  886. #ifdef AXIS_USING_DEBUG
  887. axis->acc_speed_table[index] = cur_speed;
  888. #endif
  889. index++;
  890. #ifdef AXIS_IGNORE_REPEAT_STEP
  891. }
  892. #endif
  893. step++;
  894. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  895. //保存表大小
  896. axis->acc_table_size = index;
  897. #ifdef AXIS_USING_ACC_TABLE_ONLY
  898. if (index > 0) {
  899. index -= 1;
  900. }
  901. axis->dec_table_size = index;
  902. #else
  903. cur_max_accdec = (target_speed - axis->start_speed)/ dec_steps;
  904. //保证至少1以上的加减速度
  905. if (cur_max_accdec < 1) {
  906. cur_max_accdec = 1;
  907. }
  908. //计算加速度会达到的最大值
  909. if (cur_max_accdec > axis->max_acc) {
  910. cur_max_accdec = axis->max_acc;
  911. }
  912. dec_steps = (target_speed - axis->start_speed)/ cur_max_accdec;
  913. //开始减速表计算
  914. index = 0;
  915. last_reg_value = 0;
  916. step = 0;
  917. //S加速曲线减速表计算
  918. do {
  919. //计算速度
  920. cur_speed = (target_speed - start_speed) * step / dec_steps + start_speed;
  921. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  922. reg_Value = ((clock) / cur_speed);
  923. //过滤器重复的加减速点
  924. #ifdef AXIS_IGNORE_REPEAT_STEP
  925. if (last_reg_value != reg_Value) {
  926. #endif
  927. last_reg_value = reg_Value;
  928. AXIS_DEC_REG_TABLE(axis)[index] = reg_Value;
  929. AXIS_DEC_NUMBER_TABLE(axis)[index] = (period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value;
  930. if (AXIS_DEC_NUMBER_TABLE(axis)[index] < axis->min_steps) AXIS_DEC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  931. #ifdef AXIS_USING_DEBUG
  932. axis->dec_speed_table[index] = cur_speed;
  933. #endif
  934. index++;
  935. #ifdef AXIS_IGNORE_REPEAT_STEP
  936. }
  937. #endif
  938. step++;
  939. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  940. //保存减速表大小
  941. axis->dec_table_size = index;
  942. if (axis->dec_table_size > 0) {
  943. axis->dec_table_size -= 1;
  944. }
  945. #endif
  946. }
  947. /**
  948. * 以S曲线减速的方式计算加减速表
  949. *
  950. * @author LXZ (021720)
  951. *
  952. * @param axis 轴对象
  953. * @param target_speed 目标速度
  954. */
  955. static void axis_mode1_calc_accdec(axis_object_t *axis, int target_speed) {
  956. int acc_steps = 0; //加速时间单位数
  957. int dec_steps = 0; //减速时间单位数
  958. int cur_accdec = 0; //当前加减速度
  959. int cur_max_accdec = 0; //当前最大加速度减速度
  960. int cur_speed = 0; //当前速度
  961. int ddc_speed = 0; //减减速开始速度
  962. int cur_aacddc = 0; //当前加加速减减速
  963. int mid_speed = 0; //中间速度
  964. int index = 0;
  965. int clock = axis->clock;
  966. int clock_ratio = axis->clock / 1000000;
  967. int start_speed = axis->start_speed;
  968. //周期临时值
  969. int period;
  970. int reg_Value = 0;
  971. int last_reg_value = 0;
  972. period = axis->period;
  973. //限制加速度周期
  974. if (period < 1) period = 1;
  975. //限制最小加速度时间单位
  976. acc_steps = axis->acc_time / period;
  977. if (acc_steps < 10) {
  978. acc_steps = 10;
  979. }
  980. dec_steps = axis->dec_time / period;
  981. if (dec_steps < 10) {
  982. dec_steps = 10;
  983. }
  984. //转换倍率
  985. period *= 1000;
  986. //保证加减速尽量对齐,需要保证加减数是偶数,由于计算误差,加1能让结果更加逼近设置的时间
  987. acc_steps++;
  988. acc_steps >>= 1;
  989. dec_steps++;
  990. dec_steps >>= 1;
  991. //保证是偶次数加减数,能减少计算误差
  992. //if ((min_acc_step & 0x01) != 0)
  993. // min_acc_step++;
  994. //目标速度不能比开始速度小
  995. if (target_speed < start_speed) {
  996. target_speed = start_speed;
  997. }
  998. //S加速算法需要先计算出加加速
  999. //推导过程:
  1000. //S加减速度分为加加速与减加速度两个过程,假定两个过程是对称的,那么总占用时间为加速时间t的一半
  1001. //因此利用积分公式(dv = sadt, vm = (vd - v0) / 2 => a = vm / (2 * (t / 2))可以得到acc = (vd - v0) * 2 / t
  1002. //其中a与acc表示加速度,vd表示目标速度,v0表示开始速度t表示加速时间一半
  1003. //加加速度aac与加速度关系acc为acc = aac * (t / 2)
  1004. //从而公式为aac = (vd - v0) * 4 / (t ^2)
  1005. //其中acc表示加速度,aac表示加加速,vd为目标速度,v0为开始速度,t为总的加速时间,在这算法里它就是加速度步数
  1006. //由于加速度步数要对称就必须保持偶数,加上一些计算偏差以及为了保证电机正常运算必须限制参数
  1007. //因此实际上两个过程在实际上是很难对称的,这就造成了实际加速时间肯定会比设定的长,具体长多
  1008. //跟最大加加速,最大中速度,最小脉冲数,计算偏差,最小加速度步数有关
  1009. cur_aacddc = ((target_speed - axis->start_speed)) / (acc_steps * acc_steps);
  1010. //保证至少1以上的加减速度
  1011. if (cur_aacddc < 1) {
  1012. cur_aacddc = 1;
  1013. }
  1014. //计算加速度会达到的最大值
  1015. cur_max_accdec = cur_aacddc * acc_steps;
  1016. if (cur_max_accdec > axis->max_acc) {
  1017. cur_max_accdec = axis->max_acc;
  1018. }
  1019. //限制加加速度,加加速度过大会导致过冲
  1020. if (cur_aacddc > axis->max_aac) {
  1021. cur_aacddc = axis->max_aac;
  1022. }
  1023. //由于加加速比计算结果小,所以需要更多步去达到最高速,需要重新加速步
  1024. acc_steps = cur_max_accdec / cur_aacddc;
  1025. if (cur_aacddc == 0) cur_aacddc = 1;
  1026. //开始计算加速表
  1027. mid_speed = (target_speed + axis->start_speed) >> 1;
  1028. ddc_speed = target_speed - ((cur_aacddc * acc_steps * acc_steps) >> 1);
  1029. if (ddc_speed < mid_speed) {
  1030. ddc_speed = mid_speed;
  1031. }
  1032. cur_speed = axis->start_speed;
  1033. //S加速曲线加速表计算
  1034. do {
  1035. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  1036. //否则会造成波形中间下移,导致减加速流程过长
  1037. if (cur_speed >= mid_speed) {
  1038. cur_accdec = cur_max_accdec;
  1039. //保证只能进一次
  1040. mid_speed *= 3;
  1041. }
  1042. if (cur_speed >= ddc_speed) { //减减速需要提前判断,尽量保证流程对称
  1043. //减加速流程
  1044. if (cur_accdec > cur_aacddc) {
  1045. cur_accdec -= cur_aacddc;
  1046. }
  1047. else {
  1048. //保证至少有这个加加速,让速度有机会达到目标速度
  1049. cur_accdec = cur_aacddc;
  1050. }
  1051. }
  1052. //计算速度
  1053. cur_speed += cur_accdec;
  1054. if (cur_speed > target_speed) cur_speed = target_speed;
  1055. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  1056. reg_Value = ((clock) / cur_speed);
  1057. //过滤器重复的加减速点
  1058. #ifdef AXIS_IGNORE_REPEAT_STEP
  1059. if (last_reg_value != reg_Value) {
  1060. #endif
  1061. last_reg_value = reg_Value;
  1062. AXIS_ACC_REG_TABLE(axis)[index] = reg_Value;
  1063. AXIS_ACC_NUMBER_TABLE(axis)[index] = (period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value;
  1064. if (AXIS_ACC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  1065. AXIS_ACC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  1066. }
  1067. #ifdef AXIS_USING_DEBUG
  1068. axis->acc_speed_table[index] = cur_speed;
  1069. #endif
  1070. index++;
  1071. #ifdef AXIS_IGNORE_REPEAT_STEP
  1072. }
  1073. #endif
  1074. if (cur_speed < ddc_speed) { //还没到开始减速的速度
  1075. //加加速流程
  1076. cur_accdec += cur_aacddc;
  1077. if (cur_accdec >= cur_max_accdec) {
  1078. cur_accdec = cur_max_accdec;
  1079. }
  1080. }
  1081. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  1082. //保存表大小
  1083. axis->acc_table_size = index;
  1084. #ifdef AXIS_USING_ACC_TABLE_ONLY
  1085. if (index > 0) {
  1086. index -= 1;
  1087. }
  1088. axis->dec_table_size = index;
  1089. #else
  1090. if (dec_steps != acc_steps) {
  1091. cur_aacddc = ((target_speed - axis->start_speed)) / (dec_steps * dec_steps);
  1092. //保证至少1以上的加减速度
  1093. if (cur_aacddc < 1) {
  1094. cur_aacddc = 1;
  1095. }
  1096. //计算加速度会达到的最大值
  1097. cur_max_accdec = cur_aacddc * dec_steps;
  1098. if (cur_max_accdec > axis->max_acc) {
  1099. cur_max_accdec = axis->max_acc;
  1100. }
  1101. //限制加加速度,加加速度过大会导致过冲
  1102. if (cur_aacddc > axis->max_aac) {
  1103. cur_aacddc = axis->max_aac;
  1104. }
  1105. //由于加加速比计算结果小,所以需要更多步去达到最高速,需要重新加速步
  1106. dec_steps = cur_max_accdec / cur_aacddc;
  1107. //curMaxAccDec = curAacDdc * decSteps;
  1108. if (cur_aacddc == 0) cur_aacddc = 1;
  1109. }
  1110. //如果减速时间一样,就不重复计算表了
  1111. if (dec_steps == acc_steps) {
  1112. int j = 0;
  1113. while (j < index) {
  1114. AXIS_DEC_REG_TABLE(axis)[j] = AXIS_ACC_REG_TABLE(axis)[j];
  1115. AXIS_DEC_NUMBER_TABLE(axis)[j] = AXIS_ACC_NUMBER_TABLE(axis)[j];
  1116. j++;
  1117. }
  1118. axis->dec_table_size = index;
  1119. if (axis->dec_table_size > 0) {
  1120. axis->dec_table_size -= 1;
  1121. }
  1122. return;
  1123. }
  1124. //开始减速表计算
  1125. index = 0;
  1126. last_reg_value = 0;
  1127. mid_speed = (target_speed + axis->start_speed) >> 1;
  1128. ddc_speed = target_speed - ((cur_aacddc * dec_steps * dec_steps) >> 1);
  1129. if (ddc_speed < mid_speed) {
  1130. ddc_speed = mid_speed;
  1131. }
  1132. cur_speed = axis->start_speed;
  1133. //S加速曲线减速表计算
  1134. do {
  1135. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  1136. //否则会造成波形中间下移,导致减加速流程过长
  1137. if (cur_speed >= mid_speed) {
  1138. cur_accdec = cur_max_accdec;
  1139. //保证只可能进一次
  1140. mid_speed *= 3;
  1141. }
  1142. if (cur_speed >= ddc_speed) { //减减速需要提前判断,尽量保证流程对称
  1143. //减加速流程
  1144. if (cur_accdec > cur_aacddc) {
  1145. cur_accdec -= cur_aacddc;
  1146. }
  1147. else {
  1148. //保证至少有这个加加速,让速度有机会达到目标速度
  1149. cur_accdec = cur_aacddc;
  1150. }
  1151. }
  1152. //计算速度
  1153. cur_speed += cur_accdec;
  1154. if (cur_speed > target_speed) cur_speed = target_speed;
  1155. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  1156. reg_Value = ((clock) / cur_speed);
  1157. //过滤器重复的加减速点
  1158. #ifdef AXIS_IGNORE_REPEAT_STEP
  1159. if (last_reg_value != reg_Value) {
  1160. #endif
  1161. last_reg_value = reg_Value;
  1162. AXIS_DEC_REG_TABLE(axis)[index] = reg_Value;
  1163. AXIS_DEC_NUMBER_TABLE(axis)[index] = (period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value;
  1164. if (AXIS_DEC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  1165. AXIS_DEC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  1166. }
  1167. #ifdef AXIS_USING_DEBUG
  1168. axis->dec_speed_table[index] = cur_speed;
  1169. #endif
  1170. index++;
  1171. #ifdef AXIS_IGNORE_REPEAT_STEP
  1172. }
  1173. #endif
  1174. if (cur_speed < ddc_speed) { //还没到开始减速的速度
  1175. //加加速流程
  1176. cur_accdec += cur_aacddc;
  1177. if (cur_accdec >= cur_max_accdec) {
  1178. cur_accdec = cur_max_accdec;
  1179. }
  1180. }
  1181. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  1182. //保存减速表大小
  1183. axis->dec_table_size = index;
  1184. if (axis->dec_table_size > 0) {
  1185. axis->dec_table_size -= 1;
  1186. }
  1187. #endif
  1188. }
  1189. /**
  1190. * 以定加加速的S曲线方式计算加减速表
  1191. *
  1192. * @author LXZ (021720)
  1193. *
  1194. * @param axis 轴对象
  1195. * @param target_speed 目标速度
  1196. */
  1197. static void axis_mode2_calc_accdec(axis_object_t *axis, int target_speed) {
  1198. int cur_accdec = 0; //当前加减速度
  1199. int cur_max_accdec = 0; //当前最大加速度减速度
  1200. int cur_speed = 0; //当前速度
  1201. int ddc_speed = 0; //减减速开始速度
  1202. int cur_aacddc = 0; //当前加加速减减速
  1203. int mid_speed = 0; //中间速度
  1204. int index = 0;
  1205. int clock = axis->clock;
  1206. int clock_ratio = axis->clock / 1000000;
  1207. int start_speed = axis->start_speed;
  1208. //周期临时值
  1209. int period;
  1210. int reg_Value = 0;
  1211. int last_reg_value = 0;
  1212. period = axis->period;
  1213. //限制加速度周期
  1214. if (period < 1) period = 1;
  1215. //转换倍率
  1216. period *= 1000;
  1217. //目标速度不能比开始速度小
  1218. if (target_speed < start_speed) {
  1219. target_speed = start_speed;
  1220. }
  1221. //开始计算加速表
  1222. mid_speed = (target_speed + axis->start_speed) / 2;
  1223. cur_speed = axis->start_speed;
  1224. cur_aacddc = axis->max_aac;
  1225. cur_max_accdec = axis->max_acc;
  1226. cur_accdec = 0;
  1227. ddc_speed = 0;
  1228. //S加速曲线加速表计算
  1229. do {
  1230. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  1231. //否则会造成波形中间下移,导致减加速流程过长
  1232. if (cur_speed >= mid_speed) { //减减速需要提前判断,尽量保证流程对称
  1233. //减加速流程
  1234. if (ddc_speed != 0) { //ddc_speed是为了保证第一次开始减速的时候,加加速不掉下来,从而保证曲线中心至少在上方
  1235. if (cur_accdec > cur_aacddc) {
  1236. cur_accdec -= cur_aacddc;
  1237. }
  1238. else {
  1239. //保证至少有这个加加速,让速度有机会达到目标速度
  1240. cur_accdec = cur_aacddc;
  1241. }
  1242. }
  1243. else {
  1244. ddc_speed = mid_speed;
  1245. }
  1246. }
  1247. //计算速度
  1248. cur_speed += cur_accdec;
  1249. if (cur_speed > target_speed) cur_speed = target_speed;
  1250. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  1251. reg_Value = ((clock) / cur_speed);
  1252. //过滤器重复的加减速点
  1253. #ifdef AXIS_IGNORE_REPEAT_STEP
  1254. if (last_reg_value != reg_Value) {
  1255. #endif
  1256. last_reg_value = reg_Value;
  1257. AXIS_ACC_REG_TABLE(axis)[index] = reg_Value;
  1258. AXIS_ACC_NUMBER_TABLE(axis)[index] = (period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value;
  1259. if (AXIS_ACC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  1260. AXIS_ACC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  1261. }
  1262. #ifdef AXIS_USING_DEBUG
  1263. axis->acc_speed_table[index] = cur_speed;
  1264. #endif
  1265. index++;
  1266. #ifdef AXIS_IGNORE_REPEAT_STEP
  1267. }
  1268. #endif
  1269. if (cur_speed < mid_speed) {
  1270. //加加速流程
  1271. cur_accdec += cur_aacddc;
  1272. if (cur_accdec >= cur_max_accdec) {
  1273. cur_accdec = cur_max_accdec;
  1274. }
  1275. }
  1276. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  1277. //保存表大小
  1278. axis->acc_table_size = index;
  1279. #ifdef AXIS_USING_ACC_TABLE_ONLY
  1280. if (index > 0) {
  1281. index -= 1;
  1282. }
  1283. axis->dec_table_size = index;
  1284. #else
  1285. if (dec_steps != acc_steps) {
  1286. cur_aacddc = ((target_speed - axis->start_speed)) / (dec_steps * dec_steps);
  1287. //保证至少1以上的加减速度
  1288. if (cur_aacddc < 1) {
  1289. cur_aacddc = 1;
  1290. }
  1291. //计算加速度会达到的最大值
  1292. cur_max_accdec = cur_aacddc * dec_steps;
  1293. if (cur_max_accdec > axis->max_acc) {
  1294. cur_max_accdec = axis->max_acc;
  1295. }
  1296. //限制加加速度,加加速度过大会导致过冲
  1297. if (cur_aacddc > axis->max_aac) {
  1298. cur_aacddc = axis->max_aac;
  1299. }
  1300. //由于加加速比计算结果小,所以需要更多步去达到最高速,需要重新加速步
  1301. dec_steps = cur_max_accdec / cur_aacddc;
  1302. //curMaxAccDec = curAacDdc * decSteps;
  1303. if (cur_aacddc == 0) cur_aacddc = 1;
  1304. }
  1305. //如果减速时间一样,就不重复计算表了
  1306. if (axis->max_dec == axis->max_dec) {
  1307. int j = 0;
  1308. while (j < index) {
  1309. AXIS_DEC_REG_TABLE(axis)[j] = AXIS_ACC_REG_TABLE(axis)[j];
  1310. AXIS_DEC_NUMBER_TABLE(axis)[j] = AXIS_ACC_NUMBER_TABLE(axis)[j];
  1311. j++;
  1312. }
  1313. axis->dec_table_size = index;
  1314. if (axis->dec_table_size > 0) {
  1315. axis->dec_table_size -= 1;
  1316. }
  1317. return;
  1318. }
  1319. //开始减速表计算
  1320. index = 0;
  1321. last_reg_value = 0;
  1322. mid_speed = (target_speed + axis->start_speed) / 2;
  1323. ddc_speed = 0;
  1324. cur_accdec = 0;
  1325. cur_max_accdec = axis->max_dec;
  1326. cur_speed = axis->start_speed;
  1327. //S加速曲线减速表计算
  1328. do {
  1329. //正常的情况下,速度达到目标速度一半后,加速度肯定达到最大值,如果没有达到,必须强制达到
  1330. //否则会造成波形中间下移,导致减加速流程过长
  1331. if (cur_speed >= mid_speed) { //减减速需要提前判断,尽量保证流程对称
  1332. //减加速流程
  1333. if (ddc_speed != 0) {
  1334. if (cur_accdec > cur_aacddc) {
  1335. cur_accdec -= cur_aacddc;
  1336. }
  1337. else {
  1338. //保证至少有这个加加速,让速度有机会达到目标速度
  1339. cur_accdec = cur_aacddc;
  1340. }
  1341. }
  1342. else {
  1343. ddc_speed = mid_speed;
  1344. }
  1345. }
  1346. //计算速度
  1347. cur_speed += cur_accdec;
  1348. if (cur_speed > target_speed) cur_speed = target_speed;
  1349. //计算该速度对应的寄存器值与以及当前频率下需要满足加速周期的脉冲速
  1350. reg_Value = ((clock) / cur_speed);
  1351. //过滤器重复的加减速点
  1352. #ifdef AXIS_IGNORE_REPEAT_STEP
  1353. if (last_reg_value != reg_Value) {
  1354. #endif
  1355. last_reg_value = reg_Value;
  1356. AXIS_DEC_REG_TABLE(axis)[index] = reg_Value;
  1357. AXIS_DEC_NUMBER_TABLE(axis)[index] = (period + AXIS_CALC_ROUND(reg_Value)) * clock_ratio / reg_Value;
  1358. if (AXIS_DEC_NUMBER_TABLE(axis)[index] < axis->min_steps) {
  1359. AXIS_DEC_NUMBER_TABLE(axis)[index] = axis->min_steps;
  1360. }
  1361. #ifdef AXIS_USING_DEBUG
  1362. axis->dec_speed_table[index] = cur_speed;
  1363. #endif
  1364. index++;
  1365. #ifdef AXIS_IGNORE_REPEAT_STEP
  1366. }
  1367. #endif
  1368. if (cur_speed < mid_speed) { //还没到开始减速的速度
  1369. //加加速流程
  1370. cur_accdec += cur_aacddc;
  1371. if (cur_accdec >= cur_max_accdec) {
  1372. cur_accdec = cur_max_accdec;
  1373. }
  1374. }
  1375. } while (cur_speed < target_speed && (index + 1) < AXIS_MAX_ACCDEC_STEP);
  1376. //保存减速表大小
  1377. axis->dec_table_size = index;
  1378. if (axis->dec_table_size > 0) {
  1379. axis->dec_table_size -= 1;
  1380. }
  1381. #endif
  1382. }
  1383. #endif
  1384. /**
  1385. * 计算加减速表的接口
  1386. *
  1387. * @author LXZ (021720)
  1388. *
  1389. * @param axis
  1390. * @param target_speed
  1391. */
  1392. void axis_calc_speed_table(axis_object_t *axis, int target_speed) {
  1393. if (axis->accdec_mode == 1) {
  1394. axis_mode1_calc_accdec(axis, target_speed);
  1395. }
  1396. else if (axis->accdec_mode == 2) {
  1397. axis_mode2_calc_accdec(axis, target_speed);
  1398. }
  1399. else if (axis->accdec_mode == 3) {
  1400. axis_mode3_calc_accdec(axis, target_speed);
  1401. }
  1402. else {
  1403. axis_mode0_calc_accdec(axis, target_speed);
  1404. }
  1405. }
  1406. /**
  1407. * 轴运动中断函数
  1408. *
  1409. * @author lxz
  1410. *
  1411. * @param handle
  1412. */
  1413. void axis_it_handle(void *handle) {
  1414. axis_object_t *axis = (axis_object_t *)handle;
  1415. unsigned short reg_value = 0;
  1416. axis->position += axis->feed;
  1417. switch (axis->run_mode) {
  1418. case AXIS_MODE_PP:
  1419. // if (axis->feed > 0) {
  1420. if ((axis->position - axis->dec_position) * axis->feed >= 0) { //开始减速的条件
  1421. if (axis->cur_accdec_status != AXIS_ACCDEC_STATUS_DEC) {
  1422. axis->cur_accdec_status = AXIS_ACCDEC_STATUS_DEC;
  1423. axis->cur_speed_index = axis->dec_speed_index;
  1424. axis->accdec_count = AXIS_DEC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1425. }
  1426. else if (axis->accdec_count > 1) { //减速脉冲计数
  1427. axis->accdec_count--;
  1428. }
  1429. else if (axis->cur_speed_index > 0) { //切换速度
  1430. axis->cur_speed_index--;
  1431. axis->accdec_count = AXIS_DEC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1432. }
  1433. reg_value = AXIS_DEC_REG_TABLE(axis)[axis->cur_speed_index];
  1434. }
  1435. else {
  1436. axis->cur_accdec_status = AXIS_ACCDEC_STATUS_ACC;
  1437. if (axis->accdec_count > 1) { //加速脉冲计数
  1438. axis->accdec_count--;
  1439. }
  1440. else if (axis->cur_speed_index < axis->acc_speed_index) { //切换速度
  1441. axis->cur_speed_index++;
  1442. axis->accdec_count = AXIS_ACC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1443. }
  1444. reg_value = AXIS_ACC_REG_TABLE(axis)[axis->cur_speed_index];
  1445. }
  1446. //到达位置立刻停止
  1447. if ((axis->position - axis->target_position) * axis->feed >= 0) {
  1448. AXIS_OFF(axis);
  1449. }
  1450. break;
  1451. #ifdef AXIS_PP_TASK_NUMBER
  1452. case AXIS_MODE_PP_TASKS:
  1453. if ((axis->position - axis->tasks[axis->cur_task_index].dec_position) * axis->feed >= 0) {
  1454. if (axis->cur_task_index + 1 < axis->task_number) {
  1455. if (axis->cur_accdec_status != AXIS_ACCDEC_STATUS_DEC) {
  1456. axis->cur_accdec_status = AXIS_ACCDEC_STATUS_DEC;
  1457. axis->cur_speed_index = axis->tasks[axis->cur_task_index].dec_speed_index;
  1458. axis->accdec_count = AXIS_ACC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1459. }
  1460. else if (axis->accdec_count > 1) {
  1461. axis->accdec_count--;
  1462. }
  1463. else if (axis->cur_speed_index > axis->tasks[axis->cur_task_index + 1].dst_speed_index) {
  1464. axis->cur_speed_index--;
  1465. axis->accdec_count = AXIS_ACC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1466. }
  1467. reg_value = AXIS_ACC_REG_TABLE(axis)[axis->cur_speed_index];
  1468. }
  1469. else {
  1470. if (axis->cur_accdec_status != AXIS_ACCDEC_STATUS_DEC) {
  1471. axis->cur_accdec_status = AXIS_ACCDEC_STATUS_DEC;
  1472. axis->cur_speed_index = axis->tasks[axis->cur_task_index].dec_speed_index;
  1473. axis->accdec_count = AXIS_DEC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1474. }
  1475. else if (axis->accdec_count > 1) {
  1476. axis->accdec_count--;
  1477. }
  1478. else if (axis->cur_speed_index > 0) {
  1479. axis->cur_speed_index--;
  1480. axis->accdec_count = AXIS_DEC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1481. }
  1482. reg_value = AXIS_DEC_REG_TABLE(axis)[axis->cur_speed_index];
  1483. }
  1484. }
  1485. else {
  1486. axis->cur_accdec_status = 0;
  1487. if (axis->accdec_count > 1) { //加速脉冲计数
  1488. axis->accdec_count--;
  1489. }
  1490. else if (axis->cur_speed_index < axis->tasks[axis->cur_task_index].dst_speed_index) { //切换速度
  1491. axis->cur_speed_index++;
  1492. axis->accdec_count = AXIS_ACC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1493. }
  1494. if (axis->cur_speed_index == axis->tasks[axis->cur_task_index].dst_speed_index &&
  1495. axis->accdec_count == 0) {
  1496. reg_value = axis->tasks[axis->cur_task_index].reg_value;
  1497. }
  1498. else {
  1499. reg_value = AXIS_ACC_REG_TABLE(axis)[axis->cur_speed_index];
  1500. }
  1501. }
  1502. if ((axis->position - axis->tasks[axis->cur_task_index].target_position) * axis->feed >= 0) {
  1503. axis->cur_task_index++;
  1504. axis->cur_accdec_status = 0;
  1505. if (axis->cur_task_index >= axis->task_number) {
  1506. AXIS_OFF(axis);
  1507. }
  1508. }
  1509. break;
  1510. #endif
  1511. case AXIS_MODE_PV:
  1512. axis->cur_accdec_status = AXIS_ACCDEC_STATUS_ACC;
  1513. if (axis->accdec_count > 1) {
  1514. axis->accdec_count--;
  1515. }
  1516. else if (axis->cur_speed_index < axis->acc_speed_index) {
  1517. axis->cur_speed_index++;
  1518. axis->accdec_count = AXIS_ACC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1519. }
  1520. else if (axis->cur_speed_index > axis->acc_speed_index) {
  1521. axis->cur_speed_index--;
  1522. axis->accdec_count = AXIS_ACC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1523. }
  1524. else {
  1525. axis->accdec_count = 0;
  1526. }
  1527. if (axis->accdec_count == 0 && axis->cur_speed_index == axis->acc_speed_index) {
  1528. reg_value = axis->target_speed_reg;
  1529. }
  1530. else {
  1531. reg_value = AXIS_ACC_REG_TABLE(axis)[axis->cur_speed_index];
  1532. }
  1533. break;
  1534. case AXIS_MODE_INTERP:
  1535. if (axis->accdec_count > 1) {
  1536. axis->accdec_count--;
  1537. }
  1538. // else if (axis->interp_feed != 0) {
  1539. // //检测是否有设置新的进给任务
  1540. // if (axis->interp_feed > 0) {
  1541. // axis->accdec_count = axis->interp_feed;
  1542. // axis_cw(axis);
  1543. // }
  1544. // else
  1545. // {
  1546. // axis->accdec_count = -axis->interp_feed;
  1547. // axis_ccw(axis);
  1548. // }
  1549. // axis->interp_feed = 0;
  1550. // axis->dst_period = axis->interp_reg;
  1551. // }
  1552. else {
  1553. //没有就需要轴停止
  1554. AXIS_OFF(axis);
  1555. }
  1556. reg_value = axis->dst_period;
  1557. break;
  1558. case AXIS_MODE_STOP:
  1559. //由于允许加减速表不对称,因此需要保护不要溢出
  1560. if (axis->cur_accdec_status != AXIS_ACCDEC_STATUS_DEC) {
  1561. axis->cur_accdec_status = AXIS_ACCDEC_STATUS_DEC;
  1562. axis->cur_speed_index = axis->dec_speed_index;
  1563. axis->accdec_count = AXIS_DEC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1564. }
  1565. else if (axis->accdec_count > 1) {
  1566. axis->accdec_count--;
  1567. }
  1568. else {
  1569. //计数一定脉冲后切换速度
  1570. if (axis->cur_speed_index > 0) axis->cur_speed_index--;
  1571. else AXIS_OFF(axis);
  1572. axis->accdec_count = AXIS_DEC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  1573. }
  1574. reg_value = AXIS_DEC_REG_TABLE(axis)[axis->cur_speed_index];
  1575. break;
  1576. case AXIS_MODE_EMGSTOP:
  1577. axis->home_step = 0;
  1578. AXIS_OFF(axis);
  1579. break;
  1580. }
  1581. if (axis->outputs.homing) { //回零时中断处理信号
  1582. switch (axis->home_method) { //根据方法不同回零使能判断部位也不同
  1583. case 0:
  1584. if (axis->home_step == 6) { //回零方式0需要在这里处理信号
  1585. if (AXIS_GET_HOME_SGN(axis) && axis->inputs.hw_home_sgn) { //回零信号滤波
  1586. if (++axis->home_sgn_count >= axis->home_sgn_filter)
  1587. { //确定信号
  1588. if (axis->inputs.home_encode_sgn_enable) { //使能了编码器回零信号
  1589. axis->home_step++;
  1590. }
  1591. else {
  1592. axis->home_step += 2;
  1593. AXIS_OFF(axis);
  1594. }
  1595. }
  1596. }
  1597. }
  1598. else if (axis->home_step == 7) {
  1599. if (AXIS_GET_HOME_SGN(axis)) { //回零信号滤波
  1600. if (++axis->home_sgn_count >= axis->home_sgn_filter) { //确定信号
  1601. if (axis->inputs.home_encode_sgn_enable) { //启动编码器回零信号滤波
  1602. axis->home_step++;
  1603. axis->home_encoder_sgn_count = 0;
  1604. }
  1605. else {
  1606. axis->home_step += 2;
  1607. AXIS_OFF(axis);
  1608. }
  1609. }
  1610. }
  1611. if (AXIS_GET_HOME_ENCODER_SGN(axis)) {
  1612. if (++axis->home_encoder_sgn_count >= axis->home_encoder_sgn_filter) { //确定编码器回零信号
  1613. axis->home_step++;
  1614. AXIS_OFF(axis);
  1615. }
  1616. }
  1617. }
  1618. break;
  1619. case 2:
  1620. if (axis->home_step == 3) { //回零方式0需要在这里处理信号
  1621. if (AXIS_GET_HOME_SGN(axis)) { //回零信号滤波
  1622. if (axis->inputs.home_encode_sgn_enable) { //启动编码器回零信号滤波
  1623. axis->home_step++;
  1624. axis->home_encoder_sgn_count = 0;
  1625. }
  1626. else {
  1627. if (++axis->home_sgn_count >= axis->home_sgn_filter) { //确定信号
  1628. axis->home_step += 2;
  1629. AXIS_OFF(axis);
  1630. }
  1631. }
  1632. }
  1633. }
  1634. else if (axis->home_step == 4) {
  1635. if (AXIS_GET_HOME_ENCODER_SGN(axis)) { //编码器回零信号滤波
  1636. if (++axis->home_encoder_sgn_count >= axis->home_encoder_sgn_filter) { //确定编码器回零信号
  1637. axis->home_step++;
  1638. AXIS_OFF(axis);
  1639. }
  1640. }
  1641. }
  1642. break;
  1643. }
  1644. }
  1645. AXIS_UPDATE_PERION(axis, reg_value);
  1646. if (axis->handle != 0) {
  1647. axis->handle();
  1648. }
  1649. }
  1650. /**
  1651. * 以目标速度移动到指定位置
  1652. *
  1653. * @author LXZ (021720)
  1654. *
  1655. * @param axis 轴对象
  1656. * @param rel
  1657. * 位置参考系,0表示相对坐标,1表进绝对值坐标
  1658. * @param position 目标位置
  1659. * @param target_speed 目标速度
  1660. *
  1661. * @return
  1662. * 返回0表示正常启动,返回-1表示目标超过正软件限位,返回-2表示目标超过负软件限位,
  1663. * 返回-3表示目标进给为0
  1664. */
  1665. int axis_pp(axis_object_t *axis, int rel, int position, int target_speed) {
  1666. //允许加速表可执行到的位置
  1667. int acc_index = 0;
  1668. //当前减速表可执行到的位置
  1669. int dec_index = 0;
  1670. //开始减速的位置
  1671. int dec_position = 0;
  1672. //齿轮比转换
  1673. if (axis->inputs.ratio_enable) {
  1674. position = axis_position_to_pluse(axis, position);
  1675. }
  1676. //计算目标停止位置
  1677. axis->target_position = position;
  1678. if (rel == 0) {
  1679. axis->target_position += axis->position;
  1680. }
  1681. else {
  1682. position -= axis->position;
  1683. }
  1684. if (position == 0) { //总进给为0时不动
  1685. // axis->outputs.sw_feed_zero_alarm = 1;
  1686. return -3;
  1687. }
  1688. //换算成绝对值
  1689. if (position < 0) {
  1690. position = -position;
  1691. }
  1692. //计算进给方向
  1693. if (axis->target_position > axis->position) {
  1694. axis_cw(axis);
  1695. }
  1696. else {
  1697. axis_ccw(axis);
  1698. }
  1699. if (axis->inputs.sw_lmt_enable) { //使能了软件限位
  1700. if (axis->target_position > axis->sw_positive_limit && axis->feed > 0) { //正向时目标位置比软件限位大的时候不走
  1701. axis->outputs.sw_positive_pre_alarm = 1;
  1702. return -1;
  1703. }
  1704. else if (axis->target_position < axis->sw_negative_limit && axis->feed < 0) { //反向时目标位置比软件限位小的时候不走
  1705. axis->outputs.sw_negative_pre_alarm = 1;
  1706. return -2;
  1707. }
  1708. }
  1709. #if defined(AXIS_SPEED_UNIT)
  1710. axis_calc_speed_table(axis, target_speed * axis->speed_unit);
  1711. #else
  1712. axis_calc_speed_table(axis, target_speed);
  1713. #endif
  1714. dec_index = 0;
  1715. dec_position += AXIS_DEC_NUMBER_TABLE(axis)[dec_index];
  1716. do {
  1717. //加速区域判断
  1718. //当当前的加速时速度比当前的减速时速度相等或者大的时候,可以进行一次减速
  1719. //这是为了保证加减速度差在可以接受的范围内
  1720. //这样也就可以让加减时间更加的灵活
  1721. if (AXIS_ACC_REG_TABLE(axis)[acc_index] < AXIS_DEC_REG_TABLE(axis)[dec_index] &&
  1722. dec_index < axis->dec_table_size - 1) {
  1723. //如果不能进行减加速,退出
  1724. if (position < AXIS_DEC_NUMBER_TABLE(axis)[dec_index]) break;
  1725. dec_index++;
  1726. position -= AXIS_DEC_NUMBER_TABLE(axis)[dec_index];
  1727. dec_position += AXIS_DEC_NUMBER_TABLE(axis)[dec_index];
  1728. }
  1729. else if (acc_index < (axis->acc_table_size - 1)) {
  1730. //如果已经不能加速就退出
  1731. if (position < AXIS_ACC_NUMBER_TABLE(axis)[acc_index] * AXIS_LOCATION_SMOOTH) break;
  1732. position -= AXIS_ACC_NUMBER_TABLE(axis)[acc_index];
  1733. acc_index++;
  1734. }
  1735. else {
  1736. break;
  1737. }
  1738. } while (position > 0);
  1739. axis->acc_speed_index = acc_index;
  1740. axis->dec_speed_index = dec_index;
  1741. axis->dec_position = axis->target_position - dec_position * axis->feed;
  1742. //让中断切换到定位模式
  1743. axis->run_mode = AXIS_MODE_PP;
  1744. axis_start(axis);
  1745. return 0;
  1746. }
  1747. /**
  1748. * 以目标速度执行连续运动
  1749. *
  1750. * @author LXZ (021720)
  1751. *
  1752. * @param axis 轴对象
  1753. * @param dir 运动方向,0为反转,1为正转
  1754. * @param target_speed 目标速度
  1755. */
  1756. void axis_pv(axis_object_t *axis, int dir, int target_speed) {
  1757. if (dir == 0) axis_ccw(axis);
  1758. else axis_cw(axis);
  1759. #if defined(AXIS_SPEED_UNIT)
  1760. axis_calc_speed_table(axis, target_speed * axis->speed_unit);
  1761. #else
  1762. axis_calc_speed_table(axis, target_speed);
  1763. #endif
  1764. axis->acc_speed_index = axis->acc_table_size - 1;
  1765. axis->target_speed_reg = AXIS_ACC_REG_TABLE(axis)[axis->acc_speed_index];
  1766. //让中断切换到连续运动模式
  1767. axis->run_mode = AXIS_MODE_PV;
  1768. axis_start(axis);
  1769. }
  1770. /**
  1771. * 轴插补任务
  1772. *
  1773. * @author LXZ (033020)
  1774. *
  1775. * @param axis
  1776. * @param position 进给的脉冲个数,有方向
  1777. * @param period 周期,用于速度
  1778. */
  1779. void axis_interp(axis_object_t *axis, int position, int period) {
  1780. while (AXIS_IS_ON(axis)); //为了防止漏周期功能,这里需要进行死等
  1781. axis->run_mode = AXIS_MODE_INTERP;
  1782. if (position > 0) {
  1783. axis_cw(axis);
  1784. axis->accdec_count = position;
  1785. }
  1786. else {
  1787. axis_ccw(axis);
  1788. axis->accdec_count = -position;
  1789. }
  1790. axis->dst_period = period;
  1791. axis->interp_feed = position;
  1792. AXIS_SET_PERION(axis, period);
  1793. AXIS_ON(axis);
  1794. }
  1795. #ifdef AXIS_PP_TASK_NUMBER
  1796. /**
  1797. * 初始化轴任务缓冲,并设置此时的方向
  1798. *
  1799. * @author LXZ (031420)
  1800. *
  1801. * @param axis 轴对象
  1802. * @param dir 期望运动的方向
  1803. */
  1804. void axis_init_pp_task(axis_object_t *axis, int dir) {
  1805. axis->task_number = 0;
  1806. memset(axis->tasks, 0, sizeof(axis->tasks));
  1807. if (dir) {
  1808. axis_cw(axis);
  1809. }
  1810. else {
  1811. axis_ccw(axis);
  1812. }
  1813. }
  1814. /**
  1815. * 添加进给值,该进给值都是绝对进给值,与方向与当前坐标无关,方向在初始化任务缓冲的时候就已经设置了
  1816. *
  1817. * @author LXZ (031420)
  1818. *
  1819. * @param axis 轴对象
  1820. * @param feed 进给值
  1821. * @param speed 期望速度
  1822. */
  1823. void axis_add_pp_task(axis_object_t *axis, int feed, int speed) {
  1824. if (feed <= 0) return;
  1825. if (axis->task_number < AXIS_PP_TASK_NUMBER && feed > 0) {
  1826. axis->tasks[axis->task_number].position = axis_position_to_pluse(axis, feed);
  1827. axis->tasks[axis->task_number].speed = speed;
  1828. axis->task_number++;
  1829. }
  1830. }
  1831. /**
  1832. * 启动多段速定位运动模式
  1833. *
  1834. * @author LXZ (031420)
  1835. *
  1836. * @param axis
  1837. *
  1838. * @return
  1839. * 返回0表示正常启动,返回-1表示目标超过正软件限位,返回-2表示目标超过负软件限位,
  1840. * 返回-3表示为有某段进给为0
  1841. */
  1842. int axis_start_pp_task(axis_object_t *axis) {
  1843. int speed;
  1844. int i;
  1845. int posi1; //上一个位置
  1846. int posi2; //当前计算位置
  1847. int feed = 0; //进给量
  1848. int cur_speed_index = 0; //当前速度
  1849. int dst_speed_index = 0; //目标速度
  1850. int dec_speed_index = 0; //
  1851. int dec_position = 0; //开始减速的位置
  1852. if (axis->task_number == 0) return -3;
  1853. //计算最高速度
  1854. for (i = 0, speed = 0; i < axis->task_number; i++) {
  1855. if (speed < axis->tasks[i].speed) speed = axis->tasks[i].speed;
  1856. }
  1857. #if defined(AXIS_SPEED_UNIT)
  1858. speed *= axis->speed_unit;
  1859. #endif
  1860. if (speed < axis->start_speed) {
  1861. speed = axis->start_speed;
  1862. }
  1863. axis_calc_speed_table(axis, speed);
  1864. posi1 = 0;
  1865. for (i = 0; i < axis->task_number; i++) {
  1866. #if defined(AXIS_SPEED_UNIT)
  1867. speed = axis->tasks[i].speed * axis->speed_unit;
  1868. #else
  1869. speed = axis->tasks[i].speed;
  1870. #endif
  1871. if (speed < axis->start_speed) {
  1872. speed = axis->start_speed;
  1873. }
  1874. axis->tasks[i].reg_value = axis->clock / speed;
  1875. dst_speed_index = 0;
  1876. do {
  1877. if (AXIS_ACC_REG_TABLE(axis)[dst_speed_index] > axis->tasks[i].reg_value) {
  1878. dst_speed_index++;
  1879. }
  1880. else if (AXIS_ACC_REG_TABLE(axis)[dst_speed_index] < axis->tasks[i].reg_value) {
  1881. if (dst_speed_index > 0) dst_speed_index--;
  1882. break;
  1883. }
  1884. else {
  1885. break;
  1886. }
  1887. } while ((dst_speed_index + 1) < axis->acc_table_size);
  1888. axis->tasks[i].dst_speed_index = dst_speed_index;
  1889. //计算目标位置
  1890. posi1 += axis->tasks[i].position;
  1891. axis->tasks[i].target_position = posi1 * axis->feed + axis->position;
  1892. if (axis->inputs.sw_lmt_enable) {
  1893. if (axis->tasks[i].target_position > axis->sw_positive_limit && (axis->feed > 0)) {
  1894. axis->outputs.sw_positive_pre_alarm = 1;
  1895. return -1;
  1896. }
  1897. else if (axis->tasks[i].target_position < axis->sw_negative_limit && (axis->feed < 0)) {
  1898. axis->outputs.sw_negative_pre_alarm = 1;
  1899. return -2;
  1900. }
  1901. }
  1902. if (axis->tasks[i].target_position == axis->position) {
  1903. // axis->outputs.sw_feed_zero_alarm = 1;
  1904. return -3;
  1905. }
  1906. }
  1907. posi2 = axis->tasks[i].target_position;
  1908. //进行减速位置安排
  1909. dst_speed_index = 0;
  1910. for (i = 0; i < axis->task_number; i++) {
  1911. //计算进给量
  1912. posi1 = posi2;
  1913. posi2 = axis->tasks[i].target_position;
  1914. //cur_speed_index = dst_speed_index;
  1915. dst_speed_index = axis->tasks[i].dst_speed_index;
  1916. feed = axis->tasks[i].position;
  1917. if (i + 1 == axis->task_number) {
  1918. //最后一个流程需要涉及到减停操作
  1919. //由上一个速度计算减速位置
  1920. dec_speed_index = 0;
  1921. dec_position = 0;
  1922. dec_position += AXIS_DEC_NUMBER_TABLE(axis)[dec_speed_index];
  1923. do {
  1924. //加速区域判断
  1925. //当当前的加速时速度比当前的减速时速度相等或者大的时候,可以进行一次减速
  1926. //这是为了保证加减速度差在可以接受的范围内
  1927. //这样也就可以让加减时间更加的灵活
  1928. if (cur_speed_index > dst_speed_index) { //如果当前速度比期望速度大,需要先降速再打算,
  1929. // 然而这样的机会在前面运算正常的情况下是很少出现的
  1930. if (feed < AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index]) break;
  1931. feed -= AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index];
  1932. cur_speed_index--;
  1933. }
  1934. else if (AXIS_ACC_REG_TABLE(axis)[cur_speed_index] < AXIS_DEC_REG_TABLE(axis)[dec_speed_index] &&
  1935. dec_speed_index < axis->dec_table_size - 1) { //当前速度在期望速度以下先保证减速位置
  1936. //如果不能进行减加速,退出
  1937. if (feed < AXIS_DEC_NUMBER_TABLE(axis)[dec_speed_index]) break;
  1938. dec_speed_index++;
  1939. feed -= AXIS_DEC_NUMBER_TABLE(axis)[dec_speed_index];
  1940. dec_position += AXIS_DEC_NUMBER_TABLE(axis)[dec_speed_index];
  1941. }
  1942. else if (cur_speed_index < dst_speed_index) { //如果当前速度是在期望速度以下,就需要有加速环节
  1943. //如果已经不能加速就退出
  1944. if (feed < AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index]) break;
  1945. feed -= AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index];
  1946. cur_speed_index++;
  1947. }
  1948. else {
  1949. break;
  1950. }
  1951. } while (feed > 0);
  1952. //设置停止位置
  1953. axis->tasks[i].dec_position = posi2 - axis->feed * dec_position;
  1954. axis->tasks[i].dec_speed_index = dec_speed_index;
  1955. }
  1956. else {
  1957. //当前段的减速其实就是下一段的匀速,这样才能保证进入下一段的时候速度能保证是期望的速度
  1958. dec_speed_index = axis->tasks[i + 1].dst_speed_index;
  1959. dec_position = 0;
  1960. if (dec_speed_index < dst_speed_index) {
  1961. //可以完全忽视减速部分,因此减速位置为0
  1962. dec_position += AXIS_ACC_NUMBER_TABLE(axis)[dec_speed_index];
  1963. }
  1964. do {
  1965. //加速区域判断
  1966. //当当前的加速时速度比当前的减速时速度相等或者大的时候,可以进行一次减速
  1967. //这是为了保证加减速度差在可以接受的范围内
  1968. //这样也就可以让加减时间更加的灵活
  1969. //为了保证效果,当下一阶段速比当前阶段高的时候,减速段不进行操作,因为本来就是以
  1970. //保证阶段速度不能高于指定速度的目的来做这个功能的
  1971. if (cur_speed_index > dst_speed_index) { //如果当前速度比期望速度大,需要先降速再打算,
  1972. // 然而这样的机会在前面运算正常的情况下是很少出现的
  1973. if (feed < AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index]) break;
  1974. feed -= AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index];
  1975. cur_speed_index--;
  1976. dec_speed_index = dst_speed_index;
  1977. }
  1978. else if (cur_speed_index > dec_speed_index && dec_speed_index < dst_speed_index) {
  1979. //如果当前速度比减速大,需要减速过程
  1980. if (feed < AXIS_ACC_NUMBER_TABLE(axis)[dec_speed_index]) break;
  1981. dec_speed_index++;
  1982. feed -= AXIS_ACC_NUMBER_TABLE(axis)[dec_speed_index];
  1983. dec_position += AXIS_ACC_NUMBER_TABLE(axis)[dec_speed_index];
  1984. }
  1985. else if (cur_speed_index < dst_speed_index) { //如果当前速度比期望速度小,需要进行加速
  1986. if (feed < AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index]) break;
  1987. feed -= AXIS_ACC_NUMBER_TABLE(axis)[cur_speed_index];
  1988. cur_speed_index++;
  1989. }
  1990. else {
  1991. break;
  1992. }
  1993. } while (feed > 0);
  1994. if (dec_speed_index > dst_speed_index) {
  1995. //可以完全忽视减速部分,因此减速位置为0
  1996. dec_speed_index = cur_speed_index;
  1997. }
  1998. //设置停止位置
  1999. axis->tasks[i].dec_position = posi2 - axis->feed * dec_position;
  2000. axis->tasks[i].dec_speed_index = dec_speed_index;
  2001. //修正下次计算的开始速度,如果下次的速度比这次小,减速后也应该是进入的速度
  2002. if (dst_speed_index > axis->tasks[i + 1].dst_speed_index) {
  2003. cur_speed_index = axis->tasks[i + 1].dst_speed_index;
  2004. }
  2005. }
  2006. }
  2007. axis->cur_task_index = 0;
  2008. axis->run_mode = AXIS_MODE_PP_TASKS;
  2009. axis_start(axis);
  2010. return 0;
  2011. }
  2012. #endif //#ifdef AXIS_TASK_NUMBER
  2013. /**
  2014. * 减速停止
  2015. *
  2016. * @author LXZ (021720)
  2017. *
  2018. * @param axis
  2019. */
  2020. void axis_stop(axis_object_t *axis) {
  2021. if (axis->run_mode != AXIS_MODE_STOP) {
  2022. if (axis->cur_accdec_status != AXIS_ACCDEC_STATUS_DEC) {
  2023. int cur_acc_index = axis->cur_speed_index;
  2024. int star_dec_index = 0;
  2025. //查找开始减速的点
  2026. unsigned short number = AXIS_ACC_NUMBER_TABLE(axis)[cur_acc_index];
  2027. do {
  2028. //当当前开始减速的点比当前开始加速的点速度大或者等于的时候,说明已经找到点了
  2029. if (AXIS_DEC_NUMBER_TABLE(axis)[star_dec_index] >= number) break;
  2030. star_dec_index++;
  2031. } while (star_dec_index < (axis->dec_table_size - 1));
  2032. //减速点开始位置必须速度比当前速度低,因此需要减一,但是如果是最高速,却是不需要的
  2033. if (star_dec_index > 0 && star_dec_index != ((axis->dec_table_size - 1))) star_dec_index--;
  2034. axis->dec_speed_index = star_dec_index;
  2035. //让中断切换到减速停止模式
  2036. axis->run_mode = AXIS_MODE_STOP;
  2037. }
  2038. }
  2039. }
  2040. /**
  2041. * 非停止的运行模式下保持当前方向运行到指定位置停止
  2042. * 支持PV=>PP与PP=>PP
  2043. * 当位置不够减速停止时会执行减速停止,所以需要保证有足够位置提前调用
  2044. *
  2045. * @author LXZ (021720)
  2046. *
  2047. * @param axis 轴对象
  2048. * @param position
  2049. */
  2050. void axis_stop_at(axis_object_t *axis, int position) {
  2051. int cur_position = axis->position;
  2052. int acc_index = 0;
  2053. int dec_index = 0;
  2054. //开始减速的位置
  2055. int dec_position = 0;
  2056. //停止状态下调用该函数无效
  2057. if (AXIS_IS_RUNNING(axis) == 0) return;
  2058. //齿轮比转换
  2059. if (axis->inputs.ratio_enable) {
  2060. position = axis_position_to_pluse(axis, position);
  2061. }
  2062. //如果要停的位置已经超过了,直接减速停止
  2063. if (axis->feed > 0) {
  2064. if (cur_position > position) {
  2065. axis_stop(axis);
  2066. return;
  2067. }
  2068. }
  2069. else if (cur_position <= position) {
  2070. axis_stop(axis);
  2071. return;
  2072. }
  2073. //设置要停止的目标位置
  2074. axis->target_position = position;
  2075. //计算要
  2076. position -= axis->position;
  2077. if (position < 0) {
  2078. position = -position;
  2079. }
  2080. //计算减速位置与开始减速的减速表位置
  2081. if (axis->cur_accdec_status == AXIS_ACCDEC_STATUS_DEC) { //正在减速状态下,先查找相匹配的加速点
  2082. acc_index = 0;
  2083. dec_index = axis->cur_speed_index;
  2084. while (AXIS_ACC_REG_TABLE(axis)[acc_index] > AXIS_DEC_REG_TABLE(axis)[dec_index]) {
  2085. acc_index++;
  2086. }
  2087. }
  2088. else { //直接获取当前加速点
  2089. acc_index = axis->cur_speed_index;
  2090. }
  2091. dec_index = 0;
  2092. dec_position += AXIS_DEC_NUMBER_TABLE(axis)[dec_index];
  2093. do {
  2094. if (AXIS_ACC_REG_TABLE(axis)[acc_index] < AXIS_DEC_REG_TABLE(axis)[dec_index] &&
  2095. dec_index < (axis->dec_table_size - 1)) { //计算指定速度下减速表开始位置
  2096. if (position < AXIS_DEC_NUMBER_TABLE(axis)[dec_index]) //剩余脉冲数不足
  2097. break;
  2098. //计算剩余脉冲与减速点
  2099. dec_index++;
  2100. position -= AXIS_DEC_NUMBER_TABLE(axis)[dec_index];
  2101. dec_position += AXIS_DEC_NUMBER_TABLE(axis)[dec_index];
  2102. }
  2103. else if (acc_index < (axis->acc_table_size - 1)) { //允许继续加速
  2104. if (position < AXIS_ACC_NUMBER_TABLE(axis)[acc_index] * AXIS_LOCATION_SMOOTH) //剩余脉冲不足
  2105. break;
  2106. //计算剩余脉冲
  2107. position -= AXIS_ACC_NUMBER_TABLE(axis)[acc_index];
  2108. acc_index++;
  2109. }
  2110. else {
  2111. break;
  2112. }
  2113. } while (position > 0);
  2114. //开始减速的减速表位置
  2115. axis->dec_speed_index = dec_index;
  2116. //计算减速位置
  2117. axis->dec_position = axis->target_position - dec_position * axis->feed;
  2118. if (axis->cur_accdec_status == AXIS_ACCDEC_STATUS_DEC) {
  2119. if (dec_index < axis->cur_speed_index) {
  2120. //由于当前要求的减速开始速度比当前速度要小,需要触发速度跳变
  2121. axis->cur_accdec_status = AXIS_ACCDEC_STATUS_MID;
  2122. }
  2123. }
  2124. //切换运行模式
  2125. axis->run_mode = AXIS_MODE_PP;
  2126. }
  2127. /**
  2128. * PV模式允许在设定的目标速度范围内进行变速
  2129. * 该接口只有在PV模式下才有用
  2130. *
  2131. * @author LXZ (021820)
  2132. *
  2133. * @param axis 轴对象
  2134. * @param speed 要变化的速度
  2135. */
  2136. void axis_pv_change_speed(axis_object_t *axis, int speed) {
  2137. unsigned short reg;
  2138. unsigned short index = 0;
  2139. #if AXIS_SPEED_UNIT
  2140. speed *= axis->speed_unit;
  2141. #endif
  2142. if (speed < axis->start_speed) {
  2143. speed = axis->start_speed;
  2144. }
  2145. reg = axis->clock / speed;
  2146. while (index < axis->acc_table_size) {
  2147. if (reg <= AXIS_ACC_REG_TABLE(axis)[index]) {
  2148. index++;
  2149. }
  2150. else {
  2151. break;
  2152. }
  2153. }
  2154. axis->acc_speed_index = index;
  2155. axis->target_speed_reg = reg;
  2156. }
  2157. /**
  2158. * 减速停止所有轴的动作,包括停止回零的操作
  2159. *
  2160. * @author lxz (2019/6/16/周日)
  2161. *
  2162. * @param axis
  2163. */
  2164. void axis_stop_all(axis_object_t *axis) {
  2165. axis_stop(axis);
  2166. axis->home_step = 0;
  2167. }
  2168. /**
  2169. * 以急停的方式去停止
  2170. *
  2171. * @author lxz
  2172. *
  2173. * @param axis
  2174. */
  2175. void axis_emgstop(axis_object_t *axis) {
  2176. axis->home_step = 0;
  2177. axis->run_mode = AXIS_MODE_EMGSTOP;
  2178. AXIS_OFF(axis);
  2179. }
  2180. /**
  2181. * 轴启动
  2182. *
  2183. * @author lxz
  2184. *
  2185. * @param axis
  2186. */
  2187. void axis_start(axis_object_t *axis) {
  2188. axis->cur_speed_index = 0;
  2189. axis->accdec_count = AXIS_ACC_NUMBER_TABLE(axis)[axis->cur_speed_index];
  2190. axis->cur_accdec_status = 0;
  2191. AXIS_SET_PERION(axis, AXIS_ACC_REG_TABLE(axis)[axis->cur_speed_index]);
  2192. AXIS_ON(axis);
  2193. axis->outputs.on = AXIS_IS_ON(axis) != 0;
  2194. }
  2195. /**
  2196. * 设置轴的参数
  2197. *
  2198. * @author LXZ (031420)
  2199. *
  2200. * @param axis 轴对象
  2201. * @param cmd 设置的对象
  2202. * @param argv 设置的参数
  2203. *
  2204. */
  2205. void axis_set_parameter(axis_object_t *axis, int cmd, int argv) {
  2206. switch (cmd) {
  2207. case AXIS_AXIS_NO:
  2208. axis->axis_no = argv;
  2209. break;
  2210. case AXIS_POSITION:
  2211. axis->position = argv;
  2212. break;
  2213. case AXIS_CLOCK:
  2214. axis->clock = argv;
  2215. AXIS_SET_CLOCK(axis, axis->clock);
  2216. break;
  2217. case AXIS_PERIOD:
  2218. axis->period = argv;
  2219. break;
  2220. case AXIS_MIN_STEP:
  2221. axis->min_steps = argv;
  2222. break;
  2223. #if defined(AXIS_SPEED_UNIT)
  2224. case AXIS_SPEED_UNIT:
  2225. axis->speed_unit = argv;
  2226. break;
  2227. #endif
  2228. case AXIS_ACCDEC_MODE:
  2229. axis->accdec_mode = argv;
  2230. break;
  2231. case AXIS_ACC_TIME:
  2232. axis->acc_time = argv;
  2233. break;
  2234. case AXIS_DEC_TIME:
  2235. axis->dec_time = argv;
  2236. break;
  2237. case AXIS_AAC_LMT:
  2238. axis->max_aac = argv;
  2239. break;
  2240. case AXIS_ACC_LMT:
  2241. axis->max_acc = argv;
  2242. break;
  2243. case AXIS_DEC_LMT:
  2244. axis->max_dec = argv;
  2245. break;
  2246. case AXIS_START_SPEED:
  2247. #if defined(AXIS_SPEED_UNIT)
  2248. argv *= axis->speed_unit;
  2249. #endif
  2250. axis->start_speed = argv;
  2251. break;
  2252. case AXIS_HOME_SPACE:
  2253. axis->home_space = argv;
  2254. break;
  2255. case AXIS_HOME_OFFSET:
  2256. axis->home_offset = argv;
  2257. break;
  2258. case AXIS_HOME_FIND_SPEED:
  2259. axis->home_find_speed = argv;
  2260. break;
  2261. case AXIS_HOME_HIGH_SPEED:
  2262. axis->home_high_speed = argv;
  2263. break;
  2264. case AXIS_HOME_LOW_SPEED:
  2265. axis->home_low_speed = argv;
  2266. break;
  2267. case AXIS_HOME_HIGH_SPEED_ENABLE:
  2268. if (argv) {
  2269. axis->inputs.home_high_speed_enable = 1;
  2270. }
  2271. else {
  2272. axis->inputs.home_high_speed_enable = 0;
  2273. }
  2274. break;
  2275. case AXIS_HOME_SGN:
  2276. axis->inputs.hw_home_sgn = argv;
  2277. break;
  2278. case AXIS_HOME_SLOW_SGN:
  2279. axis->inputs.hw_slow_lmt = argv;
  2280. break;
  2281. case AXIS_ERROR_SGN:
  2282. axis->inputs.alarm_sgn = argv;
  2283. break;
  2284. case AXIS_HW_POSI_SGN:
  2285. axis->inputs.hw_positive_lmt = argv;
  2286. break;
  2287. case AXIS_HW_NEGA_SGN:
  2288. axis->inputs.hw_negative_lmt = argv;
  2289. break;
  2290. case AXIS_DIR_LEVEL:
  2291. if (argv) {
  2292. axis->inputs.dir_reverse = 1;
  2293. }
  2294. else {
  2295. axis->inputs.dir_reverse = 0;
  2296. }
  2297. break;
  2298. case AXIS_POSI_SOFT_LMT: //正软件限位
  2299. if (axis->inputs.ratio_enable) {
  2300. axis->sw_positive_limit = axis_position_to_pluse(axis, argv);
  2301. }
  2302. else {
  2303. axis->sw_positive_limit = argv;
  2304. }
  2305. break;
  2306. case AXIS_NEGA_SOFT_LMT: //负软件限位
  2307. if (axis->inputs.ratio_enable) {
  2308. axis->sw_negative_limit = axis_position_to_pluse(axis, argv);
  2309. }
  2310. else {
  2311. axis->sw_negative_limit = argv;
  2312. }
  2313. break;
  2314. case AXIS_CYCLE_LENGTH: //一圈距离
  2315. // axis->cycle_length = argv;
  2316. break;
  2317. case AXIS_CYCLE_PLUSE: //一圈脉冲数
  2318. // axis->cycle_pluse = argv;
  2319. break;
  2320. case AXIS_REAL_POSITION: //针对现实单位的位置
  2321. axis->position = axis_position_to_pluse(axis, argv);
  2322. break;
  2323. case AXIS_CURRENT_DIR: //设置当前方向
  2324. if (argv) {
  2325. axis_cw(axis);
  2326. }
  2327. else {
  2328. axis_ccw(axis);
  2329. }
  2330. break;
  2331. case AXIS_RATIO_ENABLE:
  2332. if (argv) {
  2333. axis->inputs.ratio_enable = 1;
  2334. }
  2335. else {
  2336. axis->inputs.ratio_enable = 0;
  2337. }
  2338. break;
  2339. case AXIS_ENABLE_SGN_LEVEL:
  2340. if (argv) {
  2341. axis->inputs.enable_sgn_level = 1;
  2342. }
  2343. else {
  2344. axis->inputs.enable_sgn_level = 0;
  2345. }
  2346. break;
  2347. }
  2348. }
  2349. /**
  2350. * 设置轴的参数
  2351. *
  2352. * @author LXZ (031420)
  2353. *
  2354. * @param axis 轴对象
  2355. * @param cmd 设置的对象
  2356. * @param argv 设置的参数
  2357. *
  2358. */
  2359. int axis_get_parameter(axis_object_t *axis, int cmd) {
  2360. int argv = 0;
  2361. switch (cmd) {
  2362. case AXIS_AXIS_NO:
  2363. argv = axis->axis_no;
  2364. break;
  2365. case AXIS_POSITION:
  2366. argv = axis->position;
  2367. break;
  2368. case AXIS_CLOCK:
  2369. argv = axis->clock;
  2370. break;
  2371. case AXIS_PERIOD:
  2372. argv = axis->period;
  2373. break;
  2374. case AXIS_MIN_STEP:
  2375. argv = axis->min_steps;
  2376. break;
  2377. #if defined(AXIS_SPEED_UNIT)
  2378. case AXIS_SPEED_UNIT:
  2379. argv = axis->speed_unit;
  2380. break;
  2381. #endif
  2382. case AXIS_ACCDEC_MODE:
  2383. argv = axis->accdec_mode;
  2384. break;
  2385. case AXIS_ACC_TIME:
  2386. argv = axis->acc_time;
  2387. break;
  2388. case AXIS_DEC_TIME:
  2389. argv = axis->dec_time;
  2390. break;
  2391. case AXIS_AAC_LMT:
  2392. argv = axis->max_aac;
  2393. break;
  2394. case AXIS_ACC_LMT:
  2395. argv = axis->max_acc;
  2396. break;
  2397. case AXIS_DEC_LMT:
  2398. argv = axis->max_dec;
  2399. break;
  2400. case AXIS_START_SPEED:
  2401. argv = axis->start_speed;
  2402. break;
  2403. case AXIS_HOME_SPACE:
  2404. argv = axis->home_space;
  2405. break;
  2406. case AXIS_HOME_OFFSET:
  2407. argv = axis->home_offset;
  2408. break;
  2409. case AXIS_HOME_FIND_SPEED:
  2410. argv = axis->home_find_speed;
  2411. break;
  2412. case AXIS_HOME_HIGH_SPEED:
  2413. argv = axis->home_high_speed;
  2414. break;
  2415. case AXIS_HOME_LOW_SPEED:
  2416. argv = axis->home_low_speed;
  2417. break;
  2418. case AXIS_HOME_HIGH_SPEED_ENABLE:
  2419. if (axis->inputs.home_high_speed_enable) {
  2420. argv = 1;
  2421. }
  2422. break;
  2423. case AXIS_HOME_SGN:
  2424. argv = axis->inputs.hw_home_sgn;
  2425. break;
  2426. case AXIS_HOME_SLOW_SGN:
  2427. argv = axis->inputs.hw_slow_lmt;
  2428. break;
  2429. case AXIS_ERROR_SGN:
  2430. argv = axis->inputs.alarm_sgn;
  2431. break;
  2432. case AXIS_HW_POSI_SGN:
  2433. argv = axis->inputs.hw_positive_lmt;
  2434. break;
  2435. case AXIS_HW_NEGA_SGN:
  2436. argv = axis->inputs.hw_negative_lmt;
  2437. break;
  2438. case AXIS_DIR_LEVEL:
  2439. if (axis->inputs.dir_reverse) {
  2440. argv = 1;
  2441. }
  2442. break;
  2443. case AXIS_POSI_SOFT_LMT: //正软件限位
  2444. if (axis->inputs.ratio_enable) {
  2445. argv = axis_pluse_to_position(axis, axis->sw_positive_limit);
  2446. }
  2447. else {
  2448. argv = axis->sw_positive_limit;
  2449. }
  2450. break;
  2451. case AXIS_NEGA_SOFT_LMT: //负软件限位
  2452. if (axis->inputs.ratio_enable) {
  2453. argv = axis_pluse_to_position(axis, axis->sw_negative_limit);
  2454. }
  2455. else {
  2456. argv = axis->sw_negative_limit;
  2457. }
  2458. break;
  2459. case AXIS_CYCLE_LENGTH: //一圈距离
  2460. argv = axis->cycle_length;
  2461. break;
  2462. case AXIS_CYCLE_PLUSE: //一圈脉冲数
  2463. argv = axis->cycle_pluse;
  2464. break;
  2465. case AXIS_REAL_POSITION: //针对现实单位的位置
  2466. argv = axis_pluse_to_position(axis, axis->position);
  2467. break;
  2468. case AXIS_CURRENT_DIR: //设置当前方向
  2469. argv = axis->outputs.dir;
  2470. break;
  2471. case AXIS_RATIO_ENABLE:
  2472. argv = axis->inputs.ratio_enable;
  2473. break;
  2474. case AXIS_ENABLE_SGN_LEVEL:
  2475. argv = axis->inputs.enable_sgn_level;
  2476. break;
  2477. }
  2478. return argv;
  2479. }
  2480. /**
  2481. * 回零方式1
  2482. *
  2483. * @author lxz (2019/6/10/周一)
  2484. *
  2485. * @param axis
  2486. */
  2487. void axis_home_method1(axis_object_t *axis) {
  2488. switch (axis->home_step) {
  2489. case 1:
  2490. //负限位或者零点有信号 ,需要向前运动
  2491. if (axis->inputs.hw_home_sgn) {
  2492. //先是离开一定的距离
  2493. axis->home_step = 4;
  2494. }
  2495. else {
  2496. if (axis->inputs.hw_negative_lmt) {
  2497. axis_pv(axis, 0, axis->home_low_speed);
  2498. axis->home_step = 3;
  2499. }
  2500. else if (axis->inputs.hw_slow_lmt == 0 && axis->inputs.home_high_speed_enable) {
  2501. //回零减速信号位有信号,速度要采用低速回零
  2502. axis_pv(axis, 1, axis->home_high_speed);
  2503. axis->home_step = 2;
  2504. }
  2505. else {
  2506. //以回零高速查找零点信号
  2507. axis_pv(axis, 0, axis->home_low_speed);
  2508. axis->home_step = 3;
  2509. }
  2510. }
  2511. break;
  2512. case 2:
  2513. if (axis->inputs.hw_slow_lmt) {
  2514. axis_pv_change_speed(axis, axis->home_low_speed);
  2515. axis->home_step++;
  2516. }
  2517. break;
  2518. case 3:
  2519. if (axis->inputs.hw_home_sgn) {
  2520. //查到了零点, 先减速停止
  2521. axis_stop(axis);
  2522. axis->home_step++;
  2523. }
  2524. break;
  2525. case 4:
  2526. if (axis->outputs.on == 0) {
  2527. //离开原点一定距离
  2528. axis_pp(axis, 0, axis->home_space, axis->home_low_speed);
  2529. axis->home_step++;
  2530. }
  2531. break;
  2532. case 5:
  2533. if (axis->outputs.on == 0) {
  2534. if (axis->inputs.hw_home_sgn) {
  2535. axis->home_step = 4;
  2536. }
  2537. else {
  2538. //以低速回退来查找原点
  2539. axis_pv(axis, 0, axis->home_find_speed);
  2540. axis->home_step++;
  2541. }
  2542. }
  2543. break;
  2544. case 6:
  2545. if (axis->inputs.hw_home_sgn) {
  2546. AXIS_OFF(axis);
  2547. axis->home_step++;
  2548. }
  2549. break;
  2550. case 7:
  2551. if (axis->outputs.on == 0) {
  2552. //查到零点,停止
  2553. axis->home_step++;
  2554. }
  2555. break;
  2556. case 8:
  2557. if (axis->outputs.on == 0) {
  2558. //再走一段设置距离
  2559. axis_pp(axis, 0, axis->home_offset, axis->home_low_speed);
  2560. axis->home_step++;
  2561. }
  2562. break;
  2563. case 9:
  2564. if (axis->outputs.on == 0) {
  2565. //回零完毕
  2566. axis->home_step = 0;
  2567. axis->position = 0;
  2568. axis->encoder = 0;
  2569. }
  2570. break;
  2571. }
  2572. }
  2573. /**
  2574. * 回零方式0
  2575. *
  2576. * @author lxz (2019/6/10/周一)
  2577. *
  2578. * @param axis
  2579. */
  2580. void axis_home_method0(axis_object_t *axis) {
  2581. switch (axis->home_step)
  2582. {
  2583. case 1:
  2584. //负限位或者零点有信号 ,需要向前运动
  2585. if (axis->inputs.hw_home_sgn)
  2586. {
  2587. //先是离开一定的距离
  2588. axis->home_step = 4;
  2589. }
  2590. else
  2591. {
  2592. if (axis->inputs.hw_negative_lmt)
  2593. {
  2594. axis_pv(axis, 1, axis->home_low_speed);
  2595. axis->home_step = 3;
  2596. }
  2597. else if (axis->inputs.hw_slow_lmt == 0 && axis->inputs.home_high_speed_enable)
  2598. {
  2599. //回零减速信号位有信号,速度要采用低速回零
  2600. axis_pv(axis, 0, axis->home_find_speed);
  2601. axis->home_step = 2;
  2602. }
  2603. else
  2604. {
  2605. //以回零高速查找零点信号
  2606. axis_pv(axis, 0, axis->home_low_speed);
  2607. axis->home_step = 3;
  2608. }
  2609. }
  2610. break;
  2611. case 2:
  2612. if (axis->inputs.hw_slow_lmt)
  2613. {
  2614. axis_pv_change_speed(axis, axis->home_low_speed);
  2615. axis->home_step++;
  2616. }
  2617. break;
  2618. case 3:
  2619. if (axis->inputs.hw_home_sgn)
  2620. {
  2621. //查到了零点, 先减速停止
  2622. axis_stop(axis);
  2623. axis->home_step++;
  2624. }
  2625. break;
  2626. case 4:
  2627. if (axis->outputs.on == 0)
  2628. {
  2629. //离开原点一定距离
  2630. axis_pp(axis, 0, axis->home_space, axis->home_find_speed);
  2631. axis->home_step++;
  2632. }
  2633. break;
  2634. case 5:
  2635. if (axis->outputs.on == 0)
  2636. {
  2637. // if (axis->inputs.hw_home_sgn)
  2638. {
  2639. // axis->home_step = 4;
  2640. }
  2641. // else
  2642. {
  2643. //以低速回退来查找原点
  2644. axis_pv(axis, 1, axis->home_find_speed);
  2645. axis->home_step = 8;
  2646. axis->home_sgn_count = 0;
  2647. }
  2648. }
  2649. break;
  2650. case 8:
  2651. if(!axis->inputs.hw_home_sgn) //(axis->outputs.on == 0) //
  2652. {
  2653. //查到零点,停止
  2654. axis_stop(axis);
  2655. axis->home_step = 9;
  2656. }
  2657. break;
  2658. case 9:
  2659. if (axis->outputs.on == 0)
  2660. {
  2661. //再走一段设置距离
  2662. axis_pp(axis, 0, axis->home_offset, axis->home_find_speed);
  2663. axis->home_step = 10;
  2664. }
  2665. break;
  2666. case 10:
  2667. if (axis->outputs.on == 0 && axis->inputs.fin_sgn == 0)
  2668. {
  2669. //回零完毕
  2670. axis->home_step = 0;
  2671. axis->position = 0;
  2672. axis->encoder = 0;
  2673. }
  2674. break;
  2675. }
  2676. /*
  2677. switch (axis->home_step) {
  2678. case 1:
  2679. //负限位或者零点有信号 ,需要向前运动
  2680. if (axis->inputs.hw_home_sgn) {
  2681. //先是离开一定的距离
  2682. axis->home_step = 4;
  2683. }
  2684. else {
  2685. if (axis->inputs.hw_negative_lmt) {
  2686. axis_pv(axis, 1, axis->home_low_speed);
  2687. axis->home_step = 3;
  2688. }
  2689. else if (axis->inputs.hw_slow_lmt == 0 && axis->inputs.home_high_speed_enable) {
  2690. //回零减速信号位有信号,速度要采用低速回零
  2691. axis_pv(axis, 0, axis->home_high_speed);
  2692. axis->home_step = 2;
  2693. }
  2694. else {
  2695. //以回零高速查找零点信号
  2696. axis_pv(axis, 0, axis->home_low_speed);
  2697. axis->home_step = 3;
  2698. }
  2699. }
  2700. break;
  2701. case 2:
  2702. if (axis->inputs.hw_slow_lmt) {
  2703. axis_pv_change_speed(axis, axis->home_low_speed);
  2704. axis->home_step++;
  2705. }
  2706. break;
  2707. case 3:
  2708. if (axis->inputs.hw_home_sgn) {
  2709. //查到了零点, 先减速停止
  2710. axis_stop(axis);
  2711. axis->home_step++;
  2712. }
  2713. break;
  2714. case 4:
  2715. if (axis->outputs.on == 0) {
  2716. //离开原点一定距离
  2717. axis_pp(axis, 0, axis->home_space, axis->home_low_speed);
  2718. axis->home_step++;
  2719. }
  2720. break;
  2721. case 5:
  2722. if (axis->outputs.on == 0) {
  2723. if (axis->inputs.hw_home_sgn) {
  2724. axis->home_step = 4;
  2725. }
  2726. else {
  2727. //以低速回退来查找原点
  2728. axis_pv(axis, 0, axis->home_find_speed);
  2729. axis->home_step++;
  2730. axis->home_sgn_count = 0;
  2731. }
  2732. }
  2733. break;
  2734. // case 6:
  2735. // if (axis->inputs.hw_home_sgn) {
  2736. // AXIS_OFF(axis);
  2737. // axis->home_step++;
  2738. // }
  2739. // break;
  2740. case 8:
  2741. if (axis->outputs.on == 0) {
  2742. //查到零点,停止
  2743. axis->home_step++;
  2744. }
  2745. break;
  2746. case 9:
  2747. if (axis->outputs.on == 0) {
  2748. //再走一段设置距离
  2749. axis_pp(axis, 0, axis->home_offset, axis->home_low_speed);
  2750. axis->home_step++;
  2751. }
  2752. break;
  2753. case 10:
  2754. if (axis->outputs.on == 0 && axis->inputs.fin_sgn == 0) {
  2755. //回零完毕
  2756. axis->home_step = 0;
  2757. axis->position = 0;
  2758. axis->encoder = 0;
  2759. }
  2760. break;
  2761. }
  2762. */
  2763. }
  2764. /**
  2765. * 回零方式2
  2766. *
  2767. * @author LXZ (010820)
  2768. *
  2769. * @param axis
  2770. */
  2771. void axis_home_method2(axis_object_t *axis) {
  2772. switch (axis->home_step) {
  2773. case 1:
  2774. //不在零点时,不需要重复检测
  2775. if (!axis->inputs.hw_home_sgn) {
  2776. //先是离开一定的距离
  2777. axis->home_step++;
  2778. }
  2779. axis->home_sgn_count = 0;
  2780. axis->home_step++;
  2781. axis_pv(axis, 1, axis->home_low_speed);
  2782. break;
  2783. case 2:
  2784. if (!axis->inputs.hw_home_sgn) {
  2785. axis->home_step++;
  2786. axis->home_sgn_count = 0;
  2787. }
  2788. break;
  2789. case 3:
  2790. //if (axis->inputs.hw_home_sgn) {
  2791. // axis_stop(axis);
  2792. // axis->home_step++;
  2793. //}
  2794. break;
  2795. case 5:
  2796. if (axis->outputs.on == 0) {
  2797. //离开原点一定距离
  2798. axis_pp(axis, 0, axis->home_offset, axis->home_low_speed);
  2799. axis->home_step++;
  2800. }
  2801. break;
  2802. case 6:
  2803. if (axis->outputs.on == 0) {
  2804. axis->home_step = 0;
  2805. axis->position = 0;
  2806. axis->encoder = 0;
  2807. }
  2808. }
  2809. }
  2810. /**
  2811. * 开始回零动作
  2812. *
  2813. * @author LXZ (031420)
  2814. *
  2815. * @param axis 轴对象
  2816. * @param method 回零方式
  2817. * @param home_speed 回零速度
  2818. * @param find_speed 查找零点速度
  2819. */
  2820. void axis_home(axis_object_t *axis, int method, int home_speed, int find_speed) {
  2821. axis->home_method = method;
  2822. axis->home_step = 1;
  2823. axis->home_find_speed = find_speed;
  2824. axis->home_low_speed = home_speed;
  2825. }
  2826. /**
  2827. * 使能高速回原点的功能
  2828. * 当回零系统中存在减速开关的时候,使能高速功能允许执行二段速回零,当没有减速信号时采用
  2829. * 高速动作,检测到开关后会变为低速返回零点从而更加有效的加零。
  2830. *
  2831. * @author LXZ (031420)
  2832. *
  2833. * @param axis
  2834. * @param high_speed
  2835. */
  2836. void axis_home_enable_high_speed(axis_object_t *axis, int high_speed) {
  2837. axis->inputs.home_high_speed_enable = 1;
  2838. axis->home_high_speed = high_speed;
  2839. }
  2840. /**
  2841. * 禁止高速回原点的功能
  2842. *
  2843. * @author LXZ (031420)
  2844. *
  2845. * @param axis
  2846. */
  2847. void axis_home_disable_high_speed(axis_object_t *axis) {
  2848. axis->inputs.home_high_speed_enable = 0;
  2849. }
  2850. /**
  2851. * 设置回零信号
  2852. *
  2853. * @author LXZ (062820)
  2854. *
  2855. * @param axis 轴对象
  2856. * @param reg 管脚状态寄存器
  2857. * @param mask 管脚位掩
  2858. * @param value 管脚有效值
  2859. * @param filter 滤波次数
  2860. */
  2861. void axis_set_home_sgn(axis_object_t *axis, void * reg, unsigned short mask,unsigned short value, char filter) {
  2862. axis->home_sgn_register = (volatile unsigned short *) reg;
  2863. axis->home_sgn_mask = mask;
  2864. axis->home_sgn_filter = filter;
  2865. axis->home_sgn_level = value;
  2866. }
  2867. /**
  2868. * 设置编码器零点信号
  2869. *
  2870. * @author LXZ (062820)
  2871. *
  2872. * @param axis 轴对象
  2873. * @param reg 管脚状态寄存器
  2874. * @param mask 管脚位掩
  2875. * @param value 管脚有效值
  2876. * @param filter 滤波次数
  2877. */
  2878. void axis_set_home_encoder_sgn(axis_object_t *axis, void * reg, unsigned short mask,unsigned short value, char filter) {
  2879. axis->inputs.home_encode_sgn_enable = 1;
  2880. axis->home_encoder_sgn_register = (volatile unsigned short *) reg;
  2881. axis->home_encoder_sgn_mask = mask;
  2882. axis->home_encoder_sgn_filter = filter;
  2883. axis->home_encoder_sgn_level = value;
  2884. }
  2885. /**
  2886. * 执行回零动作
  2887. *
  2888. * @author lxz (2019/6/10/周一)
  2889. *
  2890. * @param axis
  2891. */
  2892. void axis_home_run(axis_object_t *axis) {
  2893. switch (axis->home_method) {
  2894. case 2:
  2895. axis_home_method2(axis);
  2896. break;
  2897. case 1:
  2898. axis_home_method1(axis);
  2899. break;
  2900. default:
  2901. axis_home_method0(axis);
  2902. break;
  2903. }
  2904. }
  2905. /**
  2906. * 对轴的一些输入输出信号进行集合处理,包括限位保护等
  2907. *
  2908. * @author lxz
  2909. *
  2910. * @param axis
  2911. */
  2912. void axis_run(axis_object_t *axis) {
  2913. axis->outputs.error_alarm = axis->inputs.alarm_sgn;
  2914. axis_home_run(axis);
  2915. if (axis->outputs.error_alarm) {
  2916. axis_emgstop(axis);
  2917. }
  2918. //软件限位保护
  2919. if (axis->inputs.sw_lmt_enable) {
  2920. if (axis->outputs.on) {
  2921. //正软件限位保护
  2922. if (axis->outputs.dir && axis->position >= axis->sw_positive_limit) {
  2923. axis_emgstop(axis);
  2924. axis->outputs.sw_positive_alarm = 1;
  2925. }
  2926. else {
  2927. axis->outputs.sw_positive_alarm = 0;
  2928. }
  2929. //负软件限位保护
  2930. if (axis->outputs.dir == 0 && axis->position <= axis->sw_negative_limit) {
  2931. axis_emgstop(axis);
  2932. axis->outputs.sw_negative_alarm = 1;
  2933. }
  2934. else {
  2935. axis->outputs.sw_negative_alarm = 0;
  2936. }
  2937. }
  2938. }
  2939. else {
  2940. axis->outputs.sw_negative_alarm = 0;
  2941. axis->outputs.sw_positive_alarm = 0;
  2942. axis->outputs.sw_negative_pre_alarm = 0;
  2943. axis->outputs.sw_positive_pre_alarm = 0;
  2944. }
  2945. //正硬件限位保护
  2946. if (axis->outputs.dir && axis->inputs.hw_positive_lmt) {
  2947. axis_emgstop(axis);
  2948. axis->outputs.hw_positive_alarm = 1;
  2949. }
  2950. else {
  2951. axis->outputs.hw_positive_alarm = 0;
  2952. }
  2953. //负硬件限位保护
  2954. if (axis->outputs.dir == 0 && axis->inputs.hw_negative_lmt) {
  2955. axis_emgstop(axis);
  2956. axis->outputs.hw_negative_alarm = 1;
  2957. }
  2958. else {
  2959. axis->outputs.hw_negative_alarm = 0;
  2960. }
  2961. if (axis->outputs.enable) {
  2962. AXIS_SET_EN(axis, 1);
  2963. }
  2964. else {
  2965. AXIS_SET_EN(axis, 0);
  2966. }
  2967. //当回零步不为0的时候,说明正在回零,这时候一些操作就要注意不要冲突
  2968. axis->outputs.homing = axis->home_step != 0;
  2969. axis->outputs.on = AXIS_IS_ON(axis) != 0;
  2970. }
  2971. /**
  2972. * 操作伺服对应IO
  2973. *
  2974. * @author xuzhenglim:276137500 (2019-12-5)
  2975. *
  2976. * @param axis
  2977. * @param type
  2978. * @param value
  2979. */
  2980. void axis_set_ouput(axis_object_t *axis, axis_output_name type, int value) {
  2981. switch (type) {
  2982. case AXIS_OUT_ENABLE:
  2983. axis->outputs.enable = value;
  2984. break;
  2985. case AXIS_OUT_ERRCLEAR:
  2986. axis->outputs.error_clear = value;
  2987. break;
  2988. }
  2989. }
  2990. /**
  2991. * 获取报警值
  2992. *
  2993. * @author LXZ (121919)
  2994. *
  2995. * @param axis 轴对象
  2996. *
  2997. * @return int 0 没有报警
  2998. * bit 0 伺服报警
  2999. * bit 1 硬件正限位
  3000. * bit 2 硬件负限位
  3001. * bit 3 软件正限位
  3002. * bit 4 软件负限位
  3003. * bit 5 软件负限位预报警
  3004. * bit 6 软件负限位预报警
  3005. *
  3006. */
  3007. int axis_get_error(axis_object_t *axis) {
  3008. int flag = 0;
  3009. if (axis->outputs.error_alarm) {
  3010. flag |= 1 << 0;
  3011. }
  3012. if (axis->outputs.hw_positive_alarm) {
  3013. flag |= 1 << 1;
  3014. }
  3015. if (axis->outputs.hw_negative_alarm) {
  3016. flag |= 1 << 2;
  3017. }
  3018. if (axis->outputs.sw_positive_alarm) {
  3019. flag |= 1 << 3;
  3020. }
  3021. if (axis->outputs.sw_negative_alarm) {
  3022. flag |= 1 << 4;
  3023. }
  3024. if (axis->outputs.sw_positive_pre_alarm) {
  3025. flag |= 1 << 5;
  3026. }
  3027. if (axis->outputs.sw_negative_pre_alarm) {
  3028. flag |= 1 << 6;
  3029. }
  3030. // if (axis->outputs.sw_feed_zero_alarm) {
  3031. // flag |= 1 << 7;
  3032. // }
  3033. return flag;
  3034. }
  3035. /**
  3036. * 清除报警
  3037. *
  3038. * @author LXZ (052620)
  3039. *
  3040. * @param axis
  3041. */
  3042. void axis_clear_error(axis_object_t *axis) {
  3043. axis->outputs.sw_negative_alarm = 0;
  3044. axis->outputs.sw_positive_alarm = 0;
  3045. axis->outputs.sw_positive_pre_alarm = 0;
  3046. axis->outputs.sw_negative_pre_alarm = 0;
  3047. axis->outputs.sw_feed_zero_alarm = 0;
  3048. }
  3049. /**
  3050. * 判断是否能正转
  3051. *
  3052. * @author LXZ (010120)
  3053. *
  3054. * @param axis
  3055. *
  3056. * @return int
  3057. */
  3058. int axis_cw_lmt(axis_object_t *axis) {
  3059. return (axis->outputs.on == 0 &&
  3060. axis->outputs.error_alarm == 0 &&
  3061. axis->outputs.homing == 0 &&
  3062. axis->outputs.hw_positive_alarm == 0 &&
  3063. axis->outputs.sw_positive_alarm == 0);
  3064. }
  3065. /**
  3066. * 判断是否能反转
  3067. *
  3068. * @author LXZ (010120)
  3069. *
  3070. * @param axis
  3071. *
  3072. * @return int
  3073. */
  3074. int axis_ccw_lmt(axis_object_t *axis) {
  3075. return (axis->outputs.on == 0 &&
  3076. axis->outputs.error_alarm == 0 &&
  3077. axis->outputs.homing == 0 &&
  3078. axis->outputs.hw_negative_alarm == 0 &&
  3079. axis->outputs.sw_negative_alarm == 0);
  3080. }
  3081. /**
  3082. * 设置软件限位
  3083. *
  3084. * @author LXZ (031420)
  3085. *
  3086. * @param axis 轴对象
  3087. * @param positive 软件正限位
  3088. * @param negative 软件负限位
  3089. */
  3090. void axis_set_software_lmt(axis_object_t *axis, int positive, int negative) {
  3091. if (axis->inputs.ratio_enable) {
  3092. axis->sw_positive_limit = axis_position_to_pluse(axis, positive);
  3093. axis->sw_negative_limit = axis_position_to_pluse(axis, negative);
  3094. }
  3095. else {
  3096. axis->sw_positive_limit = positive;
  3097. axis->sw_negative_limit = negative;
  3098. }
  3099. }
  3100. /**
  3101. * 使能软件限位
  3102. *
  3103. * @author LXZ (031420)
  3104. *
  3105. * @param axis 轴对象
  3106. */
  3107. void axis_enable_software_lmt(axis_object_t *axis) {
  3108. axis->inputs.sw_lmt_enable = 1;
  3109. }
  3110. /**
  3111. * 关闭软件限位
  3112. *
  3113. * @author LXZ (031420)
  3114. *
  3115. * @param axis 轴对象
  3116. * @param positive 软件正限位
  3117. * @param negative 软件负限位
  3118. */
  3119. void axis_disable_software_lmt(axis_object_t *axis) {
  3120. axis->inputs.sw_lmt_enable = 0;
  3121. }
  3122. /**
  3123. * 设置加减速模式,包括时间
  3124. *
  3125. * @author LXZ (031420)
  3126. *
  3127. * @param axis 轴对象
  3128. * @param mode
  3129. * 加减模式,0是直线加减速,1是S型加减速
  3130. * @param acc_time 加速度时间
  3131. * @param dec_time 减速度时间
  3132. */
  3133. void axis_set_accdec(axis_object_t *axis, int mode, int acc_time, int dec_time) {
  3134. axis->accdec_mode = mode;
  3135. axis->acc_time = acc_time;
  3136. axis->dec_time = dec_time;
  3137. }
  3138. /**
  3139. * 使能调中回调函数
  3140. *
  3141. * @author LXZ (031420)
  3142. *
  3143. * @param axis 轴对象
  3144. * @param handle 回调函数入口
  3145. */
  3146. void axis_register_irq_callback(axis_object_t *axis, void (*handle)()) {
  3147. axis->handle = handle;
  3148. }
  3149. /**
  3150. * 禁止中断回调
  3151. *
  3152. * @author LXZ (031420)
  3153. *
  3154. * @param axis
  3155. */
  3156. void axis_unregister_irq_callback(axis_object_t *axis) {
  3157. axis->handle = (void *)0;
  3158. }
  3159. /**
  3160. * 设置电子齿轮比
  3161. *
  3162. * @author LXZ (051820)
  3163. *
  3164. * @param axis
  3165. * @param cycle_pluse 一圈脉冲数
  3166. * @param cycle_length 一圈长度
  3167. * @param lenrate 放大倍数
  3168. */
  3169. void axis_set_ratio(axis_object_t *axis, int cycle_pluse, int cycle_length,int lenrate)
  3170. {
  3171. axis->cycle_length = cycle_length;
  3172. axis->cycle_pluse = cycle_pluse;
  3173. axis->length_rate = lenrate;
  3174. }
  3175. /**
  3176. * 使能齿轮比定位
  3177. *
  3178. * @author LXZ (060120)
  3179. *
  3180. * @param axis
  3181. */
  3182. void axis_enable_ratio(axis_object_t *axis) {
  3183. axis->inputs.ratio_enable = 1;
  3184. }
  3185. /**
  3186. * 禁止齿轮比定位
  3187. *
  3188. * @author LXZ (060120)
  3189. *
  3190. * @param axis
  3191. */
  3192. void axis_disable_ratio(axis_object_t *axis) {
  3193. axis->inputs.ratio_enable = 0;
  3194. }
  3195. /**
  3196. * 位置转脉冲
  3197. *
  3198. * @author LXZ (051820)
  3199. *
  3200. * @param axis
  3201. */
  3202. int axis_position_to_pluse(axis_object_t *axis, int value)
  3203. {
  3204. double length = (double)(axis->cycle_length) / axis->length_rate;
  3205. unsigned int pluse = axis->cycle_pluse;
  3206. double res = value;
  3207. //参数保护
  3208. if (length == 0)
  3209. {
  3210. length = 1;
  3211. }
  3212. if (pluse == 0)
  3213. {
  3214. pluse = 1;
  3215. }
  3216. res *= pluse;
  3217. res /= length;
  3218. if (res > 0)
  3219. {
  3220. res += 0.5;
  3221. }
  3222. else
  3223. {
  3224. res -= 0.5;
  3225. }
  3226. return (int)(res);
  3227. }
  3228. /**
  3229. * 脉冲转位置
  3230. *
  3231. * @author LXZ (051820)
  3232. *
  3233. * @param axis
  3234. */
  3235. int axis_pluse_to_position(axis_object_t *axis, int value)
  3236. {
  3237. double length = (double)(axis->cycle_length) / axis->length_rate;
  3238. unsigned int pluse = axis->cycle_pluse;
  3239. double res = value;
  3240. //参数保护
  3241. if (length == 0)
  3242. {
  3243. length = 1;
  3244. }
  3245. if (pluse == 0)
  3246. {
  3247. pluse = 1;
  3248. }
  3249. res *= length;
  3250. res /= pluse;
  3251. if (res > 0)
  3252. {
  3253. res += 0.5;
  3254. }
  3255. else
  3256. {
  3257. res -= 0.5;
  3258. }
  3259. return (int)(res);
  3260. }
  3261. /**
  3262. * 转速转频率
  3263. *
  3264. * @author LXZ (051820)
  3265. *
  3266. * @param axis 轴对象
  3267. * @param value 转速
  3268. *
  3269. * @return int 转换结果(频率)
  3270. */
  3271. int axis_revs_to_freq(axis_object_t *axis, int value) {
  3272. unsigned int pluse = axis->cycle_pluse;
  3273. int res = 0;
  3274. if (pluse == 0) {
  3275. pluse = 1;
  3276. }
  3277. res = pluse * value / 60;
  3278. return res;
  3279. }
  3280. /**
  3281. * 频率转转速
  3282. *
  3283. * @author LXZ (051820)
  3284. *
  3285. * @param axis 轴对象
  3286. * @param value 频率
  3287. *
  3288. * @return int 转换结果(转速)
  3289. */
  3290. int axis_freq_to_revs(axis_object_t *axis, int value) {
  3291. unsigned int pluse = axis->cycle_pluse;
  3292. int res = 0;
  3293. if (pluse == 0) {
  3294. pluse = 1;
  3295. }
  3296. res = value * 60 / pluse;
  3297. return res;
  3298. }
  3299. /**
  3300. * @brief 速度单位 单位距离 / min ,返回频率
  3301. * 距离单位为 0.01
  3302. * @param axis_no
  3303. * @param value
  3304. * @return int
  3305. */
  3306. int axis_speed_to_freq(axis_object_t *axis, int value)
  3307. {
  3308. double length = (double)(axis->cycle_length) / axis->length_rate;
  3309. unsigned int pluse = axis->cycle_pluse;
  3310. double res;
  3311. //参数保护
  3312. if (length == 0)
  3313. {
  3314. length = 1;
  3315. }
  3316. if (pluse == 0)
  3317. {
  3318. pluse = 1;
  3319. }
  3320. res = pluse / length;
  3321. res = res * value;
  3322. res = res / 60;
  3323. //ratio = ratio * value / 60;
  3324. return (int)(res);
  3325. }