【Python】Python實現串口通信(Python+Stm32)

🎉歡迎來到Python專欄~Python實現串口通信


  • ☆* o(≧▽≦)o *☆~我是小夏與酒🍹
  • ?博客主頁:小夏與酒的博客
  • 🎈該系列文章專欄:Python學習專欄
  • 文章作者技術和水平有限,如果文中出現錯誤,希望大家能指正🙏
  • 📜 歡迎大家關注! ??
    圖標

CSDN

🎉 目錄-Python實現串口通信

  • 一、實現效果
  • 二、說明
  • 三、Python串口通信代碼詳解
    • 3.1 包下載
    • 3.2 代碼詳解
  • 四、Stm32串口通信
    • 4.1 硬件部分
    • 4.2 代碼部分
  • 五、參考文章

遇見未來

一、實現效果

🥝視頻演示:

Python和Stm32實現串口通信演示

🥝圖片展示:
PyCharm端發送數據:
效果1
stm32接收數據并回傳:
效果2

二、說明

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 sleepdef recv(serial):while True:data = serial.read_all()if data == '':continueelse:breaksleep(0.02)return datadef 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 == '':continueelse:breaksleep(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顯示屏
oled接口
關于串口,本篇文章使用的是USART1,如下圖:
引腳圖
引腳PA9是發送端,PA10是接收端,由于是TTL電平,所以需要一個USB轉TTL的模塊才可以與電腦的USB串口進行連接:
硬件連接2

如果需要這塊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 == '':continueelse:breaksleep(0.02)return data

以十六進制發送和接收的串口通信完整代碼:

import serial
from time import sleepdef recv(serial):while True:data = serial.read_all().hex()if data == '':continueelse:breaksleep(0.02)return datadef 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);
}

這部分根據實際需求修改和調試即可。

展示修改后的通信效果,還有一些瑕疵,但是對于普通的項目可以使用了:
hex

下面給出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 <stdio.h>
#include <stdarg.h>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);}
}

最后來兩張和電腦連接的圖片:
展示1
展示2

五、參考文章

python中串口通信的步驟及實現。

python實現串口收發。

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

Python字符串前綴u、r、b、f含義。

Python Serial串口的簡單數據收發。

csdn

🧸結尾


  • ?? 感謝您的支持和鼓勵! 😊🙏
  • 📜您可能感興趣的內容:
  • 【FPGA零基礎學習之旅#9】狀態機基礎知識
  • 【FPGA零基礎學習之旅#8】阻塞賦值與非阻塞賦值講解
  • 【Arduino TinyGo】【最新】使用Go語言編寫Arduino-環境搭建和點亮LED燈
  • 【全網首發開源教程】【Labview機器人仿真與控制】Labview與Solidworks多路支配關系-四足爬行機器人仿真與控制
    遇見未來

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696767.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696767.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696767.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

springboot208基于springboot物流管理系統

基于spring boot物流管理系統設計與實現 摘 要 社會發展日新月異&#xff0c;用計算機應用實現數據管理功能已經算是很完善的了&#xff0c;但是隨著移動互聯網的到來&#xff0c;處理信息不再受制于地理位置的限制&#xff0c;處理信息及時高效&#xff0c;備受人們的喜愛。…

jax可微分編程的筆記

jax可微分編程的筆記 1.1.1 求導的基本概念 所謂的導數是一個從集合F到自身的映射. 有時,我們也將一個從函數到函數的映射稱為一個操作, 這里的操作在物理學中也被稱作一個算符. 但在計算機中的操作符相當于數學中的一個函數,而非從 函數到函數的映射. 應該指出的是,如果我們…

vue小記——this(2)

在Vue的方法中使用普通函數作為回調函數&#xff0c;那么在該回調函數中&#xff0c;this將不會指向Vue實例&#xff0c;而是指向全局對象&#xff08;在瀏覽器中是window&#xff09;。 錯誤 &#xff1a; export default { data() { return { message: Hello Vue! }; …

npm 包發布

name publish必填項&#xff08;version,nameverson構成唯一標識&#xff09;&#xff0c;唯一&#xff0c;所以publish前驗證庫里是否存在該名稱&#xff0c;方式npm info xxx npm ERR! 404 cy_test is not in the npm registry.可以使用。規則&#xff1a;不能以.或者_開頭…

maven工程打包引入本地jar包

1、通過maven生成本地區倉庫包 mvn install:install-file --settings D:\lkx\download\apache-maven-3.6.3\conf\settings.xml -Dfileaspose-cad-21.8.jar -DartifactIdaspose-cad -DgroupIdsystem.core -Dversion21.8 -Dpackagingjar -DgeneratePomtrue # --settings&#xf…

進程線程間的通信:2024/2/22

作業1&#xff1a;代碼實現線程互斥機制 代碼&#xff1a; #include <myhead.h>//臨界資源 int num10;//創建一個互斥鎖 pthread_mutex_t mutex;//任務一 void *task1(void *arg) {//獲取鎖資源pthread_mutex_lock(&mutex);num123;sleep(3);printf("task1:num…

PacketSender-用于發送/接收 TCP、UDP、SSL、HTTP 的網絡實用程序

PacketSender-用于發送/接收 TCP、UDP、SSL、HTTP 的網絡實用程序 PacketSender是一款開源的用于發送/接收 TCP、UDP、SSL、HTTP 的網絡實用程序&#xff0c;作者為dannagle。 其官網地址為&#xff1a;https://packetsender.com/&#xff0c;Github源代碼地址&#xff1a;htt…

