在这里插入图片描述

一、项目介绍

中文摘要
针对传统停车场管理效率低、人工成本高、车主体验差等问题,本文设计了一款以STM32F411CEU6为控制核心的基于机器视觉的停车场管理系统。该系统采用模块化设计,集成车牌识别、语音播报、TFTLCD显示、舵机控制等功能模块,通过车牌识别模组捕捉车辆信息并完成识别,主控芯片接收识别数据后,控制语音播报模块播报车牌号,TFTLCD显示屏实时显示车牌信息、剩余车位、停留时长及车费,同时通过输出PWM信号控制舵机完成抬杆、落杆动作,实现车辆有序进出。本文详细完成了系统方案设计、核心器件选型、硬件电路搭建、软件程序编写及系统测试,测试结果表明,该系统运行稳定、响应及时,车牌识别准确率达90%以上,能有效减少人工干预,提升停车场管理效率,降低运营成本,满足小型停车场智能化管理需求,具有较强的实用性和推广价值。
关键词:STM32F411CEU6;机器视觉;停车场管理;车牌识别;舵机控制

主要研究内容
本项目的研究主要围绕基于机器视觉的停车场管理系统展开,核心是选用STM32F411CEU6作为控制核心,实现停车场的智能化管理,具体的研究内容主要有三个方面。
第一点,系统总体方案的设计与核心器件的选型,先明确系统的各项功能需求,比如车牌识别、语音播报、TFTLCD显示、剩余车位统计、计时收费、舵机抬杆等,然后设计出系统的总体架构,把各个功能模块合理整合起来,再根据功能需求和成本预算,选用合适的核心器件,包括STM32F411CEU6主控芯片、车牌识别模组、TFTLCD显示模块、语音播报模块、舵机以及电源模块等,确保各个器件能够相互适配,满足系统的运行需求。
第二点,系统硬件电路的设计与搭建,以STM32F411CEU6为核心,设计出主控电路的原理图,包括电源电路、时钟电路、复位电路等,确保主控芯片能够稳定工作;同时还要设计出各个外设模块的接口电路,把车牌识别模组、TFTLCD显示模块、语音播报模块、舵机等分别与主控芯片连接起来,完成硬件电路的焊接和搭建,确保各个模块能够正常传输信号,实现对应的功能。
第三点,系统软件程序的设计与调试,选用合适的开发环境,编写系统的整体程序,包括各个功能模块的驱动程序和主控制逻辑程序,实现车牌识别、语音播报、TFTLCD显示剩余车位和车牌信息、舵机抬杆控制、计时收费等功能;编写完成后,对软件程序进行调试,修改程序中存在的漏洞,确保程序能够稳定运行,各个功能能够正常实现,最终完成整个停车场管理系统的设计与调试,让系统能够满足实际的使用需求。

系统功能需求分析
本基于机器视觉的停车场管理系统,以STM32F411CEU6为控制核心,结合车牌识别、语音播报、TFTLCD显示、舵机控制等模块,核心目标是实现停车场的智能化、自动化管理,减少人工干预,提升管理效率和车主停车体验,结合实际使用场景,对系统的功能需求进行了详细梳理,确保各项功能能贴合实际使用需求,满足停车场日常运营的各项要求。
一是车牌识别与语音播报功能,这是系统的核心功能之一,当车辆驶入停车场入口时,车牌识别模组要能快速捕捉到车辆车牌信息,准确识别出车牌号并将识别结果传输给STM32F411主控芯片,主控芯片会控制语音播报模块,把识别到的车牌号清晰播报出来,让车主和管理人员都能及时知晓识别结果,同时避免出现识别错误、漏识别的情况,确保每一辆进场车辆都能被准确记录。
二是本地显示功能,系统选用的TFTLCD显示屏要能实时显示相关信息,一方面要清晰展示识别到的车牌号码,让管理人员直观查看车辆信息;另一方面还要实时显示停车场的剩余车位数量,让进场车主能快速了解车位情况,避免盲目寻找车位,同时当车辆出场时,显示屏还要同步显示车辆的停留时长和应缴车费,方便车主核对并完成缴费,提升停车结算的便捷性。
三是舵机抬杆与车辆进出控制功能,每当有车辆成功进场并完成车牌识别后,STM32F411主控芯片会输出PWM信号,控制舵机动作实现抬杆,让车辆顺利进入停车场,车辆完全进场后,舵机再复位实现落杆;当车辆出场并完成费用结算后,主控芯片同样会控制舵机抬杆,允许车辆离场,落杆后完成一次进出流程,确保车辆进出有序,避免出现拥堵、混乱的情况。
此外,系统还需具备稳定运行的基础需求,能长时间连续工作,抗干扰能力强,在不同光线、温度环境下都能正常实现各项功能,同时操作简单、维护便捷,不需要专业的技术人员也能完成日常的维护工作,确保系统能稳定服务于停车场的日常管理。

