Python与STM32F103之间的串口通信

之前写了一篇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);   
		}
	}	 
 }

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

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

物联沃分享整理
物联沃-IOTWORD物联网 » Python与STM32F103之间的串口通信

发表评论