久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 18789|回復: 18
打印 上一主題 下一主題
收起左側

51單片機的6自由度機械臂 16路舵機控制 源碼

  [復制鏈接]
跳轉到指定樓層
樓主
這是我畢設的源碼 16路舵機控制實現6自由度機械臂控制,采用的是51單片機。


完整源碼下載:
6自由度手臂源代碼.rar (589.48 KB, 下載次數: 344)


單片機主程序:
  1. /***************************************************************************************************************
  2. 文 件 名:main.c  
  3. 功能描述:
  4. 備    注: 16路舵機控制
  5. ****************************************************************************************************************/
  6. #include "STC15Fxxxx.H"  //STC15系列單片機
  7. #include <intrins.h>
  8. #include "UART.H"
  9. #include "timer.h"
  10. #include "util.h"
  11. #include "ps2/ps2.h"
  12. #include "flash/flash.h"//頭文件
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include "LED/led.h"
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include "adc/adc.h"
  19. extern uint8 flag_p;
  20. extern bit flag_RecFul;
  21. //extern uchar KEY[9];
  22. uint16 pos[7][MOTOR_NUM]={ {1000,1500,1500,1500,1500,1500,1500,1500,1500},
  23.                                          {1000,1500,1500,1500,1500,1500,1500,1500,1500},
  24.                                          {1000,1500,1500,1500,1500,1500,1500,1500,1500},
  25.                                          {1000,500,500,500,500,500,500,500,500},
  26.                                          {1000,1500,1500,1500,1500,1500,1500,1500,1500},
  27.                                          {1000,500,500,500,500,500,500,500,500},
  28.                                          {1000,1500,1500,1500,1500,1500,1500,1500,1500}
  29. };         //位置
  30. uint16 pwm[MOTOR_NUM]=    {1500,1500,1500,1500,1500,1500,1500,1500,1500};
  31. uint16 UartRec[MOTOR_NUM]={1500,1500,1500,1500,1500,1500,1500,1500,1500};
  32. uint8 redata[257] = {0};    // 定義接收數據變量數組
  33. uint8 line=0;                                        //緩存存入口與出口之間的距離,即當前緩存中有多少個沒有執行的數據
  34. uint8 point_now=0;                                //與point_aim一起標記緩存出口位置,即取數位置
  35. uint8 point_aim=1;
  36. uint8 point_in=2;                                //標記緩存入口位置,即上一行數據存放位置
  37. bit flag_connect = 0;
  38. bit flag_stop=1;                                //表示一行執行結束
  39. uint8 flag_vpwm=0;                                //表示到達了該更新pwm[]的時間
  40. bit flag_in=1;                                         //表示緩存中有空閑空間
  41. bit flag_out=0;                                        //表示緩存中有可執行數據的標志位
  42. bit flag_run_ready=0;                        //表示有要要放入緩存的EErom數據
  43. uint16 n=1000;                                        //用來計算需要建立多少個中間數據
  44. uint16 m=1;                                                //用來累計已經執行了多少中間數據
  45. double dp;
  46. double dp0[MOTOR_NUM] = {0};                                        //插補增量
  47. bit flag_download = 0;//判斷是否下載
  48. bit flag_read = 0;// 讀取flash內容,發送上位機
  49. bit flag_connect_run = 0;//連接上位機的執行flash保存的命令
  50. bit flag_stop_download = 0;//停止下載
  51. bit flag_online_run = 0;
  52. bit flag_uart2_rev = 0;
  53. bit flag_uart2_rev_time_out = 0;
  54. bit flag_ps2_rev = 0;
  55. bit flag_read_adc = 0;
  56. unsigned long send_mode = 0;//當前串口接收到命令狀態存儲
  57. MotorData motor_data;//舵機總信息
  58. MotorOneCmd motor_one_cmd;//單個命令
  59. CurrentItem cur_item;
  60. uint16 tuoji_count = 0;//脫機執行次數
  61. bit flag_scan_ps2 = 0;
  62. uint8 error = 0;
  63. uchar file_list[MAX_SUPPORT_FILE_SAVE] = {0};
  64. int file_list_count = 0;
  65. int file_last_num = 0;
  66. char ps2_buf[120] = {0};
  67. char uart2_buf[50] = {0};
  68. uint cur_count = 0;
  69. uchar ad_value = 0;
  70. uchar beep_mode = 1;
  71. uchar key_bak;
  72. uchar ps2_key;
  73. uchar ps2_mode=0;

  74. void updata_file_list()
  75. {
  76.         uchar i = 0;
  77.         uchar j = 0;
  78.         file_last_num = -1;
  79.         ReadMoterInfor();
  80.         for (i = 0; i < motor_data.filecount; i++)
  81.         {
  82.                 if (motor_data.file_flag[i] == 1)
  83.                 {
  84.                         file_list[j] = i;
  85.                         j++;
  86.                         file_last_num = i;
  87.                 }
  88.         }
  89.         file_list_count = j;
  90. }
  91. void InitMotor()
  92. {
  93.         ReadMoterInfor();//讀取舵機控制信息
  94.         updata_file_list();
  95.         memset(&cur_item,0,sizeof(cur_item));
  96.         beep_mode = motor_data.beep_mode;
  97. }

  98. /***************************************************************************************************************
  99. 函 數 名:主函數  
  100. 功能描述:入口函數 ,進行各種初始化配置
  101. 輸入參數:無  
  102. 返 回 值:無  
  103. 備    注:
  104. ****************************************************************************************************************/       
  105. void main(void)
  106. {
  107.         uint temp = 0;        
  108.         P0M1=0x00;                                   //設置P0口為強推挽輸出模式
  109.         P0M0=0xFF;
  110.        
  111.         P1M1|=0x80;
  112.         P1M0|=0xc8;
  113.        
  114.         P5M1|=0x00;
  115.   P5M0|=0x2d;
  116.        
  117.         P4M0|=0x20;
  118.         P4M1|=0x00;
  119.        
  120.         Timer_init();          //定時器初始化
  121.         Timer0(31);                  //定時任意值,啟動定時器,進入定時器循環
  122. #if MOTOR_NUM > 9
  123.         Timer1(30);
  124. #endif
  125.         SpiFlashInit();//初始化flash
  126.         while((temp = SpiFlashReadID())!=W25Q64)LED_ALL_ON();//判斷flash有沒有接錯
  127.         LED_ALL_OFF();
  128.         InitMotor();
  129.         UART1_Init();          //串口1初始化
  130.         UART2_Init();  //串口2初始化
  131. #if PS_SUPPORT
  132.         Timer3_init();
  133. #endif       
  134.         InitADC(7);
  135.         BEEP_On_Or_OFF();
  136.         while(1)
  137.         {
  138.                 if(flag_vpwm==1)                  
  139.                 {       
  140.                         vpwm();                                        //更新pwm[]數組
  141.                         flag_vpwm=0;               
  142.                 }
  143.                 if( flag_RecFul==1)                   //串口接受完一條指令
  144.                 {
  145.                         DealRec();                                 //處理串口緩存中的數據
  146.                         flag_RecFul=0;
  147.                 }
  148.                 GetOneMotorCMD();//獲取一個命令
  149.                 SendUartState();//發送狀態信息
  150. #if PS_SUPPORT
  151.                 scan_ps2();
  152. #endif
  153.                 LED_State();
  154.                 Check_Power();
  155.           cur_count++;
  156.         }
  157. }
  158. void Check_Power()
  159. {
  160.         if ((cur_count % 800) == 0)
  161.         {
  162.                 StartADC(7);
  163.                 //cur_count=0;
  164.         }
  165.         if (flag_read_adc)
  166.         {
  167.                 flag_read_adc = 0;
  168.                 //UART_Put_Inf("adc:",ad_value);
  169.                 if (ad_value > 46)//根據電壓粗略估計
  170.                 {
  171.                         //UART_Put_Inf("adc:",ad_value);
  172.                   BEEP_OFF();
  173.                 //        LED2_OFF();
  174.                 }
  175.                 else
  176.                 {
  177.                                 //UART_Put_Inf("adc1111:",ad_value);
  178.                                 BEEP=~BEEP;
  179.                                 LED1=0;
  180.                                 LED2=0;
  181.                                 LED3=0;
  182.                 }
  183.                
  184.         }
  185. }
  186. void LED_State()
  187. {
  188.         uint error_count =  0;
  189.         if (error != 0)
  190.         {
  191.                 if (error & ERROR_FLASH_FULL)
  192.                 {
  193.                         error_count = 100;
  194.                 }
  195.                 if (error & ERROR_FLASH_FILE_FULL)
  196.                 {
  197.                         error_count += 100;
  198.                 }
  199.                 if (error & ERROR_FLASH_WRITE)
  200.                 {
  201.                         error_count += 100;
  202.                 }
  203.                 if (error & ERROR_FLASH_WRITE1)
  204.                 {
  205.                         error_count += 100;
  206.                 }
  207.                 if ((cur_count % error_count) == 0)//判斷flash是否正確
  208.                 {
  209.                         LED1_ON_OR_OFF();
  210.                 }
  211.         }
  212.        
  213.         if (flag_ps2_rev)
  214.         {
  215.                 LED1_ON();
  216.                 if ((cur_count % 100) == 0)
  217.                 {
  218.                         flag_ps2_rev = 0;
  219.                         LED1_OFF();
  220.                 }
  221.         }
  222.         if (flag_connect)
  223.         {
  224.                 LED3_ON();
  225.         }
  226.         else
  227.         {
  228.                 LED3_OFF();
  229.         }
  230. }
  231. void scan_ps2()
  232. {
  233.         int  kind = 0;
  234.         char *p = NULL;
  235.         char buf[15] = {0};
  236.         char i = 0;
  237.         if (flag_scan_ps2)//
  238.         {
  239.                 flag_scan_ps2 = 0;
  240.                 ps2_key=PS2_DataKey();
  241.                 ps2_mode=PS2_RedLight();
  242.         //UART_Put_Inf("mode",ps2_mode);       
  243.                 if(ps2_mode==0)
  244.                 {
  245.                         if(key_bak == ps2_key)return;
  246.                         key_bak=ps2_key;
  247.                         BEEP=~BEEP;
  248.                         switch(ps2_key)
  249.                         {
  250.                                 case PSB_PAD_UP:kind = 1;break;
  251.                                 case PSB_PAD_DOWN:kind = 2;break;
  252.                                 case PSB_PAD_LEFT:kind = 3;break;
  253.                                 case PSB_PAD_RIGHT:kind = 4;break;

  254.                                 case PSB_TRIANGLE:kind = 7;break;
  255.                                 case PSB_CROSS:kind = 8;break;
  256.                                 case PSB_PINK:kind = 9;break;
  257.                                 case PSB_CIRCLE:kind = 10;break;

  258.                                 case PSB_L1:kind = 6;break;
  259.                                 case PSB_L2:kind = 5;break;
  260.                                 case PSB_R1:kind = 12;break;
  261.                                 case PSB_R2:kind = 11;break;
  262.                                 default:break;
  263.                         }
  264.                                 if (kind != 0)
  265.                                 {               
  266.                                         flag_ps2_rev = 1;
  267.                                         flag_connect = 1;
  268.                                         SpiFlashRead(ps2_buf,(PS2_FLASH_ADDR)<<WRITE_BIT_DEPTH,sizeof(ps2_buf));
  269.                                         sprintf(buf,"%dK",kind);
  270.                                         //UART1_SendStr(buf);
  271.                                         p = strstr(ps2_buf,buf);
  272.                                         if (p != NULL)
  273.                                         {
  274.                                                 p = p + strlen(buf);
  275.                                                 while(i < 14 && *p != 0)
  276.                                                 {
  277.                                                         buf[i] = *p++;
  278.                                                         i++;
  279.                                                         if (*p == '#')
  280.                                                                 break;
  281.                                                 }
  282.                                                 if (i < 12)
  283.                                                 {
  284.                                                         buf[i] = '\r';
  285.                                                         buf[i+1] = '\n';
  286.                                                         memcpy(redata,buf,sizeof(buf));
  287.                                                         flag_RecFul = 1;
  288.                                                 }
  289.                                                 UART1_SendStr(redata);
  290.                                         }
  291.                                 }
  292.                         }
  293.                 else if(ps2_mode==1)//綠燈模式
  294.                 {
  295.                         switch(ps2_key)
  296.                                 {
  297.                                         case PSB_PAD_UP:pwm[1]+=10;if(pwm[1]>=2300) pwm[1]=2300;break;
  298.                                         case PSB_PAD_DOWN:pwm[1]-=10;if(pwm[1]<=700) pwm[1]=700;break;
  299.                                         case PSB_PAD_LEFT:pwm[2]+=10;if(pwm[2]>=2300) pwm[2]=2300;break;
  300.                                         case PSB_PAD_RIGHT:pwm[2]-=10;if(pwm[2]<=700) pwm[2]=700;break;
  301.                
  302.                                         case PSB_TRIANGLE:pwm[3]+=10;if(pwm[3]>=2300) pwm[3]=2300;break;
  303.                                         case PSB_CROSS:pwm[3]-=10;if(pwm[3]<=700) pwm[3]=700;break;
  304.                                         case PSB_PINK:pwm[4]+=10;if(pwm[4]>=2300) pwm[4]=2300;break;
  305.                                         case PSB_CIRCLE:pwm[4]-=10;if(pwm[4]<=700) pwm[4]=700;break;

  306.                                         case PSB_L1:pwm[5]+=10;if(pwm[5]>=2300) pwm[5]=2300;break;
  307.                                         case PSB_L2:pwm[5]-=10;if(pwm[5]<=700)  pwm[5]=700;break;
  308.                                         case PSB_R1:pwm[6]+=10;if(pwm[6]>=2300) pwm[6]=2300;break;
  309.                                         case PSB_R2:pwm[6]-=10;if(pwm[6]<=700)  pwm[6]=700;break;
  310.                                         default:break;
  311.                                 }
  312.                 }
  313.         }
  314. }
  315. /***************************************************************************************************************
  316. 函 數 名:從flash讀取舵機總的信息
  317. 功能描述:初始化舵機控制信息
  318. 輸入參數:無  
  319. 返 回 值:無  
  320. 備    注:
  321. ****************************************************************************************************************/       
  322. void ReadMoterInfor()
  323. {
  324.         memset(&motor_data,0,sizeof(motor_data));//清 0
  325.         SpiFlashRead((char *)&motor_data,(CMD_FLASH_ADDR)<<WRITE_BIT_DEPTH,sizeof(motor_data));//讀取信息
  326.         if (motor_data.CRC1 != 0x12345678 || motor_data.sum < 0 || motor_data.duoji_count  > MOTOR_NUM)//判斷信息存儲是否有錯
  327.         {
  328.                 memset(&motor_data,0,sizeof(motor_data));
  329.                 //memset(&cur_item,0,sizeof(cur_item));
  330.         }
  331.         else//正常信息
  332.         {
  333.                 //UART1_SendOneChar(motor_data.sum + 0x30);
  334.                 //cur_item.tuoji_count = motor_one_cmd.tuoji_count;//脫機運行次數
  335.                 //cur_item.cur_num = 0;//清 0
  336.         }
  337.                
  338. }
  339. void ReadOneCmdInfor(unsigned int addr)
  340. {
  341.         memset(&motor_one_cmd,0,sizeof(motor_one_cmd));//清 0
  342.         SpiFlashRead((char *)&motor_one_cmd,((((unsigned long)addr)<<4) + FILE_FLASH_ADDR)<<WRITE_BIT_DEPTH,sizeof(motor_one_cmd));//讀取信息
  343.         if (motor_one_cmd.start >= motor_one_cmd.end || motor_one_cmd.cur_file_num != (addr) || motor_data.file_flag[motor_one_cmd.cur_file_num] == 0)//判斷信息存儲是否有錯
  344.         {
  345.                 memset(&motor_one_cmd,0,sizeof(motor_one_cmd));
  346.         }
  347.         else//正常信息,以后留著驗證用的
  348.         {
  349.                
  350.                
  351.                 cur_item.tuoji_count = motor_one_cmd.tuoji_count;//脫機運行次數
  352.                 cur_item.cur_num = motor_one_cmd.start;
  353.                 //UART1_SendOneChar(motor_one_cmd.tuoji_count + 0x30);
  354.                 //cur_item.cur_num = 0;//清 0
  355.         }
  356.                
  357. }
  358. /***************************************************************************************************************
  359. 函 數 名:把舵機信息寫到flash中
  360. 功能描述:把舵機信息寫到flahs中
  361. 輸入參數:無  
  362. 返 回 值:無  
  363. 備    注:
  364. ****************************************************************************************************************/       
  365. void WriteMoterInfor()
  366. {
  367.         uchar temp = 0;
  368.         motor_data.CRC1 = 0x12345678;//校驗碼
  369.         motor_data.duoji_count = MOTOR_NUM-1;
  370.         temp = motor_data.filecount;
  371.         SpiFlashEraseSector(CMD_FLASH_ADDR >> 4);//擦除以前存儲的信息
  372.         SpiFlashWrite((char *)&motor_data,CMD_FLASH_ADDR<<WRITE_BIT_DEPTH,sizeof(motor_data)); //寫入flash
  373.         ReadMoterInfor();
  374.         if (temp != motor_data.filecount)
  375.         {
  376.                 error |= ERROR_FLASH_WRITE;
  377.         }
  378.         else
  379.         {
  380.                 error &= ~ERROR_FLASH_WRITE;
  381.         }
  382. }
  383. void WriteOneCmdInfor(unsigned int addr)
  384. {
  385.         uchar temp = 0;
  386.         temp = motor_one_cmd.end;
  387.         if (((((unsigned long)addr)<<4) + FILE_FLASH_ADDR) % 16 == 0)
  388.                 SpiFlashEraseSector(((((unsigned long)addr)<<4) + FILE_FLASH_ADDR) >> 4);//擦除以前存儲的信息
  389.         SpiFlashWrite((char *)&motor_one_cmd,((((unsigned long)addr)<<4) + FILE_FLASH_ADDR)<<WRITE_BIT_DEPTH,sizeof(motor_one_cmd)); //寫入flash
  390.         ReadOneCmdInfor(addr);
  391.         if (temp !=  motor_one_cmd.end)
  392.         {
  393.                 error |= ERROR_FLASH_WRITE1;
  394.         }
  395.         else
  396.         {
  397.                 error &= ~ERROR_FLASH_WRITE1;
  398.         }
  399. }
  400. /***************************************************************************************************************
  401. 函 數 名:獲取一串舵機的控制字符串
  402. 功能描述:處理從flash讀取的舵機控制字符串處理
  403. 輸入參數:無  
  404. 返 回 值:無  
  405. 備    注:
  406. ****************************************************************************************************************/       
  407. void GetOneMotorCMD()
  408. {
  409. #if DEBUG
  410.         uchar buf[20] = {0};
  411. #endif
  412.         if (flag_stop_download)//接收到了上位機的停止下載的命令
  413.         {
  414.                 flag_download = 0;//清楚下載狀態標志位
  415.                 flag_stop_download = 0;
  416.                 flag_read = 0;
  417.                 if (motor_data.filecount < MAX_SUPPORT_FILE_SAVE)
  418.                 {
  419.                         updata_file_list();
  420.                         motor_data.sum = motor_one_cmd.end;
  421.                         motor_data.file_flag[motor_data.filecount] = 1;
  422.                         motor_one_cmd.cur_file_num = file_last_num + 1;
  423.                         motor_data.filecount = motor_one_cmd.cur_file_num + 1;
  424.                         error &= ~MAX_SUPPORT_FILE_SAVE;
  425. #if DEBUG
  426.                         sprintf(buf,"%d %d\r\n",(uint)motor_data.filecount,(uint)motor_data.file_flag[motor_data.filecount-1]);
  427.                         UART1_SendStr(buf);
  428. #endif
  429.                         WriteMoterInfor();
  430.                         WriteOneCmdInfor(motor_one_cmd.cur_file_num);
  431.                         updata_file_list();
  432. #if DEBUG
  433.                        
  434.                         sprintf(buf,"%d %d\r\n",(uint)motor_data.filecount,(uint)motor_data.file_flag[motor_data.filecount-1]);
  435.                         UART1_SendStr(buf);
  436. #endif
  437.                 }
  438.                 else
  439.                 {
  440.                         error |= MAX_SUPPORT_FILE_SAVE;
  441.                 }
  442.                 if        (!(error &(MAX_SUPPORT_FILE_SAVE | ERROR_FLASH_FULL)))
  443.                         send_mode |= SEND_DOWN_OK;//狀態位置為
  444.         }
  445.         if (flag_connect)//如果當前跟上位機聯機狀態
  446.         {
  447.                 if (flag_read)//如果上位機讀取flash內存儲的信息
  448.                 {               
  449.                         if (cur_item.cur_num < motor_one_cmd.end)//判斷是否超過之前存儲的數
  450.                         {
  451.                                 if ((send_mode & SEND_SEND_FILE))//開始接收到讀取命令需要先發送個start
  452.                                 {
  453.                                         UART1_SendStr("#Start\r\n");
  454.                                         send_mode &= ~SEND_READ_FILE;
  455.                                 }
  456.                                 memset(redata,0,WRITE_SIZE);//清 0
  457.                                 SpiFlashRead(redata,(((long)cur_item.cur_num)<<WRITE_BIT_DEPTH),WRITE_SIZE);//讀取信息
  458. #if DEBUG
  459.                                 sprintf(buf,"%d\r\n",cur_item.cur_num);
  460.                                 UART1_SendStr(buf);
  461. #endif
  462.                                 UART1_SendStr(redata);//發送
  463.                                 cur_item.cur_num++;
  464.                         }
  465.                         else//否則
  466.                         {
  467.                                 if (cur_item.cur_num > 0)
  468.                                         UART1_SendStr("#End\r\n");//發送結束字符串
  469.                                   flag_read = 0;
  470.                         }
  471.                         send_mode = 0;//請 0
  472.                 }       
  473.                 if (flag_online_run)
  474.                 {
  475.                         if ((send_mode & SEND_CC) != 0  || cur_item.cur_num == motor_one_cmd.start)//如果當前需要更新舵機命令
  476.                         {
  477.                                 if (cur_item.tuoji_count > 0)//脫機次數沒結束
  478.                                 {
  479.                                         if (cur_item.cur_num < motor_one_cmd.end)//判斷是否讀取結束
  480.                                         {
  481.                                                 SpiFlashRead(redata,((long)cur_item.cur_num)<<WRITE_BIT_DEPTH,WRITE_SIZE);//讀取命令
  482.                                                 flag_RecFul = 1;//標志位為1,
  483.                                                 cur_item.cur_num++;//
  484.                                         }
  485.                                         else//執行玩一遍
  486.                                         {
  487.                                                 cur_item.cur_num = motor_one_cmd.start;
  488.                                                 cur_item.tuoji_count--;//減一
  489.                                         }
  490.                                 }
  491.                                 else//執行完成
  492.                                 {
  493.                                         flag_online_run = 0;
  494.                                         if (flag_connect_run)//如果上位機選擇執行的功能,需要發送 AGF作為結束
  495.                                         {
  496.                                                 UART1_SendStr("#AGF\r\n");
  497.                                                 flag_connect_run = 0;
  498.                                         }
  499.                                 }
  500.                                 //讀取數據
  501.                         }
  502.                 }
  503.         }
  504.         else//脫機
  505.         {
  506.                 if (file_list_count < 0)
  507.                 {
  508.                         return;
  509.                 }
  510.                 if (cur_item.tuoji_count > 0)
  511.                 {
  512.                         if ((send_mode & SEND_CC) != 0  || cur_item.cur_num == motor_one_cmd.start)//如果當前需要更新舵機命令
  513.                         {
  514.                                 if (cur_item.cur_num < motor_one_cmd.end)//判斷是否讀取結束
  515.                                 {
  516.                                         SpiFlashRead(redata,((long)cur_item.cur_num)<<WRITE_BIT_DEPTH,WRITE_SIZE);//讀取命令
  517.                                         flag_RecFul = 1;//標志位為1,
  518.                                         cur_item.cur_num++;//
  519.                                 }
  520.                                 else//執行玩一遍
  521.                                 {
  522.                                         cur_item.cur_num = motor_one_cmd.start;
  523.                                         cur_item.tuoji_count--;//減一
  524.                                 }
  525.                                 //讀取數據
  526.                         }
  527.                 }
  528.                 else
  529.                 {
  530.                         ReadOneCmdInfor(file_list[cur_item.file_num]);
  531.                         file_list_count--;
  532.                         cur_item.file_num++;
  533.                 }
  534.         }
  535.                
  536.        
  537. }
  538. /***************************************************************************************************************
  539. 函 數 名:發送串口狀態信息
  540. 功能描述:根據狀態標志位發送相應的信息
  541. 輸入參數:無  
  542. 返 回 值:無  
  543. 備    注:
  544. ****************************************************************************************************************/       
  545. void SendUartState()
  546. {
  547.         uchar buf[40] = {0};
  548.         uchar read_motor_num = 0;
  549.         uint i = 0;
  550.         static int count = 0;
  551.         if (send_mode)//如果有狀態需要發送
  552.         {
  553.                 if (send_mode & SEND_A) //發送A
  554.                 {
  555.                         UART1_SendOneChar('A');
  556.                         send_mode &= ~SEND_A;//清狀態
  557.                 }
  558.                 if (send_mode & SEND_CC) //發送CC
  559.                 {
  560.                         UART1_SendStr("#CC\r\n");
  561.                         send_mode &= ~SEND_CC;
  562.                 }
  563.                 if (send_mode & SEND_DOWN_OK)//發送下載ok的狀態字符串
  564.                 {
  565.                         sprintf(buf,"#Down+OK+%d\r\n",(int)motor_data.filecount-1);
  566.                         UART1_SendStr(buf);
  567.                         send_mode &= ~SEND_DOWN_OK;
  568. #if DEBUG
  569.                         sprintf(buf,"%d\r\n",(uint)motor_data.filecount);
  570.                         UART1_SendStr(buf);
  571. #endif
  572.                 }
  573.                 if (send_mode & SEND_START_OK)//發送連接時候的字符串
  574.                 {
  575.                         UART1_SendStr("#Veri+UART+OK+20160906+176\r\n");
  576.                         send_mode &= ~SEND_START_OK;
  577.                 }
  578.                 if (send_mode & SEND_READ_FILE)//發送讀取文件的時候字符串
  579.                 {
  580.                         if (motor_data.filecount > 0)//如果保存的有舵機命令
  581.                         {
  582.                                 //#Name:1.txt--Size:48--Name:2.txt--Size:190--Name:desktop.ini--Size:531--
  583.                                 UART1_SendStr("#");//發送
  584.                                 for (i = 0; i < motor_data.filecount;i++)
  585.                                 {
  586.                                         if (motor_data.file_flag[i] == 1)
  587.                                         {
  588.                                                 ReadOneCmdInfor(i);
  589.                                                 if (motor_one_cmd.end - motor_one_cmd.start <= 0)
  590.                                                 {
  591.                                                         motor_data.file_flag[i] = 0;
  592.                                                         WriteMoterInfor();
  593. #if DEBUG
  594.                                                         sprintf(buf,"E=%d S=%d",motor_one_cmd.end, motor_one_cmd.start);
  595. #endif
  596.                                                 }
  597.                                                 else
  598.                                                 {
  599.                                                         sprintf(buf,"Name:%d.txt--Size:%d--",i,motor_one_cmd.end - motor_one_cmd.start);//獲取命令個數
  600.                                                         UART1_SendStr(buf);//發送
  601.                                                 }
  602.                                         }

  603.                                 }
  604.                                 UART1_SendStr("\r\n");                               
  605.                         }
  606.                         else
  607.                         {
  608.                                 sprintf(buf,"#\r\n",motor_data.sum);
  609.                                 UART1_SendStr(buf);
  610.                         }
  611.                         send_mode &= ~SEND_READ_FILE;
  612.                 }
  613.                 if (send_mode & SEND_SET_OFFLINE_OK)//設置脫機運行次數
  614.                 {
  615.                         WriteOneCmdInfor(motor_one_cmd.cur_file_num);//保存
  616.                         UART1_SendStr("#Enable+OK...\r\n");
  617.                         send_mode &= ~SEND_SET_OFFLINE_OK;
  618.                 }
  619.                 if (send_mode & SEND_SET_DISABLEOFFLINE_OK)//禁止脫機運行
  620.                 {
  621.                         for (i = 0; i < motor_data.filecount;i++)
  622.                         {
  623.                                 if (motor_data.file_flag[i] == 1)
  624.                                 {
  625.                                         ReadOneCmdInfor(i);
  626.                                         motor_one_cmd.tuoji_count = 0;
  627.                                         WriteOneCmdInfor(i);
  628.                                 }

  629.                         }
  630.                         WriteMoterInfor();
  631.                         UART1_SendStr("#Disable+OK...\r\n");
  632.                         send_mode &= ~SEND_SET_DISABLEOFFLINE_OK;
  633.                 }
  634.                 if (send_mode & SEND_SET_ONLINE_OK)//發送聯機運行狀態
  635.                 {
  636.                         UART1_SendStr("#OK\r\n");
  637.                         sprintf(buf,"#%dGC%d\r\n",cur_item.file_num,tuoji_count);
  638.                         UART1_SendStr(buf);
  639.                         UART1_SendStr("#LP=0\r\n");
  640.                         send_mode &= ~SEND_SET_ONLINE_OK;
  641.                         flag_connect_run = 1;
  642.                 }
  643.                 if (send_mode & SEND_SET_DELETE_ONE_FILE_OK)//發送刪除文件命令
  644.                 {
  645.                         //cur_item.tuoji_count = 0;
  646.                         if (cur_item.delete_num < motor_data.filecount)
  647.                         {
  648.                                 motor_data.file_flag[cur_item.delete_num] = 0;
  649.                                 WriteMoterInfor();
  650.                                 updata_file_list();
  651.                                 if (cur_item.delete_num  == motor_data.filecount-1)
  652.                                 {
  653.                                         motor_data.filecount = file_last_num + 1;
  654.                                         if (file_last_num == -1)
  655.                                         {
  656.                                                 motor_data.sum = 0;
  657.                                         }
  658.                                         else
  659.                                         {
  660.                                                 ReadOneCmdInfor(file_last_num);
  661.                                                 motor_data.sum = motor_one_cmd.end;
  662.                                                 motor_data.sum = (((long int)(motor_data.sum) >>4)<<4) + (1<<4);
  663.                                         }
  664.                                         WriteMoterInfor();
  665.                                 }
  666.                                 updata_file_list();               
  667.                                 UART1_SendStr("#FDel+OK\r\n");
  668.                         }
  669.                         send_mode &= ~SEND_SET_DELETE_ONE_FILE_OK;
  670.                        
  671.                 }
  672.                 if (send_mode & SEND_SET_DELETE_ALL_FILE_OK)//發送擦除所有文件的命令
  673.                 {
  674.                         UART1_SendStr("#Format+Start\r\n");
  675.                         SpiFlashEraseChip();
  676.                         cur_item.tuoji_count = 0;
  677.                         motor_data.sum = 0;
  678.                         motor_data.filecount = 0;
  679.                         memset(motor_data.file_flag,0,sizeof(motor_data.file_flag));
  680.                         WriteMoterInfor();
  681.                         UART1_SendStr("#Format+OK\r\n");
  682.                         send_mode &= ~SEND_SET_DELETE_ALL_FILE_OK;
  683.                         updata_file_list();
  684.                 }
  685.                 if (send_mode & SEND_SET_PS2_OK)
  686.                 {
  687.                         UART1_SendStr("#PS2+OK...\r\n");
  688.                         send_mode &= ~SEND_SET_PS2_OK;
  689.                 }
  690.                
  691. #define MATHION_HAND_NUM 20
  692.                 if (send_mode & SEND_SET_READ_UART_MOTOR_ANGLE)
  693.                 {
  694.                         if (cur_item.read_num < MATHION_HAND_NUM)
  695.                         {
  696.                                 if (flag_uart2_rev)
  697.                                 {
  698.                                         read_motor_num = atoi(uart2_buf + 1);
  699.                                         if (read_motor_num == cur_item.read_num)
  700.                                         {
  701.                                                 i = atoi(uart2_buf+5);
  702.                                                 sprintf(uart2_buf,"#%dP%d",(int)read_motor_num,i);
  703.                                                 UART1_SendStr(uart2_buf);
  704.                                                 cur_item.read_num++;
  705.                                                 buf[0] = '#';
  706.                                                 buf[1] = cur_item.read_num / 100 % 10 + 0x30;
  707.                                                 buf[2] = cur_item.read_num / 10 % 10 + 0x30;
  708.                                                 buf[3] = cur_item.read_num % 10 + 0x30;
  709.                                                 buf[4] = 'P';buf[5] = 'R';buf[6] = 'A';buf[7] = 'D';buf[8] = '\r';buf[9] = '\n';
  710.                                                 UART2_SendStr(buf);
  711.                                                
  712.                                         }
  713.                                         flag_uart2_rev = 0;
  714.                                         count = 0;
  715.                                        
  716.                                 }
  717.                                 else
  718.                                 {
  719.                                         count++;
  720.                                         if (count >= 10)
  721.                                         {
  722.                                                 cur_item.read_num++;
  723.                                                 buf[0] = '#';
  724.                                                 buf[1] = cur_item.read_num / 100 % 10 + 0x30;
  725.                                                 buf[2] = cur_item.read_num / 10 % 10 + 0x30;
  726.                                                 buf[3] = cur_item.read_num % 10 + 0x30;
  727.                                                 buf[4] = 'P';buf[5] = 'R';buf[6] = 'A';buf[7] = 'D';buf[8] = '\r';buf[9] = '\n';
  728.                                                 UART2_SendStr(buf);
  729.                                                 flag_uart2_rev = 0;
  730.                                                 flag_uart2_rev_time_out = 0;
  731.                                                 count = 0;
  732.                                         }
  733.                                 }
  734.                         }
  735.                         else
  736.                         {
  737.                                 send_mode &= ~SEND_SET_READ_UART_MOTOR_ANGLE;
  738.                                 cur_item.read_num= 0;
  739.                                 UART1_SendStr("\r\n");
  740.                         }
  741.                 }
  742.         }
  743.         if (send_mode & SEND_SET_SET_UART_MOTOR_PULK)
  744.         {
  745.                 if (cur_item.pulk_num < MATHION_HAND_NUM)
  746.                 {
  747.                         count++;
  748.                         if (count >= 20)
  749.                         {
  750.                                 sprintf(uart2_buf,"#%dPULK\r\n",(int)cur_item.pulk_num);
  751.                                 UART2_SendStr(uart2_buf);
  752. #if DEBUG
  753.                                 UART1_SendStr(uart2_buf);
  754. #endif
  755.                                 cur_item.pulk_num++;
  756.                                 count = 0;
  757.                         }
  758.                 }
  759.                 else
  760.                 {
  761.                         send_mode &= ~SEND_SET_SET_UART_MOTOR_PULK;
  762.                 }
  763.         }
  764.         if (send_mode & SEND_SET_SET_UART_MOTOR_ANGLE)
  765.         {
  766.                 if (cur_item.pulk_num < MATHION_HAND_NUM)
  767.                 {
  768.                         count++;
  769.                         if (count >= 5)
  770.                         {
  771.                                 sprintf(uart2_buf,"#%dPMOD%d\r\n",(int)cur_item.pulk_num,(int)cur_item.angle_mode);
  772.                                 UART2_SendStr(uart2_buf);
  773. #if DEBUG
  774.                                 UART1_SendStr(uart2_buf);
  775. #endif
  776.                                 cur_item.pulk_num++;
  777.                                 count = 0;
  778.                         }
  779.                 }
  780.                 else
  781.                 {
  782.                         sprintf(buf,"#255PMOD%d+0K...\r\n",(int)cur_item.angle_mode);
  783.                         UART1_SendStr(buf);
  784.                         send_mode &= ~SEND_SET_SET_UART_MOTOR_ANGLE;
  785.                         flag_uart2_rev = 0;
  786.                 }
  787.         }
  788.         if (send_mode & SEND_SET_BEEP_ON)
  789.         {
  790.                 ReadMoterInfor();
  791.                 motor_data.beep_mode = 1;
  792.                 beep_mode = 1;
  793.                 WriteMoterInfor();
  794.                 UART1_SendStr("#FMQENABLE+OK...\r\n");
  795.                 send_mode &= ~SEND_SET_BEEP_ON;
  796.         }
  797.         if (send_mode & SEND_SET_BEEP_OFF)
  798.         {
  799.                 ReadMoterInfor();
  800.                 motor_data.beep_mode = 0;
  801.                 beep_mode = 0;
  802.                 WriteMoterInfor();
  803.                 UART1_SendStr("#FMQDISABLE+OK...\r\n");
  804.                 send_mode &= ~SEND_SET_BEEP_OFF;
  805.         }               
  806. }
  807. /***************************************************************************************************************
  808. 函 數 名:作業初位置,末尾置更新函數  
  809. 功能描述:從緩存中取一個新的目標位置替換原來的目標位置,原來的目標位置變為新的初位置,一次更替
  810.                 :有效的數據是插補增量,和插補次數,知道這兩個量,和當前初位置即可
  811. 備    注: 先進先出,循環訪問       
  812. ****************************************************************************************************************/       
  813. void change(void)
  814. {       
  815.         uchar s;
  816.         if(line>0)                                   //緩存中有數據
  817.         {  
  818.                 line--;                                   //執行一行
  819.                 if(line<5)                        //緩存允許放入新的數據                       
  820.                         flag_in=1;
  821.                 point_now++;                //取數位置更新
  822.                 point_aim++;
  823.                
  824.                 if(point_aim==7)
  825.                            point_aim=0;
  826.                 if(point_now==7)
  827.                            point_now=0;
  828.                 n=pos[point_aim][0]*4/5;        //計算新的插補次數
  829.                 for(s=1;s<MOTOR_NUM;s++)        //計算新的插補增量
  830.                 {
  831.                  if(pos[point_aim][s]>pos[point_now][s])
  832.                         {
  833.                                    dp=pos[point_aim][s]-pos[point_now][s];
  834.                                    dp0[s]=dp/n;
  835.                         }
  836.                     if(pos[point_aim][s]<=pos[point_now][s])
  837.                         {
  838.                                 dp=pos[point_now][s]-pos[point_aim][s];
  839.                                 dp0[s]=dp/n;
  840.                                 dp0[s]=-dp0[s];
  841.                         }
  842.            }
  843.                 m=0;                                          //m清0
  844.                 flag_stop=0;                          //產生了新的目標位置,停止標志清零
  845.                
  846.         }
  847.         else                                                  //沒有緩存數據,即line==0
  848.         {
  849.                 flag_out=0;                                //緩存中沒有數據
  850.         }
  851. }
  852. /***************************************************************************************************************
  853. 函 數 名:vpwm()  
  854. 功能描述:數據插補,插補時間間隔為20/12ms,由timer0控制,使舵機平滑實現速度控制
  855.                 :另一個功能是執行完一行后去更新下一行數據,即調用change()
  856. 備    注:
  857. ****************************************************************************************************************/       
  858. void vpwm(void)                 
  859. {
  860.         uchar j=0;
  861.         uchar how=0;
  862.   static uchar flag_how;
  863.         static uchar flag_Tover;

  864.         if(flag_stop==1)                                           //一行作業全部完成
  865.         {       
  866.                 if(flag_out==1)                                         //緩沖數組中有數據
  867.                 {
  868.                         change();                                        //更新行
  869.                 }
  870.         }
  871.         else                                                                //不是一行數據全部完成,處于中間插補階段
  872.         {
  873.                 m++;                                                        //用來累加插補過的次數
  874.                 if(m==n)                                                //n是本行作業要插補的總次數
  875.                 {
  876.                   flag_Tover=1;                                //一行數據的執行時間已經完成
  877.                         send_mode |= SEND_CC;
  878.                 }
  879.                 for(j=1;j<MOTOR_NUM;j++)
  880.                 {
  881.                         if(abs(pwm[j]-pos[point_aim][j])<5)
  882.                         {                                                           //檢測靠近終點位置
  883.                            how++;                                           //是,則累加一個
  884.                            pwm[j]=pos[point_aim][j];//并且直接過度到終點位置
  885.                         }       
  886.                         else                                                //不靠近終點,繼續插補
  887.                                 pwm[j]=pos[point_now][j]+m*dp0[j];
  888.                 }        
  889.                 //UART_Put_Inf("pwm",pwm[1]);
  890.                 if(how==MOTOR_NUM-1)
  891.                         flag_how=1;                                                  //16個舵機都到達終點
  892.                 how=0;
  893.                 if((flag_Tover==1)&&(flag_how==1))
  894.                 {                                                                //從插補次數,和脈寬寬度兩方面都到達終點,本作業行完成
  895.                          flag_Tover=0;
  896.                          flag_how=0;
  897.                          flag_stop=1;
  898.                 }
  899.                
  900.          }
  901.         return;

  902. }

  903.                           
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏13 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:196638 發表于 2017-5-5 20:20 | 只看該作者
點個贊!
回復

