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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

注釋stm32單片機之串口1解析控制舵機程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:698951 發表于 2021-9-26 22:30 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
一款機械臂程序分享
  1. /***************************************************************
  2.         @筆者:tacbo
  3.         功能列表:
  4.         1、單個舵機控制(支持PWM舵機和總線舵機)
  5.         2、多個舵機控制(支持PWM舵機和總線舵機)
  6.         3、手柄控制舵機
  7.         4、串口控制舵機
  8.         5、OLED顯示舵機的執行情況
  9.         6、USB一鍵下載
  10.         7、可支持總線MP3 總線WIFI等設備
  11.         8、上位機圖形化編程
  12.         9、控制6自由度機械臂                        
  13. ***************************************************************/


  14. #include "tb_rcc.h"                        //配置時鐘文件
  15. #include "tb_gpio.h"                //配置IO口文件
  16. #include "tb_global.h"                //存放全局變量
  17. #include "tb_delay.h"                //存放延時函數
  18. #include "tb_type.h"                //存放類型定義
  19. #include "tb_usart.h"                //存放串口功能文件
  20. #include "tb_timer.h"                //存放定時器功能文件
  21.                                 
  22. #include "ADC.h"                        //存放ADC的
  23. #include "PS2_SONY.h"                //存放索尼手柄
  24. #include "w25q64.h"                        //存儲芯片的操作
  25. #include "oled_i2c.h"                //OLED文件

  26. #include <stdio.h>                        //標準庫文件
  27. #include <string.h>                        //標準庫文件
  28. #include <math.h>                        //標準庫文件

  29. #define VERSION                                20170919        //版本定義
  30. #define CYCLE                                 1000                //PWM模塊周期
  31. #define PS2_LED_RED                  0x73                //PS2手柄紅燈模式
  32. #define PS2_LED_GRN                  0x41                //PS2手柄綠燈模式
  33. #define PSX_BUTTON_NUM                 16                        //手柄按鍵數目
  34. #define PS2_MAX_LEN                 64                        //手柄命令最大字節數
  35. #define FLAG_VERIFY                 0x25                //校驗標志
  36. #define ACTION_SIZE                 0x80                //一個動作的存儲大小

  37. #define W25Q64_INFO_ADDR_SAVE_STR                        (((8<<10)-2)<<10)//(8*1024-1)*1024                //eeprom_info結構體存儲的位置

  38. void system_init(void);                                        //系統初始化
  39. void beep_led_dis_init(void);                        //開機提示
  40. void handle_nled(void);                                        //LED工作指示燈提示
  41. void soft_reset(void);                                        //軟件復位

  42. void car_pwm_set(int car_left, int car_right);        //電機控制函數
  43. void handle_ps2(void);                                                        //手柄數據解析
  44. void handle_button(void);                                                //手柄按鍵解析
  45. void parse_psx_buf(unsigned char *buf, unsigned char mode);        //手柄按鍵解析子函數
  46. void handle_car(void);                                                                                //搖桿數據解析控制車

  47. void handle_uart(void);                                        //串口解析
  48. void parse_cmd(u8 *cmd);                                //命令解析

  49. void action_save(u8 *str);                                //動作保存函數
  50. int get_action_index(u8 *str);                        //獲取動作組序號
  51. void print_group(int start, int end);        //打印動作組
  52. void int_exchange(int *int1, int *int2);        //兩個int互換

  53. void do_group_once(int group_num);                 //執行動作組1次
  54. void handle_action(void);                                //處理動作組執行
  55. u8 check_dj_state(void);                                //獲取舵機的狀態

  56. void do_action(u8 *uart_receive_buf);                        //執行動作
  57. void replace_char(u8*str, u8 ch1, u8 ch2);                //字符串字母替換
  58. void rewrite_eeprom(void);                                                //寫入eeprom_info結構體
  59. void handle_adc(void);                                                        //處理ADC數據
  60. void handle_oled(void);                                                        //處理OLED數據


  61. u8 psx_buf[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};         //存儲手柄的數據
  62. const char *pre_cmd_set_red[PSX_BUTTON_NUM] = {                                        //紅燈模式下按鍵的配置
  63.         "<PS2_RED01:#005P0600T2000!^$DST:5!>",        //L2                                                  
  64.         "<PS2_RED02:#005P2400T2000!^$DST:5!>",        //R2                                                  
  65.         "<PS2_RED03:#004P0600T2000!^$DST:4!>",        //L1                                                  
  66.         "<PS2_RED04:#004P2400T2000!^$DST:4!>",        //R1                        
  67.         "<PS2_RED05:#002P2400T2000!^$DST:2!>",        //RU                                                  
  68.         "<PS2_RED06:#003P0600T2000!^$DST:3!>",        //RR                                                  
  69.         "<PS2_RED07:#002P0600T2000!^$DST:2!>",        //RD                                                  
  70.         "<PS2_RED08:#003P2400T2000!^$DST:3!>",        //RL                                
  71.         "<PS2_RED09:$DJ_RECORD_DO:1!>",                        //SE    執行1次                                          
  72.         "<PS2_RED10:$DJ_RECORD_CLEAR!>",                //AL        清除                                          
  73.         "<PS2_RED11:$DJ_RECORD!>",                                //AR        學習                                          
  74.         "<PS2_RED12:$DJR!>",                                        //ST                        
  75.         "<PS2_RED13:#001P0600T2000!^$DST:1!>",        //LU                                                  
  76.         "<PS2_RED14:#000P0600T2000!^$DST:0!>",        //LR                                                                  
  77.         "<PS2_RED15:#001P2400T2000!^$DST:1!>",        //LD                                                  
  78.         "<PS2_RED16:#000P2400T2000!^$DST:0!>",        //LL                                                
  79. };

  80. const char *pre_cmd_set_grn[PSX_BUTTON_NUM] = {                                        //綠燈模式下按鍵的配置
  81.         "<PS2_GRN01:$!>",        //L2                                                  
  82.         "<PS2_GRN02:$!>",        //R2                                                  
  83.         "<PS2_GRN03:$!>",        //L1                                                  
  84.         "<PS2_GRN04:$!>",        //R1                        
  85.         "<PS2_GRN05:$!>",        //RU                                                  
  86.         "<PS2_GRN06:$!>",        //RR                                                  
  87.         "<PS2_GRN07:$!>",        //RD                                                  
  88.         "<PS2_GRN08:$!>",        //RL                                
  89.         "<PS2_GRN09:$!>",        //SE                                                         
  90.         "<PS2_GRN10:$!>",        //AL-NO                                                  
  91.         "<PS2_GRN11:$!>",        //AR-NO                                                  
  92.         "<PS2_GRN12:$!>",        //ST                        
  93.         "<PS2_GRN13:$!>",        //LU                                                  
  94.         "<PS2_GRN14:$!>",        //LR                                                                  
  95.         "<PS2_GRN15:$!>",        //LD                                                  
  96.         "<PS2_GRN16:$!>",        //LL                                                  
  97. };


  98. /*"D:\DreamSpark\OLED\MP3_UI.bmp",0 圖片取模數據
  99. unsigned char MY_PIC[] = {
  100.         0x00,0x03,0x05,0x09,0x11,0xFF,0x11,0x89,0x05,0xC3,0x00,0xE0,0x00,0xF0,0x00,0xF8,
  101.         *************************
  102.         0x80,0xFF,0x80,0xEE,0xEE,0xEE,0xF5,0xFB,0xFF,0x9C,0xBE,0xB6,0xB6,0x88,0xFF,0x00,
  103. };
  104. */




  105. int i;                                                //常用的一個臨時變量
  106. u8 car_dw = 1;                                //搖桿檔位控制
  107. u8 group_do_ok = 1;                        //動作執行完成標志
  108. int do_start_index;                        //動作組執行 起始序號
  109. int do_time;                                //動作組執行 執行次數
  110. int group_num_start;                //動作組執行 起始序號
  111. int group_num_end;                        //動作組執行 終止序號
  112. int group_num_times;                //動作組執行 起始變量
  113. u32 dj_record_time = 1000;        //學習時間默認1000


  114. /*-------------------------------------------------------------------------------------------------------
  115. *  程序從這里執行                                
  116. *  這個啟動代碼 完成時鐘配置 使用外部晶振作為STM32的運行時鐘 并倍頻到72M最快的執行速率
  117. -------------------------------------------------------------------------------------------------------*/

  118. int main(void)
  119.         {        
  120.         tb_rcc_init();                ///時鐘初始化 已經備注
  121.         
  122.         tb_gpio_init();                ///IO初始化 打開時鐘
  123.         
  124.         tb_global_init();        //全局變量初始化
  125.         
  126.         nled_init();                ///工作指示燈初始化
  127.         
  128. //        beep_init();                ///蜂鳴器初始化
  129.         
  130.         dj_io_init();                ///舵機IO口初始化
  131.                
  132.         //w25q64 init
  133.         W25Q_Init();                                //動作組存儲芯片初始化
  134.         
  135.         if(W25Q_TYPE != W25Q64){        //判斷是否是W25Q64芯片
  136.                 while(1)beep_on();                //如果不是則長鳴,說明芯片有問題,無法通信
  137.         }
  138.         W25Q_Read((u8 *)(&eeprom_info), W25Q64_INFO_ADDR_SAVE_STR, sizeof(eeprom_info));        //讀取全局變量
  139.         if(eeprom_info.version != VERSION) {        //判斷版本是否是當前版本
  140.                 eeprom_info.version = VERSION;                //復制當前版本
  141.                 eeprom_info.dj_record_num = 0;                //學習動作組變量賦值0
  142.                 rewrite_eeprom();                                        //寫入到存儲器  ///把結構體里面的內容讀取處理 然后再把內容寫進去
  143.         }

  144.         
  145.         //ADC_init();        ///ADC初始化
  146.         
  147.         //PSX_init();        //手柄初始化 GPIO
  148.         
  149.         
  150.         TIM2_Int_Init(20000, 71);        ///舵機 定時器初始化 定時器中斷輸出高電平
  151.         
  152.         ///小車 pwm 初始化   利用了高級定時器 PWM引腳輸出
  153.         TIM3_Pwm_Init(1000, 239);
  154.         TIM4_Pwm_Init(1000, 239);
  155.         car_pwm_set(0,0);        //設置小車的左右輪速度為0

  156.         
  157.         //串口1初始化
  158.         tb_usart1_init(115200); //配置結構體,不包括使能串口
  159.         uart1_open();  //打開串口中斷
  160.         
  161.         //串口2初始化
  162.         tb_usart2_init(115200);
  163.         uart2_open();
  164.         
  165.         //串口3初始化
  166.         tb_usart3_init(115200);
  167.         uart3_open();
  168.         
  169.         //總中斷打開
  170.         tb_interrupt_open();
  171.         
  172.         
  173.         //三個串口發送測試字符
  174.         uart1_send_str((u8 *)"uart1 check ok!");
  175.         uart2_send_str((u8 *)"uart2 check ok!");
  176.         uart3_send_str((u8 *)"uart3 check ok!");
  177.         
  178.         //總線輸出 復位總線舵機
  179.         zx_uart_send_str((u8 *)"#255P1500T2000!");
  180.         
  181.         //系統滴答時鐘初始化        
  182.         SysTick_Int_Init();        
  183.         
  184.         //蜂鳴器LED 名叫閃爍 示意系統啟動
  185.         beep_led_dis_init();
  186.         
  187.         
  188.         //執行預存命令
  189.         if(eeprom_info.pre_cmd[PRE_CMD_SIZE] == FLAG_VERIFY) {
  190.                 if(eeprom_info.pre_cmd[0] == '
  191. ) {
  192.                         memset(uart_receive_buf, 0, sizeof(uart_receive_buf));        
  193.                         strcpy((char *)uart_receive_buf, (char *)eeprom_info.pre_cmd);///把儲存的數據讀取出來
  194.                         uart1_mode = 1;
  195.                         uart1_get_ok = 1;
  196.                         uart1_send_str(uart_receive_buf);
  197.                 }
  198.         }
  199.                
  200.         //OLED初始化
  201.         //OLED_Init();
  202.         
  203.         while(1)     //parse_cmd(uart_receive_buf);                        //解析命令模式  串口改變變量和按鍵 公用這個函數 解析動作,解析動作只是改變舵機的變量,舵機控制在中斷函數
  204.                 {                        
  205.                 handle_nled();                //處理信號燈   ///利用系統內部定時器SysTick
  206.                 handle_ps2();                //處理手柄           初始化   把手柄的數據讀取出來
  207.                         
  208.                         
  209.                 handle_button();        //處理手柄按鈕              //do_action(uart_receive_buf); 獲取按鍵狀態 控制舵機
  210.                 handle_car();                //處理搖桿控制小車
  211.                
  212.                 handle_uart();                //處理串口接收數據              //定義一個指針,可以被多個函數調用 中斷接收串口數據 do_action(uart_receive_buf);
  213.                 handle_action();        //處理動作組    main 865
  214.                         
  215.                 handle_adc();                //處理ADC
  216.                 handle_oled();                //處理OLED顯示
  217.         }
  218. }



  219. //開機指示函數,蜂鳴器和工作指示燈鳴3聲作為開機指示
  220. void beep_led_dis_init(void) {
  221.         beep_on();nled_on();tb_delay_ms(100);beep_off();nled_off();tb_delay_ms(100);
  222.         beep_on();nled_on();tb_delay_ms(100);beep_off();nled_off();tb_delay_ms(100);
  223.         beep_on();nled_on();tb_delay_ms(100);beep_off();nled_off();tb_delay_ms(100);
  224. }

  225. ///工作指示燈處理,間隔1000MS閃爍一次
  226. void handle_nled(void) {
  227.         static u32 time_count=0;
  228.         static u8 flag = 0;
  229.         if(systick_ms-time_count > 1000)  {
  230.                 time_count = systick_ms;
  231.                 if(flag) {
  232.                         nled_on();
  233.                 } else {
  234.                         nled_off();
  235.                 }
  236.                 flag= ~flag;
  237.         }
  238. }

  239. //軟件復位函數,調用后單片機自動復位
  240. void soft_reset(void) {
  241.         __set_FAULTMASK(1);     
  242.         NVIC_SystemReset();
  243. }


  244. //小車控制函數
  245. //參數 左輪速度和右輪速度 范圍 -1000 到 1000
  246. void car_pwm_set(int car_left, int car_right) {
  247.         
  248.         if(car_left >= CYCLE)car_left = CYCLE-1;
  249.         else if(car_left <= -CYCLE)car_left = -CYCLE+1;
  250.         else if(car_left == 0)car_left = 1;
  251.         
  252.         if(car_right >= CYCLE)car_right = CYCLE-1;
  253.         else if(car_right <= -CYCLE)car_right = -CYCLE+1;
  254.         else if(car_right == 0)car_right = 1;
  255.         
  256.         //car_left = car_left/car_dw;
  257.         //car_right = car_right/car_dw;
  258.         
  259.         if(car_right>0) {
  260.                 TIM_SetCompare4(TIM4,1);
  261.                 TIM_SetCompare3(TIM4,car_right);  ///設置CCR,初始化已經設置的CCR沒影響  占空比
  262.         }
  263.         else
  264.                 {
  265.                 TIM_SetCompare4(TIM4,-car_right);
  266.                 TIM_SetCompare3(TIM4,1);
  267.                
  268.         }

  269.         if(car_left>0)
  270.                 {
  271.                 TIM_SetCompare4(TIM3,1);
  272.                 TIM_SetCompare3(TIM3,car_left);   ///設置占空比 CCR PWM比較寄存器
  273.         }
  274.         else
  275.         {
  276.                 TIM_SetCompare4(TIM3,-car_left);
  277.                 TIM_SetCompare3(TIM3,1);
  278.                
  279.         }        

  280. //        //總線馬達設置        
  281. //        sprintf((char *)cmd_return, "#0233P%dT0!#034P%dT0!",
  282. //        (int)(1500+car_left), (int)(1500+car_right));
  283. //        zx_uart_send_str(cmd_return);
  284.                
  285.         return;
  286. }


  287. //處理手柄
  288. void handle_ps2(void)
  289.         {
  290.         static u32 systick_ms_bak = 0;
  291.         //每20ms處理1次
  292.         if(systick_ms - systick_ms_bak < 20)
  293.                 {
  294.                 return;
  295.         }
  296.                
  297.         systick_ms_bak = systick_ms;
  298.         
  299.         //讀寫手柄數據
  300.         psx_write_read(psx_buf); //把psx buf數據處理
  301.         
  302. #if 0
  303.                 //測試手柄數據,1為打開 0為關閉
  304.         sprintf((char *)cmd_return, "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x\r\n",
  305.         (int)psx_buf[0], (int)psx_buf[1], (int)psx_buf[2], (int)psx_buf[3],
  306.         (int)psx_buf[4], (int)psx_buf[5], (int)psx_buf[6], (int)psx_buf[7], (int)psx_buf[8]);
  307.         uart1_send_str(cmd_return);
  308. #endif         
  309.         
  310.         return;
  311. }


  312. //處理手柄按鍵
  313. void handle_button(void)
  314.         {
  315.         static unsigned char psx_button_bak[2] = {0};///首先對這個數組清空
  316.         //對比兩次獲取的按鍵值是否相同 ,相同就不處理,不相同則處理
  317.         
  318.         if((psx_button_bak[0] == psx_buf[3])   //psx buf 是已經獲取的值
  319.         && (psx_button_bak[1] == psx_buf[4]))
  320.         {        
  321.                
  322.         }
  323.         
  324.         
  325.         else {
  326.                 //處理buf3和buf4兩個字節,這兩個字節存儲這手柄16個按鍵的狀態
  327.                 parse_psx_buf(psx_buf+3, psx_buf[1]);   ///獲取狀態  把按鍵獲取的數值 輸入到函數處理
  328.                 psx_button_bak[0] = psx_buf[3];//把這兩個值 放入到數組
  329.                 psx_button_bak[1] = psx_buf[4];
  330.         }
  331.         return;
  332. }



  333. //處理手柄按鍵字符,buf為字符數組,mode是指模式 主要是紅燈和綠燈模式  獲取按鈕狀態
  334. void parse_psx_buf(unsigned char *buf, unsigned char mode) ///mode就是紅燈或者綠燈
  335.         {
  336.         u8 i, pos = 0;
  337.         static u16 bak=0xffff, temp, temp2;
  338.         temp = (buf[0]<<8) + buf[1];
  339.         
  340.         if(bak != temp)
  341.                 {
  342.                 temp2 = temp;
  343.                 temp &= bak;
  344.                 for(i=0;i<16;i++) {//16個按鍵一次輪詢
  345.                         if((1<<i) & temp)
  346.                                 {
  347.                         }
  348.                                 
  349.                         
  350.                                 else
  351.                                         {
  352.                                 if((1<<i) & bak)
  353.                                         {        //press 表示按鍵按下了
  354.                                                                                                                         
  355.                                         memset(uart_receive_buf, 0, sizeof(uart_receive_buf));                                        ///把數組清空
  356.                                         if(mode == PS2_LED_RED)
  357.                                                 {
  358.                                                 memcpy((char *)uart_receive_buf, (char *)pre_cmd_set_red[i], strlen(pre_cmd_set_red[i]));
  359.                                         }
  360.                                                 else if(mode == PS2_LED_GRN)
  361.                                                         {
  362.                                                 memcpy((char *)uart_receive_buf, (char *)pre_cmd_set_grn[i], strlen(pre_cmd_set_grn[i]));
  363.                                         } //把按下的按鍵對應的數值傳遞給接收數組 用來解析
  364.                                                         
  365.                                                         else continue;
  366.                                        
  367.                                         pos = str_contain_str(uart_receive_buf, (u8 *)"^"); ///通過按鍵 解析模式
  368.                                         if(pos)
  369.                                                 uart_receive_buf[pos-1] = '\0';
  370.                                        
  371.                                         if(str_contain_str(uart_receive_buf, (u8 *)"[        DISCUZ_CODE_0        ]quot;)) //命令模式
  372.                                                 {
  373.                                                 uart1_close();
  374.                                                 uart1_get_ok = 0;
  375.                                                 strcpy((char *)cmd_return, (char *)uart_receive_buf+11);
  376.                                                 strcpy((char *)uart_receive_buf, (char *)cmd_return);
  377.                                                 uart1_get_ok = 1;
  378.                                                 uart1_open();
  379.                                                 uart1_mode = 1;
  380.                                         }
  381.                                                 
  382.                                        
  383.                                        
  384.                                                 else if(str_contain_str(uart_receive_buf, (u8 *)"#"))
  385.                                                         {
  386.                                                 uart1_close();
  387.                                                 uart1_get_ok = 0;
  388.                                                 strcpy((char *)cmd_return, (char *)uart_receive_buf+11);
  389.                                                 strcpy((char *)uart_receive_buf,(char *) cmd_return);
  390.                                                 uart1_get_ok = 1;
  391.                                                 uart1_open();
  392.                                                 uart1_mode = 2;
  393.                                         }
  394.                                        
  395.                                         //uart1_send_str(uart_receive_buf);
  396.                                         bak = 0xffff;
  397.                                 } else {//release 表示按鍵松開了
  398.                                                                                 
  399.                                         memset(uart_receive_buf, 0, sizeof(uart_receive_buf));                                       
  400.                                         if(mode == PS2_LED_RED) {
  401.                                                 memcpy((char *)uart_receive_buf, (char *)pre_cmd_set_red[i], strlen(pre_cmd_set_red[i]));
  402.                                         } else if(mode == PS2_LED_GRN) {
  403.                                                 memcpy((char *)uart_receive_buf, (char *)pre_cmd_set_grn[i], strlen(pre_cmd_set_grn[i]));
  404.                                         } else continue;        
  405.                                        
  406.                                         pos = str_contain_str(uart_receive_buf, (u8 *)"^");
  407.                                         if(pos) {
  408.                                                 if(str_contain_str(uart_receive_buf+pos, (u8 *)"[        DISCUZ_CODE_0        ]quot;)) {
  409.                                                         //uart1_close();
  410.                                                         //uart1_get_ok = 0;
  411.                                                         strcpy((char *)cmd_return, (char *)uart_receive_buf+pos);
  412.                                                         cmd_return[strlen((char *)cmd_return) - 1] = '\0';
  413.                                                         strcpy((char *)uart_receive_buf, (char *)cmd_return);
  414.                                                         parse_cmd(uart_receive_buf);
  415.                                                         //uart1_get_ok = 1;
  416.                                                         //uart1_mode = 1;
  417.                                                 } else if(str_contain_str(uart_receive_buf+pos, (u8 *)"#")) {
  418.                                                         //uart1_close();
  419.                                                         //uart1_get_ok = 0;
  420.                                                         strcpy((char *)cmd_return, (char *)uart_receive_buf+pos);
  421.                                                         cmd_return[strlen((char *)cmd_return) - 1] = '\0';
  422.                                                         strcpy((char *)uart_receive_buf, (char *)cmd_return);
  423.                                                         do_action(uart_receive_buf);
  424.                                                         //uart1_get_ok = 1;
  425.                                                         //uart1_mode = 2;
  426.                                                 }
  427.                                                 //uart1_send_str(uart_receive_buf);
  428.                                         }        
  429.                                 }

  430.                         }
  431.                 }
  432.                 bak = temp2;
  433.                 beep_on();mdelay(10);beep_off();
  434.         }        
  435.         return;
  436. }

  437. //int型 取絕對值函數
  438. int abs_int(int int1) {
  439.         if(int1 > 0)return int1;
  440.         return (-int1);
  441. }


  442. //處理小車函數 主要處理搖桿的數據 這里 8為左搖桿 6為右搖桿
  443. void handle_car(void)
  444.         {
  445.         static int car_left, car_right, car_left_bak, car_right_bak;
  446.         
  447.         if(psx_buf[1] != PS2_LED_RED)return;
  448.         
  449.         if(abs_int(127 - psx_buf[8]) < 5 )
  450.                 psx_buf[8] = 127;
  451.         
  452.         if(abs_int(127 - psx_buf[6]) < 5 )
  453.                 psx_buf[6] = 127;
  454.         
  455.         car_left = (127 - psx_buf[8]) * 8;
  456.         car_right = (127 - psx_buf[6]) * 8;
  457.         
  458. //        if(abs_int(car_left_bak-car_left) < 20 && abs_int(car_right_bak-car_right) < 20)return;
  459. //        if(abs_int(car_left_bak-car_left) > 40)car_left_bak = car_left;
  460. //        if(abs_int(car_right_bak-car_right) > 40)car_right_bak = car_right;
  461.         
  462.         if(car_left != car_left_bak || car_right != car_right_bak)
  463.                 {
  464.                 car_pwm_set(car_left, car_right);   ///把速度傳送到定時器PWM寄存器
  465.                 car_left_bak = car_left;
  466.                 car_right_bak = car_right;
  467.         }
  468. }



  469. //處理串口接收到的數據    ///首先通過中斷獲取串口的數據
  470. void handle_uart(void)
  471.    
  472. ///串口接收中斷,判斷中斷標志位,進入中斷函數,把數據保存在數組,判斷數組內容,返回uart1_get_ok
  473. ///當接收到數據之后,馬上執行串口解析動作,判斷數據,執行動作
  474.     {
  475.     if(uart1_get_ok)
  476.         
  477.         {
  478.         if(uart1_mode == 1)  //命令模式
  479.             {                    
  480.             //uart1_send_str("cmd:");
  481.             //uart1_send_str(uart_receive_buf);
  482.             parse_cmd(uart_receive_buf);            //解析命令模式
  483.         }
  484.             
  485.         
  486.         else if(uart1_mode == 2)           ///單個命令 只有一種模式
  487.             {            //單個舵機調試
  488.             //uart1_send_str("sig:");
  489.             //uart1_send_str(uart_receive_buf);
  490.             do_action(uart_receive_buf);    ///處理接收數據內容
  491.         }
  492.             
  493.             else if(uart1_mode == 3)
  494.                 {        //多路舵機調試
  495.             //uart1_send_str("group:");
  496.             //uart1_send_str(uart_receive_buf);
  497.             do_action(uart_receive_buf);
  498.         }
  499.                
  500.                 else if(uart1_mode == 4)
  501.                     {        //存儲模式
  502.             //uart1_send_str("save:");
  503.             //uart1_send_str(uart_receive_buf);
  504.             action_save(uart_receive_buf);
  505.         }
  506.                     
  507.         uart1_mode = 0;
  508.         uart1_get_ok = 0;
  509.     }

  510.     return;
  511. }


  512. /*
  513.     所有舵機停止命令:$DST!
  514.     第x個舵機停止命令:$DST:x!
  515.     單片機重啟命令:$RST!
  516.     檢查動作組x到y組命令:$CGP:x-y!
  517.     執行第x個動作:$DGS:x!
  518.     執行第x到y組動作z次:$DGT:x-y,z!
  519.     小車左輪x速度,右輪y速度:$DCR:x,y!
  520.     所有舵機復位命令:$DJR!
  521.     獲取應答信號:$GETA!
  522. */
  523. //命令解析函數
  524. void parse_cmd(u8 *cmd)
  525.     {
  526.     int pos, i, index, int1, int2;
  527.     u8 temp_buf[160];
  528.     u32 long1;
  529.    
  530.     //uart1_send_str(cmd);
  531.    
  532.     if(pos = str_contain_str(uart_receive_buf, (u8 *)"$DST!"), pos)  ///接收信息比較 所有舵機停止命令:$DST!
  533.         {
  534.         group_do_ok  = 1;         //動作執行完成標志
  535.             
  536.         for(i=0;i<DJ_NUM;i++)    ///停止舵機
  537. ……………………

  538. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

代碼下載: 注釋stm32單片機之串口1解析控制舵機.7z (1.18 MB, 下載次數: 10)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂1 踩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久人体视频 | 国产精品久久久久久久久久三级 | 亚洲一区在线日韩在线深爱 | 一区二区三区中文字幕 | 成人在线亚洲 | 成人羞羞国产免费视频 | 国产精品中文字幕在线 | 久久人爽 | 91大神在线看 | 久久三区 | 91精品国产一区二区三区 | 亚洲精品乱码久久久久久9色 | 久久极品 | 一区二区三区精品视频 | 亚洲瑟瑟| 久久免费看 | 国产精品久久国产精品 | 国产亚洲网站 | 精品欧美一区二区三区久久久 | 日韩一区二区免费视频 | 依人成人 | 狠狠干av | 天天综合永久入口 | 九九热在线视频观看这里只有精品 | 国产精品美女久久久久久免费 | 国产综合在线视频 | 日本人做爰大片免费观看一老师 | 懂色av蜜桃av | 国产精品色 | 久久99精品久久久久久国产越南 | 午夜播放器在线观看 | 成人妇女免费播放久久久 | 999久久久久久久 | 日韩欧美手机在线 | 日韩精品在线观看视频 | 7777奇米影视 | 欧美日韩视频在线第一区 | 久久国产精品视频 | 91视频大全 | avhd101在线成人播放 | 欧美日韩中 |