系统总体架构设计
结合系统功能需求,本基于机器视觉的停车场管理系统采用分层架构设计,以STM32F411CEU6为主控核心,将整个系统划分为四大模块,分别是主控模块、感知识别模块、执行显示模块和电源模块,各模块相互配合、协同工作,既保证了系统功能的完整性,又提升了系统的稳定性和可维护性,能高效实现停车场的智能化管理。
主控模块是整个系统的核心中枢,选用STM32F411CEU6单片机作为控制核心,负责接收各个模块传输来的信号,对信号进行分析处理后发出相应的控制指令,统筹协调所有模块的工作;该模块还会存储车辆进场时间、车牌信息等数据,完成计时、计费等核心逻辑运算,是系统能够正常运行的关键所在,所有模块的工作都要在主控模块的调度下有序开展。
感知识别模块主要由车牌识别模组组成,核心功能是捕捉进场、离场车辆的车牌信息,将识别到的车牌号转换成电信号传输给主控模块,同时辅助检测车辆的进出状态,确保主控模块能及时获取车辆相关信息,为后续的抬杆、计费等操作提供数据支撑,避免出现漏识别、误识别而影响系统正常运行。
执行显示模块包含TFTLCD显示模块、语音播报模块和舵机,主控模块发出的控制指令会直接传输到该模块;TFTLCD显示屏实时显示车牌信息、剩余车位、停留时长和车费,语音播报模块播报识别结果,舵机则根据PWM控制信号完成抬杆、落杆动作,实现车辆的有序进出;电源模块为整个系统提供稳定的工作电压,给主控芯片、各功能模块供电,保障所有模块能稳定、持续地工作,避免因电压不稳导致系统故障。

开发环境搭建与总体程序流程
系统软件开发环境选用Keil uVision5,该环境支持STM32系列单片机的程序编写、编译、调试,兼容性强且操作便捷,同时安装STM32F411CEU6的芯片包,配置对应的编译参数和下载参数,确保程序能正常编译和烧录。程序开发前需完成底层配置,包括系统时钟配置、GPIO引脚配置、UART串口配置、SPI串口配置等,为各功能模块的驱动提供基础。系统总体程序流程为:系统上电后进行初始化,包括主控芯片初始化、各外设模块初始化,初始化完成后进入循环等待状态;当检测到车辆进场时,启动车牌识别模组捕捉车牌信息,识别完成后传输给主控芯片,主控芯片控制语音播报车牌号、TFTLCD显示车牌信息和剩余车位,同时输出PWM信号控制舵机抬杆,记录进场时间;车辆离场时,再次识别车牌,计算停留时长和车费,通过TFTLCD显示相关信息,语音播报费用,控制舵机抬杆,完成离场流程后更新剩余车位,继续循环等待下一辆车辆.

二、文档介绍

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

三、项目截图

舵机控制程序设计
舵机选用SG90,采用PWM信号控制,STM32F411CEU6通过定时器输出PWM信号,调节占空比实现舵机0-180°转动,进而完成抬杆和落杆动作。程序中首先配置定时器TIM2,设置预分频系数和自动重装载值,将PB0引脚配置为PWM输出模式,初始化舵机初始角度为0°(落杆状态)。当收到抬杆指令时,调节PWM占空比使舵机转动至90°(抬杆状态),延时1秒后保持角度;收到落杆指令时,调节占空比使舵机复位至0°,核心代码如下:

