1、所用软件:MounRiver Studio
2、库函数为 成都逐飞科技有限公司 提供
由于初次接触是小白,程序比较乱,不精简,小车基本能实现简单避障但细节方面还需要进一步改进,望各位大佬轻喷
#include "zf_common_headfile.h"
// **************************** 代码区域 ****************************
#define MOTOR3_A A1 // 定义3电机正反转引脚
#define MOTOR3_B TIM5_PWM_CH1_A0 // 定义3电机PWM引脚
#define MOTOR4_A A2 // 定义4电机正反转引脚
#define MOTOR4_B TIM5_PWM_CH4_A3 // 定义4电机PWM引脚
#define S_MOTOR_PIN TIM2_PWM_CH1_A15 //定义舵机引脚 方向控制
#define yuntai_pin TIM4_PWM_CH3_D14 //定义超声波舵机引脚
#define Trig E14 //定义超声波触发引脚端口
#define Echo E15 //定义超声波触发引脚端口
uint32 wait_time = 0; //超时检测变量
float distance_time = 0; //测距的时间变量
float distance = 0; //转换出来的距离 单位为厘米
//前进函数 speed_power1=0最快 speed_power1=5000 不动
void run_go (int speed_power1 )
{
gpio_set_level(MOTOR3_A, 1);
pwm_set_duty(MOTOR3_B, speed_power1);
gpio_set_level(MOTOR4_A, 1);
pwm_set_duty(MOTOR4_B, speed_power1);
system_delay_ms(100);
}
//后退函数 speed_power1=10000最快 speed_power1=5000 不动
void run_back (int speed_power2 )
{
gpio_set_level(MOTOR3_A, 1);
pwm_set_duty(MOTOR3_B, speed_power2);
gpio_set_level(MOTOR4_A, 1);
pwm_set_duty(MOTOR4_B, speed_power2);
system_delay_ms(100);
}
// 停止函数
void run_stop()
{
gpio_set_level(MOTOR3_A, 1);
pwm_set_duty(MOTOR3_B, 5000);
gpio_set_level(MOTOR4_A, 1);
pwm_set_duty(MOTOR4_B, 5000);
system_delay_ms(100);
}
//右拐
void turn_right()
{
pwm_init(S_MOTOR_PIN, 50, 2*10000/20);
pwm_set_duty(S_MOTOR_PIN, 2*10000/20);
}
//左拐
void turn_left()
{
pwm_init(S_MOTOR_PIN, 50, 0.8*10000/20);
pwm_set_duty(S_MOTOR_PIN, 0.8*10000/20);
}
//归中
void middle()
{
float duty=0;
duty = 1.5*10000/20;
pwm_init(S_MOTOR_PIN, 50, duty);
pwm_set_duty(S_MOTOR_PIN, 1.5*10000/20);
}
//超声波转向
void yuntai(float a) //a=2 左45度 a=1右45度 a=1.5归中
{
uint16 duty=0;
duty = a*10000/20;
pwm_init(yuntai_pin, 50, duty);
/*
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;
*/
pwm_set_duty(yuntai_pin, duty);
}
//距离函数
float get_distance()
{
gpio_set_level(Trig, 1);//E14输出高电平
system_delay_us(10) ;
gpio_set_level(Trig, 0);//E14输出低电平
while(!gpio_get_level(Echo));
timer_start(TIM_1, TIMER_US);
wait_time = 0;
while(gpio_get_level(Echo))
{
if(wait_time++ > 10000000) //超时检测
{
break; //超过等待时间
}
system_delay_us(1) ;
}
if(wait_time<200000) distance_time = timer_get(TIM_1);//获取定时的时间
else distance_time = 200000;
//timer_stop(TIM_1); //关闭定时器以清除计时
distance = distance_time/58.0; //计算距离 cm
return(distance);
}
int main()
{
interrupt_global_disable(); // 关闭总中断
clock_init(SYSTEM_CLOCK_144M); // 务必保留,设置系统时钟。
debug_init(); // 务必保留,本函数用于初始化MPU 时钟 调试串口
gpio_init(MOTOR3_A, GPO, 0, GPIO_PIN_CONFIG);
pwm_init(MOTOR3_B,17000,0);
gpio_init(MOTOR4_A, GPO, 0, GPIO_PIN_CONFIG);
pwm_init(MOTOR4_B,17000,0);
uart_init(UART_8, 115200, UART8_TX_E14, UART8_RX_E15); //串口8初始化引脚号,TX为E15,RX为A10
gpio_init(Trig, GPO, GPIO_LOW, GPO_PUSH_PULL); // 初始化E14引脚,作为输出
gpio_init(Echo, GPI, GPIO_LOW, GPI_FLOATING_IN ); // 初始化E15引脚,作为输入引脚使用
// float get_distance=0;
interrupt_global_enable(); // 总中断最后开启
system_delay_ms(100);
while(1)
{
float left_distance=0; //检测左侧距离
float right_distance=0;//检测右侧侧距离
yuntai(1.5);
middle();
run_go(2500);
//system_delay_ms(2000);
//printf("distance = %.2f cm\r\n \r\n", get_distance());
while (30<=get_distance()) {;} //前方无障碍直行
run_stop();
yuntai(2);
system_delay_ms(1000);
left_distance=get_distance();
//system_delay_ms(2000);
yuntai(1);
system_delay_ms(1000);
right_distance=get_distance();
//system_delay_ms(2000);
while(left_distance>=30&&right_distance>=30)//左右两侧都大于30cm 默认右拐
{
yuntai(1);
run_back(7500);
system_delay_ms(1000);
run_stop();
system_delay_ms(500);
turn_right();
system_delay_ms(1000);
run_go(2500);
if(30<=get_distance()) {;}
else
{ run_stop();
break;
}
system_delay_ms(2000);
break;
}
while(left_distance>=30&&right_distance<=30)//左侧无障碍右侧有 则后退停止前行左拐
{
yuntai(2);
run_back(7500);
system_delay_ms(500);
run_stop();
system_delay_ms(500);
turn_left();
system_delay_ms(1000);
run_go(2500);
if(30<=get_distance()) {;}
else
{ run_stop();
break;
}
system_delay_ms(2000);
break;
}
while(right_distance>=30&&left_distance<=30)//左侧有障碍右侧无
{
yuntai(1);
run_back(7500);
system_delay_ms(500);
run_stop();
turn_right();
system_delay_ms(1000);
run_go(2500);
if(30<=get_distance()) {;}
else
{ run_stop();
break;
}
system_delay_ms(2000);
break;
}
while(left_distance<=30&&right_distance<=30)//左右两侧有障碍则后退 前行右拐
{
run_back(7500);
system_delay_ms(2000);
run_stop();
system_delay_ms(100);
turn_right();
system_delay_ms(1000);
run_go(2500);
system_delay_ms(2000);
break;
}
}
}