欢迎来到Python专栏~Python实现串口通信

☆* o(≧▽≦)o *☆嗨~我是小夏与酒 ✨博客主页:小夏与酒的博客 该系列文章专栏:Python学习专栏 文章作者技术和水平有限,如果文中出现错误,希望大家能指正 欢迎大家关注! ❤️

 目录-Python实现串口通信

一、实现效果二、说明三、Python串口通信代码详解3.1 包下载3.2 代码详解

四、Stm32串口通信4.1 硬件部分4.2 代码部分

五、参考文章

一、实现效果

諾视频演示:

Python和Stm32实现串口通信演示

諾图片展示: PyCharm端发送数据: stm32接收数据并回传:

二、说明

Python技能树:Python入门技能树。 版本:Python 3.10。 IDE:PyCharm。 自制Stm32f103原理图与PCB:【stm32开发】stm32+oled最小系统板资料(原理图、PCB、示例代码)【六一】

需要本文章完整项目文件的话(Python串口通信代码+stm32-oled最小系统板资料+stm32串口通信完整项目),可以从该链接下载:【Python+Stm32串口通信】完整项目资料,或者三连本文章之后私聊我免费领取哦~

三、Python串口通信代码详解

3.1 包下载

直接:

pip install pyserial

然后等待包的下载和安装完成。

3.2 代码详解

先上本次文章的完整代码:

import serial

from time import sleep

def recv(serial):

while True:

data = serial.read_all()

if data == '':

continue

else:

break

sleep(0.02)

return data

def send(send_data):

if (serial.isOpen()):

serial.write(send_data.encode('utf-8')) # 编码

print("发送成功", send_data)

else:

print("发送失败!")

if __name__ == '__main__':

serial = serial.Serial('COM3', 9600, timeout=0.5)

if serial.isOpen() :

print("open success")

else :

print("open failed")

#这里如果不加上一个while True,程序执行一次就自动跳出了

while True:

a = input("输入要发送的数据:")

send(a)

sleep(0.5) # 起到一个延时的效果

data =recv(serial)

if data != '' :

print("receive : ",data)

if data == b'x':

print("exit")

break

关于Python实现串口通信的参考文章我都列到文末啦~感谢相关文章的大佬!

代码分析: 首先是包的导入:

import serial

from time import sleep

定义串口接收函数:

def recv(serial):

while True:

data = serial.read_all()

if data == '':

continue

else:

break

sleep(0.02)

return data

定义串口发送函数:

def send(send_data):

if (serial.isOpen()):

serial.write(send_data.encode('utf-8')) # 编码

print("发送成功", send_data)

else:

print("发送失败!")

主程序部分:

if __name__ == '__main__':

serial = serial.Serial('COM3', 9600, timeout=0.5)

if serial.isOpen() :

print("open success")

else :

print("open failed")

#这里如果不加上一个while True,程序执行一次就自动跳出了

while True:

a = input("输入要发送的数据:")

send(a)

sleep(0.5) # 起到一个延时的效果

data =recv(serial)

if data != '' :

print("receive : ",data)

if data == b'x':

print("exit")

break

主程序部分的作用就是开启串口,在while循环中发送或者接收串口的数据,并且在接收到数据x之后,结束程序。

需要注意的是,下面这部分代码中,9600为波特率,且需要输入正确的端口号,不然程序会报错!

serial = serial.Serial('COM3', 9600, timeout=0.5)

这部分是字符串前缀,前缀b表示该字符串是bytes类型:

if data == b'x':

四、Stm32串口通信

4.1 硬件部分

参考板子的原理图,连接好OLED显示屏: 关于串口,本篇文章使用的是USART1,如下图: 引脚PA9是发送端,PA10是接收端,由于是TTL电平,所以需要一个USB转TTL的模块才可以与电脑的USB串口进行连接:

如果需要这块stm32的实物开发板的话(低价出),可以联系我~

4.2 代码部分

在串口通信中,一般使用hex格式进行收发,但是在目前的代码中,我们发送的数据为字符串,所以在stm32的oled显示中,数据和发送的不一致。

参考文章:Python 串口发送十六进制数据。

修改Python中的发送和接收函数:

#以十六进制的格式发送数据

def send(send_data):

send_data_hex = bytes.fromhex(send_data)

if (serial.isOpen()):

serial.write(send_data_hex) # 编码

print("发送成功", send_data_hex)

else:

print("发送失败!")

#以十六进制的格式接收数据

def recv(serial):

while True:

data = serial.read_all().hex()

