找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2444|回复: 12
收起左侧

STM32寻迹小车程序理解的问题

  [复制链接]
ID:526143 发表于 2019-5-15 17:12 | 显示全部楼层 |阅读模式
这个是stm32寻迹控制轮子程序但是我到现在都没读懂他到底定义是哪四个io口,PA6,PA7 PB8,PB9,OR,PC6,PC7,PC8,PC9,求大神指点

  1. #include "motor_control.h"
  2. #include "SysTick.h"
  3. #include "UltrasonicWave.h"
  4. #include "pwm_output.h"
  5. #include "usart1.h"

  6. #define ONWARD   1
  7. #define BACKWARD 0
  8. extern vu8  count;
  9. extern vu32 averge_distance;
  10. vu8 left,right,middle;
  11. vu32 S2;
  12. vu32 S4;
  13. vu32 S1;
  14. vu32 timer;
  15. //u16 Pwm_Right;
  16. //u16 Pwm_Left;

  17. /**************************************
  18.     函数名    :Control_GPIO_Config
  19.     函数描述:配置Control小车用到的I/O口
  20.     输入参数:无
  21.     输出参数:无
  22. **************************************/
  23. void  GPIO_Configuration(void)
  24. {
  25.     GPIO_InitTypeDef GPIOA_InitStructure,GPIOB_InitStructure;   //定义两个GPIO_InitTypeDef类型的结构体
  26.    
  27.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE);//开启GPIOA外设时钟

  28.     GPIOA_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9; //选择要控制的GPIOA引脚
  29.     GPIOA_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式为推挽式输出
  30.     GPIOA_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速度为50Mhz
  31.     GPIO_Init(GPIOA,&GPIOA_InitStructure); //调用库函数初始化    GPIOA
  32.     //刚开始停止电机转动
  33.     GPIO_SetBits(GPIOC,GPIO_Pin_8|GPIO_Pin_9);
  34.    
  35.    
  36.     //RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE);  //开启GPIOB的时钟
  37.    
  38.     GPIOB_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;  //选择要控制的GPIOB引脚
  39.     GPIOB_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //配置引脚模式为推挽式输出
  40.     GPIOB_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //设置引脚速度为50MHz
  41.    
  42.     GPIO_Init(GPIOC,&GPIOB_InitStructure);            //调用初始化GPIOB
  43.     GPIO_SetBits(GPIOC,GPIO_Pin_6|GPIO_Pin_7);        //启动关闭电机
  44.       
  45. }

  46. /*****************************************
  47.    函数名        : Control_GPIOE_Config
  48.    输入描述 : 对传感器输入信号的管脚配置
  49.    输入参数 :无
  50.    输出参数 :无
  51. ******************************************/
  52. void Control_GPIOE_Config(void)
  53. {
  54.     GPIO_InitTypeDef GPIOB_InitStructure;  //定义GPIOE管脚结构体变量
  55.    
  56.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,ENABLE);//开启GPIOE外设时钟
  57.    
  58.     GPIOB_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_4;
  59.     GPIOB_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //输入采用浮空输入
  60.    
  61.     GPIO_Init(GPIOB,&GPIOB_InitStructure);
  62. }

  63. /********************************************
  64. * 函数名 :TIM3_GPIO_Config
  65. * 描述  :配置TIM3复用输出PWM时用到的I/O
  66. * 输入  :无
  67. * 输出  :无
  68. * 调用  :内部调用
  69. *********************************************/
  70. void TIM3_GPIO_Config(void)
  71. {
  72.     GPIO_InitTypeDef GPIO_InitStructure;
  73.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //配置GPIOC的管脚
  74.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //开启TIM3时钟
  75.     /**配置pwm输出的对应GPIO管脚****/
  76.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  77.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;      //复用推挽式输出
  78.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  79.   GPIO_Init(GPIOA, &GPIO_InitStructure);
  80. }


  81. /*****************************************************************************
  82. *文件名           : TIM_Configuration
  83. *描述             : TIM4 初始化
  84. * 输入            : 无
  85. * 输出            : 无
  86. * 返回            : 无
  87. ******************************************************************************/
  88. void TIM3_Configuration(u16 CCR_Val_12,u16 CCR_Val_34)
  89. {
  90.    
  91.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  92.     TIM_OCInitTypeDef    TIM_OCInitStructure;
  93.    
  94.     //CCR_Val_12 = 900;
  95.     //CCR_Val_34 = 900;
  96.     /* -----------------------------------------------------------------------
  97.     TIM3 Configuration: generate 2 PWM signals with 2 different duty cycles:
  98.     TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
  99.     TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
  100.     TIM3 Frequency = 36 KHz.
  101.       TIM3 Channel1 duty cycle = (CCR_Val_12/ TIM3_ARR)* 100 = 50%
  102.       TIM3 Channel1 duty cycle = (CCR_Val_34/ TIM3_ARR)* 100 = 50%
  103.   ----------------------------------------------------------------------- */
  104.     /***通道1的配置*****/
  105.     TIM_TimeBaseStructure.TIM_Period = 999;        //设定总周期值
  106.     TIM_TimeBaseStructure.TIM_Prescaler = 0;      //设置预分频:不预分频,即为36MHz
  107.     TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;    //设置时钟分频系数:不分频
  108.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
  109.    
  110.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  111.    
  112.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;        //配置为PWM模式1
  113.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
  114.   TIM_OCInitStructure.TIM_Pulse = CCR_Val_12;       //设置跳变值,当计数器计数到这个值时,电平发生跳变
  115.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //当定时器计数值小于CCR_Val时为高电平
  116.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  117.   TIM_OCInitStructure.TIM_Pulse = CCR_Val_34;      //设置通道3的电平跳变值,输出另外一个占空比的PWM
  118.    
  119.   TIM_OC1Init(TIM3, &TIM_OCInitStructure);     //使能通道1
  120.   TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
  121.    

  122.   TIM_OC2Init(TIM3, &TIM_OCInitStructure);      //使能通道2
  123.     TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
  124.     /***通道3的配置*****/
  125.    
  126.   TIM_ARRPreloadConfig(TIM3, ENABLE);             // 使能TIM3重载寄存器ARR
  127.   TIM_Cmd(TIM3, ENABLE);                   //使能定时器3   
  128.    
  129. //  TIM_OC3Init(TIM3, &TIM_OCInitStructure);      //使能通道3
  130. //    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);


  131. //  TIM_OC4Init(TIM3, &TIM_OCInitStructure);      //使能通道4
  132. //    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
  133. //   
  134.    
  135. }

  136. /*************壁障前进***********/
  137. void Forward_run(void)
  138. {
  139.      /*左侧轮子停转*/
  140. //                Pwm_Left = 900;
  141. //                Pwm_Right = 900;
  142.                
  143.                 TIM3_Configuration(700,700);
  144.    
  145.                
  146.                 GPIO_ResetBits(GPIOC,GPIO_Pin_8);//0
  147.                 GPIO_SetBits(GPIOC,GPIO_Pin_9);//1
  148.    
  149.                 GPIO_ResetBits(GPIOC,GPIO_Pin_6);//0
  150.                 GPIO_SetBits(GPIOC,GPIO_Pin_7);//1
  151.         
  152. }
  153. /*************壁障后退***********/
  154. void Backward_run(void)
  155. {
  156.    
  157.     /*左侧轮子停转*/
  158. //                Pwm_Left = 900;
  159. //                Pwm_Right = 900;
  160.                
  161.                 TIM3_Configuration(700,700);
  162.    
  163.          GPIO_SetBits(GPIOC,GPIO_Pin_8);//1
  164.                 GPIO_ResetBits(GPIOC,GPIO_Pin_9);//0
  165.          
  166.           GPIO_SetBits(GPIOC,GPIO_Pin_6);//1
  167.           GPIO_ResetBits(GPIOC,GPIO_Pin_7);//0

  168.                

  169. }
  170. /*************壁障左转***********/
  171. void Left_turn(void)
  172. {
  173.    /*左侧轮子停转*/
  174. //     Pwm_Left = 900;
  175. //     Pwm_Right = 900;
  176.   
  177.     TIM3_Configuration(700,700);
  178.   
  179. //    GPIO_ResetBits(GPIOB,GPIO_Pin_1);//0 //右电机转动
  180. //    GPIO_SetBits(GPIOB,GPIO_Pin_0);//1

  181.    
  182.     GPIO_SetBits(GPIOC,GPIO_Pin_8); //左电机停止
  183.     GPIO_SetBits(GPIOC,GPIO_Pin_9);
  184.    
  185.   GPIO_ResetBits(GPIOC,GPIO_Pin_6);//0 //右电机转动
  186.     GPIO_SetBits(GPIOC,GPIO_Pin_7);//1
  187. }
  188. /*************壁障右转***********/
  189. void Right_turn(void)
  190. {
  191. /***右侧停转*/
  192. //     Pwm_Left = 900;
  193. //     Pwm_Right = 900;
  194.   

  195.     TIM3_Configuration(700,700);
  196.    
  197.   GPIO_ResetBits(GPIOC,GPIO_Pin_8);//0 //左电机转动
  198.     GPIO_SetBits(GPIOC,GPIO_Pin_9);//1
  199.    
  200.   GPIO_SetBits(GPIOC,GPIO_Pin_6); //右电机停止
  201.     GPIO_SetBits(GPIOC,GPIO_Pin_7);
  202.    
  203. //    GPIO_SetBits(GPIOB,GPIO_Pin_2);//1
  204. //    GPIO_ResetBits(GPIOB,GPIO_Pin_4);//0
  205. }
  206. /*************停止**********/
  207. void Stop(void)
  208. {     
  209.          /*左侧轮子停转*/
  210. //                Pwm_Left = 0;
  211. //                Pwm_Right = 0;
  212.                
  213.                 TIM3_Configuration(0,0);
  214.    
  215.       
  216.                 GPIO_SetBits(GPIOC,GPIO_Pin_8);
  217.                 GPIO_SetBits(GPIOC,GPIO_Pin_9);
  218.                
  219.                 GPIO_SetBits(GPIOC,GPIO_Pin_6);
  220.                 GPIO_SetBits(GPIOC,GPIO_Pin_7);

  221. }
  222. /*************循迹前进***********/
  223. void Xunji_Forward_run(void)
  224. {
  225.      /*左侧轮子停转*/
  226. //                Pwm_Left = 900;
  227. //                Pwm_Right = 900;
  228.                
  229.                 TIM3_Configuration(400,400);
  230.    
  231.                
  232.                 GPIO_ResetBits(GPIOC,GPIO_Pin_8);//0
  233.                 GPIO_SetBits(GPIOC,GPIO_Pin_9);//1
  234.    
  235.                
  236.                 GPIO_ResetBits(GPIOC,GPIO_Pin_6);//0
  237.                 GPIO_SetBits(GPIOC,GPIO_Pin_7);//1
  238.         
  239. }

  240. /*************循迹左转***********/
  241. void Xunji_Left_turn(void)
  242. {
  243.    /*左侧轮子停转*/
  244. //     Pwm_Left = 900;
  245. //     Pwm_Right = 900;
  246.   
  247.     TIM3_Configuration(400,400);
  248.   
  249. //    GPIO_ResetBits(GPIOB,GPIO_Pin_1);//0 //右电机转动
  250. //    GPIO_SetBits(GPIOB,GPIO_Pin_0);//1

  251.    
  252.     GPIO_SetBits(GPIOC,GPIO_Pin_8); //左电机停止
  253.     GPIO_SetBits(GPIOC,GPIO_Pin_9);
  254.    
  255.   GPIO_ResetBits(GPIOC,GPIO_Pin_6);//0 //右电机转动
  256.     GPIO_SetBits(GPIOC,GPIO_Pin_7);//1
  257. }

  258. /*************循迹右转***********/
  259. void Xunji_Right_turn(void)
  260. {
  261. /***右侧停转*/
  262. //     Pwm_Left = 900;
  263. //     Pwm_Right = 900;
  264.   

  265.     TIM3_Configuration(400,400);
  266.    
  267.   GPIO_ResetBits(GPIOC,GPIO_Pin_8);//0 //左电机转动
  268.     GPIO_SetBits(GPIOC,GPIO_Pin_9);//1
  269.    
  270.   GPIO_SetBits(GPIOC,GPIO_Pin_6); //右电机停止
  271.     GPIO_SetBits(GPIOC,GPIO_Pin_7);
  272.    
  273. //    GPIO_SetBits(GPIOB,GPIO_Pin_2);//1
  274. //    GPIO_ResetBits(GPIOB,GPIO_Pin_4);//0
  275. }
  276. /*************循迹停止***********/
  277. void Xunji_Stop(void)
  278. {     
  279.          /*左侧轮子停转*/
  280. //                Pwm_Left = 0;
  281. //                Pwm_Right = 0;
  282.                
  283.                 TIM3_Configuration(400,400);
  284.    
  285.       
  286.                 GPIO_SetBits(GPIOC,GPIO_Pin_8);
  287.                 GPIO_SetBits(GPIOC,GPIO_Pin_9);
  288.                
  289.                 GPIO_SetBits(GPIOC,GPIO_Pin_6);
  290.                 GPIO_SetBits(GPIOC,GPIO_Pin_7);

  291. }
  292. void  COMM(void) //方向函数
  293. {
  294.          Degree(20,1);
  295. //    TIM_SetCompare1(TIM2,11);
  296.          Delay_ms(700);
  297.          Average_Distance();
  298.          S2=averge_distance;
  299.         
  300.          Degree(150,1);
  301. //    TIM_SetCompare1(TIM2,4);
  302.          Delay_ms(700);
  303.          Average_Distance();
  304.          S4=averge_distance;
  305.         
  306.          Degree(85,1);
  307. //    TIM_SetCompare1(TIM2,8);
  308.          Delay_ms(700);
  309.          S1=averge_distance;
  310.          
  311.         if(S2<30||S4<30) //只要左右各有距离小于20CM小车后退
  312.         {      
  313.         Backward_run(); //后退  
  314.         Delay_ms(700);                    
  315.         }
  316.    
  317.     if(S2>S4)
  318.     {
  319.         Right_turn(); //车的左边比车的右边距离小,右转
  320.         Delay_ms(700);   
  321.     }
  322.     else
  323.     {
  324.         Left_turn(); //车的左边比车的右边距离大,左转
  325.         Delay_ms(700);   
  326.     }
  327.      }

  328. /***************************************************
  329. * 函数名         : Auto_run
  330. * 描述           : 避障程序
  331. * 输入           : 无
  332. * 输出           : 无
  333. * 返回           : 无
  334. ****************************************************/
  335. void Auto_run(void)                                       //检测障碍
  336. {        

  337.     Average_Distance();

  338.     if(averge_distance<30)
  339.     {
  340.          Stop();//小车停止
  341.          COMM(); //方向函数
  342.      }
  343.    
  344.      else
  345.     {
  346.         if(averge_distance>30)
  347.       {
  348.       Forward_run();
  349.             

  350.       }
  351.     }
  352. }

  353. /***************************************************
  354. * 函数名         : 循迹程序
  355. * 输入           : 无
  356. * 输出           : 无
  357. * 返回           : 无
  358. ****************************************************/
  359. void Xunji_run(void)                                       //检测障碍
  360. {        
  361.      //四路寻迹传感器有信号(白线)为0 没有信号(黑线)为1
  362.            if(Out1==0 && Out2==0&&Out3==0 &&Out4==0 )
  363.              {
  364.                  Xunji_Forward_run();//实现小车的前进
  365.               }
  366.               else if(Out1==1 && Out2==0&&Out3==0 &&Out4==1 )
  367.              {
  368.                  Xunji_Stop();//实现小车的停止
  369.               }
  370.               else if(Out1==0 && Out2==1&&Out3==1 &&Out4==0 )
  371.              {
  372.                  Xunji_Forward_run();//实现小车的前进   
  373.               }
  374.                 else if(Out1==0 && Out2==1&&Out3==0 &&Out4==0 )
  375.              {
  376. //                 TurnRight();//实现小车的左转
  377.                  Xunji_Left_turn();
  378.               }
  379.               else if(Out1==1 && Out2==0&&Out3==0 &&Out4==0 )
  380.              {
  381. //                 TurnRight();//实现小车的左转
  382.                  Xunji_Left_turn();
  383.               }
  384.              else if(Out1==0 && Out2==0&&Out3==1 &&Out4==1 )
  385.              {
  386.                  Xunji_Right_turn();//实现小车的前进
  387.               }     
  388.                else if(Out1==0 && Out2==1&&Out3==1 &&Out4==1 )
  389.              {
  390. //                 TurnRight();//实现小车的左转
  391.                   Xunji_Left_turn();
  392.               }     
  393.               else if(Out1==0 && Out2==0&&Out3==0 &&Out4==1 )
  394.              {
  395. //                 TurnLeft();//实现小车的右转
  396.                  Xunji_Right_turn();//实现小车的左转
  397.               }     
  398.                else if(Out1==0 && Out2==0&&Out3==1 &&Out4==0     )
  399.              {
  400. //                 TurnLeft();//实现小车的右转
  401.                  Xunji_Right_turn();//实现小车的左转
  402.                  
  403.               }
  404.               else if(Out1==1 && Out2==1&&Out3==0 &&Out4==0     )
  405.              {
  406. //                 RunToForward();//实现小车的前进
  407.                  Xunji_Left_turn();
  408.               }
  409.               else if(Out1==1 && Out2==1&&Out3==1 &&Out4==0     )
  410.              {      
  411. //                 TurnLeft();//实现小车的右转
  412.                   Xunji_Right_turn();//实现小车的左转
  413.               }
  414.               else
  415.                  {
  416.                      Xunji_Stop();//实现小车的停止
  417.                   }


  418. }
