基于STM32F103的二维码识别项目——串口通讯篇

无线手持二维码识别项目是中山大学电子与信息工程学院(微电子学院)的工程应用训练课程的设计要求。项目是基于STM32F103开发的,开源代码:stm32f103zet6-qrcode-detect,bilibili:基于STM32F1的无线手持二维码识别项目。CSDN总目录:基于STM32F103的二维码识别项目。项目移植了Zbar库进行二维码识别,而非使用二维码识别模块。

此篇文章讲述有线串口通讯相关的设计。

项目预留了有线的方式实现串口通讯,这样通过USB转TTL,实现了STM32将二维码识别信息传输到电脑。

一、 串口通讯简介

在这里插入图片描述

异步通信

  • 在异步通信中,数据传输不需要共享时钟信号,数据以独立的字节或字符进行传输。每个字符都有自己的起始和停止位来标识数据的开始和结束。
  • 这种方式适用于不连续、不规则的数据流,常见于串口通信如RS-232。

起始位

  • 起始位用于标识一个数据帧的开始。当线路空闲时,通常保持在高电平(逻辑1),起始位是低电平(逻辑0),用于告诉接收端接下来是一个数据帧。

数据位

  • 数据位是实际传输的数据,每个字符通常由5到9位组成(最常见的是8位)。数据位的长度可以在通信双方之间协商。

奇偶校验位

  • 奇偶校验位用于错误检测,可以选择不使用(无校验)、偶校验或奇校验。校验位是通过计算数据位中的1的数量来决定的,以确保数据的正确性。

停止位

  • 停止位用于标识一个数据帧的结束。停止位可以是1位、1.5位或2位(常见的是1位)。高电平(逻辑1)表示数据传输的结束,允许接收端有时间准备好接收下一个字符。

波特率

  • 波特率是指每秒钟传输的比特数,是通信速率的衡量标准。常见的波特率有9600、19200、38400、57600、115200等。通信双方必须使用相同的波特率才能正常通信。

单工、半双工和全双工

  • 单工:数据只能单方向传输。例如,只能从A传输到B,不能反向。
  • 半双工:数据可以双向传输,但不能同时进行。例如,对讲机通信。
  • 全双工:数据可以同时双向传输。例如,电话通信。

二、 代码详情

//串口
void USART_Config(){
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);  //PA2 TX PA3 RX
	
  USART_InitTypeDef UI;//声明 串口初始化结构体
	UI.USART_BaudRate = 115200;//波特率
	UI.USART_HardwareFlowControl  = USART_HardwareFlowControl_None;
	UI.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	UI.USART_Parity = USART_Parity_No;
	UI.USART_StopBits = USART_StopBits_1;
	UI.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1,&UI);

	GPIO_InitTypeDef GPIO_InitStructure;//声明 GPIO初始化结构体
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX			   //串口输出PA9
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;	    //复用推挽输出
	GPIO_Init(GPIOA,&GPIO_InitStructure); 
	
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX			 //串口输入PA10
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;		  //模拟输入
	GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */
//	
//	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//打开中断
	USART_Cmd(USART1,ENABLE);//使能串口2
}

1. 使能外设时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
  • RCC_APB2PeriphClockCmd 是用来使能时钟的函数。
  • RCC_APB2Periph_GPIOA 使能GPIOA端口时钟。
  • RCC_APB2Periph_USART1 使能USART1外设时钟。
  • ENABLE 表示使能(打开)时钟。

2. 配置USART参数

USART_InitTypeDef UI;
UI.USART_BaudRate = 115200; // 波特率
UI.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
UI.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
UI.USART_Parity = USART_Parity_No;
UI.USART_StopBits = USART_StopBits_1;
UI.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &UI);
  • USART_InitTypeDef 是一个结构体,用于存储USART初始化参数。
  • UI.USART_BaudRate 设置波特率为115200。
  • UI.USART_HardwareFlowControl 设置硬件流控制为无(None)。
  • UI.USART_Mode 设置USART模式为接收(Rx)和发送(Tx)。
  • UI.USART_Parity 设置无奇偶校验。
  • UI.USART_StopBits 设置停止位为1位。
  • UI.USART_WordLength 设置数据位长度为8位。
  • USART_Init(USART1, &UI) 用这些参数初始化USART1。

3. 配置GPIO引脚

GPIO_InitTypeDef GPIO_InitStructure;

// 配置TX引脚(PA9)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);

// 配置RX引脚(PA10)
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 模拟输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
  • GPIO_InitTypeDef 是一个结构体,用于存储GPIO初始化参数。
  • 配置TX引脚(PA9):
    • GPIO_Pin_9 指定引脚9。
    • GPIO_Speed_50MHz 设置引脚速率为50MHz。
    • GPIO_Mode_AF_PP 设置引脚模式为复用推挽输出(适用于USART的TX引脚)。
    • GPIO_Init(GPIOA, &GPIO_InitStructure) 用这些参数初始化GPIOA的第9引脚。
  • 配置RX引脚(PA10):
    • GPIO_Pin_10 指定引脚10。
    • GPIO_Mode_IN_FLOATING 设置引脚模式为浮空输入(适用于USART的RX引脚)。
    • GPIO_Init(GPIOA, &GPIO_InitStructure) 用这些参数初始化GPIOA的第10引脚。

4. 使能USART

USART_Cmd(USART1, ENABLE);
  • USART_Cmd 是用来使能或失能USART的函数。
  • ENABLE 表示使能USART1。

三、 上位机程序