使用道具 舉報

板凳
ID:183825 發表于 2017-8-15 14:03 | 只看該作者
kankan 看看看 學習學習!!謝謝!!
回復

使用道具 舉報

地板
ID:242730 發表于 2017-10-25 13:01 來自觸屏版 | 只看該作者
請問樓主用的是單片機控制舵機控制板嗎
回復

使用道具 舉報

5#
ID:253033 發表于 2018-3-9 22:09 | 只看該作者
學習學習
回復

使用道具 舉報

6#
ID:253033 發表于 2018-3-9 23:04 | 只看該作者
單用單片機可以嗎不用其他的東西?
回復

使用道具 舉報

7#
ID:384210 發表于 2018-8-8 15:12 | 只看該作者
新來初到,能下載嗎
回復

使用道具 舉報

8#
ID:362243 發表于 2018-8-27 10:37 | 只看該作者
你好,
只有程序嗎?
回復

使用道具 舉報

9#
ID:396582 發表于 2018-9-15 20:35 | 只看該作者
你好,請問這是用中斷輸出pwm控制的嗎,怎么實現同時控制幾個舵機啊。聽說程序模擬pwm波誤差大
回復

使用道具 舉報

10#
ID:312557 發表于 2018-11-11 14:45 | 只看該作者
學習下  看看看 學習學習!!謝謝!!
回復