复制代码






回复

使用道具 举报

ID:526143 发表于 2019-5-19 16:38 | 显示全部楼层
没有大佬解答一下吗?
回复

使用道具 举报

ID:563677 发表于 2019-6-25 13:53 来自手机 | 显示全部楼层
6,7,8,9吧
回复

使用道具 举报

ID:839922 发表于 2021-4-1 19:38 | 显示全部楼层
根据主板原理图看接口
回复

使用道具 举报

ID:996669 发表于 2023-3-22 20:26 | 显示全部楼层
请问你有完整的STM32寻迹小车程序吗?
回复

使用道具 举报

ID:844772 发表于 2023-3-23 08:38 | 显示全部楼层
单单从这两句看
//刚开始停止电机转动
    GPIO_SetBits(GPIOC,GPIO_Pin_8|GPIO_Pin_9);
显然是让 PC8和9 置高,但前边又没给GPIOC 初始化,所以不是你迷惑,是程序问题。
回复

使用道具 举报

ID:1066823 发表于 2023-3-23 09:27 | 显示全部楼层
既然是pin  那就是唯一,看原理图或芯片手册
回复

使用道具 举报

ID:646520 发表于 2023-3-23 14:36 | 显示全部楼层
19年的帖子....,这是哪个大神找出来的
回复

