基于STM32f103c8t6的简单红外巡迹避障小车制作

这篇具有很好参考价值的文章主要介绍了基于STM32f103c8t6的简单红外巡迹避障小车制作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、硬件部分

1、模块选择

(1)电源

电源模块选用的是18650锂电池(充电器及电池底座)、3.3v稳压模块。
基于STM32f103c8t6的简单红外巡迹避障小车制作
基于STM32f103c8t6的简单红外巡迹避障小车制作

(2)车模

淘宝最常见的智能车底。
基于STM32f103c8t6的简单红外巡迹避障小车制作

(3)电机

买的智能车带有四个电机,选用L298N电机驱动板对电机进行驱动。

基于STM32f103c8t6的简单红外巡迹避障小车制作

(4)巡迹及避障

巡迹选用四路红外模块实现,避障选用超声波模块HC-SR04实现。

基于STM32f103c8t6的简单红外巡迹避障小车制作
基于STM32f103c8t6的简单红外巡迹避障小车制作

(5)其它

热熔胶枪,焊笔,杜邦线,主控制器STM32f103c8t6核心板,烧录工具(usb转ttl模块、ST-Link或J-Link)等。

2、硬件连接

(1)电源

将电池组引出线的正极接L298N模块的+12V(Vcc)端,负极接L298N模块的GND端,再将L298N的+5V端和GND端与3.3V稳压模块的5V与GND分别相连。最后把稳压模块的3.3V和GND与STM32核心板上的3.3V与GND相连。

(3)电机

将一侧电机的两极分别与L298N模块的Out1和Out2相连,另一侧的电机与Out3和Out4相连(写程序时测试正转与反转如何控制)。将L298N上的IN1,IN2,IN3,IN4分别与STM32核心板上的四个不同的IO口连接(本人连接的是PA7,PA6,PB1,PB0)。

(4)红外

四个红外模块与主控板上对应的端口相连即可。主控板上的3.3V与GND与STM32核心板上的3.3V和GND相连,IN1,IN2,IN3,IN4分别与STM32核心板上的四个不同的IO口连接(本人连接的是PB4,PB5,PB6,PB7)。

(4)超声波

HC-SR04上的5V与GND与STM32核心板上的5V和GND相连,TRIG与ECHO与STM32核心板上的两个不同的IO口连接(本人连接的是PB11,PB10)。

二、软件部分

1、电机

编程思路:控制核心板IO口的电平(即电机驱动模块的IN1,IN2,IN3,IN4)从而控制Out1、Out2、Out3、Out4的电平高低,进而控制电机使其正转、反转、不转。由于单纯地拉高拉低电平只能让电机在转与不转的状态切换,故决定利用TIM3的四个通道分别产生四路PWM信号来控制电机速度。

/*Head File*/
#ifndef _PWM_H
#define _PWM_H
#include <stm32f10x.h>
#include <sys.h>

#define PWMA1   TIM3->CCR1  
#define PWMA2   TIM3->CCR2 
#define PWMB1   TIM3->CCR3  
#define PWMB2   TIM3->CCR4

void PWM_Init(uint16_t Arr,uint16_t Psc);
void Set_LeftMotor(int speed);
void Set_RightMotor(int speed);

#endif
#include <PWM.h>

void PWM_Init(uint16_t Arr,uint16_t Psc){
	GPIO_InitTypeDef GPIO_InitStruct;         
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_OCInitTypeDef TIM_OCInitStruct;   
	
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);        
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;      
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;      
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
 
	TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);     
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;       
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;     
	TIM_TimeBaseInitStruct.TIM_Period=Arr;         
	TIM_TimeBaseInitStruct.TIM_Prescaler=Psc;      	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
 
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;          
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;
	
	TIM_OC1Init(TIM3,&TIM_OCInitStruct );          
	TIM_OC2Init(TIM3,&TIM_OCInitStruct );
	TIM_OC3Init(TIM3,&TIM_OCInitStruct );          
	TIM_OC4Init(TIM3,&TIM_OCInitStruct);
	
	TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
	TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable);      
	TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable);		
	
	TIM_ARRPreloadConfig(TIM3,ENABLE);      
	
	TIM_Cmd(TIM3,ENABLE);    
}

