用hal库写一个循迹代码
时间: 2024-05-18 09:12:55 浏览: 121
循迹程序源码
好的,以下是一份基于HAL库的循迹代码,代码中使用了两个红外传感器进行循迹,如果需要使用其他传感器或调整控制逻辑,可以根据具体情况进行修改。
```
#include "main.h"
#include "stm32f1xx_hal.h"
// 定义红外传感器的引脚号
#define LEFT_SENSOR_PIN GPIO_PIN_0
#define LEFT_SENSOR_PORT GPIOA
#define RIGHT_SENSOR_PIN GPIO_PIN_1
#define RIGHT_SENSOR_PORT GPIOA
// 定义小车电机的引脚号
#define LEFT_MOTOR_PIN GPIO_PIN_0
#define LEFT_MOTOR_PORT GPIOB
#define RIGHT_MOTOR_PIN GPIO_PIN_1
#define RIGHT_MOTOR_PORT GPIOB
// 定义红外传感器的阈值
#define SENSOR_THRESHOLD 1500
// 定义小车电机的PWM周期和分辨率
#define PWM_PERIOD 1000
#define PWM_RESOLUTION 100
// 定义小车电机的速度
#define MOTOR_SPEED 50
// 定义小车控制状态
typedef enum {
FORWARD,
LEFT,
RIGHT
} CarState;
// 初始化红外传感器
void IR_Sensor_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = LEFT_SENSOR_PIN | RIGHT_SENSOR_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(LEFT_SENSOR_PORT, &GPIO_InitStruct);
}
// 初始化小车电机
void Motor_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
TIM_HandleTypeDef htim = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_TIM4_CLK_ENABLE();
GPIO_InitStruct.Pin = LEFT_MOTOR_PIN | RIGHT_MOTOR_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(LEFT_MOTOR_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM4_IRQn);
htim.Instance = TIM4;
htim.Init.Prescaler = SystemCoreClock / (PWM_PERIOD * PWM_RESOLUTION) - 1;
htim.Init.CounterMode = TIM_COUNTERMODE_UP;
htim.Init.Period = PWM_RESOLUTION - 1;
htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim);
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_1);
HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim, TIM_CHANNEL_2);
}
// 控制小车电机向前走
void Motor_Forward(void) {
TIM4->CCR1 = MOTOR_SPEED * PWM_RESOLUTION / 100;
TIM4->CCR2 = MOTOR_SPEED * PWM_RESOLUTION / 100;
}
// 控制小车电机向左转
void Motor_Left(void) {
TIM4->CCR1 = 0;
TIM4->CCR2 = MOTOR_SPEED * PWM_RESOLUTION / 100;
}
// 控制小车电机向右转
void Motor_Right(void) {
TIM4->CCR1 = MOTOR_SPEED * PWM_RESOLUTION / 100;
TIM4->CCR2 = 0;
}
// 获取红外传感器的值
uint16_t IR_Sensor_Read(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
return HAL_GPIO_ReadPin(GPIOx, GPIO_Pin);
}
// 控制小车运动
void Car_Control(CarState state) {
switch(state) {
case FORWARD:
Motor_Forward();
break;
case LEFT:
Motor_Left();
break;
case RIGHT:
Motor_Right();
break;
default:
Motor_Forward();
break;
}
}
// 定时器中断处理函数,每隔10ms读取红外传感器的值并控制小车运动
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
uint16_t left_value, right_value;
CarState state = FORWARD;
left_value = IR_Sensor_Read(LEFT_SENSOR_PORT, LEFT_SENSOR_PIN);
right_value = IR_Sensor_Read(RIGHT_SENSOR_PORT, RIGHT_SENSOR_PIN);
if(left_value < SENSOR_THRESHOLD && right_value < SENSOR_THRESHOLD) {
state = FORWARD;
} else if(left_value < SENSOR_THRESHOLD && right_value > SENSOR_THRESHOLD) {
state = LEFT;
} else if(left_value > SENSOR_THRESHOLD && right_value < SENSOR_THRESHOLD) {
state = RIGHT;
} else {
state = FORWARD;
}
Car_Control(state);
}
// 程序入口函数
int main(void) {
HAL_Init();
IR_Sensor_Init();
Motor_Init();
HAL_TIM_Base_Start_IT(&htim4);
while (1) {}
}
```
以上是一个基于HAL库的循迹代码,代码中使用了定时器中断处理函数来实现每隔10ms读取红外传感器的值并控制小车运动。如果您有其他问题或疑问,可以继续提出来,我会尽力为您解答。
阅读全文