if data == '':

continue

else:

break

sleep(0.02)

return data

以十六进制发送和接收的串口通信完整代码:

import serial

from time import sleep

def recv(serial):

while True:

data = serial.read_all().hex()

if data == '':

continue

else:

break

sleep(0.02)

return data

def send(send_data):

send_data_hex = bytes.fromhex(send_data)

if (serial.isOpen()):

serial.write(send_data_hex) # 编码

print("发送成功", send_data_hex)

else:

print("发送失败!")

if __name__ == '__main__':

serial = serial.Serial('COM3', 9600, timeout=0.5)

if serial.isOpen() :

print("open success")

else :

print("open failed")

#这里如果不加上一个while True,程序执行一次就自动跳出了

while True:

a = input("输入要发送的数据:")

send(a)

sleep(0.5) # 起到一个延时的效果

data =recv(serial)

if data != '' :

print("receive : ",data)

✨注意: 本文章中stm32的数据接收和发送格式为:

uint8_t Serial_RxData;

void Serial_SendByte(uint8_t Byte)

{

USART_SendData(USART1, Byte);

while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

}

这部分根据实际需求修改和调试即可。

展示修改后的通信效果,还有一些瑕疵,但是对于普通的项目可以使用了:

下面给出stm32的部分代码:

main.c:

#include "stm32f10x.h" // Device header

#include "Delay.h"

#include "OLED.h"

#include "Serial.h"

uint8_t RxData;

int main(void)

{

OLED_Init();

OLED_ShowString(1, 1, "RxData:");

Serial_Init();

while (1)

{

if (Serial_GetRxFlag() == 1)

{

RxData = Serial_GetRxData();

Serial_SendByte(RxData);

OLED_ShowHexNum(1, 8, RxData, 2);

}

}

}

Serial.c:

#include "stm32f10x.h" // Device header

#include

#include

uint8_t Serial_RxData;

uint8_t Serial_RxFlag;

void Serial_Init(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

USART_InitTypeDef USART_InitStructure;

USART_InitStructure.USART_BaudRate = 9600;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_Init(USART1, &USART_InitStructure);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_Init(&NVIC_InitStructure);

USART_Cmd(USART1, ENABLE);

}

void Serial_SendByte(uint8_t Byte)

{

USART_SendData(USART1, Byte);

while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);

}

void Serial_SendArray(uint8_t *Array, uint16_t Length)

{

uint16_t i;

for (i = 0; i < Length; i ++)

{

Serial_SendByte(Array[i]);

}

}

void Serial_SendString(char *String)

{

uint8_t i;

for (i = 0; String[i] != '\0'; i ++)

{

Serial_SendByte(String[i]);

}

}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)

{

uint32_t Result = 1;

while (Y --)

{

Result *= X;

}

return Result;

}

void Serial_SendNumber(uint32_t Number, uint8_t Length)

{

uint8_t i;

for (i = 0; i < Length; i ++)

{

Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');

}

}

int fputc(int ch, FILE *f)

{

Serial_SendByte(ch);

return ch;

}

void Serial_Printf(char *format, ...)

{

char String[100];

va_list arg;

va_start(arg, format);

vsprintf(String, format, arg);

va_end(arg);

Serial_SendString(String);

}

uint8_t Serial_GetRxFlag(void)

{

if (Serial_RxFlag == 1)

{

Serial_RxFlag = 0;

return 1;

}

return 0;

}

uint8_t Serial_GetRxData(void)

{

return Serial_RxData;

}

void USART1_IRQHandler(void)

{

if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)

{

Serial_RxData = USART_ReceiveData(USART1);

Serial_RxFlag = 1;

USART_ClearITPendingBit(USART1, USART_IT_RXNE);

}

}

最后来两张和电脑连接的图片:

五、参考文章

python中串口通信的步骤及实现。

python实现串口收发。

详解Python中字符串前“b”,“r”,“u”,“f”的作用。

Python字符串前缀u、r、b、f含义。

Python Serial串口的简单数据收发。

笠结尾

❤️ 感谢您的支持和鼓励!  您可能感兴趣的内容:【FPGA零基础学习之旅#9】状态机基础知识【FPGA零基础学习之旅#8】阻塞赋值与非阻塞赋值讲解 【Arduino TinyGo】【最新】使用Go语言编写Arduino-环境搭建和点亮LED灯【全网首发开源教程】【Labview机器人仿真与控制】Labview与Solidworks多路支配关系-四足爬行机器人仿真与控制

查看原文