axis_motion.c 96 KB

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