void Set_RightMotor(int speed){
	if(speed<0)			PWMA1=2000,PWMA2=2000+speed;
	else 	          PWMA2=2000,PWMA1=2000-speed;
}
	
void Set_LeftMotor(int speed){
	if(speed<0)			PWMB1=2000,PWMB2=2000+speed;
	else 	          PWMB2=2000,PWMB1=2000-speed;
}

2、红外

编程思路:检测到黑线时红外模块将会把返回高电平,否则返回低电平。
故只需要读取对应的IO端口电平用以控制小车转向从而实现巡线。(由于在自己铺的简易赛道上四路红外巡线效果和两路巡线效果差不多,所以只用了中间两个红外模块进行巡线,外侧两个用来辅助超声波模块实现避障)

#ifndef _SENSOR_H
#define _SENSOR_H
#include <stm32f10x.h>

void Sensor_Init(void);
unsigned char Sensor_Detect(void);

#endif

#include <sensor.h>
#include <delay.h>

#define STRAIGHT 0
#define LEFTS 1
#define LEFTL 2
#define RIGHTS 3
#define RIGHTL 4
#define STOP 5
#define BACK 6

uint8_t left1;
uint8_t left0;
uint8_t right1;
uint8_t right0;
uint8_t counter=0;
float length;


void Sensor_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
}

unsigned char Sensor_Detect(void){
	left1=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_9);
	left0=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8);
	right0=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7);
	right1=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6);
	if(left0==1&&right0==0)return LEFTS;
	else if(left1==0&&right1==1)return LEFTL;
	else if(left0==0&&right0==1)return RIGHTS;
	else if(left1==1&&right1==0)return RIGHTL;
	else if(left1==1&&left0==1&&right0==1&&right1==1)return STOP;
	else if(left1==0&&right1==0)return BACK;
	else return STRAIGHT;
}

3、超声波

/*Head File*/
#ifndef __HC_H
#define __HC_H	
#include "sys.h"


void hcsr04_NVIC(void);

void Hcsr04Init(void);

static void OpenTimerForHc(void);

static void CloseTimerForHc(void);

void TIM4_IRQHandler(void);

u32 GetEchoTimer(void);

float Hcsr04GetLength(void);

#endif
#include "hc.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"	
#include "led.h"
#define TRIG_Send  PBout(11)
#define ECHO_Reci  PBin(10)

#define HCSR04_PORT     GPIOB
#define HCSR04_CLK      RCC_APB2Periph_GPIOB
#define HCSR04_TRIG     GPIO_Pin_11
#define HCSR04_ECHO     GPIO_Pin_10

u16 msHcCount = 0;

void hcsr04_NVIC()
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
			
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;             
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       
	NVIC_Init(&NVIC_InitStructure);
}

void Hcsr04Init()
{  
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
   
    GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
     
    GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;     
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  
    GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);    
     
          
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);   
     
    TIM_DeInit(TIM2);
    TIM_TimeBaseStructure.TIM_Period = (1000-1); 
    TIM_TimeBaseStructure.TIM_Prescaler =(72-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);          
        
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);  
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    
    hcsr04_NVIC();
    TIM_Cmd(TIM4,DISABLE);     
}


static void OpenTimerForHc()  
{
   TIM_SetCounter(TIM4,0);
   msHcCount = 0;
   TIM_Cmd(TIM4, ENABLE); 
}

static void CloseTimerForHc()    
{
   TIM_Cmd(TIM4, DISABLE); 
}

void TIM4_IRQHandler(void)  
{
   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
   {
       TIM_ClearITPendingBit(TIM4, TIM_IT_Update  ); 
       msHcCount++;
   }
}
 

u32 GetEchoTimer(void)
{
   u32 t = 0;
   t = msHcCount*1000;
   t += TIM_GetCounter(TIM4);
   TIM4->CNT = 0;  
   Delay_ms(50);
   return t;
}
 