【AI繪畫工具分別有哪些?】

目前有許多AI繪畫工具可供選擇&#xff0c;以下列舉了一些常見的AI繪畫工具&#xff1a; 1. DeepArt.io&#xff1a;該工具使用深度學習算法生成藝術風格的圖像&#xff0c;并可以將輸入圖像與指定的藝術風格進行合并。 2. Prisma&#xff1a;這是一款非常流行的AI繪畫應用&a…

SQL Server —— While語句循環

一&#xff1a;簡介 while 循環是有條件的循環控制語句。滿足條件后&#xff0c;再執行循環體中的SQL語句。 while: break, 如果有多條語句可以在while后面添加begin-end。關于while的語法 while(條件) -- begin -- 語句1 -- 語句2 -- break 根據情況是否添加break -- end 二…

leetcode日記(32)字符串相乘

做了很久很久……真的太繁瑣了&#xff01;&#xff01; class Solution { public:string multiply(string num1, string num2) {string s;string str;if (num1 "0" || num2 "0") return "0";for(int inum2.size()-1;i>0;i--){int c2num2[…

Open CASCADE學習|全局屬性

目錄 1、概念解釋 質心&#xff1a; 重心&#xff1a; 慣性矩&#xff1a; 慣性矩陣&#xff1a; 主慣性矩&#xff1a; 靜態慣性矩&#xff1a; 2、API 1、概念解釋 質心&#xff1a; 質心是質量中心的簡稱&#xff0c;指物質系統上被認為質量集中于此的一個假想點。…

Qt:tabWidget控件

一、tabWidget用來做什么 tabWidget控件用來進行不同控件頁面的跳轉&#xff0c; 二、控件的一些函數功能 添加一個頁面&#xff0c;返回index int addTab(QWidget *widget, const QString &); int addTab(QWidget *widget, const QIcon& icon, const QString &…

pytest教程-11-初識fixture

領取資料&#xff0c;咨詢答疑&#xff0c;請?wei: June__Go 上一小節我們學習了使用allure生成html測試報告的方法&#xff0c;本小節我們講解一下pytest fixture測試夾具的使用方法。 前言 在做自動化的過程中&#xff0c;編寫用例時候需要用到用例的前置和用例的后置&a…

2024年了,抖店還能做嗎?適合新手嗎?

我是電商珠珠 現在已經24年了&#xff0c;抖店也已經發展了四年了。其中有很多在門外觀望的人&#xff0c;還在猶豫不決。認為抖店發展到今天&#xff0c;所有的紅利早已在20年的時候就消失殆盡了&#xff0c;特別是沒有經驗的如果入駐了&#xff0c;既不能享受平臺紅利&#…

后端程序員入門react筆記(四)-綜合運用,寫一個小demo

樣式模塊化 有時候我們會遇到這樣的問題&#xff0c;有兩個css對一個class聲明了樣式&#xff0c;這樣的話后引入的css會覆蓋前面的css樣式&#xff0c;導致樣式沖突&#xff0c;那么我們怎么解決這種問題呢&#xff0c;我們可以使用樣式的模塊化&#xff0c;我們起名一個inde…

全棧筆記_瀏覽器擴展篇(插件開發 - chrome瀏覽器proxy代理)

代理類型 常用的包括http、https、socks代理 配置權限 要讓擴展使用代理接口,需要聲明proxy權限: // manifest.json "permissions": ["proxy" ]設置代理服務器 chrome.proxy.settings.set({ scope: ‘regular’, value: 代理配置},回調函數) 代理配…

【前端面經2】京東一面

題目來源&#xff1a;牛客網 自我介紹 動態參數解析的解決方案 對于動態部分使用…args進行接受&#xff0c;可以把動態部分提取成數組 前端安全問題 CDN劫持 內容安全策略CSP 安全沙箱 Iframe 跨站腳本攻擊XSS 攻擊者通過在目標網站上注入惡意腳本&#xff0c;使之在…

OpenHarmony驅動框架HDF中設備管理服務構建過程詳解

前言 如下圖&#xff0c;開源鴻蒙系統驅動框架HDF在內核中的實現&#xff0c;可以分為向用戶層提供設備服務的管理模塊&#xff08;Manager&#xff09;&#xff0c;和實際管理硬件的Host模塊。 Manager分為DeviceManageService和 DeviceServiceManage&#xff0c;前者負責提供…

1.WEB滲透測試-前置基礎知識-ip地址

ip地址&#xff1a; ip地址指的是互聯網協議地址&#xff0c;是IP協議提供的一種統一的地址格式&#xff0c;以每一臺聯網的主機都有一個對應的ip地址&#xff0c;ip地址也可以理解為分配給用戶上網使用的網際協議的設備的數字標簽。通俗的來說就是你打電話時候的每個人都有自己…

AIGC 實戰:如何使用 Docker 在 Ollama 上離線運行大模型(LLM)

Ollama簡介 Ollama 是一個開源平臺&#xff0c;用于管理和運行各種大型語言模型 (LLM)&#xff0c;例如 Llama 2、Mistral 和 Tinyllama。它提供命令行界面 (CLI) 用于安裝、模型管理和交互。您可以使用 Ollama 根據您的需求下載、加載和運行不同的 LLM 模型。 Docker簡介 D…