找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2039|回复: 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 单片机教程网

快速回复 返回顶部 返回列表