usr_motor.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /*
  2. * usr_gpio.c
  3. *
  4. * Created on: 2022年4月11日
  5. * Author: amos
  6. */
  7. #include "usr_motor.h"
  8. #define BOUNCE_THRESHOLD 2 // 800ms长按阈值
  9. #define LONG_PRESS_THRESHOLD 80 // 800ms长按阈值
  10. #define CONTINUOUS_INTERVAL 40 // 300ms内算连续按键
  11. #define USER_STOP_TIMER 200 // 长按2s不放,停止混匀
  12. #define FIND_OPTIC_SPEED 50 // 找光开速度
  13. #define FIND_OPTIC_BACK_SPEED 43 // 过光开回退速度
  14. #define FIND_OPTIC_BACK_GAP 2 // 过光开回退速度
  15. #define MAX_RUNCNT 4 // 找光开速度
  16. typedef enum swing_state {
  17. SWING_IDLE,
  18. SWING_START,
  19. SWING_LOOP,
  20. SWING_END,
  21. LOOP_START,
  22. LOOP_END,
  23. EMERGENCY_END,
  24. FIND_GAPNUM,
  25. FIND_HOMEGAP,
  26. SWING_ERR,
  27. } swing_state_def;
  28. typedef enum {
  29. KEY_IDLE, // 空闲状态
  30. KEY_SHORT, // 短按
  31. KEY_CONTINUE, // 连续按
  32. KEY_LONG, // 空闲状态,长按抬起,复位设备
  33. KEY_END //混匀状态,长按不释放,停止混匀
  34. } KeyState;
  35. volatile
  36. struct {
  37. KeyState state;
  38. uint32_t press_tick; // 按下时刻(10ms单位)
  39. uint32_t release_tick; // 当前释放时刻
  40. uint32_t last_release_tick; // 新增:上一次释放时刻
  41. uint32_t click_count; // 连续按键计数
  42. uint32_t last_level;
  43. uint32_t key_valid_flag; // 连续按键标志
  44. } key_ctrl;
  45. swing_state_def sw_st, last_st;
  46. unsigned int keyState = 0;
  47. unsigned int MotorOptState = 0;
  48. extern uint32_t conter100ms;
  49. uint32_t conter10ms;
  50. int32_t runLoopTime = 600;
  51. int32_t runLoopSpeed = 80;
  52. uint32_t curtimeinner;
  53. uint32_t timeinner = 6000;
  54. uint32_t swingtime = 100;
  55. uint32_t swingtimeRight = 40;
  56. uint32_t swingtimePause = 100;
  57. int32_t backOptFlag = 0;
  58. int32_t startLoopConter = 0;
  59. int32_t swingspeed = 60;
  60. int32_t stateFistin;
  61. int32_t REVORFWD;
  62. //extern uint8_t error_set(uint8_t error);
  63. uint32_t timerBuf[16];
  64. uint32_t timerconter;
  65. uint32_t intoGap;
  66. uint32_t OutGap;
  67. uint32_t lastGap;
  68. uint32_t judgeGap;
  69. uint32_t curGap;
  70. uint32_t checkPWM;
  71. MOTOR_DIR findhomedir;
  72. uint32_t intoGapFlag;
  73. uint32_t resetFromSwingFlag;
  74. uint32_t swingLoopHigtTime = 0;
  75. uint32_t swingHigStopflage = 0;
  76. uint32_t swingStoptime = 0;
  77. uint32_t startFindHometime = 0;
  78. uint32_t findHome = 0;
  79. extern void DelayMS(uint32_t ms);
  80. //冒泡法排序,排序结果有小到大
  81. void Bubble_Sort(unsigned int *Array,unsigned int n)
  82. {
  83. unsigned char i, j;
  84. unsigned int temp;
  85. for(i=0;i<n-1;i++)
  86. {
  87. for(j=i+1;j<n;j++)
  88. {
  89. if(Array[i] > Array[j])
  90. {
  91. temp = Array[i];
  92. Array[i] = Array[j];
  93. Array[j] = temp;
  94. }
  95. }
  96. }
  97. }
  98. uint32_t Read_Motor(void) {
  99. return (HAL_GPIO_ReadPin(MINI7_V2_REF_SW2_GPIO_Port,MINI7_V2_REF_SW2_Pin)) ? 1 : 0; // 检查PF5引脚值
  100. }
  101. uint32_t Read_key(void) {
  102. return (HAL_GPIO_ReadPin(MINI7_V2_KEY_GPIO_Port,MINI7_V2_KEY_Pin)) ? 1 : 0; // 检查PF5引脚值
  103. }
  104. uint32_t TIMER_GetCounter(void) {
  105. return htim3.Instance->CNT;
  106. }
  107. /**
  108. * @brief SetMotorPwm
  109. *
  110. * @param value between 0-100
  111. *
  112. * @return None
  113. *
  114. * @details
  115. */
  116. void SetMotorPwm(int dir, int32_t value) {
  117. /* Start PWM counter */
  118. unsigned int DutyCycle;
  119. if (value > 100) {
  120. value = 100;
  121. } else if (value < 0) {
  122. value = 0;
  123. DutyCycle = 0;
  124. }
  125. DutyCycle = value*10;
  126. if (dir) {
  127. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
  128. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, DutyCycle);
  129. } else {
  130. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, DutyCycle);
  131. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);
  132. }
  133. }
  134. /**
  135. * @brief GPIO PA/PB/PG/PH IRQ
  136. *
  137. * @param None
  138. *
  139. * @return None
  140. *
  141. * @details The PA/PB/PG/PH default IRQ, declared in startup_M031Series.s.
  142. */
  143. void KYE_IRQHandler(void) {
  144. volatile uint32_t temp;
  145. conter10ms = sysinf.conter10ms;
  146. /* To check if PB.2 interrupt occurred */
  147. {
  148. uint8_t curr_level = Read_key();
  149. if (curr_level != key_ctrl.last_level) {
  150. key_ctrl.last_level = curr_level;
  151. if (curr_level == 0) { // 下降沿(按下)
  152. key_ctrl.press_tick = conter10ms;
  153. if (key_ctrl.state == KEY_SHORT) {
  154. key_ctrl.last_release_tick =
  155. key_ctrl.release_tick; // 更新上次释放时间
  156. } else {
  157. key_ctrl.last_release_tick = 0;
  158. }
  159. } else { // 上升沿(释放)
  160. key_ctrl.release_tick = conter10ms;
  161. uint32_t press_duration = 0;
  162. if(key_ctrl.press_tick){
  163. press_duration = key_ctrl.release_tick - key_ctrl.press_tick;
  164. }
  165. key_ctrl.press_tick = 0;
  166. // 长按判定
  167. if (press_duration <= BOUNCE_THRESHOLD) {
  168. key_ctrl.state = KEY_IDLE;
  169. key_ctrl.last_release_tick = 0;
  170. } else if (press_duration >= LONG_PRESS_THRESHOLD) {
  171. key_ctrl.state = KEY_LONG;
  172. key_ctrl.last_release_tick = 0; // 更新上次释放时间
  173. key_ctrl.key_valid_flag = 1;
  174. }
  175. // 短按判定
  176. else {
  177. key_ctrl.click_count = 1;
  178. key_ctrl.state = KEY_SHORT;
  179. if ((key_ctrl.release_tick - key_ctrl.last_release_tick) <=
  180. CONTINUOUS_INTERVAL) {
  181. key_ctrl.key_valid_flag = 1;
  182. key_ctrl.click_count++;
  183. key_ctrl.state = KEY_CONTINUE;
  184. }
  185. }
  186. }
  187. }
  188. }
  189. }
  190. void check_keyShortValid(void) {
  191. volatile uint32_t temp;
  192. /* To check if PB.2 interrupt occurred */
  193. if (key_ctrl.state == KEY_SHORT) {
  194. if ((conter10ms - key_ctrl.release_tick) > CONTINUOUS_INTERVAL * 2) {
  195. key_ctrl.key_valid_flag = 1;
  196. }
  197. }
  198. if (sw_st != SWING_IDLE && key_ctrl.press_tick) {
  199. if ((conter10ms - key_ctrl.press_tick) > USER_STOP_TIMER) {
  200. key_ctrl.state = KEY_END;
  201. key_ctrl.key_valid_flag = 1;
  202. key_ctrl.press_tick = 0;
  203. }
  204. }
  205. }
  206. /**
  207. * @brief GPIO PC/PD/PE/PF IRQ
  208. *
  209. * @param None
  210. *
  211. * @return None
  212. *
  213. * @details The PC/PD/PE/PF default IRQ, declared in startup_M031Series.s.
  214. */
  215. void OPTO_IRQHandler(void) {
  216. //
  217. // volatile unsigned int temp;
  218. /* To check if PB.2 interrupt occurred */
  219. {
  220. conter10ms = sysinf.conter10ms;
  221. switch(sw_st){
  222. case FIND_GAPNUM:{
  223. if (Read_Motor()){
  224. intoGap = TIMER_GetCounter();
  225. }else{
  226. OutGap = TIMER_GetCounter();
  227. if((conter10ms - startFindHometime) > MOTOR_LOOP_TIM){
  228. if(MAX_RUNCNT > timerconter){
  229. if(OutGap > intoGap){
  230. timerBuf[timerconter++] = OutGap - intoGap;
  231. }else{
  232. timerBuf[timerconter++] = OutGap + 0x10000 - intoGap;
  233. }
  234. if(MAX_RUNCNT == timerconter){
  235. Bubble_Sort(timerBuf,MAX_RUNCNT);
  236. judgeGap = 0;
  237. if(timerBuf[0]*1.25<timerBuf[1]){
  238. judgeGap = timerBuf[0]+timerBuf[0];
  239. }else{
  240. judgeGap = timerBuf[1]+timerBuf[0];
  241. }
  242. // for(unsigned int i =0;i<(MAX_RUNCNT/2);i++){
  243. // judgeGap += timerBuf[i];
  244. // }
  245. judgeGap =judgeGap*0.625;
  246. timerBuf[timerconter++] = judgeGap ;
  247. /*判决门限为最低两个值均值的1.5倍*/
  248. }
  249. }else{
  250. if(OutGap > intoGap){
  251. curGap = OutGap - intoGap;
  252. }else{
  253. curGap = OutGap + 0x10000 - intoGap;
  254. }
  255. timerBuf[timerconter++] = curGap ;
  256. if(curGap > judgeGap){
  257. sw_st = FIND_HOMEGAP;
  258. SetMotorPwm(MOTOR_REV, 0);
  259. SetMotorPwm(MOTOR_FWD, 0);
  260. stateFistin = 1;
  261. checkPWM = checkPWM*0.8; /*降速便于复位*/
  262. findhomedir = (MOTOR_DIR)!findhomedir;
  263. }
  264. if(timerconter==sizeof(timerBuf)){
  265. SetMotorPwm(MOTOR_REV, 0);
  266. SetMotorPwm(MOTOR_FWD, 0);
  267. timerconter = 0;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. break;
  274. case FIND_HOMEGAP:{
  275. /*找远点阶段,光开亮停止*/
  276. if (Read_Motor()){
  277. SetMotorPwm(MOTOR_REV, 0);
  278. SetMotorPwm(MOTOR_FWD, 0);
  279. intoGapFlag = 1;
  280. intoGap = TIMER_GetCounter();
  281. }
  282. }
  283. break;
  284. case SWING_LOOP:{
  285. /*找远点阶段,光开亮停止*/
  286. if(startLoopConter > 0){
  287. startLoopConter --;
  288. }else{
  289. if (Read_Motor()){
  290. SetMotorPwm(MOTOR_REV, 0);
  291. SetMotorPwm(MOTOR_FWD, 0);
  292. intoGapFlag = 1;
  293. intoGap = TIMER_GetCounter();
  294. }
  295. }
  296. }break;
  297. default:{
  298. SetMotorPwm(MOTOR_REV, 0);
  299. SetMotorPwm(MOTOR_FWD, 0);
  300. // sw_st = FIND_GAPNUM;
  301. // stateFistin = 1;
  302. }break;
  303. }
  304. }
  305. }
  306. /**
  307. * @brief Motor_Init
  308. *
  309. * @param init key and optic input
  310. *
  311. * @return None
  312. *
  313. * @details
  314. */
  315. void Motor_Init()
  316. {
  317. key_ctrl.last_level = 1;
  318. timeinner = sysinf.timeinner;
  319. swingspeed = sysinf.swingspeed;
  320. swingtime =sysinf.swingtime;
  321. swingtimeRight =sysinf.swingtimeRight;
  322. swingtimePause =sysinf.swingtimePause;
  323. runLoopTime = sysinf.runLoopTime;
  324. runLoopSpeed =sysinf.runLoopSpeed;
  325. }
  326. /**
  327. * @brief Motor_mix
  328. *
  329. * @param init key and optic input
  330. *
  331. * @return 0正常,1没离开光开,2,没回到光开
  332. *
  333. * @details 设置夹爪转动参数。
  334. */
  335. uint32_t Motor_mix(uint32_t time, uint32_t speed, uint32_t swing,
  336. uint32_t timeRight, uint32_t timePause) {
  337. timeinner = time;
  338. swingtime = swing;
  339. swingspeed = speed;
  340. swingtimeRight = timeRight;
  341. swingtimePause = timePause;
  342. // timeinner = time - time % (swing + timeRight);
  343. // curtimeinner = timeinner;
  344. if (speed == 0) {
  345. swingspeed = MOTOR_CHECK_SPEED;
  346. }
  347. curtimeinner = sysinf.conter10ms;
  348. sw_st = SWING_LOOP;
  349. stateFistin = 1;
  350. return 0;
  351. }
  352. /**
  353. * @brief Motor_deal_key
  354. *
  355. * @param 按键处理,短按,左右摇;连续点击,转圈摇;长按,复位;
  356. *
  357. * @return 0正常,1没离开光开,2,没回到光开
  358. *
  359. * @details 夹爪根据。
  360. */
  361. uint32_t Motor_deal_key(swing_state_def st, KeyState key) {
  362. if (st == SWING_IDLE) {
  363. switch (key) {
  364. case KEY_SHORT:
  365. curtimeinner = conter10ms;
  366. sw_st = SWING_LOOP;
  367. startLoopConter = 2;
  368. stateFistin = 1;
  369. backOptFlag = 1;
  370. findhomedir = MOTOR_REV;
  371. break;
  372. // case KEY_CONTINUE:
  373. // curtimeinner = conter10ms;
  374. // sw_st = LOOP_START;
  375. // stateFistin = 1;
  376. // break;
  377. case KEY_LONG:
  378. curtimeinner = conter10ms;
  379. sw_st = FIND_GAPNUM;
  380. stateFistin = 1;
  381. break;
  382. default:
  383. break;
  384. }
  385. }
  386. if (key == KEY_LONG || key == KEY_END ) {
  387. sw_st = FIND_GAPNUM;
  388. stateFistin = 1;
  389. resetFromSwingFlag = 0;
  390. }
  391. return 0;
  392. }
  393. /**
  394. * @brief Motor_mix_work
  395. *
  396. * @param init key and optic input
  397. *
  398. * @return 0正常,1没离开光开,2,没回到光开
  399. *
  400. * @details 夹爪根据。
  401. */
  402. uint32_t Motor_mix_work(void) {
  403. static uint32_t last10ms;
  404. static uint32_t firstINGap;
  405. static uint32_t powerOnFlag = 1;
  406. check_keyShortValid();
  407. if(powerOnFlag){
  408. powerOnFlag = 0;
  409. // Motor_Check(0);
  410. resetFromSwingFlag = 0;
  411. sw_st = FIND_GAPNUM;
  412. stateFistin = 1;
  413. }
  414. conter10ms = sysinf.conter10ms;
  415. if (key_ctrl.key_valid_flag) {
  416. key_ctrl.key_valid_flag = 0;
  417. Motor_deal_key(sw_st, key_ctrl.state);
  418. key_ctrl.state = KEY_IDLE;
  419. }
  420. if(sw_st == SWING_ERR){
  421. /*电机故障,不执行操作*/
  422. return 0;
  423. }
  424. switch (sw_st) {
  425. case SWING_IDLE: {
  426. SetMotorPwm(MOTOR_REV, 0);
  427. SetMotorPwm(MOTOR_FWD, 0);
  428. } break;
  429. case FIND_GAPNUM: {
  430. if (stateFistin) {
  431. timerconter = 0;
  432. intoGap = 0;
  433. OutGap = 0;
  434. lastGap = 0;
  435. judgeGap = 0;
  436. HAL_TIM_Base_Stop(&htim4);
  437. HAL_TIM_Base_Start(&htim4);
  438. last10ms = conter10ms;
  439. stateFistin = 0;
  440. startFindHometime = conter10ms;
  441. findhomedir = MOTOR_REV;
  442. checkPWM = swingspeed;
  443. SetMotorPwm(findhomedir, checkPWM);
  444. } else {
  445. if (((conter10ms - last10ms) > MOTOR_LOOP_TIM*4 )&&(timerconter < MAX_RUNCNT)) {
  446. /*电机不动,返回报错*/
  447. SetMotorPwm(MOTOR_REV, 0);
  448. sw_st = SWING_ERR;
  449. // error_set(ERROR_MOTOR_FIALED);
  450. return 1;
  451. }
  452. }
  453. } break;
  454. case FIND_HOMEGAP: {
  455. if (stateFistin) {
  456. last10ms = conter10ms;
  457. stateFistin = 0;
  458. intoGapFlag = 0;
  459. firstINGap = 0;
  460. SetMotorPwm(findhomedir, checkPWM);
  461. } else {
  462. if (!intoGapFlag && (conter10ms - last10ms) > MOTOR_LOOP_TIM) {
  463. /*电机来回不动,返回报错*/
  464. stateFistin = 1;
  465. checkPWM = checkPWM/0.85; /*降速便于复位*/
  466. }
  467. if(intoGapFlag){
  468. if(!firstINGap){
  469. /*进入缝隙,置位,延时判读*/
  470. firstINGap = 1;
  471. last10ms = conter10ms;
  472. }else{
  473. if((conter10ms - last10ms) > MOTOR_MOVEFORM_OPTIC_TIM){
  474. if(Read_Motor()){
  475. sw_st = SWING_IDLE;
  476. stateFistin = 1;
  477. findHome = 1;
  478. }
  479. else{
  480. sw_st = FIND_HOMEGAP;
  481. stateFistin = 1;
  482. findhomedir = (MOTOR_DIR)!findhomedir;
  483. checkPWM = checkPWM*0.9; /*降速便于复位*/
  484. }
  485. }
  486. }
  487. }
  488. }
  489. } break;
  490. case LOOP_START: {
  491. if (stateFistin) {
  492. SetMotorPwm(MOTOR_REV, runLoopSpeed);
  493. last10ms = conter10ms;
  494. stateFistin = 0;
  495. } else {
  496. if ((conter10ms - last10ms) == (runLoopTime)) {
  497. SetMotorPwm(MOTOR_REV, 0);
  498. SetMotorPwm(MOTOR_FWD, 0);
  499. }
  500. if ((conter10ms - last10ms) >= (runLoopTime + swingtimePause)) {
  501. sw_st = LOOP_END;
  502. stateFistin = 1;
  503. REVORFWD = 0;
  504. }
  505. }
  506. } break;
  507. case LOOP_END: {
  508. sw_st = FIND_GAPNUM;
  509. stateFistin = 1;
  510. REVORFWD = 1;
  511. } break;
  512. case SWING_LOOP: {
  513. if (stateFistin ) {
  514. /**/
  515. if(backOptFlag){
  516. if(swingtime< (conter10ms - swingStoptime)){
  517. checkPWM = swingspeed;
  518. backOptFlag = 0;
  519. SetMotorPwm(findhomedir, checkPWM);
  520. stateFistin = 0;
  521. last10ms = conter10ms;
  522. swingHigStopflage = 0;
  523. }
  524. }else{
  525. SetMotorPwm(findhomedir, checkPWM);
  526. stateFistin = 0;
  527. last10ms = conter10ms;
  528. swingHigStopflage = 0;
  529. }
  530. intoGapFlag = 0;
  531. firstINGap = 0;
  532. } else{
  533. if (!intoGapFlag && (conter10ms - last10ms) > MOTOR_LOOP_TIM) {
  534. /*速度过底,电机回不来*/
  535. backOptFlag = 1;
  536. swingStoptime = conter10ms;
  537. findhomedir = MOTOR_REV;
  538. stateFistin = 1;
  539. }
  540. if(intoGapFlag){
  541. if(!firstINGap){
  542. /*进入缝隙,置位,延时判读*/
  543. firstINGap = 1;
  544. last10ms = conter10ms;
  545. }else{
  546. if((conter10ms - last10ms) > MOTOR_MOVEFORM_OPTIC_TIM){
  547. stateFistin = 1;
  548. if(Read_Motor()){
  549. backOptFlag = 1;
  550. swingStoptime = conter10ms;
  551. findhomedir = MOTOR_REV;
  552. }
  553. else{
  554. findhomedir = (MOTOR_DIR)!findhomedir;
  555. checkPWM = checkPWM*0.9; /*降速便于复位*/
  556. }
  557. }
  558. }
  559. }
  560. if ((conter10ms - curtimeinner) > (timeinner)){
  561. resetFromSwingFlag = 0;
  562. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
  563. __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
  564. timerconter = 0;
  565. memset(timerBuf,0,sizeof(timerBuf));
  566. stateFistin = 1;
  567. sw_st = FIND_GAPNUM;
  568. }
  569. }
  570. } break;
  571. default:
  572. sw_st = SWING_ERR;
  573. break;
  574. }
  575. return 0;
  576. }
  577. /**
  578. * @brief Motor_mix
  579. *
  580. * @param init key and optic input
  581. *
  582. * @return 空闲返回1 其他返回0
  583. *
  584. * @details 设置夹爪转动参数。
  585. */
  586. uint32_t Motor_idle() {
  587. return(sw_st == SWING_IDLE);
  588. }
  589. uint32_t print_home_time() {
  590. if(findHome){
  591. findHome = 0;
  592. Van_Device_Printf(VAN_LOG_NOTICE,"gap:%d ",timerconter);
  593. if(timerconter > sizeof(timerBuf)){
  594. timerconter = sizeof(timerBuf);
  595. }
  596. for(unsigned int i=0;i<timerconter;i++){
  597. Van_Device_Printf(VAN_LOG_NOTICE," %d ",timerBuf[i]);
  598. }
  599. Van_Device_Printf(VAN_LOG_NOTICE,"\n");
  600. }
  601. return 0;
  602. }