第五步,实现循迹小车:
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的延时,防止单片机运行过快,卡死。