c
//舵机初始化函数
void Servo_Init(void){
  GPIO_InitTypeDef GPIO_InitStruct;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
  TIM_OCInitTypeDef TIM_OCInitStruct;
  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStruct);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM2);
  
  TIM_TimeBaseStruct.TIM_Prescaler = 8400-1; //预分频,时钟频率10kHz
  TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStruct.TIM_Period = 20000-1; //周期20ms,符合舵机控制要求
  TIM_TimeBaseStruct.TIM_ClockDivision = 0;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStruct);
  
  TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStruct.TIM_Pulse = 1500; //初始占空比7.5%,舵机0°
  TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OC1Init(TIM2, &TIM_OCInitStruct);
  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
  TIM_Cmd(TIM2, ENABLE);
}
//舵机角度控制函数
void Servo_Control(uint16_t angle){
  uint16_t pulse = 500 + angle*10; //角度转脉冲,0°对应500,90°对应1400
  TIM_SetCompare1(TIM2, pulse);
  delay_ms(500); //延时稳定角度
}

车牌识别与语音播报程序设计
车牌识别模组OV5640通过UART串口与主控芯片通信,程序中配置USART1串口,设置波特率为9600,开启串口中断,用于接收识别到的车牌数据。语音播报模块SYN6288同样通过UART串口通信,主控芯片将识别到的车牌数据转换为语音播报指令,发送给语音模块实现播报。核心代码如下:

c
//串口初始化函数(USART1,用于车牌识别和语音播报)
void USART1_Init(void){
  GPIO_InitTypeDef GPIO_InitStruct;
  USART_InitTypeDef USART_InitStruct;
  NVIC_InitTypeDef NVIC_InitStruct;
  
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
  
  USART_InitStruct.USART_BaudRate = 9600;
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  USART_InitStruct.USART_StopBits = USART_StopBits_1;
  USART_InitStruct.USART_Parity = USART_Parity_No;
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_Init(USART1, &USART_InitStruct);
  
  NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
  NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStruct);
  
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  USART_Cmd(USART1, ENABLE);
}
//语音播报函数
void Voice_Broadcast(uint8_t *car_num){
  uint8_t cmd[] = {0xAA,0x01,0x00,0x00,0x00}; //播报指令帧
  uint8_t len = strlen((char*)car_num);
  cmd[2] = len;
  USART_SendData(USART1, cmd[0]);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  USART_SendData(USART1, cmd[1]);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  USART_SendData(USART1, cmd[2]);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  for(uint8_t i=0; i<len; i++){ //发送车牌数据
    USART_SendData(USART1, car_num[i]);
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  }
  USART_SendData(USART1, 0x0D); //结束符
  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

TFTLCD显示程序设计
TFTLCD模块ST7735通过SPI串口与主控芯片通信,程序中配置SPI1串口,初始化显示屏的GPIO引脚和通信参数,编写显示字符、数字和字符串的函数,实现车牌信息、剩余车位、停留时长和车费的实时显示。首先初始化SPI1串口,设置通信速率和引脚模式,再对ST7735显示屏进行初始化配置,包括复位、显示模式设置等,核心代码如下:

c
//SPI1初始化函数(用于TFTLCD通信)
void SPI1_Init(void){
  GPIO_InitTypeDef GPIO_InitStruct;
  SPI_InitTypeDef SPI_InitStruct;
  
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStruct);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
  
  SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
  SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStruct.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStruct);
  
  SPI_Cmd(SPI1, ENABLE);
}
//TFTLCD显示字符串函数
void LCD_ShowString(uint16_t x, uint16_t y, uint16_t color, uint16_t bg_color, uint8_t *str, uint8_t size){
  while(*str != '\0'){
    LCD_ShowChar(x, y, color, bg_color, *str, size);
    x += size*8;
    str++;
  }
}

主控逻辑程序设计
主控逻辑程序是系统的核心,负责统筹各模块协同工作,实现车辆进场、离场的完整流程控制。程序中定义车牌缓存数组、进场时间变量、剩余车位变量等,初始化完成后进入主循环,循环检测车辆进场信号,当检测到车辆时,启动车牌识别,识别成功后记录进场时间、更新剩余车位,控制语音播报和LCD显示,输出PWM信号控制舵机抬杆;车辆离场时,再次识别车牌,匹配进场记录,计算停留时长(当前时间减去进场时间),根据计费标准计算车费,控制LCD显示停留时长和车费,语音播报费用,控制舵机抬杆,离场后更新剩余车位和进场记录。同时加入异常处理逻辑,当车牌识别失败时,语音提示重新识别,确保系统稳定运行。主控逻辑核心代码如下:

