超声波测距避障需要舵机的参与来测量小车左右的距离,达到避障的目的。
1、舵机工作原理:
舵机的转动角度是通过调节PWM(脉冲宽度调制)信号的占空比来实现的,标准PWM信号的周期固定为20ms(50Hz),理论上脉宽分布应在1ms到2ms之间,但实际上脉宽可由0.5ms到2.5ms之间,脉宽和舵机的转角0°~180°相对应。
**接线:**信号线接在PA6
servomotor.h:
#ifndef _SERVOM_H
#define _SERVOM_H
#include "sys.h"
void ServoM_Init(void); //舵机初始化
void Servo_control(int angle); //舵机控制函数
void front_detection(void); //舵机向前
void left_detection(void); //舵机左转
void right_detection(void); //舵机右转
void ControlLeftOrRight(void); //舵机自检函数
#define Servo_pin GPIO_Pin_6
#define Servo_port GPIOA
#define Servo_RCC RCC_APB2Periph_GPIOA
#endif
servomotor.c:
//舵机控制程序
//舵机控制需要一个周期20ms(50Hz)的pwm波, 理论上0°~180°对应脉宽为1ms~2ms,实际上则为0.5ms~2.5ms
void ServoM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(Servo_RCC, ENABLE); //使能PA端口时钟
GPIO_InitStructure.GPIO_Pin = Servo_pin; //PA6端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(Servo_port, &GPIO_InitStructure); //根据设定参数初始化
}
void Servo_control(int angle)
{
int pulsewidth; //定义脉宽变量
pulsewidth=(angle*11)+500; //将角度转换为500~2480的脉宽值
GPIO_SetBits(Servo_port,Servo_pin);
delay_us(pulsewidth);
GPIO_ResetBits(Servo_port,Servo_pin);
delay_ms(20-pulsewidth/1000); //延时周期内剩余时间
}
//云台舵机向前
void front_detection()
{
int i=0;
//此处减少循环次数,为了增加小车遇到障碍物的反应速度
for(i=0; i<15; i++) //产生PWM个数,等效延时以保证能转到响应角度
{
Servo_control(90);
}
}
//云台舵机向左
void left_detection()
{
int i=0;
//此处减少循环次数,为了增加小车遇到障碍物的反应速度
for(i=0; i<15; i++) //产生PWM个数,等效延时以保证能转到响应角度(从一个角度转动另外一个角度的时间)
{
Servo_control(175);
}
}
//云台舵机向右
void right_detection()
{
int i=0;
//此处减少循环次数,为了增加小车遇到障碍物的反应速度
for(i=0; i<25; i++) //产生PWM个数,等效延时以保证能转到响应角度
{
Servo_control(5);
}
}
void ControlLeftOrRight(void) //舵机自检函数
{
u8 i;
left_detection(); //电机转到左边
for(i=0;i<=5;i++)
{
delay_ms(100);
}
right_detection(); //电机转到右边
for(i=0;i<=5;i++)
{
delay_ms(100);
}
front_detection(); //电机转到前方
for(i=0;i<=5;i++)
{
delay_ms(100);
}
}
上面程序中舵机转向有一个for循环是因为舵机转到指定角度需要一定的时间,如果不加for循环 舵机无法转到指定的角度。循环的次数可以改变,转动角度越大,需要循环的次数越多。
舵机转动测试:
main.c
int main()
{
ServoM_Init();
delay_init();
while(1)
{
ControlLeftOrRight();
}
}
测试效果欢迎观看视频:
小车测试效果