float Hcsr04GetLength(void )
{
   u32 t = 0;
   int i = 0;
   float lengthTemp = 0;
   float sum = 0;
   while(i!=5)
   {
      TRIG_Send = 1;      
      Delay_us(20);
      TRIG_Send = 0;
      while(ECHO_Reci == 0);      
      OpenTimerForHc();        
      i = i + 1;
      while(ECHO_Reci == 1);
      CloseTimerForHc();        
      t = GetEchoTimer();        
      lengthTemp = ((float)t/58.0);//cm
      sum = lengthTemp + sum ;
        
    }
    lengthTemp = sum/5.0;
    return lengthTemp;
}


4、控制

控制小车的代码主要在Speed_Control()函数中编写。如果不使用超声波模块的话,也可以在定时器1的中断服务函数中编写。

/*Head File*/
#ifndef _CONTROL_H
#define	_CONTROL_H

void TIM1_UP_IRQHandler(void);
void Speed_Control(unsigned char Flag,float length);
#endif
#include <control.h>
#include <Sensor.h>
#include <PWM.h>
#include <delay.h>
#include <usart.h>
#include <stdio.h>
#define STRAIGHT 0
#define LEFTS 1
#define LEFTL 2
#define RIGHTS 3
#define RIGHTL 4
#define STOP 5
#define BACK 6

extern uint8_t left0;
extern uint8_t left1;
extern uint8_t right0;
extern uint8_t right1;
extern float length;

void TIM1_UP_IRQHandler(void){
	if(TIM_GetITStatus(TIM1,TIM_IT_Update)==SET){
		
	}
	TIM_ClearITPendingBit(TIM1,TIM_IT_Update); 	
}

void Speed_Control(unsigned char Flag,float length){
	if(Flag==STOP){
		Set_LeftMotor(0);
		Set_RightMotor(0);
	}	
	
	if(length<18.0){
		if(Flag==RIGHTL){
			Set_LeftMotor(-2000);
			Set_RightMotor(2000);
		}	
		else if(Flag==LEFTL){
			Set_LeftMotor(2000);
			Set_RightMotor(-2000);
		}
		else{
			Set_LeftMotor(-2000);
			Set_RightMotor(2000);
		}
	}
}

5、主函数

#include <stm32f10x.h>
#include <timer.h>
#include <usart.h>
#include <PWM.h>
#include <sensor.h>
#include <led.h>
#include <delay.h>
#include <stdio.h>
#include <hc.h>
#include <control.h>
#include <OLED.h>
#define STRAIGHT 0
#define LEFTS 1
#define LEFTL 2
#define RIGHTS 3
#define RIGHTL 4
#define STOP 5
#define BACK 6
extern float length;

int main(){
	Led_Init();	
	Delay_Init();
	Sensor_Init();
	Hcsr04Init();
	PWM_Init(1999,71);
	TIM1_Init(1999,71);
	TIM2_Init(1999,71);
	uart_init(115200);
	OLED_Init();
	while(1){
		int flag=Sensor_Detect();
		Speed_Control(flag,Hcsr04GetLength());
	}
}

三、总结

整个工程参考了许多不同的代码(简称究极缝合怪),故代码风格不统一。由于调试过程中把红外模块撞坏了,所以控制代码没有写得很完善,但是各个模块工作正常。在加入超声波模块之前,对巡迹功能进行了测试,虽然速度比较慢,但还是能完成巡迹工作。加入超声波模块后,也能实现较高精度的障碍检测(可以多用几个超声波模块,这样避障功能更完善)。
工程链接:https://pan.baidu.com/s/1CslspOudO7mCGkAVzEmbaQ?pwd=14j9
提取码:14j9
视频演示:循迹功能展示文章来源地址https://www.toymoban.com/news/detail-413709.html

