process.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. #include "process.h"
  2. #include "gpio.h"
  3. #include "ac780x_gpio.h"
  4. #include "string.h"
  5. #include "adc.h"
  6. #include "Motor.h"
  7. #include "W25Q64.h"
  8. #include "AngleSensor.h"
  9. #include "motor_control.h"
  10. #include "cfg.h"
  11. #include "Rtcx.h"
  12. #include "storage.h"
  13. #include "IB_Reader.h"
  14. #include "math.h"
  15. uint8_t g_devicebusy = 0;
  16. uint16_t g_blinkLedTime = 0; /*LED闪烁频率控制时间*/
  17. uint16_t g_blinkLedTgtTime = BLINK_LED_DFTT; /*LED目标闪烁频率*/
  18. uint16_t g_period1000ms = 0;
  19. uint8_t g_detectTime = 0; /*状态检测时间*/
  20. uint16_t g_angleRead_Interval = 5; //读取编码器角度间隔
  21. uint16_t g_angleRead_Count = 0; //读取编码器角度计数
  22. uint32_t g_poweroff_count = 0; /*外部电源停止后、每秒计数加1*/
  23. #define STATUS_DETECTINTERVAL (10) /*10ms */
  24. uint8_t g_runstate; //运行状态,切换LED灯光
  25. uint8_t g_lockstatus = STATUS_UNKOWN;
  26. uint8_t g_coverstatus = STATUS_COVERCLOSE;
  27. //电机状态
  28. uint8_t g_motorstate = MOTOR_INIT;
  29. uint8_t g_runReady = 0;
  30. uint16_t g_runTime = 0;
  31. static float g_target_position = 0; // 动作时,PID目标位置
  32. static uint8_t g_motor_dir = MOTOR_TUNR_NULL; // 电机动作时的转动方向 ,0 不动 1 正向, 2 反向
  33. //状态持续计数,用来起到滤波作用
  34. //uint8_t tmp_status;
  35. uint8_t g_lockcount[STATUS_LOCKALL]={0};
  36. uint8_t g_covercount[STATUS_COVERALL]={0};
  37. static float s_angle = 0.0;
  38. //static float tmp_angle = 0.0;
  39. static uint8_t get_lockstatus(void);
  40. //static PID g_pid = {0};
  41. //static uint8_t tmp_speed;
  42. static uint8_t tmp_pwmout;
  43. //static uint8_t tmp_time = 0;
  44. static void update_runstate()
  45. {
  46. switch(g_lockstatus){
  47. case STATUS_INTERMEDIATE:
  48. g_runstate = STATE_INTERMEDIATE;
  49. break;
  50. case STATUS_LOCK:
  51. g_runstate = STATE_LOCK;
  52. break;
  53. case STATUS_UNLOCK:
  54. g_runstate = STATE_UNLOCK;
  55. break;
  56. case STATUS_SAMPLE:
  57. g_runstate = STATE_SAMPLE;
  58. break;
  59. case STATUS_UNKOWN:
  60. g_runstate = STATE_EXCEPTION;
  61. break;
  62. default:
  63. break;
  64. };
  65. }
  66. void Process_Init(void)
  67. {
  68. /*初始化控制变量.*/
  69. g_blinkLedTime = 0;
  70. g_blinkLedTgtTime = BLINK_LED_DFTT;
  71. g_detectTime = 0;
  72. g_runstate = STATE_LOCK;
  73. g_angleRead_Interval = 500;
  74. g_angleRead_Count = 0;
  75. s_angle = AngleSensor_GetAngle();
  76. g_lockstatus=get_lockstatus();
  77. g_coverstatus=Gpio_IsOpenCover()>0?STATUS_COVEROPEN:STATUS_COVERCLOSE;
  78. g_motorstate = MOTOR_READY;
  79. /*上电默认LED点亮.*/
  80. update_runstate();
  81. }
  82. void Process_RunPrd(void)
  83. {
  84. /*周期性地检查LED闪烁,LED2和LED3同时闪烁.*/
  85. if (g_blinkLedTime >= g_blinkLedTgtTime)
  86. {
  87. g_blinkLedTime = 0;
  88. g_blinkLedTgtTime = BLINK_LED_DFTT;
  89. update_runstate();
  90. switch(g_runstate){
  91. case STATE_LOCK:
  92. REDLED_OFF;
  93. GREENLED_TOGGLE;
  94. break;
  95. case STATE_UNLOCK:
  96. GREENLED_OFF;
  97. REDLED_TOGGLE;
  98. break;
  99. case STATE_INTERMEDIATE:
  100. REDGREEN_TOGGLE;
  101. break;
  102. case STATE_SAMPLE:
  103. REDLED_OFF;
  104. GREENLED_TOGGLE;
  105. g_blinkLedTgtTime = 200;
  106. break;
  107. case STATE_OPENCOVER:
  108. REDLED_OFF;
  109. GREENLED_ON;
  110. break;
  111. case STATE_EXCEPTION:
  112. default:
  113. GREENLED_OFF;
  114. REDLED_ON;
  115. break;
  116. };
  117. //printADCValue();
  118. //printMotorCurrent();
  119. //printf(" Motor Current:%f mA \r\n", getMotorCurrent());
  120. //W25Q64_PrintInfo();
  121. //AngleSensor_PrintInfo();
  122. }
  123. //
  124. if(g_period1000ms >= 1000){
  125. g_period1000ms=0;
  126. //Storage_CountReduce();
  127. //g_poweroff_count++;
  128. // if(Gpio_IsDC24()){
  129. // printf(" DC24 Supply \r\n");
  130. //
  131. // }else{
  132. // printf(" Battery Supply \r\n");
  133. //
  134. // }
  135. printMotorCurrent();
  136. //printf(" Battery Voltage:%f V \r\n", getBatteryVoltage());
  137. //RTCx_PrintDateTime();
  138. //AngleSensor_PrintInfo();
  139. //IB_Print();
  140. }
  141. /*
  142. //10ms
  143. if(g_detectTime >= 10){
  144. g_detectTime = 0;
  145. //锁状态
  146. _status=get_lockstatus();
  147. for(i=0; i<STATUS_LOCKALL; i++){
  148. if(_status == i){
  149. g_lockcount[i]++;
  150. if(g_lockcount[i] >= 5){
  151. g_lockstatus = i;
  152. }
  153. }else{
  154. g_lockcount[i]=0;
  155. }
  156. }
  157. //上盖状态
  158. _status=Gpio_IsOpenCover()>0?STATUS_COVEROPEN:STATUS_COVERCLOSE;
  159. for(i=0; i<STATUS_COVERALL; i++){
  160. if(_status == i){
  161. g_covercount[i]++;
  162. if(g_covercount[i] >= 10){
  163. g_coverstatus = i;
  164. }
  165. }else{
  166. g_covercount[i]=0;
  167. }
  168. }
  169. }
  170. */
  171. }
  172. static uint8_t get_motor_dir(float target){
  173. if(target > s_angle ){
  174. return MOTOR_TUNR_P; // 正转
  175. }else if(target < s_angle){
  176. return MOTOR_TUNR_N; // 反转
  177. }
  178. return MOTOR_TUNR_NULL;
  179. }
  180. void Process_Timer1_CB(void)
  181. {
  182. if (g_blinkLedTime < 0xFFFF)
  183. {
  184. g_blinkLedTime++;
  185. }
  186. if(g_detectTime < 0xFF){
  187. g_detectTime++;
  188. }
  189. if(g_runReady){
  190. g_runTime++;
  191. }
  192. if(g_period1000ms < 0xFFFF)
  193. {
  194. g_period1000ms++;
  195. }
  196. g_angleRead_Count++;
  197. if(g_angleRead_Count >= g_angleRead_Interval){
  198. g_angleRead_Count=0;
  199. AngleSensor_Read();
  200. }
  201. }
  202. void Process_Timer0_CB(void)
  203. {
  204. AngleSensor_Read();
  205. //s_angle = AngleSensor_GetAngle();
  206. // if(s_angle < 0){ //处理异常
  207. // if((MOTOR_READY != g_motorstate) && (MOTOR_STOPED != g_motorstate)){
  208. // Motor_Brake();
  209. // g_motorstate = MOTOR_STOPED;
  210. // g_runReady =1;
  211. // g_runTime=0;
  212. // }
  213. // }
  214. //
  215. // g_lockstatus=get_lockstatus();
  216. // g_coverstatus=Gpio_IsOpenCover()>0?STATUS_COVEROPEN:STATUS_COVERCLOSE;
  217. //
  218. // //处理开关锁
  219. // switch(g_motorstate){
  220. // case MOTOR_READY:
  221. // break;
  222. // case MOTOR_LOCKING:
  223. // if(/*(STATUS_LOCK == g_lockstatus)|| */(STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
  224. // Motor_Brake();
  225. // g_motorstate = MOTOR_STOPED;
  226. // g_runReady =1;
  227. // g_runTime=0;
  228. // }else{
  229. // PID_Calc(&g_pid, config->lock_threshold+3, s_angle);
  230. //
  231. // if(g_pid.error > 0){
  232. // tmp_speed =(uint8_t)(g_pid.output);
  233. // tmp_speed = tmp_speed<30?30:tmp_speed;
  234. // Motor_Positive(tmp_speed);
  235. //
  236. // }else{
  237. // Motor_Brake();
  238. // g_motorstate = MOTOR_STOPED;
  239. // g_runReady =1;
  240. // g_runTime=0;
  241. // }
  242. //
  243. // }
  244. //
  245. // break;
  246. // case MOTOR_UNLOCKING:
  247. // if(/*(STATUS_UNLOCK == g_lockstatus)|| */(STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
  248. // Motor_Brake();
  249. // g_motorstate = MOTOR_STOPED;
  250. // g_runReady =1;
  251. // g_runTime=0;
  252. // }else{
  253. // PID_Calc(&g_pid, config->unlock_threshold-3, s_angle);
  254. //
  255. // if(g_pid.error < 0){
  256. // tmp_speed =(uint8_t)(-g_pid.output);
  257. // tmp_speed = tmp_speed<30?30:tmp_speed;
  258. // Motor_Negative(tmp_speed);
  259. //
  260. // }else{
  261. // Motor_Brake();
  262. // g_motorstate = MOTOR_STOPED;
  263. // g_runReady =1;
  264. // g_runTime=0;
  265. // }
  266. //
  267. // }
  268. // break;
  269. //
  270. // case MOTOR_SAMPLEING:
  271. // if(/*(STATUS_SAMPLE == g_lockstatus)|| */(STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
  272. // Motor_Brake();
  273. // g_motorstate = MOTOR_STOPED;
  274. // g_runReady =1;
  275. // g_runTime=0;
  276. // }else{
  277. // PID_Calc(&g_pid, g_sample_position, s_angle);
  278. //
  279. // if(g_pid.error < 0){
  280. // tmp_speed =(uint8_t)(-g_pid.output);
  281. // tmp_speed = tmp_speed<30?30:tmp_speed;
  282. // Motor_Negative(tmp_speed);
  283. //
  284. // }else{
  285. // Motor_Brake();
  286. // g_motorstate = MOTOR_STOPED;
  287. // g_runReady =1;
  288. // g_runTime=0;
  289. // }
  290. //
  291. // }
  292. // break;
  293. // case MOTOR_STOPED:
  294. // if(g_runTime >= 5000){ //5S
  295. // g_motorstate = MOTOR_READY;
  296. // }
  297. //
  298. // break;
  299. // default:
  300. // break;
  301. // };
  302. //
  303. }
  304. void Process_MotorControl(float angle)
  305. {
  306. //printf("P_M angle: %f \r\n", angle);
  307. s_angle = angle;
  308. if(s_angle < 0){ //处理异常
  309. if((MOTOR_READY != g_motorstate) && (MOTOR_STOPED != g_motorstate)){
  310. Motor_Brake();
  311. g_motorstate = MOTOR_STOPED;
  312. g_runReady =1;
  313. g_runTime=0;
  314. }
  315. }
  316. g_lockstatus=get_lockstatus();
  317. g_coverstatus=Gpio_IsOpenCover()>0?STATUS_COVEROPEN:STATUS_COVERCLOSE;
  318. //处理开关锁
  319. switch(g_motorstate){
  320. case MOTOR_READY:
  321. break;
  322. case MOTOR_LOCKING:
  323. if(/*(STATUS_LOCK == g_lockstatus)|| */(STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
  324. Motor_Brake();
  325. g_motorstate = MOTOR_STOPED;
  326. g_runReady =1;
  327. g_runTime=0;
  328. }else{
  329. if(angle < g_target_position){
  330. tmp_pwmout = MC_Calculate(g_target_position, angle, getMotorCurrent());
  331. if(MOTOR_TUNR_P == g_motor_dir){
  332. Motor_Positive(tmp_pwmout);
  333. }else if(MOTOR_TUNR_N == g_motor_dir){
  334. Motor_Negative(tmp_pwmout);
  335. }
  336. }else{
  337. Motor_Brake();
  338. g_motorstate = MOTOR_STOPED;
  339. g_runReady =1;
  340. g_runTime=0;
  341. }
  342. }
  343. break;
  344. case MOTOR_UNLOCKING:
  345. if(/*(STATUS_UNLOCK == g_lockstatus)|| */(STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
  346. Motor_Brake();
  347. g_motorstate = MOTOR_STOPED;
  348. g_runReady =1;
  349. g_runTime=0;
  350. }else{
  351. if(angle > g_target_position){
  352. tmp_pwmout = MC_Calculate(g_target_position, angle, getMotorCurrent());
  353. if(MOTOR_TUNR_P == g_motor_dir){
  354. Motor_Positive(tmp_pwmout);
  355. }else if(MOTOR_TUNR_N == g_motor_dir){
  356. Motor_Negative(tmp_pwmout);
  357. }
  358. }else{
  359. Motor_Brake();
  360. g_motorstate = MOTOR_STOPED;
  361. g_runReady =1;
  362. g_runTime=0;
  363. }
  364. }
  365. break;
  366. case MOTOR_SAMPLEING:
  367. if(/*(STATUS_SAMPLE == g_lockstatus)|| */(STATUS_UNKOWN == g_lockstatus) ||(g_runTime >= 2000)){
  368. Motor_Brake();
  369. g_motorstate = MOTOR_STOPED;
  370. g_runReady =1;
  371. g_runTime=0;
  372. }else{
  373. if(angle > g_target_position){
  374. tmp_pwmout = MC_Calculate(g_target_position, angle, getMotorCurrent());
  375. if(MOTOR_TUNR_P == g_motor_dir){
  376. Motor_Positive(tmp_pwmout);
  377. }else if(MOTOR_TUNR_N == g_motor_dir){
  378. Motor_Negative(tmp_pwmout);
  379. }
  380. }else{
  381. Motor_Brake();
  382. g_motorstate = MOTOR_STOPED;
  383. g_runReady =1;
  384. g_runTime=0;
  385. }
  386. }
  387. break;
  388. case MOTOR_STOPED:
  389. if(g_runTime >= 5000){ //5S
  390. g_motorstate = MOTOR_READY;
  391. g_angleRead_Interval = 500;
  392. }
  393. g_angleRead_Interval = 200;
  394. break;
  395. default:
  396. break;
  397. };
  398. }
  399. uint8_t get_lockstatus(void)
  400. {
  401. static float _tmpf_min=0;
  402. static float _tmpf_max = 0;
  403. uint8_t status = STATUS_UNKOWN;
  404. if(s_angle<0){
  405. return status;
  406. }
  407. if((config->lock_threshold - config->unlock_threshold) > 10.0){
  408. if((s_angle > config->lock_threshold)){
  409. status = STATUS_LOCK;
  410. }else if(s_angle < config->unlock_threshold){
  411. status = STATUS_UNLOCK;
  412. }else {
  413. if(fabsf(config->sample_threshold1 - config->sample_threshold2) > 10.0 )
  414. {
  415. if(config->sample_threshold1 > config->sample_threshold2){
  416. _tmpf_max = config->sample_threshold1;
  417. _tmpf_min = config->sample_threshold2;
  418. }else{
  419. _tmpf_max = config->sample_threshold2;
  420. _tmpf_min = config->sample_threshold1;
  421. }
  422. if((s_angle > _tmpf_min) && (s_angle < _tmpf_max)){
  423. status = STATUS_SAMPLE;
  424. }else{
  425. status = STATUS_INTERMEDIATE;
  426. }
  427. }else{ //不支持取样
  428. status = STATUS_INTERMEDIATE;
  429. }
  430. }
  431. }
  432. return status;
  433. }
  434. uint8_t Process_GetLockStatus(void)
  435. {
  436. return get_lockstatus();
  437. }
  438. uint8_t Process_GetCoverStatus(void)
  439. {
  440. if(Gpio_IsOpenCover()){
  441. return STATUS_COVEROPEN;
  442. }else{
  443. return STATUS_COVERCLOSE;
  444. }
  445. }
  446. uint8_t Process_OpLock(uint8_t speed)
  447. {
  448. if((MOTOR_READY == g_motorstate) && (STATUS_LOCK != g_lockstatus)){
  449. g_motorstate = MOTOR_LOCKING;
  450. g_runReady =1;
  451. g_runTime=0;
  452. g_angleRead_Interval = 5;
  453. g_target_position = config->lock_threshold+3;
  454. MC_Init(s_angle);
  455. g_motor_dir = get_motor_dir(g_target_position);
  456. printf("Process_OpLock\r\n");
  457. }
  458. return 0;
  459. }
  460. uint8_t Process_OpUnlock(uint8_t speed)
  461. {
  462. // uint8_t id = 0;
  463. if((MOTOR_READY == g_motorstate) && (STATUS_UNLOCK != g_lockstatus)){
  464. g_motorstate = MOTOR_UNLOCKING;
  465. g_runReady =1;
  466. g_runTime=0;
  467. g_angleRead_Interval = 5;
  468. g_target_position = config->unlock_threshold-3;
  469. MC_Init(s_angle);
  470. g_motor_dir = get_motor_dir(g_target_position);
  471. printf("Process_OpUnlock\r\n");
  472. }
  473. return 0;
  474. }
  475. uint8_t Process_OpSample(uint8_t speed)
  476. {
  477. // uint8_t id = 0;
  478. // 参数不符合要求
  479. if(fabsf(config->sample_threshold1 - config->sample_threshold2) <= 10.0 ){
  480. return 0;
  481. }
  482. if((MOTOR_READY == g_motorstate) && (STATUS_LOCK == g_lockstatus)){
  483. g_motorstate = MOTOR_SAMPLEING;
  484. g_runReady =1;
  485. g_runTime=0;
  486. g_angleRead_Interval = 5;
  487. g_target_position = (config->sample_threshold1 + config->sample_threshold2)/2;
  488. MC_Init(s_angle);
  489. g_motor_dir = get_motor_dir(g_target_position);
  490. printf("Process_OpSample \r\n");
  491. }
  492. return 0;
  493. }
  494. float Process_GetAngle(void)
  495. {
  496. return s_angle;
  497. }
  498. uint8_t Process_AngleCalibration(void)
  499. {
  500. float angle_raw = AngleSensor_GetAngleRaw();
  501. if(angle_raw >= 0){
  502. config->angle_offset = (200 - angle_raw);
  503. AngleSensor_Setoffset(config->angle_offset);
  504. }
  505. return 0;
  506. }
  507. uint8_t Process_CalibrationThreshold(uint8_t param)
  508. {
  509. if(0 == param){
  510. config->unlock_threshold = s_angle;
  511. }else if(1 == param){
  512. config->lock_threshold = s_angle;
  513. }else if(2 == param){
  514. config->sample_threshold1 = s_angle;
  515. }else if(3 == param){
  516. config->sample_threshold2 = s_angle;
  517. }
  518. return 0x00;
  519. }
  520. void Process_Storage(void)
  521. {
  522. static uint8_t pre_lstatus = STATUS_INTERMEDIATE;
  523. static uint8_t pre_cstatus = STATUS_COVEROPEN;
  524. if(Gpio_IsDC24()){
  525. pre_lstatus = g_lockstatus;
  526. pre_cstatus = g_coverstatus;
  527. }else{
  528. if(pre_lstatus != g_lockstatus){
  529. if(STATUS_LOCK == g_lockstatus){
  530. Storage_AddItem(ITEM_RECORD, EVENT_MANUAL_LOCK);
  531. }else if(STATUS_UNLOCK == g_lockstatus){
  532. Storage_AddItem(ITEM_RECORD, EVENT_MANUAL_UNLOCK);
  533. }
  534. pre_lstatus = g_lockstatus;
  535. }
  536. if(pre_cstatus != g_coverstatus){
  537. if(STATUS_COVEROPEN == g_coverstatus){
  538. Storage_AddItem(ITEM_RECORD, EVENT_OPENCOVER);
  539. }
  540. pre_cstatus = g_coverstatus;
  541. }
  542. }
  543. }
  544. void Process_Poweroff(void)
  545. {
  546. static float battery_v = 0.0;
  547. if(Gpio_IsDC24()){
  548. g_poweroff_count = 0;
  549. }else{
  550. battery_v = getBatteryVoltage();
  551. if((g_poweroff_count >= 2*60*60) || (battery_v < (3.3))){ // 2小时后或电池电压小于3.3V 关机
  552. g_poweroff_count = 0;
  553. Storage_Save();
  554. mdelay(500);
  555. LDOEn_DISABLE;
  556. //NVIC_SystemReset();
  557. //printf(" NVIC_SystemReset \r\n");
  558. }
  559. }
  560. }
  561. void Process_MotorP(uint8_t speed)
  562. {
  563. if(speed > 0){
  564. Motor_Positive(speed);
  565. }else{
  566. Motor_Brake();
  567. }
  568. }
  569. void Process_MotorN(uint8_t speed)
  570. {
  571. if(speed > 0){
  572. Motor_Negative(speed);
  573. }else{
  574. Motor_Brake();
  575. }
  576. }