草庐IT

Python与STM32F103串口通信

def__init__1923 2024-01-05 原文

之前写了一篇Python与STM32F103通信的文章,但是存在一定的问题,比如说有时串口接收不到返回的数据,还有就是接收数据接收的不全,感觉有可能是读取的时候用serial.read_all()这个方法和正点原子例程中串口缓冲区的发送有矛盾,所以参考了一下其他文章,写一篇新文章记录一下。

上一篇文章链接:(29条消息) 使用Python与Stm32进行通信_def__init__1923的博客-CSDN博客_stm32单片机 pythonhttps://blog.csdn.net/weixin_47428902/article/details/126296318?spm=1001.2014.3001.5501

方法:利用python的serial函数库与STM32进行通信。

没有安装serial库的话请先安装,terminal输入指令:

pip install serial

将Stm32用USB串口连接到电脑,打开设备管理器查看端口,端口为COM4。

在Pycharm中写下Python程序:

import serial


# 串口打开函数
def open_ser():
    port = 'COM4'  # 串口号
    baudrate = 115200  # 波特率
    try:
        global ser
        ser = serial.Serial(port, baudrate, timeout=2)
        if ser.isOpen() == True:
            print("串口打开成功")
    except Exception as exc:
        print("串口打开异常", exc)


# 数据发送
def send_msg():

    try:
        send_datas = input("请输入要发送的数据:\n")
        ser.write(str(send_datas+'\r\n').encode("gbk"))
        print('-' * 80)
        print("已发送数据:")
        print(send_datas)
        print('-' * 80)
        # send_datas1 = 875
        # ser.write(str(send_datas1).encode("gbk"))
        # print("已发送数据:", send_datas1)
    except Exception as exc:
        print("发送异常", exc)


# 接收数据
def read_msg():

    try:
        print("等待接收数据......")
        while True:
            data = ser.read(ser.in_waiting).decode('gbk')
            if data != '':
                break
        print('-' * 80)
        print("已接受到数据:")
        print(data)
        print('-' * 80)
    except Exception as exc:
        print("读取异常", exc)


# 关闭串口
def close_ser():

    try:
        ser.close()
        if ser.isOpen():
            print("串口未关闭")
        else:
            print("串口已关闭")
    except Exception as exc:
        print("串口关闭异常", exc)


if __name__ == '__main__':
    ser = None
    open_ser()  # 打开串口

    while 1:
        print('----------请选择你要进行的操作----------')
        print('---1:发送数据--2:接收数据--3:关闭串口---')
        op = input('请输入:')
        if op == '1':
            send_msg()  # 写数据
        if op == '2':
            read_msg()  # 读数据
        if op == '3':
            close_ser()  # 关闭串口
            break

        先讲解一下代码:第一部分,打开串口。port选择您的端口号,波特率选择115200,保持跟您STM32串口通信的波特率一致即可。serial.Serial()函数的参数timeout代表超时时间,可选择参数:1.timeout = None: 长时间等待   2.timeout = 0: 不阻塞形式 (读完之后就返回)   3.timeout = x: x秒后超时 (float allowed)。

# 串口打开函数
def open_ser():
    port = 'COM4'  # 串口号
    baudrate = 115200  # 波特率
    try:
        global ser
        ser = serial.Serial(port, baudrate, timeout=2)
        if ser.isOpen() == True:
            print("串口打开成功")
    except Exception as exc:
        print("串口打开异常", exc)

        接下来是第二部分:数据发送部分。首先先输入要发送的输入,写入串口时进行gbk编码,然后再进行发送。注意看,send_datas后面写了+'\r\n',这是因为正点原子串口通信那个例程代码写的协议是接收数据要以'\r\n'结尾,所以加上了这两个字符,否则STM32认为接收数据无效。

# 数据发送
def send_msg():

    try:
        send_datas = input("请输入要发送的数据:\n")
        ser.write(str(send_datas+'\r\n').encode("gbk"))
        print('-' * 80)
        print("已发送数据:")
        print(send_datas)
        print('-' * 80)
        # send_datas1 = 875
        # ser.write(str(send_datas1).encode("gbk"))
        # print("已发送数据:", send_datas1)
    except Exception as exc:
        print("发送异常", exc)

         再下来是第三部分:数据接收部分。使用ser.read(ser.in_waiting)这个方法来接收数据,测试后尝试没有数据接收不全的情况,所以最好就采用这种方法吧。接收后进行gbk解码,解码完成后打印接收到的数据。

# 接收数据
def read_msg():

    try:
        print("等待接收数据......")
        while True:
            data = ser.read(ser.in_waiting).decode('gbk')
            if data != '':
                break
        print('-' * 80)
        print("已接受到数据:")
        print(data)
        print('-' * 80)
    except Exception as exc:
        print("读取异常", exc)

        再下来是第四部分:串口关闭部分。这部分不需要解释,大家应该都能看懂。

# 关闭串口
def close_ser():

    try:
        ser.close()
        if ser.isOpen():
            print("串口未关闭")
        else:
            print("串口已关闭")
    except Exception as exc:
        print("串口关闭异常", exc)

        最后讲解一下主程序。先打开串口,然后进入死循环,通过input方法来做进一步决定:发送数据、接收数据、关闭串口。如果输入1,则代表发送数据;如果输入2,则代表接收数据;如果输入3,则代表关闭串口退出。下面是主程序。。。。。。。

if __name__ == '__main__':
    ser = None
    open_ser()  # 打开串口

    while 1:
        print('----------请选择你要进行的操作----------')
        print('---1:发送数据--2:接收数据--3:关闭串口---')
        op = input('请输入:')
        if op == '1':
            send_msg()  # 写数据
        if op == '2':
            read_msg()  # 读数据
        if op == '3':
            close_ser()  # 关闭串口
            break

        接下来请看演示部分。

        运行程序,弹出以下部分。

         输入1,开始发送数据。

         再输入2,接收数据。弹出以下部分。

         再输入3,关闭串口,程序结束。

         STM32F103的程序用正点原子的例程即可,代码如下。

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
 
/************************************************
 ALIENTEK精英STM32开发板实验4
 串口 实验   
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/
 int main(void)
 {		
 	u16 t;  
	u16 len;	
	u16 times=0;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 //串口初始化为115200
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
 	while(1)
	{
		if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			
			printf("你发送的消息是:\r\n\r\n");
			delay_us(10);
			
			for(t=0;t<len;t++)
			{
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			}
			printf("\r\n---end---\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
			times++;
			/*
			if(times%5000==0)
			{
				printf("精英STM32开发板 串口实验\r\n");
				printf("正点原子@ALIENTEK\r\n\r\n");
			}
			if(times%200==0)printf("\r\n请输入数据,以回车键结束\r\n"); */
			if(times%100==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
			
			delay_ms(10);   
		}
	}	 
 }

        每隔一段时间打印一下的那部分注释掉,比较烦人。

        内容基本上就是这些,希望能够给您带来帮助,有问题的话欢迎讨论。

有关Python与STM32F103串口通信的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  3. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  4. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  5. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  6. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  7. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  8. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  9. MIMO-OFDM无线通信技术及MATLAB实现(1)无线信道:传播和衰落 - 2

     MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO

  10. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

随机推荐