☰
STM32学习笔记【15.智能排队控制系统项目】
2026/10/5 18:33:38 网站建设 项目流程

智能排队控制系统

1. 模块介绍

1.1 红外传感器【红外跟随避障模块】


📌注意:如果接收到信号,OUT引脚输出低电平,亮绿灯。【与震动传感器相似】
如果未接收到信号,OUT引脚一直高电平。

顺时针旋转,灵敏度变高,检测距离变长;逆时针,灵敏度变低,检测距离变短。

驱动代码:与【震动传感器】代码一样

1.2 LCD1602显示模块

一种常见的字符型液晶显示模块。
它能够显示16列2行,共32个字符,每个字符由5*8像素点阵构成,是一种专门用来显示字母、数字、符号等的液晶显示模块。

1.2.1 引脚介绍

引脚不能接错,否则可能会烧掉板子。


RS:1——数据寄存器;0——指令寄存器
R/W: 1——读;0——写

1.2.2 基本操作时序

读操作时序:

写操作时序:

1.2.3 LCD1602显示字符串


小实验:驱动LCD1602显示内容

实验目的:

  1. 使用LCD1602显示一个字符;
  2. 使用LCD1602显示一个字符串。

硬件清单:

  • LCD1602
  • 上官二号
  • ST-Link

硬件接线

STM32LCD1602
GNDGND
5VVDD
GNDV0
B1RS
B2RW
B10E
A0D0
A1D1
A2D2
A3D3
A4D4
A5D5
A6D6
A7D7
3.3BLA
GNDBLK

代码:
写代码前,要知道两个问题:

  1. 在哪里显示字符
  2. LCD知道显示什么内容

用下面这个知道在什么地方显示内容。

写指令代码:


lcd1602.c文件

#include"lcd1602.h"#include"delay.h"// RS引脚定义#defineRS_GPIO_PortGPIOB#defineRS_GPIO_PinGPIO_PIN_1#defineRS_HIGHHAL_GPIO_WritePin(RS_GPIO_Port,RS_GPIO_Pin,GPIO_PIN_SET);#defineRS_LOWHAL_GPIO_WritePin(RS_GPIO_Port,RS_GPIO_Pin,GPIO_PIN_RESET);// RW引脚定义#defineRW_GPIO_PortGPIOB#defineRW_GPIO_PinGPIO_PIN_2#defineRW_HIGHHAL_GPIO_WritePin(RW_GPIO_Port,RW_GPIO_Pin,GPIO_PIN_SET);#defineRW_LOWHAL_GPIO_WritePin(RW_GPIO_Port,RW_GPIO_Pin,GPIO_PIN_RESET);// EN引脚定义#defineEN_GPIO_PortGPIOB#defineEN_GPIO_PinGPIO_PIN_10#defineEN_HIGHHAL_GPIO_WritePin(EN_GPIO_Port,EN_GPIO_Pin,GPIO_PIN_SET);#defineEN_LOWHAL_GPIO_WritePin(EN_GPIO_Port,EN_GPIO_Pin,GPIO_PIN_RESET);voidlcd1602_init(void){// GPIO初始化lcd1602_gpio_init();// 上电初始化lcd1602_start();}// GPIO初始化voidlcd1602_gpio_init(void){GPIO_InitTypeDef gpio_initstruct;// 打开时钟__HAL_RCC_GPIOA_CLK_ENABLE();// 使能GPIOA时钟__HAL_RCC_GPIOB_CLK_ENABLE();// 使能GPIOB时钟gpio_initstruct.Pin=GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;// 对应的引脚gpio_initstruct.Mode=GPIO_MODE_OUTPUT_PP;// 推挽输出gpio_initstruct.Pull=GPIO_PULLUP;// 上拉gpio_initstruct.Speed=GPIO_SPEED_FREQ_HIGH;// 高速HAL_GPIO_Init(GPIOA,&gpio_initstruct);gpio_initstruct.Pin=GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10;// LED1对应的引脚gpio_initstruct.Mode=GPIO_MODE_OUTPUT_PP;// 推挽输出gpio_initstruct.Pull=GPIO_PULLUP;// 上拉gpio_initstruct.Speed=GPIO_SPEED_FREQ_HIGH;// 高速HAL_GPIO_Init(GPIOB,&gpio_initstruct);}// 上电初始化voidlcd1602_start(void){//(1)延时15msdelay_ms(15);//(2)写指令38H(不检测忙信号)lcd1602_write_cmd(0x38);//(3)延时5msdelay_ms(5);//(4)不检测忙信号//(5)写指令38H:显示模式设置lcd1602_write_cmd(0x38);//(6)写指令08H:显示关闭lcd1602_write_cmd(0x08);//(7)写指令01H:显示清屏lcd1602_write_cmd(0x01);//(8)写指令06H:显示光标移动设置lcd1602_write_cmd(0x06);//(9)写指令0CH:显示开及光标设置lcd1602_write_cmd(0x0C);}// 指令voidlcd1602_write_cmd(charcmd){RS_LOW;RW_LOW;EN_LOW;GPIOA->ODR=cmd;delay_ms(5);EN_HIGH;delay_ms(5);EN_LOW;}// 数据voidlcd1602_write_data(chardataShow){RS_HIGH;RW_LOW;EN_LOW;GPIOA->ODR=dataShow;delay_ms(5);EN_HIGH;delay_ms(5);EN_LOW;}// 显示一个字符voidlcd1602_show_data(void){// 在什么地方显示lcd1602_write_cmd(0x80+0x02);// 显示什么内容lcd1602_write_data('Z');}// 显示字符串voidlcd1602_show_line(charrow,charcol,char*string){switch(row){case1:lcd1602_write_cmd(0x80+col);while(*string){lcd1602_write_data(*string);string++;}break;case2:lcd1602_write_cmd(0x80+0x40+col);while(*string){lcd1602_write_data(*string);string++;}break;}}

