🎉欢迎来到Python专栏~Python实现串口通信
- ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹
- ✨博客主页:小夏与酒的博客
- 🎈该系列文章专栏:Python学习专栏
- 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
- 📜 欢迎大家关注! ❤️
🥝视频演示:
Python和Stm32实现串口通信演示
🥝图片展示:
PyCharm端发送数据:
stm32接收数据并回传:
Python技能树:Python入门技能树。
版本:Python 3.10。
IDE:PyCharm。
自制Stm32f103原理图与PCB:【stm32开发】stm32+oled最小系统板资料(原理图、PCB、示例代码)【六一】
需要本文章完整项目文件的话(Python串口通信代码+stm32-oled最小系统板资料+stm32串口通信完整项目),可以从该链接下载:【Python+Stm32串口通信】完整项目资料,或者三连本文章之后私聊我免费领取哦~
直接:
pip install pyserial
然后等待包的下载和安装完成。
先上本次文章的完整代码:
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':
参考板子的原理图,连接好OLED显示屏:
关于串口,本篇文章使用的是USART1,如下图:
引脚PA9是发送端,PA10是接收端,由于是TTL电平,所以需要一个USB转TTL的模块才可以与电脑的USB串口进行连接:
如果需要这块stm32的实物开发板的话(低价出),可以联系我~
在串口通信中,一般使用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多路支配关系-四足爬行机器人仿真与控制