使用道具 舉報

11#
ID:615962 發表于 2019-9-24 23:32 來自觸屏版 | 只看該作者
只用單片機么?
回復

使用道具 舉報

12#
ID:645882 發表于 2019-11-20 16:51 | 只看該作者
請問 16路舵機是什么意思?是16個舵機嗎
回復

使用道具 舉報

13#
ID:683198 發表于 2020-1-7 20:45 來自觸屏版 | 只看該作者
感謝分享
回復

使用道具 舉報

14#
ID:686631 發表于 2020-1-17 12:25 | 只看該作者
舵機用單片機直接驅動?
回復

使用道具 舉報

15#
ID:138918 發表于 2020-5-14 12:53 | 只看該作者
不錯 果斷收藏學習
回復

使用道具 舉報

16#
ID:582255 發表于 2021-1-21 22:07 | 只看該作者
作者好像都沒有回帖啊
回復

使用道具 舉報

17#
ID:964559 發表于 2021-9-7 10:58 | 只看該作者
你好,有沒有電路圖
回復

使用道具 舉報

18#
ID:808223 發表于 2022-1-9 17:29 | 只看該作者
這是實現什么功能呢?
回復

使用道具 舉報

19#
ID:984082 發表于 2022-3-29 22:54 | 只看該作者
您好樓主  您的機械臂抓取物體是靠什么識別的
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲在线中文字幕 | 精品欧美一区二区三区久久久 | 五月香婷婷 | 欧美一区不卡 | 日韩精品一区二区三区第95 | 欧美成人精品在线观看 | 亚洲一区二区三区高清 | 精品美女久久久久久免费 | 国产视频中文字幕 | 免费观看成人av | 成人免费在线视频 | 久久精品国产99国产 | 殴美黄色录像 | 99re视频在线观看 | 亚洲精品自在在线观看 | 欧美不卡视频 | 在线免费观看黄色av | 欧美成人一区二区三区 | 一级做a| 国产精品96久久久久久 | 国产在线视频一区二区董小宛性色 | 女同久久 | 国产精品国产成人国产三级 | 国产精品夜色一区二区三区 | 国产乱码精品一区二区三区五月婷 | 亚洲在线看 | 视频一区二区在线 | 国产免费一区二区三区网站免费 | 日韩精品久久久久久 | 国产精品久久久久久久久免费相片 | 99精品国自产在线 | 在线一区 | 亚洲欧美激情视频 | 91精品国产综合久久精品 | 狠狠色综合久久婷婷 | 欧美国产一区二区 | 中文字幕亚洲视频 | 在线āv视频 | 亚洲精品1区 | 黄色香蕉视频在线观看 | 久久久久久亚洲精品 |