main.c中不要忘记调用lcd1602_show_line(char row, char col, char *string);

2. 智能排队控制系统

项目需求

  1. 红外传感器检测有人通过并计数
  2. 计数值显示在LCD1602
  3. 允许通过时,LED1闪烁,蜂鸣器不响,继电器不闭合;
  4. 不允许通过时,LED2闪烁,蜂鸣器响,继电器闭合。
  5. 每次允许通过5个人,之后转为不允许通过,3秒后再转为允许通过

硬件清单

  • 继电器(模拟闸机)
  • 蜂鸣器
  • 红外避障模块
  • LCD1602
  • 上官二号
  • ST-Link

硬件接线

STM32LCD1602继电器蜂鸣器红外
GNDGND
5VVDD
GNDV0
B1RS
B2RW
B10E
A0D0
A1D1
A2D2
A3D3
A4D4
A5D5
A6D6
A7D7
3.3BLAVCCVCCVCC
GNDBLKGNDGNDGND
B4OUT
B5I/O
B6IN

项目框图

2.1 搭建项目工程

基于SysTick模拟多线程实验上写
将之前所做的实验加进来:红外、LCD1602、继电器、蜂鸣器、LED。

分别调试这几个模块代码,验证硬件没问题,再进行下一步。

2.1.1 状态机

状态机(State Machine)是一种用于描述系统行为或功能行为的数学模型。它通常包含一组状态、一组转换条件以及动作执行。状态机通过在不同状态之间进行转换来模拟系统的行为。每个状态都代表系统的一个特定配置或情况,而转换规则则定义了从一个状态转换到另一个状态的条件和动作。

状态机广泛应用于多个领域包括但不限于计算机科学、电子工程、通信、自动化、机器人技术等。在计算机科学中,状态机常用于描述软件系统的行为,特别是在硬件设计、编译器设计、网络协议以及用户界面交互等方面。

状态机的主要特点包括:

  1. 有限状态:状态机通常具有有限数量的状态。这些状态可以是有序的、离散的或层次化的。
  2. 转换条件:状态之间的转换是基于特定条件触发的。当满足某个条件时,状态机会从当前状态转换到下一个状态。
  3. 动作执行:在状态转换过程中,状态机可能会执行某些动作或操作。这些动作可以包括计算、数据更新、输出信号等。
  4. 确定性和非确定性:状态机可以是确定性的(每个条件唯一对应一个转换)或非确定性(一个条件可能导致多个可能得转换)。

状态机的实现方式多种多样,可以使用编程语言中的条件语句、循环结构或专门的状态机库来实现。此外,硬件设计领域中的有限状态机(Finite State Machine,FSM)也是状态机的一种重要应用。

该项目的状态:

2.1.2 业务代码

状态代码写在tasks.c中

问题1:未检测到传感器,直接就通过。
解决:在传感器检测是否有人通过时,写成了用gate_state_get来获取了,应该是用红外传感器ia_flag_get函数检测是否有人通过。ia_flag_get() == TRUE && state == PASS_STATE。

问题2:当检测有人通过时,LCD并没有计数加1。
在中断函数中,设置的下降沿触发和GPIO_PIN_RESET 低电平触发

gpio_initstruct.Mode=GPIO_MODE_IT_FALLING;// 下降沿触发
voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){// 消抖delay_ms(20);if(GPIO_Pin==GPIO_PIN_4){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4)==GPIO_PIN_RESET)ia_flag=TRUE;}}

但是,出现一个问题,传感器靠近和离开都加了一个人,说明传感器在靠近时也产生了一个短暂的下降沿,被误识别为一次有效信号。
解决:
HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_4) == GPIO_PIN_RESET

引脚是B4,之前写成了A4。

总结:学会把项目步骤进行拆解,写业务代码前,一定要先把硬件设备连线并调试好,再接着写业务代码。
红外传感器【检测人数】→继电器【闸机】→蜂鸣器→LED1和LED2→LCD1602【显示通过人数】

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询