基于STM32的自动跟踪小车

概述

在这里插入图片描述
小车外形:
在这里插入图片描述
功能简介
利用摄像头识别前车尾部的AprilTag,得到前车位置,传回stm32主控板处理,使两车在行驶时保持恒定距离,实现自动跟车。

1.openMV4摄像头

1.1 Apriltag识别与串口传输

AprilTag是一个视觉基准库,在AR,机器人,相机校准领域广泛使用。通过特定的标志(与二维码相似,但是降低了复杂度以满足实时性要求),可以快速地检测标志,并计算相对位置。
Apriltag示例:
在这里插入图片描述
通过识别Apriltag,可以得到x,y,z三个方向的距离以及偏移角度。这里只需要三维的距离即可,通过串口传回stm32.

import sensor, image, time, math,pyb
from pyb import UART

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)  # must turn this off to prevent image washout...
sensor.set_auto_whitebal(False)  # must turn this off to prevent image washout...
clock = time.clock()
uart = UART(3, 115200)#串口波特率

f_x = (2.8 / 3.984) * 160 # find_apriltags defaults to this if not set
f_y = (2.8 / 2.952) * 120 # find_apriltags defaults to this if not set
c_x = 160 * 0.5 # find_apriltags defaults to this if not set (the image.w * 0.5)
c_y = 120 * 0.5 # find_apriltags defaults to this if not set (the image.h * 0.5)

def degrees(radians):
    return (180 * radians) / math.pi

while(True):
    clock.tick()
    img = sensor.snapshot()
    for tag in img.find_apriltags(fx=f_x, fy=f_y, cx=c_x, cy=c_y): # defaults to TAG36H11
        img.draw_rectangle(tag.rect(), color = (255, 0, 0))
        img.draw_cross(tag.cx(), tag.cy(), color = (0, 255, 0))
        print_args = (tag.x_translation(), tag.y_translation(), tag.z_translation())
            #degrees(tag.x_rotation()), degrees(tag.y_rotation()), degrees(tag.z_rotation()))
        # Translation units are unknown. Rotation units are in degrees.
       # print("Tx %f, Ty %f, Tz %f" % print_args)
        uart.write("A%.2f,B%.2f,C%.2f," % print_args+'\r\n')#设置特定格式,以便于stm32分割取得数据
        #pyb.delay(500)
   # print(clock.fps())

2. STM32主控板(型号为F407)

2.1 时钟与中断配置

附上stm32时钟示意图:
在这里插入图片描述
定时器示意图:
在这里插入图片描述
定时器分配:
在这里插入图片描述
所有时钟初始化的函数:(每个函数的详细内容在后面)

TIM8_PWM_Init(400-1,20-1);	//用于控制电机,168M/20=8.4Mhz的计数频率,重装载值400,所以PWM频率为 8.4M/400=21Khz. 
	TIM3_PWM_Init(200-1,8400-1);//用于控制舵机,50HZ
	TIM2_Int_Init(400-1,20-1);//定时中断,21KHZ
	TIM7_Int_Init(500-1,8400-1);//用于编码器计数,20HZ,50ms中断一次
	uart_init(115200);	//初始化串口1波特率为115200
	Encoder_Init_TIM4();//编码器接口初始化

2.2 串口收发与数据处理

串口中断:USART1,USART2
串口初始化函数(以USART1为例):

void uart_init(u32 bound){
   
   //GPIO端口设置
  GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟
 
	//串口1对应引脚复用映射
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
	
	//USART1端口配置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10

   //USART1 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  USART_Init(USART1, &USART_InitStructure); //初始化串口1
	
  USART_Cmd(USART1, ENABLE);  //使能串口1 
	
	USART_ClearFlag(USART1, USART_FLAG_TC);
	
#if EN_USART1_RX	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断

	//Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器、

#endif
	
}

串口中断处理函数:

void USART1_IRQHandler(void)                	//串口1中断服务程序
{
   
	u8 Res;
#ifdef OS_TICKS_PER_SEC	 	//如果时钟节拍数定义了,说明要使用ucosII了.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
   
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
   
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
   
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{
   	
				if(Res==
  • 54
    点赞
  • 375
    收藏
    觉得还不错? 一键收藏
  • 32
    评论
循迹避障小车是一种智能小车,它可以自动跟随指定的路径行驶,并根据环境情况自动避障。基于stm32的循迹避障小车设计需要进行以下步骤: 1. 硬件设计:包括小车底盘、电机驱动模块、超声波传感器、红外循迹模块、STM32单片机等硬件的选择和布局。 2. 软件设计:包括底盘控制程序、循迹算法、避障算法、通信协议等软件的编写。 3. 调试测试:对硬件和软件进行集成测试和调试,确保小车能够正常运行。 以下是基于stm32的循迹避障小车的设计流程: 1. 硬件设计 首先需要确定小车的整体尺寸和结构布局,并选择适合的电机驱动模块、超声波传感器、红外循迹模块、STM32单片机等硬件。其次,需要对这些硬件进行布局设计,确定它们在小车上的位置和连接方式。 2. 软件设计 小车的软件设计需要包括底盘控制程序、循迹算法、避障算法、通信协议等方面。其中,底盘控制程序需要实现小车的前进、后退、转向等基本动作。循迹算法需要根据红外循迹模块的信号进行分析,实现小车自动跟踪和转向。避障算法需要利用超声波传感器的信号进行分析,实现小车自动避障。通信协议需要定义小车与其他设备之间的通信格式和协议。 3. 调试测试 在整个设计过程中,需要进行多次调试测试,以确保硬件和软件的正常运行。调试测试可以分为单项测试和集成测试两个阶段。在单项测试中,需要对每个硬件和软件进行单独测试;在集成测试中,需要将所有硬件和软件进行集成测试,以确保小车能够正常运行。 总体来说,基于stm32的循迹避障小车设计需要进行综合考虑,包括硬件、软件、通信等方面的设计。只有在各个方面都考虑周全,才能设计出一款稳定可靠、功能强大的智能小车

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值