代码实现一个基于PyQt5的串口通信图形用户界面程序。程序主要功能包括选择串口端口和波特率、打开和关闭串口、发送和接收数据,以及选择数据解码模式(HEX、UTF-8、GBK)。程序初始化时,界面上有串口端口和波特率选择框、打开/关闭端口按钮、发送数据输入框及按钮、接收数据显示框和自动滚动复选框。用户可以通过选择端口和波特率,点击按钮打开或关闭串口。发送数据时,用户可以选择发送的数据编码方式,并通过输入框输入数据点击发送按钮进行发送。接收到的数据会根据选择的解码方式显示在接收数据显示框中,并且可以选择是否自动滚动显示。程序通过QTimer定时器每100毫秒检查一次是否有新数据接收,并在界面上实时更新显示。关闭窗口时,会自动关闭串口连接,确保资源释放。核心代码如下:

1. 打开/关闭端口

refresh_ports方法获取当前系统中的所有可用串口端口,并更新到端口选择下拉列表中。

def refresh_ports(self):
    ports = serial.tools.list_ports.comports()
    self.port_combo.clear()
    for port in ports:
        self.port_combo.addItem(port.device)

2. 发送数据

toggle_port方法用于打开或关闭串口。如果串口已打开,则关闭串口并停止定时器。如果串口未打开,则根据选择的端口和波特率配置串口,并尝试打开。如果成功,启动定时器以每100毫秒检查一次是否有新数据接收。如果失败,显示错误信息。

def toggle_port(self):
    if self.serial.is_open:
        self.serial.close()
        self.open_button.setText('打开端口')
        self.timer.stop()  # 端口关闭时停止定时器
    else:
        self.serial.port = self.port_combo.currentText()
        self.serial.baudrate = int(self.baudrate_combo.currentText())
        try:
            self.serial.open()
            self.open_button.setText('关闭端口')
            self.timer.start(100)  # 以100毫秒间隔启动定时器检查是否有传入数据
        except Exception as e:
            self.receive_text.append(f"无法打开端口: {e}")

3. 接收数据

receive_data方法用于从串口接收数据。根据选择的解码模式,将接收到的数据转换为相应的格式,并显示在接收区。如果启用了自动滚动选项,则自动滚动到接收区的末尾。

def receive_data(self):
    if self.serial.is_open:
        while self.serial.in_waiting:
            data = self.serial.read_all()
            if self.decode_combo.currentText() == 'HEX':
                data = data.hex()
            else:
                encoding = self.decode_combo.currentText().lower()
                data = data.decode(encoding, errors='ignore')
            self.receive_text.append(data)
            if self.auto_scroll.isChecked():
                self.receive_text.moveCursor(QTextCursor.End)

完整代码在GitHub项目的pyqt5文件夹下。

四、 打包为可执行文件

接下来我们使用pyinstaller将程序打包为exe文件。

pip install pyinstaller

我的程序名字为main.py,之后在main.py的文件目录下用下面命令即可。

pyinstaller --onefile --windowed main.py
  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于STM32二维码识别系统设计和实现可以分为硬件设计和软件设计两个部分。 硬件设计:首先,选择适合的STM32芯片作为主控,并添加相应的外设,如相机模块、触摸屏等。接下来,搭建合理的电路连接,包括电源管理、IO口配置等。同时,考虑到二维码扫描需求,需要使用合适的镜头来实现对二维码的捕捉和图像采集。确保系统稳定可靠的工作。 软件设计:首先,编写相应的驱动程序,包括摄像头驱动程序、显示屏驱动程序等。其次,设计二维码识别算法,根据相机拍摄的图像进行二维码的定位与解码。常用的二维码识别算法有ZBar等,可以根据实际需要进行选择。最后,设计用户界面,通过触摸屏等交互方式,进行扫描、识别二维码,并输出结果。 在实际操作中,可以先进行硬件电路的搭建和焊接,然后进行相应的底层软件驱动的编写和调试。随后,进行二维码识别算法的开发和优化,最后进行整体的集成测试和系统调试。系统调试完成后,还可以根据实际使用需求添加其他功能,如数据库存储、远程上传等。 总之,基于STM32二维码识别系统的设计和实现需要充分考虑硬件和软件两个方面,通过合理的硬件搭建和驱动编写,以及有效的二维码识别算法,能够实现高效、准确的二维码扫描与识别功能。 ### 回答2: 基于STM32二维码识别系统的设计与实现如下: 首先,我们需要选择合适的硬件平台。在这个项目中,我们选择了STM32微控制器作为主控芯片,它具有高性能和低功耗的特点,适合用于嵌入式系统。 接下来,我们需要一个合适的二维码识别算法。通常情况下,我们可以选择一种开源的二维码识别库,例如ZBar或ZXing。这些库支持多种类型的二维码,包括QR码和Data Matrix码。 然后,我们需要设计硬件接口。STM32的GPIO引脚可以用来连接摄像头模块,用于捕获图像。STM32还可以与LCD显示屏和键盘等外设进行通信,以便进行用户交互和结果显示。 在软件方面,我们需要编写相应的驱动程序来控制摄像头模块和LCD显示屏。同时,我们还需要编写二维码识别算法的接口程序,将图像数据传递给识别库,并获取识别结果。 最后,我们可以将系统的整体功能进行测试和调试。我们可以通过将摄像头对准包含二维码的物体,并观察LCD屏幕上是否能正确显示识别的结果来验证系统的性能。 总结起来,基于STM32二维码识别系统的设计与实现涉及硬件的选择和接口设计,以及软件的编程和测试。通过合适的硬件和软件协同,该系统能够快速、准确地识别二维码,并展示识别结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值