今天是實訓的最後一天,我們在前兩天基礎實驗的基礎上將其擴展,做項目——智能小車的循跡避障
項目要求:
1、小車開機後紅燈閃爍三次,黃燈閃爍兩次,然後亮綠燈,開始循跡行駛
2、小車行駛過程需根據軌道能平緩調整方向
3、小車行駛過程前面20cm範圍內有障礙物,需能停止,並亮紅燈;障礙物移開後,小車亮綠燈並繼續前行
設計思想:模塊化設計
(一)呼吸燈模塊
呼吸燈模塊使用紅、綠、藍三色燈,通過不同組合組成不同的顏色,初始默認三燈都是低電平,呈現白色,而其他兩燈隨機組合則會呈現不同顏色,如:紅燈和綠燈同時亮藍燈滅時呈現黃色;紅和藍組合呈現品紅或紫色等。
(二)循跡模塊
利用紅外光電和電機驅動實現,通過對紅外光電程序的輸入,小車實現直行、左轉和右轉時亮不同的燈,通過改變PA2、PB9、PA1、PC9口上的高低電平變化控制小車前進方向,通過改變PA0、PA3口上的高低電平的佔空比以控制電機的轉速。
(三)避障模塊
通過超聲波模塊實現避障,在一定的距離範圍內,小車通過超聲波接收範圍內就離數據,來判斷該範圍內是否有障礙物,有障礙物時小車就停下,障礙物移開後,小車前行。
核心代碼:(僅供參考)
/*USER CODE BEGIN Includes */
#define full_speed 200
#define null_speed 0
#define correct_speed 100
#define MOTOR_A_CON1_GPIO GPIOA
#define MOTOR_A_CON1_PIN GPIO_PIN_2
#define MOTOR_A_CON2_GPIO GPIOB
#define MOTOR_A_CON2_PIN GPIO_PIN_9
#define MOTOR_A_EN_GPIO GPIOA
#define MOTOR_A_EN_PIN GPIO_PIN_0
#define MOTOR_B_CON1_GPIO GPIOA
#define MOTOR_B_CON1_PIN GPIO_PIN_1
#define MOTOR_B_CON2_GPIO GPIOC
#define MOTOR_B_CON2_PIN GPIO_PIN_9
#define MOTOR_B_EN_GPIO GPIOA
#define MOTOR_B_EN_PIN GPIO_PIN_3
#define _HAL_TIM_SET_COMPARE(_HANDLE_, _CHANNEL_,COMPARE_) \
(*(_I0 uint32_t *)(&((_HANDLE_)->Instance->CCRl) + ((_CHANNEL_) ? 2))=(_COMPARE_))
#define Left1_GPIO GPIOC //左側探頭
#define Left1_PIN GPIO_PIN_7
#define Left2_GPIO GPIOC //左側探頭
#define Left2_PIN GPIO_PIN_6
#define Middle_GPIO GPIOB //距離檢測
#define Middle_PIN GPIO_PIN_12
#define Right1_GPIO GPIOB //右側探頭
#define Right1_PIN GPIO_PIN_15
#define Right2_GPIO GPIOB //右側探頭
#define Right2_PIN GPIO_PIN_14
#define Left1 HAL_GPIO_ReadPin(Left1_GPIO,Left1_PIN)
#define Left2 HAL_GPIO_ReadPin(Left2_GPIO,Left2_PIN)
#define Middle HAL_GPIO_ReadPin(Middle_GPIO,Middle_PIN)
#define Right1 HAL_GPIO_ReadPin(Right1_GPIO,Right1_PIN)
#define Right2 HAL_GPIO_ReadPin(Right2_GPIO,Right2_PIN)
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);//小燈初始化
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);//打開PWM
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);
/* USER CODE END 2 */
/*USER CODE BEGIN WHILE */
for(i=0;i<3;i++)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
HAL_Delay(1000);
}
for(i=0;i<2;i++)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
HAL_Delay(1000);
}
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);
HAL_TIM_Base_Start_IT(&htim2);
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(distance>20){//判斷沒有障礙物
if(Left1 == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
Correct_Left();
}
else if(Left2 == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
litter_Left();
}
else if(Middle == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
Straight();
}
else if(Right1 == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
Correct_Right();
}
else if(Right2 == GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
litter_Right();
}
else{
Straight();
}
}else{
Stop();
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);//ºì
}
/* USER CODE END 3 */
/* USER CODE BEGIN 4 */
void Change_Pulse(u
int16_t left,uint16_t right)
{
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, left);
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4, right);
}
void Correct_Left(void)
{
Change_Pulse(150,150);
HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);
}
void litter_Left(void)
{
Change_Pulse(0,150);
HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);
}
//------------------------------------------------
void Correct_Right(void)
{
Change_Pulse(150,150);
HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_RESET);
}
void litter_Right(void)
{
Change_Pulse(150,0);
HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_RESET);
}
//-----------------------------------------------------
void Straight(void)
{
Change_Pulse(150,150);
HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);
}
void Stop(void)
{
Change_Pulse(0,0);
HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_RESET);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==&htim2)
{
HAL_TIM_Base_Stop_IT(&htim2);
ultrasonic=0;
HAL_GPIO_WritePin(Trig_GPIO, Trig_PIN, GPIO_PIN_SET);
HAL_TIM_Base_Start_IT(&htim3);
}
else if(htim==&htim3)
{
HAL_GPIO_WritePin(Trig_GPIO,Trig_PIN, GPIO_PIN_RESET);
ultrasonic=1;
HAL_TIM_Base_Stop_IT(&htim3);
HAL_TIM_Base_Start_IT(&htim2);
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin==GPIO_PIN_2)
{
if(HAL_GPIO_ReadPin(Echo_GPIO, Echo_PIN))
{
ultrasonic_time=__HAL_TIM_GET_COUNTER(&htim2);
}
else if(ultrasonic==1)
{
ultrasonic=0;
ultrasonic_time=__HAL_TIM_GET_COUNTER(&htim2)-ultrasonic_time;
ultrasonic_time=ultrasonic_time*170/100;
distance = ultrasonic_time;
ultrasonic_time=ultrasonic_time%1000;
b[0]=ultrasonic_time/100+'0';
ultrasonic_time=ultrasonic_time%100;
b[1]=ultrasonic_time/10+'0';
b[2]=ultrasonic_time%10+'0';
ultrasonic_time=0;
HAL_GPIO_WritePin(Trig_GPIO,Trig_PIN, GPIO_PIN_RESET);
}
}
}
/* USER CODE END 4 */
```