基于SMT32智能小车项目 下(3.24)

第五步,实现循迹小车:

main.c

#define LeftWheel_Value HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_3)	
#define RightWheel_Value HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_4)	

while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(LeftWheel_Value== GPIO_PIN_RESET && RightWheel_Value== GPIO_PIN_RESET)
		{	
			goForward();
		}
		if(LeftWheel_Value== GPIO_PIN_RESET && RightWheel_Value== GPIO_PIN_SET)
		{	
			goLeft();
		}
		if(LeftWheel_Value== GPIO_PIN_SET && RightWheel_Value== GPIO_PIN_RESET)
		{	
			goRight();
		}
		if(LeftWheel_Value== GPIO_PIN_SET && RightWheel_Value== GPIO_PIN_SET)
		{	
			stop();
		}
    }

motor.c

#include "motor.h"
#include "gpio.h"
#include "tim.h"

void goForward(void)
{
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,199);			//左轮
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,199);		//右轮
}

void goBack(void)	//循迹小车用不到向后
{
	//左轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);
	//右轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);	
}

void goLeft(void)								//50hz,比较值至少为150电机才能带动
{
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,150);			//左轮
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,199);		//右轮
}

void goRight(void)
{
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,199);			//左轮
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,160);		//右轮
}

void stop(void)
{
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_1,0);			//左轮
	__HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,0);		//右轮
}

第六步实现跟随小车:

和循迹小车过于类似,把红外发送接收模块输入线改为PB5和PB6,代码和循迹小车一模一样,只需要把while循环中左右转函数调换一下即可。

第七步摇头避障小车:

硬件接线:

sg90 -- PB9

Trig       --    PB7

Echo     -- PB8

(电机接线和第一步接线方式,无PWM)

B-1A -- PB0

B-1B -- PB1

A-1A -- PB2

A-1B -- PB10

————————————————————

sg90.c

#include "sg90.h"
#include "gpio.h"
#include "tim.h"


void initSG90_90(void)	
{
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);	//启动定时器4中的pwm
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,15);		//舵机90度
}

void sgMiddle(void)	
{
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,15);			//舵机90度
}

void sgRight(void)									
{
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,5);			//舵机0度
}

void sgLeft(void)	
{
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,25);		//舵机180度
}

sr04.c(超声波:型号hc-sr04)

#include "sr04.h"
#include "gpio.h"
#include "tim.h"

void TIM2_Delay_us(uint16_t n_us)
{

	__HAL_TIM_ENABLE(&htim2);
	__HAL_TIM_SetCounter(&htim2, 0);
	while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );
	
	__HAL_TIM_DISABLE(&htim2);
}

float get_distance()
{
	float distance=0;
	int time=0;
	
	
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
	TIM2_Delay_us(15);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
	
	
	while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_RESET);	
	
	HAL_TIM_Base_Start(&htim2);	
	__HAL_TIM_SetCounter(&htim2, 0);
	
	while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8) == GPIO_PIN_SET);
	
	HAL_TIM_Base_Stop(&htim2);	
	time = __HAL_TIM_GetCounter(&htim2);
	
	distance = (340*time/2*0.000001*100);	
	
	return distance;
}

motor.c

#include "motor.h"
#include "gpio.h"

void goForward(void)
{
	//左轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET);
	//右轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);	
}

void goBack(void)
{
	//左轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);
	//右轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);	
}

void goLeft(void)
{
	//左轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);
	//右轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);	
}

void goRight(void)
{
	//左轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_SET);
	//右轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);	
}

void stop(void)
{
	//左轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_10,GPIO_PIN_RESET);
	//右轮
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);	
}

main.c


/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "sg90.h"
#include "sr04.h"
#include "motor.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define MIDDLE 0
#define LEFT 1
#define RIGHT 2

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	char dir;
	double disMiddle;
	double disLeft;
	double disRight;

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM4_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
	HAL_Delay(300);
	initSG90_90();
	dir=MIDDLE;
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(dir!=MIDDLE)
		{
			sgMiddle();
			dir=MIDDLE;
			HAL_Delay(300);
		}
		disMiddle=get_distance();
		
		if(disMiddle>35)//前进
		{
			goForward();
		}
		else if(disMiddle<10)	//快撞墙时后退
		{
			goBack();
			HAL_Delay(150);
		}
		else	//停下测出左右两边的距离
		{
			stop();
			
			sgLeft();
			HAL_Delay(300);
			disLeft=get_distance();
			
			sgMiddle();
			HAL_Delay(300);
			
			sgRight();
			HAL_Delay(300);
			disRight=get_distance();
			dir=RIGHT;
			
			if(disLeft<disRight)	//右边距离大,向右转
			{
				goRight();
				HAL_Delay(150);
			}
			if(disLeft>disRight)	//左边距离大,向左转
			{
				goLeft();
				HAL_Delay(150);
			}

		}
		
		
		HAL_Delay(50);		//防止单片机运行过快
	}

摇头避障小车代码延用了51单片机相同项目的代码,注意的点:

1.停下判断左右距离的时候,要把最后两个if语句放在else中,否则会有bug,但是在51单片机中没有。

2.在while循环最后要加一个50ms的延时,防止单片机运行过快,卡死。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值