使用道具 举报

ID:139866 发表于 2023-3-23 16:01 | 显示全部楼层
这程序让我想起了我以前的同事,不光代码跟注释对不上号,变量的命名也跟操作的外设对不上号,配置跟思路那必然也是没对上号。我接手他的程序简直就像到了地狱

你这程序从结果上来看,开了GPIOB和GPIOC的时钟,后面的TIM3函数里配置了GPIOA的时钟,配置有效的是PA6,PA7,PB0,PB1PB3PB4,PC6,PC7,如果程序用的时候TIM_GPIO这个函数放在 GPIO_Configuration前面的话,PA8,PA9也是能用的

一句话,烂程序,不该出现在这个世界

谢谢楼主,让我回忆起了地狱
回复

使用道具 举报

ID:996669 发表于 2023-4-2 21:52 | 显示全部楼层
请问可以发一下电机驱动的代码吗
回复

使用道具 举报

ID:291668 发表于 2023-4-2 22:34 | 显示全部楼层
哈哈,这一看就是用别的程序改的。注释没有更改。根据GPIO 时钟使能,应该是用C口的6、7、8、9来控制的。
回复

使用道具 举报

ID:894420 发表于 2023-4-3 14:49 | 显示全部楼层
应该是用C口的6、7、8、9
回复

使用道具 举报

ID:1069659 发表于 2023-4-3 16:05 | 显示全部楼层
程序从结果上来看,开了GPIOB和GPIOC的时钟,后面的TIM3函数里配置了GPIOA的时钟,配置有效的是PA6,PA7,PB0,PB1PB3PB4,PC6,PC7,如果程序用的时候TIM_GPIO这个函数放在 GPIO_Configuration前面的话,PA8,PA9也是能用的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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