控制《STM32实现智能小车红外循迹控制》

文章目录

  • 前言
  • 一、硬件选择与连接
  • 1. STM32F103C8T6最小系统板
  • 2. L298N双路电机驱动
  • 3. 红外循迹模块
  • 二、环境配置
  • 1. Device
  • 2. Output
  • 3. C/C++
  • 4. Debug
  • 三、项目管理与代码实现
  • 1. 项目结构
  • 2. 工程管理
  • 3. 具体文件
  • xunji.c
  • xunji.h
  • main.c
  • 总结

  • 前言

    这篇文章我主要讲的是让基于stm32单片机下的智能小车实现红外循迹功能,智能小车的项目非常多,比如说循迹避障、蓝牙遥控、视觉控制等等,我将会一步一步带大家走进stm32单片机的项目当中。


    一、硬件选择与连接

    在硬件部分,与前几节我所介绍的51智能小车大致一样,所不同的是把51最小系统板换成了stm32最小系统板,其他驱动、红外循迹模块都一样,具体可前往【51单片机实例】智能小车(一)了解详情。

    下面我还是会对相关重要模块进行简单介绍:

    1. STM32F103C8T6最小系统板



    配套资源:

    1. STM32F103C8主芯片一片
    2. 贴片8M晶振(通过芯片内部PLL最高达72M)ST官方标准参数
    3. 3.3V稳压芯片,最大提供800mA电流
    4. 一路miniUSB接口,可以给系统版供电,预留USB通讯功能
    5. 复位按键
    6. 标准SWD口一个,支持JLink,STLink,JLINK OB
    7. BOOT选择端口
    8. IO扩展排针 20pin x 2
    9. 电源指示灯1个
    10. 功能指示灯一个,用于验证IO口基本功能
    11. 预留串口接口,方便和5V开发板连接,用串口即可程序
    12. 高性能爱普生32768Hz晶振,价格是直插晶振的10倍价格,易起振
    13. 20K RAM,64K ROM ,TQFP48封装

    2. L298N双路电机驱动

    L298N,是一款接受高电压的电机驱动器,直流电机和步进电机都可以驱动。一片驱动芯片可同时控制两个直流减速电机做不同动作,在6V到46V的电压范围内,提供2安培的电流,并且具有过热自断和反馈检测功能,可对电机进行直接控制,通过主控芯片的I/O输入对其控制电平进行设定,就可为电机进行正转反转驱动,操作简单、稳定性好,可以满足直流电机的大电流驱动条件。

    3. 红外循迹模块

    TCRT5000传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或被反射回来但强度不够大时,红外接收管一直处于关断状态,此时模块的输出端为高电平,指示二极管一直处于熄灭状态;被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和,此时模块的输出端为低电平,指示二极管被点亮。

    接口说明:
    (1) VCC 外接3.3V-5V电压(可以直接与5v单片机和3.3v单片机相连)
    (2) GND 外接GND
    (3) OUT 小板数字量输出接口(0和1)

    二、环境配置

    1. Device

    我们选用的是STM32F103C8T6最小系统板,所以Device应选择STM32F103C8

    2. Output

    Output中应创建HEX可执行文件

    3. C/C++

    C/C++中应定义宏和包含文件路径

    4. Debug

    若选用 ST-link 或 J-link 还是其他下载器or串口,都需要事先安装相应的驱动和配置相关环境,这里我以ST-link为例配置相关环境

    三、项目管理与代码实现

    1. 项目结构

    2. 工程管理

    应在相应的工程文件下面添加上对应的.c文件

    3. 具体文件

    以下我主要说明几个比较重要的文件

    xunji.c

    #include "xunji.h"  
    #include "stm32f10x.h"
    
    void motor_gpio()
    {
    
      GPIO_InitTypeDef  GPIO_InitStructure;
    	 
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	  
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11; 		
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 	  //推挽输出 
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 
      GPIO_Init(GPIOB, &GPIO_InitStructure);			     
    
    }
    
    void xunji_gpio()
    {
    
      GPIO_InitTypeDef  GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	  
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_7;		
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //上拉输入
      GPIO_Init(GPIOA, &GPIO_InitStructure);		
    
    }
    void pwm()
    {
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    	TIM_OCInitTypeDef  TIM_OCInitStructure;
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_8; 		
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用输出 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 
        GPIO_Init(GPIOB, &GPIO_InitStructure);	
    	
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);	  //使能定时器4时钟 
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);   //使能GPIOB时钟
    	  
    	TIM_TimeBaseStructure.TIM_Period =99;    //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    	TIM_TimeBaseStructure.TIM_Prescaler =71;     //设置用来作为TIMx时钟频率除数的预分频值
    	TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //设置时钟分割:TDTS = Tck_tim
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //TIM向上计数模式 
    	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);    
    	
    	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //选择定时器模式:TIM脉冲宽度调制模式1
     	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //比较输出使能
    	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    //输出极性:TIM输出比较极性高
     	TIM_OCInitStructure.TIM_Pulse=0;
    	
    	TIM_OC1Init(TIM4, &TIM_OCInitStructure);  
    	TIM_OC3Init(TIM4, &TIM_OCInitStructure);  
    	
    
    	TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);   //使能TIM4在CCR1上的预装载寄存器
    	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);   //使能TIM4在CCR3上的预装载寄存器
    
    	
    	TIM_Cmd(TIM4, ENABLE);   //使能TIM4
    }
    void run()
    {
    
    		TIM_SetCompare1(TIM4,30);
       		TIM_SetCompare3(TIM4,30);
    		IN1 = 1;
    		IN2 = 0;
    		
    		IN3 = 1;
    		IN4 = 0;
    }
    void back()
    {
    		TIM_SetCompare1(TIM4,70);
    		TIM_SetCompare3(TIM4,70);
    	
    		IN1 = 0;
    		IN2 = 1;
    		
     
    		IN3 = 0;
    		IN4 = 1;
    }
    void right()
    {
    		TIM_SetCompare1(TIM4,0);
    		TIM_SetCompare3(TIM4,30);
    	
    		IN1 = 1;
    		IN2 = 0;
    	
    		IN3 = 0;
    		IN4 = 0;
    }
    void left()
    {
    		TIM_SetCompare1(TIM4,30);
    		TIM_SetCompare3(TIM4,0);
    		
    		IN1 = 0;
    		IN2 = 0;
    		
    		IN3 = 1;
    		IN4 = 0;
    }
    
    void stop()
    {
    
    		 IN1 = 0;
    		 IN2 = 0;
    		
    		 IN3 = 0;
    		 IN4 = 0;
    	}
    
    

    xunji.h

    
    #ifndef __xunji_H
    #define __xunji_H 	
    
    #include "sys.h"  
    
    #define      IN1         PBout(0)
    #define      IN2         PBout(1)
    
    #define      IN3         PBout(10)
    #define      IN4         PBout(11)
    
    
    #define      LEFT_ONE      PAin(3)  
    #define      LEFT_TWO      PAin(7) 
     
    void run(void);
    void left(void);
    void right(void);
    void back(void);;
    void stop(void);
    void motor_gpio(void);
    void xunji_gpio(void);
    void pwm(void);
    #endif
    
    

    main.c

    #include "stm32f10x.h"
    #include "xunji.h"
    #include "delay.h"
    
     void Init()
    {
    	TIM_SetCompare1(TIM4,25);
    	TIM_SetCompare3(TIM4,25);
    	IN1=1;
    	IN2=0;
    	IN3=1;
    	IN4=0;
    }
     
     int main(void)
     {	
    
    		motor_gpio();
    		xunji_gpio();
    		pwm();             
    		delay_init();
    	  	Init();
    			while(1)
    			{
    
    					if(LEFT_ONE==0&&LEFT_TWO==0)
    					{
    							 run();
    					}
    					
    					else if(LEFT_ONE==0&&LEFT_TWO==1)
    					{
    					
    							right();
    					}
    					
    					else if(LEFT_ONE==1&&LEFT_TWO==0)
    					{
    					
    							left();
    					}
    					
    		      else if(LEFT_ONE==1&&LEFT_TWO==1)
    					{
    							run();
    					}
    					else
    						stop();
    			 }
    }
    

    总结

    本节是以STM32F103C8T6最小系统为CPU,通过一些外围电路和软件编程实现小车红外循迹的功能。整个设计过程中最大的特点是利用简单的理论原理将红外循迹模块、L298N驱动模块、51单片机这三个模块有效的结合起来,利用红外循迹原理与pwm调节占空比的简单结合实现对小车红外循迹奠定编程理论基础,提高了效率,降低了编程的复杂度,具有很强的研究的意义,智能化的发展促使了智能小车往功能更加强大的方向发展。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 控制《STM32实现智能小车红外循迹控制》

    发表评论