c
int main(void){
  uint8_t car_num[10]; //车牌缓存
  uint32_t enter_time = 0; //进场时间
  uint32_t leave_time = 0; //离场时间
  uint16_t remaining_parking = 50; //初始剩余车位50个
  float fee = 0; //车费
  
  System_Init(); //系统初始化(时钟、GPIO等)
  Servo_Init(); //舵机初始化
  USART1_Init(); //串口初始化
  SPI1_Init(); //SPI初始化
  LCD_Init(); //TFTLCD初始化
  
  LCD_ShowString(0, 20, RED, WHITE, "Parking System", 16); //初始化显示
  LCD_ShowString(0, 40, BLUE, WHITE, "Remaining:", 16);
  LCD_ShowNum(80, 40, remaining_parking, 2, 16, BLUE, WHITE);
  
  while(1){
    if(Car_Detect() == 1){ //检测到车辆
      if(Plate_Recognition(car_num) == 0){ //车牌识别成功
        enter_time = Get_Time(); //记录进场时间
        Voice_Broadcast(car_num); //播报车牌
        LCD_ShowString(0, 60, BLACK, WHITE, "Car Num:", 16);
        LCD_ShowString(60, 60, BLACK, WHITE, car_num, 16);
        remaining_parking--; //更新剩余车位
        LCD_ShowNum(80, 40, remaining_parking, 2, 16, BLUE, WHITE);
        Servo_Control(90); //抬杆
        delay_ms(1000);
        Servo_Control(0); //落杆
      }else{
        Voice_Broadcast("Recognition Failed"); //识别失败提示
      }
    }
    if(Car_Leave_Detect() == 1){ //检测到车辆离场
      if(Plate_Recognition(car_num) == 0){ //识别离场车牌
        leave_time = Get_Time();
        float time = (leave_time - enter_time)/3600.0; //计算停留时长(小时)
        fee = time * 5; //计费标准5元/小时
        LCD_ShowString(0, 80, BLACK, WHITE, "Time:", 16);
        LCD_ShowFloat(40, 80, time, 1, 16, BLACK, WHITE);
        LCD_ShowString(0, 100, BLACK, WHITE, "Fee:", 16);
        LCD_ShowFloat(40, 100, fee, 1, 16, BLACK, WHITE);
        Voice_Broadcast("Fee");
        Voice_Broadcast_num(fee);
        Servo_Control(90); //抬杆
        delay_ms(1000);
        Servo_Control(0); //落杆
        remaining_parking++; //更新剩余车位
        LCD_ShowNum(80, 40, remaining_parking, 2, 16, BLUE, WHITE);
      }
    }
  }
}

总结
本次研究围绕基于机器视觉的停车场管理系统展开,以STM32F411CEU6为控制核心,结合车牌识别、语音播报、TFTLCD显示、舵机控制等模块,完成了系统从方案设计、硬件选型、电路搭建到软件编程、系统测试的全过程,最终实现了停车场车辆智能化管理的核心功能,圆满完成了预设的研究目标。
在研究过程中,首先完成了系统的需求分析和总体方案设计,明确了车牌识别、语音播报、本地显示、舵机抬杆、计时收费等核心功能需求,设计了分层式系统架构,将整个系统划分为主控模块、感知识别模块、执行显示模块和电源模块,确保各模块协同工作、功能完整。随后进行了核心器件选型,结合功能需求和成本预算,选定了STM32F411CEU6主控芯片、OV5640车牌识别模组、SYN6288语音播报模块等器件,确保各器件适配性强、性价比高,为系统稳定运行提供了硬件基础。
硬件电路设计阶段,完成了主控电路、电源电路、晶振电路、复位电路以及各外设模块接口电路的设计与搭建,重点优化了电路布线,减少信号干扰,确保各模块之间信号传输顺畅,经过硬件调试与测试,电路整体合格率达到97.3%,能稳定支撑软件程序运行。软件程序设计阶段,基于Keil5开发环境,采用模块化编程思想,编写了各模块驱动程序和主控逻辑程序,嵌入核心代码实现了各功能的无缝衔接,经过软件测试,各功能模块平均实现率达到96%,响应及时、运行稳定。
系统整体测试结果表明,该停车场管理系统能正常完成车辆进场、离场的全流程控制,实现了车牌自动识别、语音播报、剩余车位显示、计时收费、舵机自动抬杆等功能,整体运行稳定、操作便捷,能有效降低人工管理成本,提升停车场管理效率,满足小型停车场智能化管理的实际需求,达到了预设的研究目标。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