基于stm32的智能小车设计
图2.11 TIMx_PSC寄存器各位描述
接下来介绍自动重装载寄存器(TIMx_ARR),该寄存器的各位描述如下图所示:
图2.12 TIMx_ARR寄存器各位描述
通过设置这两个寄存器,我们就可以算出PWM的输出周期,计算公式为: Tout=((arr+1)*(psc+1))/Tclk。其中Tclk为系统时钟周期。
其次我们介绍捕获/比较模式寄存器(TIMx_CCMR1/2),总共有两个,TIMx_CCMR1和
TIMx_CCMR2,TIMx_CCMR1控制通道CH1和CH2,TIMx_CCMR2控制CH3和CH4。因为这2个寄存器差不多,我们仅以通道CH1为例,介绍其中的TIMx_CCMR1为例,该寄存器的各位描述如下图所示:
图2.13 TIMx_CCMR1/2寄存器各位描述
这里我们只介绍该寄存器的OCxM位,我们就以TIMx_CCMR1中的OC1M(控制通道CH1)为例,该位功能如下图所示:
- 15 -
基于stm32的智能小车设计
图2.14 OC1M功能描述
我们使用的是PWM输出模式,所以OC1M必须设置为110/111。OC2M(控制通道CH2)各位描述与OC1M相同,我们这要不在叙述。
然后我们介绍捕获/比较使能寄存器(TIMx_CCER),该寄存器控制着各个输入/输出通道
的开关,对于该寄存器,各位描述如下图所示:
图2.15 TIMx_CCER寄存器描述
该寄存器比较简单,因为我们只介绍通道1,所以我们只讲CC1E位。如果我们想使能输入/捕获1,我们只需使用CC1E位。要想使PWM从I/O口输出,此位必须设置为1。
最后介绍捕获/比较寄存器(TIMx_CCR1~4),总共有4个,分别对应CH1~4,因为这4个寄存器相似,我们仅以TIMx_CCR1为例,该寄存器的给位介绍如下图所示:
图2.16 TIMx_CCR1寄存器各位描述
- 16 -
基于stm32的智能小车设计
在输出模式下,该寄存器的值与CNT中的值进行比较,根据结果,实现电平的翻转。至此,我们把用到的几个寄存器都介绍完毕,下面我们就介绍如何通过库函数来配置实现PWM三路输出。
? 开启TIM3时钟以及复用功能输出。使能GPIO和端口复用功能时钟。库函
数使能TIM3、GPIO以及复用功能时钟的方法是: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
? 初始化TIM3,设置TIM3的PSC和ARR。在开启了TIM3的时钟之后,我
们要设置PSC和ARR寄存器的值来控制PWM的输出周期。调用的格式如下:
TIM_TimeBaseStructure.TIM_Period=arr; TIM_TimeBaseStructure.TIM_Prescaler=psc; TIM_TimeBaseStructure.TIM_ClockDivision=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
? 设置TIM3_CH1、CH2、CH3的PWM模式,使能TIM3的CH1、CH2、CH3
输出。在库函数中PWM通道设置是通过TIM_OC1Init~TIM_OC4Init来设置的,这里我们需要3路PWM输出,所以我们需要使用函数TIM_OC1Init、TIM_OC2Init、TIM_OC3Init。库函数的调用格式如下: TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC3Init(TIM3, &TIM_OCInitStructure);
? 使能TIM3。完成以上配置后,我们要使能定时器TIM3。库函数调用格式
如下:
TIM_Cmd(TIM3, ENABLE);
- 17 -
基于stm32的智能小车设计
? 通过修改TIM3_CCRx(x为1,2,3)来控制占空比。库函数格式如下:
Void TIM_SetComparex(TIM3,uint16_t Compare2);
我们可以知道,通过定时器3控制PWM波的占空比,从而实现速度方面的控制。其中arr和psc可以控制PWM波的周期,TIM3_CCRx可以控制PWM波的占空比。我们只需要调用此函数就可以实现不同的速度控制。
对于运动方向控制的代码我们就以后退为例,由于端口寄存器过于简单,我们不在此介绍端口的寄存器。我们仅介绍如何通过库函数进行端口配置。对各个I/O端口配置的过程相似,我们仅以PD8为例:主要过程如下所示: ? 使能I/O口时钟,调用格式如下所示:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOC, ENABLE);
? 初始化I/O参数,调用格式如下所示:
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); ? 操作I/0口
GPIO_SetBits(GPIOD,GPIO_Pin_8);PD8置1 GPIO_ResetBits(GPIOD,GPIO_Pin_8);PD8置0
我们知道了如何对端口进行操作之后就可以随意的控制小车的运动啦,运动方向的程序设计,其基本函数单元如下所示: void Left_Low(void);…
我们调用这些函数,就可以实现不同运动方向的控制。主要代码详见附录3.
2.3 避障模块设计
在人类身体构造系统中,眼睛可以使我们非常方便的采集到外界环境的信息,然后把信息及时的传输到大脑,并对外界环境信息的变化做出相应的处理。而对智能小车来说,避障模块之于小车就相当于眼睛之于人类。避障模块可以采集外部地形数据,然后把所采集的地形数据传输到中央处理模块,从而实现躲避障碍的功能。避障模块所采用的器件在市场中有许多类型,比如红外检测,光位移检
- 18 -
基于stm32的智能小车设计
测,超声波检测等。本次试验我们使用的是HC-SR04超声波检测,超声波由于具有检测能力强,传播路径宽,因此我们决定使用HC-SR04器件。
在使用HC-SR04模块进行超声波测距的同时,我们可以使用舵机进行辅助。舵机的主要作用是改变HC-SR04模块的照射方向,从而控制超声波的发射方向。在程序编写过程中,如果小车前方遇见障碍时,我们可以直接控制舵机的转向,而小车的车身可以保持不变,在测量结束后,小车再做相应的动作。 2.3.1 避障模块器件结构及其原理
HC-SR04超声波测距模块测量范围在2cm-400cm之间,可以实现无接触式测距功能。HC-SR04超声波测距模块由一个超声波发射器、一个超声波接收器和控制电路组成,避障模块的实物结构图如图2.17所示:
图2.17 实物正反面结构图
如结构图所示VCC提供5v电源,GND为接地线,TRIG为触发信号线,ECHO为回向信号输出线。基本原理如下:采用IO口TRIG触发测距,给至少10us的高电平信号,在TRIG触发沿到来后,超声波发射器会自动发出8个40KHz的方波,并且检测是否有信号返回,当超声波接收器接收到超声波时,表明有信号返回,通过IO口ECHO输出一高电平,高电平持续的时间就是超声波从发射到返回的时间。因此测量距离=(高电平持续时间*340m/s)/2。测量时序图如图2.18所示:
- 19 -