一、设计目的

本设计旨在通过基于STM32单片机的快递小车设计,使学生掌握STM32单片机的基本原理和应用技能,同时能够通过对快递小车的设计和实现,掌握嵌入式系统的设计和实现方法,提高学生的实际操作能力。

二、设计方案

本设计采用STM32F103C8T6单片机作为控制中心,通过蓝牙模块和超声波传感器实现快递小车的控制和避障功能。

  1. 硬件设计

(1)STM32F103C8T6单片机

STM32F103C8T6单片机是一款高性能、低功耗、32位的ARM Cortex-M3处理器,拥有72MHz的主频、64KB的Flash存储器、20KB的SRAM存储器,可以满足嵌入式系统的设计需求。

(2)驱动电机

本设计采用4个直流电机控制快递小车的行驶,其中两个电机控制前进和后退,另外两个电机控制左右转弯。驱动电机采用L298N电机驱动模块进行驱动。

(3)超声波传感器

本设计采用HC-SR04超声波传感器进行避障控制,该传感器可以测量物体与传感器之间的距离,通过距离值判断是否需要避障。

(4)蓝牙模块

本设计采用HC-05蓝牙模块进行远程控制,可以通过Android手机控制快递小车的行驶方向和速度。

  1. 软件设计

(1)系统框图

本设计采用Keil uVision4作为开发环境,通过编写C语言程序实现快递小车的控制和避障功能。系统框图如下所示:

系统框图

(2)程序流程图

本设计程序主要分为两个部分,一部分是远程控制部分,另一部分是超声波避障部分。程序流程图如下所示:

程序流程图

三、实现步骤

  1. 硬件连接

将STM32单片机、驱动电机、超声波传感器和蓝牙模块按照下图连接即可:

硬件连接图

  1. 软件编写

(1)远程控制部分

远程控制部分的程序主要是通过蓝牙模块接收Android手机发送的控制指令,并通过PWM信号控制电机的转速。

#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"

#define PWMA   TIM3->CCR1
#define AIN1   PBout(0)
#define AIN2   PBout(1)
#define PWMB   TIM3->CCR2
#define BIN1   PBout(10)
#define BIN2   PBout(11)

void TIM3_PWM_Init(u16 arr,u16 psc);

int main(void)
{
    u8 data;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    delay_init();
    USART1_Init(9600);
    TIM3_PWM_Init(7199,0);
    while(1)
    {
        if(USART_RX_STA&0x8000)
        {
            data=USART_RX_BUF[0];
            USART_RX_STA=0;
            switch(data)
            {
                case 'w':AIN1=0;AIN2=1;PWMA=500;BIN1=0;BIN2=1;PWMB=500;break;
                case 's':AIN1=1;AIN2=0;PWMA=500;BIN1=1;BIN2=0;PWMB=500;break;
                case 'a':AIN1=1;AIN2=0;PWMA=300;BIN1=0;BIN2=1;PWMB=300;break;
                case 'd':AIN1=0;AIN2=1;PWMA=300;BIN1=1;BIN2=0;PWMB=300;break;
                case 'q':PWMA=0;PWMB=0;break;
                default:break;
            }
        }
        delay_ms(10);
    }
}

void TIM3_PWM_Init(u16 arr,u16 psc)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period=arr;
    TIM_TimeBaseStructure.TIM_Prescaler=psc;
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse=0;
    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
    TIM_OC1Init(TIM3,&TIM_OCInitStructure);
    TIM_OC2Init(TIM3,&TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
    TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

    TIM_Cmd(TIM3,ENABLE);
}

(2)超声波避障部分

超声波避障部分的程序主要是通过超声波传感器测量前方物体与快递小车的距离,如果距离小于一定阈值,则停止前进并向后倒退一段时间,然后左转或右转避开障碍物。

#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"

#define PWMA   TIM3->CCR1
#define AIN1   PBout(0)
#define AIN2   PBout(1)
#define PWMB   TIM3->CCR2
#define BIN1   PBout(10)
#define BIN2   PBout(11)
#define Trig PBout(12)
#define Echo PBin(11)

void TIM3_PWM_Init(u16 arr,u16 psc);

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    delay_init();
    USART1_Init(9600);
    TIM3_PWM_Init(7199,0);
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period=arr;
    TIM_TimeBaseStructure.TIM_Prescaler=psc;
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse=0;
    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
    TIM_OC1Init(TIM3,&TIM_OCInitStructure);
    TIM_OC2Init(TIM3,&TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
    TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

    while(1)
    {
        u32 time=0;
        float distance=0;
        Trig=1;
        delay_us(10);
        Trig=0;
        while(Echo==0);
        while(Echo==1)
        {
            time++;
            delay_us(1);
        }
        distance=(float)time*0.017;
        if(distance<30)
        {
            AIN1=1;AIN2=0;PWMA=500;BIN1=1;BIN2=0;PWMB=500;
            delay_ms(1000);
            AIN1=0;AIN2=1;PWMA=500;BIN1=1;BIN2=0;PWMB=500;
            delay_ms(1000);
            AIN1=1;AIN2=0;PWMA=500;BIN1=0;BIN2=1;PWMB=500;
            delay_ms(1000);
        }
        else
        {
            AIN1=0;AIN2=1;PWMA=500;BIN1=0;BIN2=1;PWMB=500;
        }
    }
}

void TIM3_PWM_Init(u16 arr,u16 psc)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period=arr;
    TIM_TimeBaseStructure.TIM_Prescaler=psc;
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse=0;
    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;
    TIM_OC1Init(TIM3,&TIM_OCInitStructure);
    TIM_OC2Init(TIM3,&TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable);
    TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

    TIM_Cmd(TIM3,ENABLE);
}

四、实现效果

通过上述步骤的实现,可以实现快递小车的远程控制和避障功能,具体效果如下图所示:

实现效果图

五、总结

通过本次课程设计,我掌握了STM32单片机的基本原理和应用技能,同时也了解了嵌入式系统的设计和实现方法。通过对快递小车的设计和实现,我提高了自己的实际操作能力,深入理解了嵌入式系统的工作原理和应用场景

基于stm32快递小车3000字课程设计

原文地址: http://www.cveoy.top/t/topic/g2K6 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录