找回密码
 会员注册
查看: 31|回复: 0

PythonPython实现串口通信(Python+Stm32)

[复制链接]

3

主题

0

回帖

10

积分

新手上路

积分
10
发表于 2024-9-5 12:48:21 | 显示全部楼层 |阅读模式
🎉欢迎来到Python专栏~Python实现串口通信☆*o(≧▽≦)o*☆嗨~我是小夏与酒🍹✨博客主页:小夏与酒的博客🎈该系列文章专栏:Python学习专栏文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏📜欢迎大家关注!❤️🎉目录-Python实现串口通信一、实现效果二、说明三、Python串口通信代码详解3.1包下载3.2代码详解四、Stm32串口通信4.1硬件部分4.2代码部分五、参考文章一、实现效果🥝视频演示:Python和Stm32实现串口通信演示🥝图片展示:PyCharm端发送数据:stm32接收数据并回传:二、说明Python技能树:Python入门技能树。版本:Python3.10。IDE:PyCharm。自制Stm32f103原理图与PCB:【stm32开发】stm32+oled最小系统板资料(原理图、PCB、示例代码)【六一】需要本文章完整项目文件的话(Python串口通信代码+stm32-oled最小系统板资料+stm32串口通信完整项目),可以从该链接下载:【Python+Stm32串口通信】完整项目资料,或者三连本文章之后私聊我免费领取哦~三、Python串口通信代码详解3.1包下载直接:pipinstallpyserial1然后等待包的下载和安装完成。3.2代码详解先上本次文章的完整代码:importserialfromtimeimportsleepdefrecv(serial):whileTrue:data=serial.read_all()ifdata=='':continueelse:breaksleep(0.02)returndatadefsend(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)ifserial.isOpen():print("opensuccess")else:print("openfailed")#这里如果不加上一个whileTrue,程序执行一次就自动跳出了whileTrue:a=input("输入要发送的数据:")send(a)sleep(0.5)#起到一个延时的效果data=recv(serial)ifdata!='':print("receive:",data)ifdata==b'x':print("exit")break1234567891011121314151617181920212223242526272829303132333435363738关于Python实现串口通信的参考文章我都列到文末啦~感谢相关文章的大佬!📜代码分析:首先是包的导入:importserialfromtimeimportsleep12定义串口接收函数:defrecv(serial):whileTrue:data=serial.read_all()ifdata=='':continueelse:breaksleep(0.02)returndata123456789'运行运行定义串口发送函数:defsend(send_data):if(serial.isOpen()):serial.write(send_data.encode('utf-8'))#编码print("发送成功",send_data)else:print("发送失败!")123456'运行运行主程序部分:if__name__=='__main__':serial=serial.Serial('COM3',9600,timeout=0.5)ifserial.isOpen():print("opensuccess")else:print("openfailed")#这里如果不加上一个whileTrue,程序执行一次就自动跳出了whileTrue:a=input("输入要发送的数据:")send(a)sleep(0.5)#起到一个延时的效果data=recv(serial)ifdata!='':print("receive:",data)ifdata==b'x':print("exit")break123456789101112131415161718主程序部分的作用就是开启串口,在while循环中发送或者接收串口的数据,并且在接收到数据x之后,结束程序。需要注意的是,下面这部分代码中,9600为波特率,且需要输入正确的端口号,不然程序会报错!serial=serial.Serial('COM3',9600,timeout=0.5)1这部分是字符串前缀,前缀b表示该字符串是bytes类型:ifdata==b'x':1四、Stm32串口通信4.1硬件部分参考板子的原理图,连接好OLED显示屏:关于串口,本篇文章使用的是USART1,如下图:引脚PA9是发送端,PA10是接收端,由于是TTL电平,所以需要一个USB转TTL的模块才可以与电脑的USB串口进行连接:如果需要这块stm32的实物开发板的话(低价出),可以联系我~4.2代码部分在串口通信中,一般使用hex格式进行收发,但是在目前的代码中,我们发送的数据为字符串,所以在stm32的oled显示中,数据和发送的不一致。参考文章:Python串口发送十六进制数据。修改Python中的发送和接收函数:#以十六进制的格式发送数据defsend(send_data):send_data_hex=bytes.fromhex(send_data)if(serial.isOpen()):serial.write(send_data_hex)#编码print("发送成功",send_data_hex)else:print("发送失败!")12345678'运行运行#以十六进制的格式接收数据defrecv(serial):whileTrue:data=serial.read_all().hex()ifdata=='':continueelse:breaksleep(0.02)returndata12345678910'运行运行以十六进制发送和接收的串口通信完整代码:importserialfromtimeimportsleepdefrecv(serial):whileTrue:data=serial.read_all().hex()ifdata=='':continueelse:breaksleep(0.02)returndatadefsend(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)ifserial.isOpen():print("opensuccess")else:print("openfailed")#这里如果不加上一个whileTrue,程序执行一次就自动跳出了whileTrue:a=input("输入要发送的数据:")send(a)sleep(0.5)#起到一个延时的效果data=recv(serial)ifdata!='':print("receive:",data)123456789101112131415161718192021222324252627282930313233343536✨注意:本文章中stm32的数据接收和发送格式为:uint8_tSerial_RxData;1voidSerial_SendByte(uint8_tByte){ USART_SendData(USART1,Byte); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);}12345这部分根据实际需求修改和调试即可。展示修改后的通信效果,还有一些瑕疵,但是对于普通的项目可以使用了:下面给出stm32的部分代码:main.c:#include"stm32f10x.h"//Deviceheader#include"Delay.h"#include"OLED.h"#include"Serial.h"uint8_tRxData;intmain(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); } }}12345678910111213141516171819202122232425Serial.c:#include"stm32f10x.h"//Deviceheader#include#includeuint8_tSerial_RxData;uint8_tSerial_RxFlag;voidSerial_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDefGPIO_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_InitTypeDefUSART_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_InitTypeDefNVIC_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);}voidSerial_SendByte(uint8_tByte){ USART_SendData(USART1,Byte); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);}voidSerial_SendArray(uint8_t*Array,uint16_tLength){ uint16_ti; for(i=0;i
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 06:05 , Processed in 0.441899 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表