超声波避障小车

一、超声波模块的介绍

采用HC-SR04超声波模块,该芯片具有较高的集成度以及良好的稳定性,测度距离十分精确,十分稳定。
供电电压为DC5V供电电流小于10mA,探测距离为0.010m-3.5m,一共有四个引脚VCC(DC5V)、Triger(发射端)Echo(接收端)、GND(地)。

实物长这样:
超声波实物

该模块是利用单片机的IO触发电平测距,过程如下:
单片机内部利用普通定时器产生一个超过10us的高电平信号之后,超声波就可以自主发送8个频率为40khz的方波,同时回波引脚(echo)端的电平从0变成1(此时应该开启定时器计时),然后等待信号的返回;
若有信号返回,单片机IO口就立刻输出一高电平,回波引脚端的电平从1变成0(此时停止定时器计时),高电平持续的时间就是超声波从发射到返回的时间,利用高电平产生的时间可以计算小车与障碍物的距离;
最终测得的距离就是:测试距离=(高电平时间*声速(340M/S))/2,可以反复测量距离。

代码实现:
在程序开始首先初始化超声波,使能定时器并设置时基的自动重装载初值1000,psc为预分频值72,这样的话我们产生一次中断的时间是1ms,并设置抢占优先级0,子优先级3。HC_SR04_Echo引脚接收到高电平,打开定时器,且每1ms进入一次中断。在测量时首先让Trig发送一个大于10us的高电平,然后拉高HC_SR04_Trig,当Echo为0时打开定时器计时,当Echo为1时关闭定时器,通过公式计算距离。

 

超声波部分的相关代码

/* 获取接收到的高电平的时间(us*/
 uint32_t Get_HC_SR04_Time(void)
 {
     uint32_t t=0;
     t=Acoustic_Distance_Count*1000;//us
     t+=TIM_GetCounter(TIM2);//获取计数器的值
     TIM2->CNT =0;
     Acoustic_Distance_Count=0;
     Systic_Delay_us(100);
    return t;
}
/*获取距离*/
void Get_HC_SR04_Distance(void)
{
    static uint16_t count=0;
    switch(count)
    {
        case 1:
        {
            GPIO_SetBits(Acoustic_Port,HC_SR04_Trig);//Trig发送一个大于10us的高电平
        }break;

        case 15:
        {
            count=0;
            GPIO_ResetBits(Acoustic_Port,HC_SR04_Trig);
            while(GPIO_ReadInputDataBit(Acoustic_Port,HC_SR04_Echo)==0);//当Echo为0时打开定时器计时
            Open_Tim2();
            while(GPIO_ReadInputDataBit(Acoustic_Port,HC_SR04_Echo)==1);//当Echo为1时关闭定时器计时
            Close_Tim2();
            HC_SR04_Distance=(float)(Get_HC_SR04_Time()/5.78);

        }break;
        default:break;
    }
    count++;
}

还可以添加两个led灯来判断超声波测距功能的实现,其中:
PB7引脚上连接的是距离过近led,如果近距离内出现障碍,它会亮起;
PB9引脚上连接的是距离过远led,如果在很远的距离范围里都没有障碍,它会亮起;
如果距离适中,那么两个led都不会亮起。

int main(void) 
{
 	SysTick_Init();
 	iniTim();
 	while(1) 
 	{
 		double len = 0;
  		len = get_length();
  		if ( len < 0.5 ) //如果距离够近
  		{
  			GPIO_SetBits(GPIOB,GPIO_Pin_7);//点亮距离过近led
   			GPIO_ResetBits(GPIOB,GPIO_Pin_9);//复位距离过远led
  		}
  		else 
   		{
   			if(toofar)//距离长到tim溢出,> 17m
   			{
    				GPIO_SetBits(GPIOB,GPIO_Pin_9);//点亮距离过远led
    				GPIO_ResetBits(GPIOB,GPIO_Pin_7);//复位距离过近led
   			}
   			else
   			{
     				GPIO_ResetBits(GPIOB,GPIO_Pin_7);//复位距离过近led
    				GPIO_ResetBits(GPIOB,GPIO_Pin_7);//复位距离过近led
    			}
  		}  
 	}
}

 

 

二、舵机模块的介绍

本系统使用的是SG90型号的舵机,舵机是伺服电机的一种,伺服电机就是带有反馈环节的电机,我们可以通过伺服电机进行精确的位置控制或者输出较高的扭矩,本系统需要判断前、左、右三个方向的障碍物???可以且对转向的力度小???

舵机实物图如下:

  

内部结构

  • ①:信号线:接收来自微控制器的控制信号;

  • ②:电位器:可以测量输出轴的位置量,属于整个伺服机构的反馈部分;

  • ③:内部控制器:处理来自外部控制的信号,驱动电机以及处理反馈的位置信号,是整个伺服机构的核心;

  • ④:电机:作为执行机构,输出多少转速,转矩,位置;

  • ⑤:传动机构/舵机系统:该机构根据一定传动比,将电机输出的行程缩放到最终输出的角度上;

因此舵机是伺服电机的一种,整体电机就是一个闭环系统,输入相应的信号,就能控制舵机输出对应的位置量。

 

硬件连接

舵机的硬件布线比较简单,我们只需要三条线:电源线,信号线,地线

如果单个舵机的电流比较小,例如SG90这种舵机,在空闲的时候大约只消耗10mA的电流,在旋转的时候需要消耗100-250mA,因此,一般控制系统如果具备这样的输出能力,可以直接进行驱动;

如果舵机所需电流较大,则需要额外增加驱动电路,将数字控制端和功率端隔离开;

或者需要同时驱动多个舵机,可以使用PCA9685对多路PWM进行驱动;

 

 

伺服控制

通过向舵机的信号信号线发送PWM信号来控制舵机的输出量;

上一篇文章有介绍过PWM,一般来说,PWM的周期以及占空比,我们是可控的,所以PWM脉冲的占空比直接决定了输出轴的位置。

下面举个例子;

  • 当我们向舵机发送脉冲宽度为1.5毫秒(ms)的信号时,舵机的输出轴将移至中间位置(90度);

  • 脉冲宽度为1ms时,舵机的输出轴将移至最小的位置(0度);

  • 脉冲宽度为2ms时,舵机的输出轴将移至最小的位置(180度);

注意:不同类型和品牌的伺服电机之间最大位置和最小位置的角度可能会不同。许多伺服器仅旋转约170度(或者只有90度),但宽度为1.5 ms的伺服脉冲通常会将伺服设置为中间位置(通常是指定全范围的一半)

具体可以参考下图;

 

 

舵机模块接口简单,舵机模块只有三个引脚。分别引引出了三根线左右两边是电源正负接口线,中间一根是PWM信号线直接连接单片机的控制引脚。通过控制单片机的引脚输出的脉冲宽度进而控制舵机旋转的角度。舵机每增加0.1ms 舵机对应增加9度。
0.5ms---------0
1.0ms---------45
1.5ms---------90
2.0ms---------135
2.5ms-----------180
20ms的时基脉冲,如果想让舵机转90度,就应该发生一个高电平持续时间为1.5ms,周期为20ms的方波,duty=1.5/20=7.5%。在这里设置定时器自动重装载寄存器arr的值为1000,所以当占空比为百分之75是,在程序中就要设置占空比为75/1000=7.5%, 这就是具体的算法。
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值