到了这里,关于基于STM32f103c8t6的简单红外巡迹避障小车制作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于STM32F103C8T6ADC检测交流电压

    上篇文章写了硬件部分的实现思路,通过采样电阻的到小电压后经过二级放大电路得到单片机可处理的交流电压,此文介绍了如何采用单片机采集交流电压以及stm32ADC外设的使用。首先是硬件电路部分。  电路没有采用核心板,而是直接将芯片焊接到主板上,采用type-c接口供

    2024年02月12日
    浏览(53)
  • 基于STM32F103C8T6的HC-06蓝牙通信

    如果朋友们 遇到了如下问题 ,可以仔细借鉴本文章和另一篇专门讲解 蓝牙通信问题 的文章,一定能够解决你在蓝牙通信时遇到的诸多困难 1.在调试蓝牙模块AT指令时无返回值 2.身边 无USB转TTL模块 可以直接调试蓝牙模块(本人就是由于无模块花了了整整一天才调试成功)

    2024年02月03日
    浏览(60)
  • 基于stm32f103c8t6的fft频率计

    之前项目中需要用到正弦信号的频率测量,也参考了几个大佬的博客(链接如下),但可能是由于stm32的型号不匹配,虽然也在网上查了一些需要修改的地方,但结果一直不太对,后来经过自己摸索结果终于对了,在这里给大家分享下,具体原理不在赘述。 参考的部分大佬博

    2024年02月14日
    浏览(60)
  • 基于STM32F103C8T6的超声波测距应用

    #一、超声波HC_SR04简介 #二、超声波工作原理 #三、超声波测距步骤 #四、硬件接线 #五、项目代码 一、超声波HC_SR04简介 超声波传感器模块上面通常有两个超声波元器件,一个用于发射,一个用于接收。电路板上有四个引脚:VCC、GND、Trig(触发)、Echo(回应) 工作电压与电流

    2024年02月03日
    浏览(43)
  • 基于STM32F103C8T6(HAL库)的HC-SR501红外人体传感及HC-SR04超声波测距

    一、基于STM32F103C8T6最小系统板和STM32CubeMX实现LED灯循环闪烁 二、基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发 三、实战小例程 基于STM32F103C8T6最小系统板和STM32CubeMX驱动WS2812B光立方 四、基于STM32F103C8T6最小系统板HAL库CubeMX驱动HC-SR501红外人体传感模块 五、基于STM32F103C8

    2023年04月17日
    浏览(100)
  • 基于stm32f103c8t6的定时器详解(持续更新)

    先声明:stm32f103c8t6中没有基本定时器、只有TIM1-TIM4:分别是高级定时器和通用定时器(对照下图请自行阅读stm32f103x的datasheet) 1、定时器功能:定时、输出比较、输入捕获、互补输出,其中基本定时器只有定时功能、通用定时器只没有互补输出功能、高级定时器具有所有功能

    2023年04月24日
    浏览(65)
  • HX711压力传感器(基于STM32F103C8T6)

    HX711模块是我们目前比较常见的压力传感器模块,主要的作用是用来做压力检测,重量监测等等。博主的这篇博文主要实现功能为,在对重量或者压力进行监测的同时,可以累加或者清零数值,在此基础上就可以对比如饮水量进行统计等等。 HX711模块是市面上比较常见的模块

    2024年02月11日
    浏览(53)
  • [STM32F103C8T6]基于stm32的循迹,跟随,避障智能小车

    目录 1.小车驱动主要是通过L9110S模块来驱动电机 motor.c 2.我们可以加入串口控制电机驱动(重写串口接收回调函数,和重定向printf) Uart.c main.c  3.点动功能 uart.c main.c 为什么使用的是HAL_Delay()要设置滴答定时器的中断优先级呢? 4.小车PWM调速,  6.跟随功能 7.避障功能 超声波测距

    2024年02月13日
    浏览(54)
  • 基于STM32F103C8T6的UAV飞控板硬件设计

    一、主控单元:         主控单元基于意法半导体公司的STM32F103C8T6单片机进行设计。STM32F103C8T6DE 内核为ARM Cortex-M3;最大主频:72MHz ;工作电压范围:2V~3.6V ;程序存储容量:64KB; 程序存储器类型:FLASH ;RAM总容量:20KB; GPIO端口数量:37 ;封装为LQFP-48;串行单线调试(

    2024年02月08日
    浏览(54)
  • 基于stm32f103c8t6及AS608-----指纹锁项目

              博主纯小白, 本文适合于初学者,大佬还请勿喷,欢迎提出意见,有纰漏之处将及时纠正。 在浅学了stmf103c8t6后,想着依据现在所拥有的知识和能力做一个小项目。 注:工程代码在文章末尾。 掌握C语言基础....这个最基础啦... 接触过类似单片机,稍微看得懂芯片

    2023年04月09日
    浏览(81)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包