servocom_app.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. #include "global.h"
  2. #include "servocom_app.h"
  3. servo_param_t servo_x,servo_y;
  4. long olddwXRealPos[5],olddwYRealPos[5];
  5. long x_cycle_PULSE,x_cycle_LENGTH,y_cycle_PULSE,y_cycle_LENGTH;
  6. //伺服通讯命令反馈。
  7. char servo_com_cmd_fb[SERVO_COM_CMD_NUMBER+1];
  8. //华创伺服参数读取列表
  9. servo_com_cmd_t servo_com_cmd_table[SERVO_AXISNUM][SERVO_COM_CMD_NUMBER] ={{
  10. //命令编码-------目标地址-------------通讯个数--------------数值地址------------------ID--------------CMD-cycle-time---回调函数
  11. {HANDSHAKE, SERVO_ADDR_HAND, 1,(unsigned char *)&servo_x.handshake, SERVO_X_COM_ID,0x03,0,50,servo_com_respone},
  12. {DI_MODE_SW, SERVO_ADDR_DI_MODE_SW, 2,(unsigned char *)&servo_x.di_function_set, SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  13. {DO_TARR_SW, SERVO_ADDR_DO_TARR_OV, 2,(unsigned char *)&servo_x.do_function_set, SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  14. {CTRL_MODE_SET, SERVO_ADDR_MODE_SET, 1,(unsigned char *)&servo_x.ctrl_mode_set, SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  15. {MOTOR_DIR_SET, SERVO_ADDR_MOTOR_DIR, 1,(unsigned char *)&servo_x.motor_dir_set, SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  16. {TARR_SOURCE_SEL,SERVO_ADDR_TARR_SEL, 14,(unsigned char *)&servo_x.tarr_source_sel,SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  17. {TARR_LIMIT12_SET, SERVO_ADDR_LIMIT_SET, 9,(unsigned char *)&servo_x.tarr_Plimit1_sel,SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  18. {SPEED_LIMIT_SET,SERVO_ADDR_SPEED_SET, 3,(unsigned char *)&servo_x.speed_plimit_set,SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  19. {TARR_BASE_SET, SERVO_ADDR_TARBASE_SET, 3,(unsigned char *)&servo_x.tarr_basis, SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  20. {ALARM_REST, SERVO_ADDR_ALARM_REST, 1,(unsigned char *)&servo_x.alarmrest, SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  21. {SERVO_RESTART, SERVO_ADDR_SERVO_RESTART,1,(unsigned char *)&servo_x.restart, SERVO_X_COM_ID,0x06,0,50,servo_com_respone},
  22. {ALARM_CODE, SERVO_ADDR_ALARM_CODE, 1,(unsigned char *)&servo_x.alarmcode, SERVO_X_COM_ID,0x03,1,50,servo_com_respone},
  23. {ENCODE_FB, SERVO_ADDR_ENCODE_FB, 2,(unsigned char *)&servo_x.encode, SERVO_X_COM_ID,0x03,1,50,servo_com_respone}
  24. },
  25. {
  26. {HANDSHAKE, SERVO_ADDR_HAND, 1,(unsigned char *)&servo_y.handshake, SERVO_Y_COM_ID,0x03,0,50,servo_com_respone},
  27. {DI_MODE_SW, SERVO_ADDR_DI_MODE_SW, 2,(unsigned char *)&servo_y.di_function_set, SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  28. {DO_TARR_SW, SERVO_ADDR_DO_TARR_OV, 2,(unsigned char *)&servo_y.do_function_set, SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  29. {CTRL_MODE_SET, SERVO_ADDR_MODE_SET, 1,(unsigned char *)&servo_y.ctrl_mode_set, SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  30. {MOTOR_DIR_SET, SERVO_ADDR_MOTOR_DIR, 1,(unsigned char *)&servo_y.motor_dir_set, SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  31. {TARR_SOURCE_SEL,SERVO_ADDR_TARR_SEL, 14,(unsigned char *)&servo_y.tarr_source_sel,SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  32. {TARR_LIMIT12_SET, SERVO_ADDR_LIMIT_SET, 9,(unsigned char *)&servo_y.tarr_Plimit1_sel,SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  33. {SPEED_LIMIT_SET,SERVO_ADDR_SPEED_SET, 3,(unsigned char *)&servo_y.speed_plimit_set,SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  34. {TARR_BASE_SET, SERVO_ADDR_TARBASE_SET, 3,(unsigned char *)&servo_y.tarr_basis, SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  35. {ALARM_REST, SERVO_ADDR_ALARM_REST, 1,(unsigned char *)&servo_y.alarmrest, SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  36. {SERVO_RESTART, SERVO_ADDR_SERVO_RESTART,1,(unsigned char *)&servo_y.restart, SERVO_Y_COM_ID,0x06,0,50,servo_com_respone},
  37. {ALARM_CODE, SERVO_ADDR_ALARM_CODE, 1,(unsigned char *)&servo_y.alarmcode, SERVO_Y_COM_ID,0x03,1,50,servo_com_respone},
  38. {ENCODE_FB, SERVO_ADDR_ENCODE_FB, 2,(unsigned char *)&servo_y.encode, SERVO_Y_COM_ID,0x03,1,50,servo_com_respone}
  39. }
  40. };
  41. /*
  42. * 伺服通讯命令函数
  43. *
  44. * @author laz
  45. *
  46. * @param cmd
  47. */
  48. static void servo_com_cmd(unsigned short axis,unsigned char cmd)
  49. {
  50. int i,cyckletime;
  51. switch(axis)
  52. {
  53. case X_AXIS:
  54. for(i=0;i<SERVO_COM_CMD_NUMBER;i++)
  55. {
  56. if(cmd==servo_com_cmd_table[0][i].cmdcode){
  57. break;
  58. }
  59. }
  60. if(servo_com_cmd_table[0][i].dir==0) {//单次通讯
  61. //添加单次采集命令
  62. modbus_master_add_once_cmd(
  63. &master1,
  64. servo_com_cmd_table[0][i].cmdcode, //命令编码
  65. servo_com_cmd_table[0][i].id, //设备ID
  66. servo_com_cmd_table[0][i].cmd, //命令码
  67. servo_com_cmd_table[0][i].address, //10
  68. servo_com_cmd_table[0][i].number, //10
  69. servo_com_cmd_table[0][i].value, //数据存放位置
  70. servo_com_cmd_table[0][i].respone_timeout, //50ms超时时间(不包括通讯必须时间)
  71. servo_com_cmd_table[0][i].servo_on_respone //不需要回调函数
  72. );
  73. }
  74. else
  75. {
  76. if(cmd==ENCODE_FB)cyckletime=100;
  77. else cyckletime=1000;
  78. //添加循环采集命令
  79. modbus_master_add_period_cmd(
  80. &master1,
  81. servo_com_cmd_table[0][i].cmdcode, //命令编码
  82. servo_com_cmd_table[0][i].id, //设备ID
  83. servo_com_cmd_table[0][i].cmd, //命令码
  84. servo_com_cmd_table[0][i].address, //10
  85. servo_com_cmd_table[0][i].number, //10
  86. servo_com_cmd_table[0][i].value, //数据存放位置
  87. servo_com_cmd_table[0][i].respone_timeout, //50ms超时时间(不包括通讯必须时间)
  88. servo_com_cmd_table[0][i].servo_on_respone,//不需要回调函数
  89. cyckletime //1000ms采集一次
  90. );
  91. }
  92. break;
  93. case Y_AXIS:
  94. for(i=0;i<SERVO_COM_CMD_NUMBER;i++)
  95. {
  96. if(cmd==servo_com_cmd_table[1][i].cmdcode){
  97. break;
  98. }
  99. }
  100. if(servo_com_cmd_table[1][i].dir==0) {//单次通讯
  101. //添加单次采集命令
  102. modbus_master_add_once_cmd(
  103. &master1,
  104. servo_com_cmd_table[1][i].cmdcode, //命令编码
  105. servo_com_cmd_table[1][i].id, //设备ID
  106. servo_com_cmd_table[1][i].cmd, //命令码
  107. servo_com_cmd_table[1][i].address, //10
  108. servo_com_cmd_table[1][i].number, //10
  109. servo_com_cmd_table[1][i].value, //数据存放位置
  110. servo_com_cmd_table[1][i].respone_timeout, //50ms超时时间(不包括通讯必须时间)
  111. servo_com_cmd_table[1][i].servo_on_respone //不需要回调函数
  112. );
  113. }
  114. else
  115. {
  116. if(cmd==ENCODE_FB)cyckletime=100;
  117. else cyckletime=1000;
  118. //添加循环采集命令
  119. modbus_master_add_period_cmd(
  120. &master1,
  121. servo_com_cmd_table[1][i].cmdcode, //命令编码
  122. servo_com_cmd_table[1][i].id, //设备ID
  123. servo_com_cmd_table[1][i].cmd, //命令码
  124. servo_com_cmd_table[1][i].address, //10
  125. servo_com_cmd_table[1][i].number, //10
  126. servo_com_cmd_table[1][i].value, //数据存放位置
  127. servo_com_cmd_table[1][i].respone_timeout, //50ms超时时间(不包括通讯必须时间)
  128. servo_com_cmd_table[1][i].servo_on_respone,//不需要回调函数
  129. cyckletime //1000ms采集一次
  130. );
  131. }
  132. break;
  133. }
  134. }
  135. /*
  136. * 伺服通讯,故障清除函数
  137. *
  138. * @author laz
  139. *
  140. * @param aixs
  141. */
  142. int clr_com_servo_alarm(unsigned short axis)
  143. {
  144. switch(axis)
  145. {
  146. case X_AXIS:
  147. servo_com_cmd(axis,ALARM_REST);
  148. break;
  149. case Y_AXIS:
  150. servo_com_cmd(axis,ALARM_REST);
  151. break;
  152. }
  153. return 1;
  154. }
  155. /*
  156. * 伺服通讯,获取伺服故障代码
  157. *
  158. * @author laz
  159. *
  160. * @param aixs
  161. */
  162. int get_alarm_code(unsigned short axis)
  163. {
  164. switch(axis)
  165. {
  166. case X_AXIS:
  167. return (servo_x.alarmcode);
  168. break;
  169. case Y_AXIS:
  170. return (servo_y.alarmcode);
  171. break;
  172. }
  173. return 0;
  174. }
  175. /*
  176. * 伺服通讯,编码转换长度计算
  177. *
  178. * @author laz
  179. *
  180. * @param encode 伺服编码
  181. * gearratio,齿轮比
  182. */
  183. static long encode_to_length(long encode,float gearratio)
  184. {
  185. float pos;
  186. pos=encode;
  187. pos=(float)(pos/ENCODE_17BIT);
  188. pos*= x_cycle_PULSE;
  189. pos/= gearratio;
  190. return (long)(pos);
  191. }
  192. /*
  193. * 伺服通讯,位置设置值
  194. *
  195. * @author laz
  196. *
  197. * @param axis
  198. * pos,
  199. */
  200. int axis_set_com_pos(unsigned short axis,long pos )
  201. {
  202. switch(axis)
  203. {
  204. case X_AXIS:
  205. servo_x.precode=servo_x.encode-pos;
  206. break;
  207. case Y_AXIS:
  208. servo_y.precode=servo_y.encode-pos;
  209. break;
  210. }
  211. return 1;
  212. }
  213. /*
  214. * 伺服通讯,长度值
  215. *
  216. * @author laz
  217. *
  218. * @param axis
  219. */
  220. static long axis_get_com_pos(unsigned short axis)
  221. {
  222. switch(axis)
  223. {
  224. case X_AXIS:
  225. if(servo_x.encode>=servo_x.precode)
  226. return(encode_to_length(servo_x.encode-servo_x.precode,YGearRatio));
  227. else
  228. return(encode_to_length(servo_x.precode-servo_x.encode,YGearRatio));
  229. break;
  230. case Y_AXIS:
  231. if(servo_y.encode>=servo_y.precode)
  232. return(encode_to_length(servo_y.encode-servo_y.precode,YGearRatio));
  233. else
  234. return(encode_to_length(servo_y.precode-servo_y.encode,YGearRatio));
  235. break;
  236. }
  237. return 0;
  238. }
  239. /*
  240. * 伺服通讯,//频率转换为转速
  241. *
  242. * @author laz
  243. *
  244. * @param freq 伺服的频率
  245. * rerurn 伺服的转速
  246. */
  247. static unsigned short freq_to_speed(unsigned short freq)
  248. {
  249. if(freq==0)return 1;
  250. if(y_cycle_LENGTH==0)return 1;
  251. return(freq*60/x_cycle_PULSE+1);
  252. }
  253. /*
  254. * 伺服通讯,读取编码次数
  255. *
  256. * @author laz
  257. *
  258. * @param axis
  259. * times 读取次数
  260. */
  261. void read_encode_value_cmd(unsigned short axis,unsigned short times)
  262. {
  263. int i=0;
  264. switch(axis)
  265. {
  266. case X_AXIS:
  267. servo_x.cmd_fb[ENCODE_FB]=0;
  268. for(i=0;i<times;i++)servo_com_cmd(axis,ENCODE_FB);
  269. break;
  270. case Y_AXIS:
  271. servo_y.cmd_fb[ENCODE_FB]=0;
  272. for(i=0;i<times;i++)servo_com_cmd(axis,ENCODE_FB);
  273. break;
  274. }
  275. }
  276. /*
  277. * 伺服通讯,读取长度值
  278. *
  279. * @author laz
  280. *
  281. * @param axis
  282. */
  283. long get_encode_value(unsigned short axis)
  284. {
  285. switch(axis)
  286. {
  287. case X_AXIS:
  288. return axis_get_com_pos(axis);
  289. break;
  290. case Y_AXIS:
  291. return axis_get_com_pos(axis);
  292. break;
  293. }
  294. return 0;
  295. }
  296. /*
  297. * 伺服通讯,伺服轴通讯回调函数
  298. *
  299. * @author laz
  300. *
  301. *
  302. */
  303. static void servo_axis_com_respone(unsigned short axis,servo_param_t *servo_axis,modbus_master_cmd_t *cmd, unsigned char *respone, int length)
  304. {
  305. switch(cmd->cmdcode)
  306. {
  307. case HANDSHAKE:
  308. servo_axis->cmd_fb[HANDSHAKE]=cmd->cmdcode;
  309. break;
  310. case DI_MODE_SW:
  311. servo_axis->cmd_fb[DI_MODE_SW]=cmd->cmdcode;
  312. break;
  313. case DO_TARR_SW:
  314. servo_axis->cmd_fb[DO_TARR_SW]=cmd->cmdcode;
  315. break;
  316. case CTRL_MODE_SET:
  317. servo_axis->cmd_fb[CTRL_MODE_SET]=cmd->cmdcode;
  318. break;
  319. case MOTOR_DIR_SET:
  320. servo_axis->cmd_fb[MOTOR_DIR_SET]=cmd->cmdcode;
  321. break;
  322. case TARR_SOURCE_SEL:
  323. servo_axis->cmd_fb[TARR_SOURCE_SEL]=cmd->cmdcode;
  324. break;
  325. case TARR_LIMIT12_SET:
  326. servo_axis->set_tarr_OKflag++;
  327. servo_axis->cmd_fb[TARR_LIMIT12_SET]=cmd->cmdcode;
  328. break;
  329. case SPEED_LIMIT_SET:
  330. servo_axis->set_tarr_OKflag++;
  331. servo_axis->cmd_fb[SPEED_LIMIT_SET]=cmd->cmdcode;
  332. break;
  333. case TARR_BASE_SET:
  334. servo_axis->set_tarr_OKflag++;
  335. servo_axis->cmd_fb[TARR_BASE_SET]=cmd->cmdcode;
  336. break;
  337. case ALARM_REST:
  338. servo_axis->cmd_fb[ALARM_REST]=cmd->cmdcode;
  339. break;
  340. case SERVO_RESTART:
  341. servo_axis->cmd_fb[SERVO_RESTART]=cmd->cmdcode;
  342. break;
  343. case ALARM_CODE:
  344. servo_axis->cmd_fb[ALARM_CODE]=cmd->cmdcode;
  345. if(servo_axis->alarmcode>0)servo_axis->alarm_flag=1;
  346. else servo_axis->alarm_flag=0;
  347. break;
  348. case ENCODE_FB:
  349. servo_axis->cmd_fb[ENCODE_FB]=cmd->cmdcode;
  350. get_encode_value(axis);
  351. break;
  352. default:
  353. break;
  354. }
  355. }
  356. static int servo_com_get_alarm(unsigned short axis)
  357. {
  358. switch(axis)
  359. {
  360. case X_AXIS:
  361. axis_x_com_alarm=axis_x_com_alarm;
  362. break;
  363. case Y_AXIS:
  364. axis_y_com_alarm=axis_y_com_alarm;
  365. break;
  366. }
  367. return 1;
  368. }
  369. /*
  370. * 伺服通讯,通讯回调函数
  371. *
  372. * @author laz
  373. *
  374. *
  375. */
  376. void servo_com_respone(modbus_master_cmd_t *cmd, unsigned char *respone, int length)
  377. {
  378. #if X_USERING_TARR == 1
  379. if(cmd->id==SERVO_X_COM_ID)servo_axis_com_respone(X_AXIS,&servo_x,cmd,respone,length);
  380. #endif
  381. #if Y_USERING_TARR == 1
  382. if(cmd->id==SERVO_Y_COM_ID)servo_axis_com_respone(Y_AXIS,&servo_y,cmd,respone,length);
  383. #endif
  384. }
  385. //设置位置+转矩模式下的转矩配置
  386. int set_servo_postotarr_limit(unsigned short axis,int tarr,
  387. unsigned short P_freq,unsigned short N_freq,
  388. unsigned short dir)
  389. {
  390. switch(axis)
  391. {
  392. case X_AXIS:
  393. //配置扭矩模式下的速度限制、扭矩限制、扭矩基准值
  394. servo_x.speed_plimit_set=freq_to_speed(P_freq);
  395. servo_x.speed_nlimit_set=freq_to_speed(N_freq);
  396. if(tarr<200)tarr=200;
  397. if(dir)servo_x.tarr_limit_set=-tarr;
  398. else servo_x.tarr_limit_set=tarr;
  399. servo_com_cmd(axis,SPEED_LIMIT_SET);
  400. servo_x.cmd_fb[SPEED_LIMIT_SET]=0;//清除反馈命令
  401. //转矩的基准值设置
  402. servo_x.tarr_basis=servo_x.tarr_limit_set-100;
  403. servo_x.tarr_basis_up=100;
  404. servo_x.tarr_basis_dw=50;
  405. servo_com_cmd(axis,TARR_BASE_SET);
  406. servo_x.cmd_fb[TARR_BASE_SET]=0;//清除反馈命令
  407. servo_x.set_tarr_OKflag=0;
  408. sw_timer_start(&servo_x.timer, 1, 0);//1S超时
  409. break;
  410. case Y_AXIS:
  411. //配置扭矩模式下的速度限制、扭矩限制、扭矩基准值
  412. servo_y.speed_plimit_set=freq_to_speed(P_freq);
  413. servo_y.speed_nlimit_set=freq_to_speed(N_freq);
  414. if(tarr<200)tarr=200;
  415. if(dir)servo_y.tarr_limit_set=-tarr;
  416. else servo_y.tarr_limit_set=tarr;
  417. servo_com_cmd(axis,SPEED_LIMIT_SET);
  418. servo_y.cmd_fb[SPEED_LIMIT_SET]=0;//清除反馈命令
  419. //转矩的基准值设置
  420. servo_y.tarr_basis=servo_y.tarr_limit_set-100;
  421. servo_y.tarr_basis_up=100;
  422. servo_y.tarr_basis_dw=50;
  423. servo_com_cmd(axis,TARR_BASE_SET);
  424. servo_y.cmd_fb[TARR_BASE_SET]=0;//清除反馈命令
  425. servo_y.set_tarr_OKflag=0;
  426. sw_timer_start(&servo_y.timer, 1, 0);//1S超时
  427. break;
  428. }
  429. return 1;
  430. }
  431. //转矩模式下的扭矩配置
  432. //设置位置+转矩模式下的转矩配置
  433. int set_servo_tarr_limit(unsigned short axis,int maxtarr,int mintarr,
  434. unsigned short P_freq,unsigned short N_freq,
  435. unsigned short dir)
  436. {
  437. switch(axis)
  438. {
  439. case X_AXIS:
  440. if(maxtarr<400)maxtarr=400;
  441. if(maxtarr>=2000)maxtarr=2000;
  442. //扭矩1,扭矩2的配置
  443. servo_x.tarr_Plimit1_sel=mintarr;
  444. servo_x.tarr_Nlimit1_sel=mintarr;
  445. servo_x.tarr_Plimit2_sel=maxtarr;
  446. servo_x.tarr_Nlimit2_sel=maxtarr;
  447. servo_x.speed_limit_sel=0;
  448. servo_x.speed_ai_sel=1;
  449. //配置扭矩模式下的速度限制、扭矩基准值
  450. servo_x.speed_plimit_set=freq_to_speed(P_freq);
  451. servo_x.speed_nlimit_set=freq_to_speed(N_freq);
  452. if(dir)servo_x.tarr_limit_set=-(maxtarr+200);
  453. else servo_x.tarr_limit_set=(maxtarr+200);
  454. servo_com_cmd(axis,TARR_LIMIT12_SET);
  455. servo_x.cmd_fb[TARR_LIMIT12_SET]=0;//清除反馈命令
  456. //转矩的基准值设置
  457. servo_x.tarr_basis=mintarr-100;
  458. servo_x.tarr_basis_up=100;
  459. servo_x.tarr_basis_dw=50;
  460. servo_com_cmd(axis,TARR_BASE_SET);
  461. servo_x.cmd_fb[TARR_BASE_SET]=0;//清除反馈命令
  462. servo_x.set_tarr_OKflag=0;
  463. sw_timer_start(&servo_x.timer, 1, 0);//1S超时
  464. break;
  465. case Y_AXIS:
  466. if(maxtarr<400)maxtarr=400;
  467. if(maxtarr>=2000)maxtarr=2000;
  468. //扭矩1,扭矩2的配置
  469. servo_y.tarr_Plimit1_sel=mintarr;
  470. servo_y.tarr_Nlimit1_sel=mintarr;
  471. servo_y.tarr_Plimit2_sel=maxtarr;
  472. servo_y.tarr_Nlimit2_sel=maxtarr;
  473. servo_y.speed_limit_sel=0;
  474. servo_y.speed_ai_sel=1;
  475. //配置扭矩模式下的速度限制、扭矩基准值
  476. servo_y.speed_plimit_set=freq_to_speed(P_freq);
  477. servo_y.speed_nlimit_set=freq_to_speed(N_freq);
  478. if(dir)servo_y.tarr_limit_set=-(maxtarr+200);
  479. else servo_y.tarr_limit_set=(maxtarr+200);
  480. servo_com_cmd(axis,TARR_LIMIT12_SET);
  481. servo_y.cmd_fb[TARR_LIMIT12_SET]=0;//清除反馈命令
  482. //转矩的基准值设置
  483. servo_y.tarr_basis=mintarr-100;
  484. servo_y.tarr_basis_up=100;
  485. servo_y.tarr_basis_dw=50;
  486. servo_com_cmd(axis,TARR_BASE_SET);
  487. servo_y.cmd_fb[TARR_BASE_SET]=0;//清除反馈命令
  488. servo_y.set_tarr_OKflag=0;
  489. sw_timer_start(&servo_y.timer, 1, 0);//1S超时
  490. break;
  491. }
  492. return 1;
  493. }
  494. /**
  495. * 获取转矩配置是否成功
  496. *
  497. * @author laz
  498. *
  499. * @param axis
  500. */
  501. int get_tarr_set(unsigned short axis)
  502. {
  503. switch(axis)
  504. {
  505. case X_AXIS:
  506. if(servo_x.set_tarr_OKflag==2)return 2;//配置成功
  507. if(sw_timer_expire(&servo_x.timer))return 0;//配置超时
  508. else return 1;//配置中
  509. break;
  510. case Y_AXIS:
  511. if(servo_y.set_tarr_OKflag==2)return 2;//配置成功
  512. if(sw_timer_expire(&servo_y.timer))return 0;//配置超时
  513. else return 1;//配置中
  514. break;
  515. }
  516. return 0;
  517. }
  518. //设置转矩模式下的X配置初始化
  519. static int set_ctrl_tarr_axis_init(unsigned short axis,servo_param_t *servo_axis,unsigned short mode)
  520. {
  521. switch(mode)
  522. {
  523. case 0:
  524. servo_axis->tarr_source_sel=0;//来源A
  525. servo_axis->tarr_modea_sel=0;
  526. servo_axis->tarr_modeb_sel=0;
  527. servo_axis->tarr_limit_sel=0;
  528. servo_axis->tarr_ai_sel=1;
  529. servo_axis->tarr_Plimit1_sel=3000;
  530. servo_axis->tarr_Nlimit1_sel=3000;
  531. servo_axis->tarr_Plimit2_sel=3000;
  532. servo_axis->tarr_Nlimit2_sel=3000;
  533. servo_axis->speed_limit_sel=0;
  534. servo_axis->speed_ai_sel=1;
  535. servo_axis->speed_plimit_set=200;
  536. servo_axis->speed_nlimit_set=100;
  537. servo_axis->tarr_limit_set=50;
  538. servo_axis->tarr_basis=40;
  539. servo_com_cmd(axis,TARR_SOURCE_SEL);
  540. servo_axis->cmd_fb[TARR_SOURCE_SEL]=0;//清除反馈命令
  541. break;
  542. case 1:
  543. servo_axis->tarr_source_sel=3;//来源A
  544. servo_axis->tarr_modea_sel=0;
  545. servo_axis->tarr_modeb_sel=0;
  546. servo_axis->tarr_limit_sel=2;
  547. servo_axis->tarr_ai_sel=1;
  548. servo_axis->tarr_Plimit1_sel=200;
  549. servo_axis->tarr_Nlimit1_sel=200;
  550. servo_axis->tarr_Plimit2_sel=1000;
  551. servo_axis->tarr_Nlimit2_sel=1000;
  552. servo_axis->speed_limit_sel=0;
  553. servo_axis->speed_ai_sel=1;
  554. servo_axis->speed_plimit_set=200;
  555. servo_axis->speed_nlimit_set=100;
  556. servo_axis->tarr_limit_set=1000;
  557. servo_axis->tarr_basis=80;
  558. servo_com_cmd(axis,TARR_SOURCE_SEL);
  559. servo_axis->cmd_fb[TARR_SOURCE_SEL]=0;//清除反馈命令
  560. break;
  561. }
  562. return 1;
  563. }
  564. //设置转矩模式下的配置
  565. static int set_ctrl_tarr_config(unsigned short axis,unsigned short mode)
  566. {
  567. switch(axis)
  568. {
  569. case X_AXIS:
  570. set_ctrl_tarr_axis_init(axis,&servo_x,mode);
  571. break;
  572. case Y_AXIS:
  573. set_ctrl_tarr_axis_init(axis,&servo_y,mode);
  574. break;
  575. }
  576. return 1;
  577. }
  578. //设置伺服运行模式
  579. //0位置+转矩模式,转矩改变由通讯方式
  580. //1转矩模式,采用转矩切换方式
  581. static void set_servo_axis_mode(unsigned short axis,servo_param_t *servo_axis,unsigned short mode)
  582. {
  583. SetEn(axis, 0);//停机关使能
  584. switch(mode)
  585. {
  586. case 0:
  587. //配置DI5功能为模式1切换和极性
  588. servo_axis->di_function_set=DI__FUNCTION_POSTARRSEL;
  589. servo_axis->di_polarity= DI_NCLOSE;
  590. servo_com_cmd(axis,DI_MODE_SW);
  591. servo_axis->cmd_fb[DI_MODE_SW]=0;//清除反馈命令
  592. //配置DO3为转矩到达输出和极性
  593. servo_axis->do_function_set=DO_FUNCTION_VALUE;
  594. servo_axis->do_polarity= DI_NCLOSE;
  595. servo_com_cmd(axis,DO_TARR_SW);
  596. servo_axis->cmd_fb[DO_TARR_SW]=0;//清除反馈命令
  597. //配置控制模式
  598. servo_axis->ctrl_mode_set=CTRL_POSTOTARR_MODE;
  599. servo_com_cmd(axis,CTRL_MODE_SET);
  600. servo_axis->cmd_fb[CTRL_MODE_SET]=0;//清除反馈命令
  601. //配置转矩的方式:
  602. set_ctrl_tarr_config(axis,mode);
  603. //配置扭矩模式下的速度限制、扭矩限制、扭矩基准值
  604. set_servo_postotarr_limit(axis,1000,20000,10000,SERVO_TARR_CW);
  605. //配置超时设置
  606. sw_timer_start(&servo_axis->timer, 2, 0);//2S超时
  607. break;
  608. case 1:
  609. //配置DI5功能为模式1切换和极性
  610. servo_axis->di_function_set=DI__FUNCTION_TARRSEL;
  611. servo_axis->di_polarity= DI_NOPEN;
  612. servo_com_cmd(axis,DI_MODE_SW);
  613. servo_axis->cmd_fb[DI_MODE_SW]=0;//清除反馈命令
  614. //配置DO3为转矩到达输出和极性
  615. servo_axis->do_function_set=DO_FUNCTION_VALUE;
  616. servo_axis->do_polarity= DI_NCLOSE;
  617. servo_com_cmd(axis,DO_TARR_SW);
  618. servo_axis->cmd_fb[DO_TARR_SW]=0;//清除反馈命令
  619. //配置控制模式
  620. servo_axis->ctrl_mode_set=CTRL_TARR_MODE;
  621. servo_com_cmd(axis,CTRL_MODE_SET);
  622. servo_axis->cmd_fb[CTRL_MODE_SET]=0;//清除反馈命令
  623. //配置转矩的方式:
  624. set_ctrl_tarr_config(axis,mode);
  625. //配置扭矩模式下的速度限制、扭矩限制、扭矩基准值
  626. set_servo_tarr_limit(axis,1000,1000,20000,10000,SERVO_TARR_CW);
  627. //配置超时设置
  628. sw_timer_start(&servo_axis->timer, 2, 0);//2S超时
  629. break;
  630. }
  631. }
  632. //设置伺服运行模式
  633. //0位置+转矩模式,转矩改变由通讯方式
  634. //1转矩模式,采用转矩切换方式
  635. static void set_servo_mode(unsigned short axis,unsigned short mode)
  636. {
  637. switch(axis)
  638. {
  639. case X_AXIS:
  640. set_servo_axis_mode(X_AXIS,&servo_x,mode);
  641. break;
  642. case Y_AXIS:
  643. set_servo_axis_mode(Y_AXIS,&servo_y,mode);
  644. break;
  645. }
  646. }
  647. /**
  648. * 伺服通讯初初始化函数
  649. *
  650. * @author laz
  651. *
  652. * @param cmd
  653. */
  654. static int servo_com_init(unsigned short axis,servo_param_t *servo_axis)
  655. {
  656. //通讯握手三次
  657. switch(servo_axis->init_step)
  658. {
  659. case 0://握手
  660. servo_axis->IO_TO_COM=0;
  661. servo_com_cmd(axis,HANDSHAKE);
  662. servo_axis->cmd_fb[HANDSHAKE]=0;//清除反馈命令
  663. sw_timer_start(&servo_axis->timer, 1, 0);//1S超时
  664. servo_axis->init_step++;
  665. servo_axis->com_number++;
  666. break;
  667. case 1://判断握手情况。
  668. if (sw_timer_expire(&servo_axis->timer)){//握手超时
  669. if(servo_axis->com_number>=3){//三次通讯超时,通讯失败。
  670. servo_axis->init_step=0xF0;
  671. }
  672. else{//没有到三次继续通讯。
  673. servo_axis->init_step=0;
  674. }
  675. }
  676. if(servo_axis->cmd_fb[HANDSHAKE]==HANDSHAKE)//通讯成功
  677. {
  678. servo_axis->com_ok_number++;
  679. if(servo_axis->com_ok_number>=3){//通讯成功3次
  680. servo_axis->init_step++;
  681. servo_axis->com_number=0;
  682. }
  683. else{
  684. servo_axis->init_step=0;
  685. }
  686. }
  687. break;
  688. case 2://配置伺服驱动器。
  689. //停机关使能
  690. SetEn(axis, 0);
  691. set_servo_mode(axis,RUN_MODE);
  692. servo_axis->com_number++;
  693. sw_timer_start(&servo_axis->timer, 2, 0);//1S超时
  694. servo_axis->init_step++;
  695. break;
  696. case 3://判断配置IO情况。
  697. if (sw_timer_expire(&servo_axis->timer)){//配置失败
  698. if(servo_axis->com_number>=3){//三次配置失败,通讯失败。
  699. servo_axis->init_step=0xF1;
  700. }
  701. else{//配置没有成功重新配置。
  702. servo_axis->init_step=2;
  703. }
  704. }
  705. //配置成功
  706. if(servo_axis->cmd_fb[DI_MODE_SW]==DI_MODE_SW&&servo_axis->cmd_fb[DO_TARR_SW]==DO_TARR_SW
  707. &&servo_axis->cmd_fb[CTRL_MODE_SET]==CTRL_MODE_SET
  708. &&(servo_axis->cmd_fb[SPEED_LIMIT_SET]==SPEED_LIMIT_SET&&RUN_MODE==0
  709. ||servo_axis->cmd_fb[TARR_LIMIT12_SET]==TARR_LIMIT12_SET&&RUN_MODE==1)
  710. &&servo_axis->cmd_fb[TARR_BASE_SET]==TARR_BASE_SET){
  711. servo_axis->init_step++;
  712. }
  713. break;
  714. case 4://设置告警和清除告警的读取模式,循环读取ALARMCODE;
  715. Set_Servo_Runmode(axis,1);//设置伺服运行在通讯模式,
  716. servo_com_cmd(axis,ALARM_CODE);
  717. servo_axis->cmd_fb[ALARM_CODE]=0;//清除反馈命令
  718. servo_axis->init_step++;
  719. break;
  720. case 5://配置成功,输出使能
  721. servo_axis->IO_TO_COM=1;//配置为IO模式
  722. servo_axis->init_step=101;
  723. servo_com_cmd(axis,ENCODE_FB);
  724. servo_com_cmd(axis,ALARM_CODE);
  725. return 1;
  726. break;
  727. case 0xF1://配置失败处理
  728. servo_com_cmd(axis,SERVO_RESTART);//伺服重启
  729. servo_axis->cmd_fb[SERVO_RESTART]=0;//清除反馈命令
  730. servo_axis->init_step++;
  731. break;
  732. case 0xF2://配置失败处理
  733. if(servo_axis->cmd_fb[SERVO_RESTART]==SERVO_RESTART){
  734. ;//SetEn(X_AXIS, 0);//设置使能
  735. return 0xF2;
  736. }
  737. case 0xF0://配置失败处理
  738. return 0xF0;
  739. break;
  740. }
  741. return 0;
  742. }
  743. //伺服运行测试位置
  744. static sw_timer_t servo_com_timer;//伺服通讯定时器。
  745. unsigned char servo_test_step=0;
  746. long X_pos;
  747. int servo_test_pluse_mode(void)
  748. {
  749. static long servo_test_delay=0;
  750. memcpy(&user_datas[610],&dwYRealPos,4);
  751. memcpy(&user_datas[612],&olddwYRealPos[0],4);
  752. SERVO_STEP=servo_test_step;
  753. switch(servo_test_step)
  754. {
  755. case 1:
  756. if(RUN_MODE==0)servo_test_step++;//转矩模式+位置模式测试
  757. else servo_test_step=20;//转矩模式的,转矩1,2限制测试
  758. break;
  759. case 2:
  760. //SetEn(X_AXIS, 1);
  761. SetEn(Y_AXIS, 1);
  762. //SetPos(X_AXIS,0);
  763. SetPos(Y_AXIS,0);
  764. //扭矩模式+位置模式(轴--扭矩%--正转速度限制--反转速度限制--方向)
  765. //set_servo_postotarr_limit(X_AXIS,200,400,100,SERVO_TARR_CW);
  766. set_servo_postotarr_limit(Y_AXIS,200,4000,2000,SERVO_TARR_CW);
  767. //设置位置模式
  768. Set_Ctrlmode_trans(Y_AXIS,POS_MODE);
  769. //
  770. //Set_Ctrlmode_trans(Y_AXIS,TARR_MODE_LIMIT1);
  771. sw_timer_start(&servo_com_timer, 10, 0);
  772. servo_test_step++;
  773. // CTHL_XSavePosBuff=servo_com_timer.usec;
  774. break;
  775. case 4://位置运行
  776. AxisMovePosAccDecNotStop(Y_AXIS,2000,50000,1000,1000,20,50,50);
  777. servo_test_step++;
  778. break;
  779. case 5:
  780. if(get_tarr_set(Y_AXIS)==2)//设置扭矩完成
  781. {
  782. if(abs(dwYRealPos)>=10000)
  783. {
  784. Set_Ctrlmode_trans(Y_AXIS,TARR_MODE);//设置成为扭矩模式
  785. AxisEgmStop(Y_AXIS);
  786. servo_test_step++;
  787. }
  788. }
  789. else if(get_tarr_set(Y_AXIS)==0)//配置超时
  790. {
  791. servo_test_step=0xF0;
  792. }
  793. break;
  794. case 6://
  795. if(GetTarr(Y_AXIS))//转矩到达
  796. {
  797. servo_test_delay=dwTickCount + 1000; //维持1S
  798. servo_test_step++;
  799. }
  800. break;
  801. case 7://
  802. if(dwTickCount>=servo_test_delay)
  803. {
  804. if(GetTarr(Y_AXIS))
  805. {
  806. Set_Ctrlmode_trans(Y_AXIS,POS_MODE);//转位置模式;
  807. set_servo_postotarr_limit(Y_AXIS,250,4000,2000,SERVO_TARR_CCW);//配置转矩及方向
  808. servo_test_step++;
  809. }
  810. }
  811. break;
  812. case 8://松轴
  813. AxisMovePosAccDecNotStop(Y_AXIS,2000,-50000,1000,1000,20,50,50);
  814. servo_test_step++;
  815. break;
  816. case 9:
  817. if(get_tarr_set(Y_AXIS)==2)//设置扭矩完成
  818. {
  819. if(abs(dwYRealPos)>=10000)
  820. {
  821. Set_Ctrlmode_trans(Y_AXIS,TARR_MODE);//设置成为扭矩模式
  822. servo_test_delay=dwTickCount + 5000;
  823. servo_test_step++;
  824. }
  825. }
  826. else if(get_tarr_set(Y_AXIS)==0)//配置超时
  827. {
  828. servo_test_step=0xF0;
  829. }
  830. break;
  831. case 10://
  832. if(dwTickCount>=servo_test_delay)
  833. {
  834. if(GetTarr(Y_AXIS))//转矩到达
  835. {
  836. servo_test_delay=dwTickCount + 1000; //维持1S
  837. servo_test_step++;
  838. }
  839. }
  840. break;
  841. case 11://
  842. if(dwTickCount>=servo_test_delay)
  843. {
  844. if(GetTarr(Y_AXIS))
  845. {
  846. Set_Ctrlmode_trans(Y_AXIS,POS_MODE);//转位置模式;
  847. servo_test_delay=dwTickCount + 100;
  848. servo_test_step++;
  849. }
  850. }
  851. break;
  852. case 12://1S后转转矩模式
  853. if(dwTickCount>=servo_test_delay)
  854. {
  855. Set_Ctrlmode_trans(Y_AXIS,TARR_MODE);//转位置模式;
  856. servo_test_step++;
  857. }
  858. break;
  859. case 13://
  860. if(GetTarr(Y_AXIS))//转矩到达
  861. {
  862. servo_test_delay=dwTickCount + 1000; //维持1S
  863. AxisEgmStop(Y_AXIS);
  864. servo_test_step++;
  865. }
  866. break;
  867. case 14://
  868. if(dwTickCount>=servo_test_delay)
  869. {
  870. if(GetTarr(Y_AXIS))
  871. {
  872. Set_Ctrlmode_trans(Y_AXIS,POS_MODE);//转位置模式;
  873. servo_test_step=0;
  874. }
  875. }
  876. break;
  877. case 20://配置扭矩
  878. //SetEn(X_AXIS, 1);
  879. //SetPos(X_AXIS,0);
  880. SetPos(Y_AXIS,0);
  881. //扭矩模式,用扭矩1和扭矩2之间的切换
  882. //扭矩模式+位置模式(轴--最大扭矩--最小扭矩--正转速度限制--反转速度限制--方向)
  883. //set_servo_tarr_limit(X_AXIS,200,100,400,100,SERVO_TARR_CW);
  884. set_servo_tarr_limit(Y_AXIS,200,100,4000,2000,SERVO_TARR_CW);
  885. //设置最大扭矩限制
  886. Set_Ctrlmode_trans(Y_AXIS,TARR_MODE_MAXLIMIT);
  887. //
  888. //Set_Ctrlmode_trans(Y_AXIS,TARR_MODE_LIMIT1);
  889. sw_timer_start(&servo_com_timer, 10, 0);
  890. //servo_test_step++;
  891. break;
  892. case 21://扭矩运行
  893. if(get_tarr_set(Y_AXIS)==2)//设置扭矩完成
  894. {
  895. if(abs(dwYRealPos)>=10000)
  896. {
  897. SetEn(Y_AXIS, 1);//运行
  898. servo_test_step++;
  899. }
  900. }
  901. else if(get_tarr_set(Y_AXIS)==0)//配置超时
  902. {
  903. servo_test_step=0xF0;
  904. }
  905. break;
  906. case 22://维持运行
  907. servo_test_delay=dwTickCount + 10000; //维持10S
  908. servo_test_step++;
  909. break;
  910. case 23://切换扭矩,并维持运行
  911. if(dwTickCount>=servo_test_delay)
  912. {
  913. Set_Ctrlmode_trans(Y_AXIS,TARR_MODE_MINLIMIT); //切换成扭矩
  914. servo_test_delay=dwTickCount + 10000; //维持10S
  915. servo_test_step++;
  916. }
  917. break;
  918. case 24://停止,切换方向,重新设置
  919. if(dwTickCount>=servo_test_delay)
  920. {
  921. SetEn(Y_AXIS, 0);//停止
  922. set_servo_tarr_limit(Y_AXIS,200,100,4000,2000,SERVO_TARR_CCW);//切换方向
  923. Set_Ctrlmode_trans(Y_AXIS,TARR_MODE_MAXLIMIT);
  924. servo_test_step++;
  925. }
  926. break;
  927. case 25://运行
  928. if(get_tarr_set(Y_AXIS)==2)//设置扭矩完成
  929. {
  930. if(abs(dwYRealPos)>=10000)
  931. {
  932. SetEn(Y_AXIS, 1);//运行
  933. servo_test_step++;
  934. }
  935. }
  936. else if(get_tarr_set(Y_AXIS)==0)//配置超时
  937. {
  938. servo_test_step=0xF0;
  939. }
  940. break;
  941. case 26://维持运行
  942. servo_test_delay=dwTickCount + 10000; //维持10S
  943. servo_test_step++;
  944. break;
  945. case 27://切换扭矩
  946. if(dwTickCount>=servo_test_delay)
  947. {
  948. Set_Ctrlmode_trans(Y_AXIS,TARR_MODE_MINLIMIT); //切换成扭矩
  949. servo_test_delay=dwTickCount + 10000; //维持10S
  950. servo_test_step++;
  951. }
  952. break;
  953. case 28://停止
  954. if(dwTickCount>=servo_test_delay)
  955. {
  956. SetEn(Y_AXIS, 0);//停止
  957. servo_test_step=0;
  958. }
  959. break;
  960. }
  961. if(M0045)
  962. {
  963. M0045=0;
  964. AxisContinueMoveChangeSpeed(Y_AXIS,CHANGE_SPEED,STOP_SPEED,10,10);
  965. }
  966. if(M0046)
  967. {
  968. M0046=0;
  969. servo_test_step++;
  970. }
  971. if(M0047)
  972. {
  973. M0047=0;
  974. //配置扭矩模式下的速度限制。
  975. servo_y.speed_plimit_set=LIMIT_SPEED;
  976. servo_y.speed_nlimit_set=LIMIT_SPEED;
  977. servo_com_cmd(Y_AXIS,SPEED_LIMIT_SET);
  978. servo_y.cmd_fb[SPEED_LIMIT_SET]=0;//清除反馈命令
  979. }
  980. return 0;
  981. }
  982. //伺服运行
  983. int servo_com_run(void)
  984. {
  985. int runflag;
  986. #if X_USERING_TARR==1
  987. runflag=servo_com_init(X_AXIS,&servo_x);//初始化
  988. servo_com_get_alarm(X_AXIS);
  989. #endif
  990. #if Y_USERING_TARR==1
  991. runflag=servo_com_init(Y_AXIS,&servo_y);//初始化
  992. servo_com_get_alarm(Y_AXIS);
  993. #endif
  994. servo_test_pluse_mode();
  995. return runflag;
  996. }