基于树莓派4B与STM32的UART串口通信实验(代码开源)

这篇具有很好参考价值的文章主要介绍了基于树莓派4B与STM32的UART串口通信实验(代码开源)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:本文为手把手教学树莓派4B与 STM32 的 UART 通讯,本次项目采用树莓派4B与 STM32 进行串口通讯,将彼此的数据进行互相传输。本篇博客同时提供了基于 YOLOv5-Lite 的目标检测数据联动,即将树莓派4B检测到的信息发送至 STM32,后续可以通过这些信息进行各种需求上的控制。树莓派4BSTM32 的联动是很常见的嵌入式架构体系,通常树莓派4B负责计算量大的任务(例如:目标检测,激光雷达等),STM32 则负责进行控制任务,该架构也是目前主流的智能硬件处理框架!(文末有代码开源!

硬件实物图:基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

效果图:

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

一、树莓派4B串口

1.1 树莓派4B的Pin

树莓派4B的引脚图:

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

树莓派4B作为一款小型电脑,其提供了额外大量的 Pin 引脚适用于嵌入式的日常开发,本次实验我们需要需要实现树莓派4B与STM32F103C8T6之间的UART通讯!

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

补充说明:

树莓派4B作为上位机负责计算量大的任务(例如:目标检测,激光雷达等),STM32 则负责进行控制为主的任务。该体系框架是目前主流的人工智能嵌入式流派之一,如今多数的智能小车,智能航行器,智能机械臂都有使用该套框架!

该框架的优势:

该框架将控制任务与计算任务隔离,实现了各 CPU 的专门专精,提高了系统的稳定性(方便后期任务的扩展或者检修)。同时,STM32虽然计算能力上是远远弱于树莓派4B的,但是其GPIO的控制能力是强于树莓派的,也就是它天生根据控制优势。所以,该框架是充分发挥了各自的专长!

树莓派4B与STM32之间常用的通讯方式:

(1)、UART,(2)、SPI,(3)、I2C(该项目使用Serial)

1.2 树莓派4B安装Serial与使用

引脚连接:

根据上图树莓派4B的 Pin 引脚图中 GPIO14(TXD) 和 GPIO15(RXD) 的两个引脚分别与 STM32F103C8T6 的 PA10(RXD)PA10(RXD) 的引脚相连(交叉连接

1.2.1 安装serial

在终端输入:sudo apt-get install serial

1.2.2 打开树莓派4B串口

在终端输入:sudo raspi-config 打开界面设置

 Interfacing Options→serial→否→是

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

在终端输入:ls -al /dev/查看设备

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

1.2.3 修改串口映射关系

在终端输入:sudo nano /boot/config.txt

末行添加 dtoverlay=pi3-miniuart-bit

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

重启树莓派4B,之后终端输入:ls -la /dev/查看设备

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

1.2.4 修改配置文件

在终端输入:sudo nano /boot/cmdline.txt

修改cmdline.txt文件的内容,内容如下:

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

二、安装minicom与树莓派4B测试

2.1  minicom安装

minicom 是 Linux/树莓派4B 平台串口调试工具,相当于 windows 上的串口调试助手,此时需要先安装 minicom

sudo apt-get install minicom

在终端输入:minicom -D /dev/ttyAMA0

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

如果要退出这个minicom软件的话,先按CTRL+A再按Z就会弹出菜单,按下0回车就退出了,然后就能直接关闭了。

2.2 树莓派4B通信测试

我们使用 XCOM 串口调试助手来测试树莓派4B能否正常进行 UART 通信!

使用USB-TTL模块交叉连接树莓派4B的 UART 的引脚;

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

★特殊说明:USB-TTL 模块的 VCC 和 GND 一定都要与树莓派4B的相应 Pin 相连,不然可能因为电流的不平衡导致端口疯狂输出乱码!

我们在下图 minicom 红框区域输入 Hi IKUN!字样之后,可以在 XCOM 的端口处看到字符串成功发送到了 PC 端;

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

同理,在 XCOM 端口发送 Hi My Brother 字样之后,可以在树莓派4B的  minicom 红框区域成功接收到该信息!

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

当成功完成上述的操作之后,说明我们已经成功的配置好树莓派4B的UART功能!之后就可以尝试与 STM32 进行通信了(发送数据给XCOM不仅可以通过 minicom,也可以通过python等代码)!

三、树莓派4B与STM32通信

STM32 的代码其实就是简单的UART串口通讯代码,但实质上是有很多坑!!!作者发现大部分博主并没有说明出坑所在,这部分作者将会为读者朋友把可能出现的坑给解决掉!

3.1 树莓派4B代码 

我们利用 Python 代码写一个循环发送数字的代码程序,具体代码如下:

import serial  
import time  
  
ser = serial.Serial('/dev/ttyAMA0',115200) # 串口初始化,根据实际情况修改串口号和波特率  

# 定义要输出的数字  
num =  196 

while True:  
                
    ser.write(str(int(num)).encode()) # 发送数字到串口   
    num += 1  
    if num > 205:  
        num = 196
     
    time.sleep(0.2) # 等待1秒钟  

可以看出代码是非常简单的,但是这里读者朋友需要注意的是树莓派4B的端口发送至STM32的其实都是字符串流!在STM32端我们对发送过来的字符串流进行解码(很多博主其实都没有说明该点,导致很多朋友解码失败)!

3.2 CubeMX配置

1、RCC配置外部高速晶振(精度更高)——HSE;

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

2、SYS配置:Debug设置成Serial Wire否则可能导致芯片自锁);

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

3、I2C配置:

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

4、USART1配置:设置UART1串口;波特率:115200;开启UART串口中断;

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

5、时钟树配置

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

6、工程配置

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

3.3 STM32代码

3.3.1 OLED代码

OLED模块主要是方便显示树莓派4B发送给STM32的数据信息!考虑到实际情况,我们一般需要根据树莓派4B发送过来的数字信息,所以,我们这里利用OLED进行数字显示!

小数显示API函数:

//z_len为整数显示位数,f_len为小数显示位数,size2为字体大小
void OLED_Showdecimal(u8 x,u8 y,float num,u8 z_len,u8 f_len,u8 size2)
{         	
	u8 t,temp;
	u8 enshow;
	int z_temp,f_temp;      
	z_temp=(int)num;
	//整数部分
	for(t=0;t<z_len;t++)
	{
		temp=(z_temp/oled_pow(10,z_len-t-1))%10;
		if(enshow==0 && t<(z_len-1))
		{
			if(temp==0)
			{
				OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
				continue;
			}
			else
			enshow=1;
		}
		OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); 
	}
	//小数点
	OLED_ShowChar(x+(size2/2)*(z_len),y,'.',size2); 
	
	f_temp=(int)((num-z_temp)*(oled_pow(10,f_len)));
  //小数部分
	for(t=0;t<f_len;t++)
	{
		temp=(f_temp/oled_pow(10,f_len-t-1))%10;
		OLED_ShowChar(x+(size2/2)*(t+z_len)+5,y,temp+'0',size2); 
	}
}

篇幅有限,OLED参考博客:http://t.csdn.cn/kydg4

3.3.2 UART代码

这部分代码是比较核心的,上述博客作者已经说明了,其实树莓派4B发送给STM32的数据都是以字符串流的格式发送来得。所以,即使发送过来的是数字数据也会变成字符,这就需要我们进行解码!

uart.h:

#ifndef __UART_H
#define __UART_H

#include "stm32f1xx_hal.h" 

extern UART_HandleTypeDef huart1;

#define USART1_REC_LEN  600

extern int  USART1_RX_BUF[USART1_REC_LEN];
extern uint16_t USART1_RX_STA;
extern int USART1_NewData;

void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart);

#endif

uart.c:

#include "uart.h"
#include "oled.h"

int USART1_RX_BUF[USART1_REC_LEN];		//目标数据
uint16_t USART1_RX_STA=2;
int USART1_NewData;

extern int num;		//百位
extern int num2;    //十位
extern int num3;    //个位


void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)
{
    if(huart ==&huart1)
    { 
			
      USART1_RX_BUF[USART1_RX_STA&0X7FFF]=USART1_NewData; 					
      USART1_RX_STA++;  
			
						
      if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;

			//num = USART1_RX_BUF[USART1_RX_STA];
			
			HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1);
			
			num = USART1_RX_BUF[USART1_RX_STA-1];			
			num2 = USART1_RX_BUF[USART1_RX_STA-2];
			num3 = USART1_RX_BUF[USART1_RX_STA-3];			
    }		
}

上述UART代码,利用 UART 中断函数进行读取 USART1_NewData 的数值,因为我们最大传输的数字为3位数,所以我们分别读取缓存数组中最近的 3 个字节数据(树莓派4B发送过来的是字符串,也就是被转换成了对应数字的ASCII数值,例如:发送过来100,则STM32端接收到的为49 49 48 这3个字节)。

3.3.3 数据解码代码

control.c:

#include "control.h"
#include "uart.h"
#include "tim.h"
#include "oled.h"

int num;
int num2;
int num3;
int value;
int flag;
int last;


void TargetTracking()
{
	flag = USART1_RX_STA - last;
				
	last = USART1_RX_STA;
	
	value = (num3-48) * 100 + (num2-48) * 10 + (num-48) * 1;
	
	OLED_ShowStr(10,2,"Object Center",2);
	OLED_Showdecimal(45,4,value,3,1,16);
	
	if(flag == 2)
	{
		value = (num2-48) * 10 + (num-48) * 1;
		OLED_Showdecimal(40,4,value,3,1,16);
	}
	
}

这里默认都是 3 位数,所以之间按照 UART 数据传输高低位的数据将数据-48变为实际的数字,在×对应的比例即可得到实际值!flag 则是通过 USART1_RX_STA 变量的变化值判断一次传输过来几个字节的数据,可以判断是几位数!

读者朋友可以根据自己实际情况更改上述代码为己所用!

代码运行之后:

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

四、高级应用

智能小车的目标追踪

树莓派4B通常会出现在基于视觉技术进行规定目标的追踪,这个时候往往需要树莓派4B读取到目标框数据,然后发送给STM32下位机,之后STM32根据这些目标框信息来进行逻辑上的控制。

作者这里以上一篇博客的网络模型检测结果为例,代码如下:

import cv2
import numpy as np
import onnxruntime as ort
import serial
import time

ser = serial.Serial('/dev/ttyAMA0',115200)

def plot_one_box(x, img, color=None, label=None, line_thickness=None):
    """
    description: Plots one bounding box on image img,
                 this function comes from YoLov5 project.
    param: 
        x:      a box likes [x1,y1,x2,y2]
        img:    a opencv image object
        color:  color to draw rectangle, such as (0,255,0)
        label:  str
        line_thickness: int
    return:
        no return
    """
    tl = (
        line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1
    )  # line/font thickness
    color = color or [random.randint(0, 255) for _ in range(3)]
    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
        
    ser.write(str(int((int(x[2])-int(x[0]))/2+int(x[0]))).encode())
    print(int((int(x[2])-int(x[0]))/2+int(x[0])))
        
    cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    if label:
        tf = max(tl - 1, 1)  # font thickness
        t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
        c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
        cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled
        cv2.putText(
            img,
            label,
            (c1[0], c1[1] - 2),
            0,
            tl / 3,
            [225, 255, 255],
            thickness=tf,
            lineType=cv2.LINE_AA,
        )

def _make_grid( nx, ny):
        xv, yv = np.meshgrid(np.arange(ny), np.arange(nx))
        return np.stack((xv, yv), 2).reshape((-1, 2)).astype(np.float32)

def cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride):
    
    row_ind = 0
    grid = [np.zeros(1)] * nl
    for i in range(nl):
        h, w = int(model_w/ stride[i]), int(model_h / stride[i])
        length = int(na * h * w)
        if grid[i].shape[2:4] != (h, w):
            grid[i] = _make_grid(w, h)

        outs[row_ind:row_ind + length, 0:2] = (outs[row_ind:row_ind + length, 0:2] * 2. - 0.5 + np.tile(
            grid[i], (na, 1))) * int(stride[i])
        outs[row_ind:row_ind + length, 2:4] = (outs[row_ind:row_ind + length, 2:4] * 2) ** 2 * np.repeat(
            anchor_grid[i], h * w, axis=0)
        row_ind += length
    return outs



def post_process_opencv(outputs,model_h,model_w,img_h,img_w,thred_nms,thred_cond):
    conf = outputs[:,4].tolist()
    c_x = outputs[:,0]/model_w*img_w
    c_y = outputs[:,1]/model_h*img_h
    w  = outputs[:,2]/model_w*img_w
    h  = outputs[:,3]/model_h*img_h
    p_cls = outputs[:,5:]
    if len(p_cls.shape)==1:
        p_cls = np.expand_dims(p_cls,1)
    cls_id = np.argmax(p_cls,axis=1)

    p_x1 = np.expand_dims(c_x-w/2,-1)
    p_y1 = np.expand_dims(c_y-h/2,-1)
    p_x2 = np.expand_dims(c_x+w/2,-1)
    p_y2 = np.expand_dims(c_y+h/2,-1)
    areas = np.concatenate((p_x1,p_y1,p_x2,p_y2),axis=-1)
    
    areas = areas.tolist()
    ids = cv2.dnn.NMSBoxes(areas,conf,thred_cond,thred_nms)
    if len(ids)>0:
        return  np.array(areas)[ids],np.array(conf)[ids],cls_id[ids]
    else:
        return [],[],[]
def infer_img(img0,net,model_h,model_w,nl,na,stride,anchor_grid,thred_nms=0.4,thred_cond=0.5):
    # 图像预处理
    img = cv2.resize(img0, [model_w,model_h], interpolation=cv2.INTER_AREA)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = img.astype(np.float32) / 255.0
    blob = np.expand_dims(np.transpose(img, (2, 0, 1)), axis=0)

    # 模型推理
    outs = net.run(None, {net.get_inputs()[0].name: blob})[0].squeeze(axis=0)

    # 输出坐标矫正
    outs = cal_outputs(outs,nl,na,model_w,model_h,anchor_grid,stride)

    # 检测框计算
    img_h,img_w,_ = np.shape(img0)
    boxes,confs,ids = post_process_opencv(outs,model_h,model_w,img_h,img_w,thred_nms,thred_cond)

    return  boxes,confs,ids




if __name__ == "__main__":

    # 模型加载
    model_pb_path = "best.onnx"
    so = ort.SessionOptions()
    net = ort.InferenceSession(model_pb_path, so)
    
    # 标签字典
    dic_labels= {0:'drug',
            1:'glue',
            2:'prime'}
    
    # 模型参数
    model_h = 320
    model_w = 320
    nl = 3
    na = 3
    stride=[8.,16.,32.]
    anchors = [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90, 156, 198, 373, 326]]
    anchor_grid = np.asarray(anchors, dtype=np.float32).reshape(nl, -1, 2)
    
    video = 0
    cap = cv2.VideoCapture(video)
    flag_det = False
    while True:
        success, img0 = cap.read()
        if success:
            
            if flag_det:
                t1 = time.time()
                det_boxes,scores,ids = infer_img(img0,net,model_h,model_w,nl,na,stride,anchor_grid,thred_nms=0.4,thred_cond=0.5)
                t2 = time.time()
            
                
                for box,score,id in zip(det_boxes,scores,ids):
                    label = '%s:%.2f'%(dic_labels[id],score)
            
                    plot_one_box(box.astype(np.int16), img0, color=(255,0,0), label=label, line_thickness=None)
                    
                str_FPS = "FPS: %.2f"%(1./(t2-t1))
                
                cv2.putText(img0,str_FPS,(50,50),cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),3)
                
            
            cv2.imshow("video",img0)
        key=cv2.waitKey(1) & 0xFF    
        if key == ord('q'):
        
            break
        elif key & 0xFF == ord('s'):
            flag_det = not flag_det
            print(flag_det)
            
    cap.release() 
    
    

作者上述代码仅以目标物体中心的 x 轴坐标为例,控制机理是这样的:当 x 数值大于320(图片为640×640)时候控制小车向便宜右偏移,反之则向左偏移。目标框的w,h则可以根据实际情况设置阈值,控制小车的前进速度。当目标框的宽度 w 太小时候,加速小车前进,反之则减速!

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

基于树莓派4B与STM32的UART串口通信实验(代码开源),树莓派,STM32开发,树莓派4B,STM32,UART通讯

作者有话:

目前的 YOLOv-Lite 网络模型的 FPS 还是太低了,在该 FPS 下去进行目标追踪的控制是非常困难的。此外,实际情况下搭载在小车亦或是航行器的 Camera 在拍摄过程中避免不了强烈的高斯白噪,需要加卡尔曼滤波进行优化目标框信息!

所以,后续作者将推出可以基于视觉追踪实战的网络模型和目标追踪代码,感兴趣的读者朋友可以期待一下!

五、项目效果

基于树莓派4B与STM32通信追踪

六、项目代码

代码地址:基于树莓派4B与STM32的UART串口通信实验代码资源-CSDN文库

如果积分不够的朋友,点波关注评论区留下邮箱,作者无偿提供源码和后续问题解答。求求啦关注一波吧 !!!文章来源地址https://www.toymoban.com/news/detail-600231.html

到了这里,关于基于树莓派4B与STM32的UART串口通信实验(代码开源)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 树莓派与STM32之间串口通信

    目录 一、树莓派串口通信模块介绍 二、树莓派蓝牙、串口引脚映射对换步骤 1.启动串口 2. 禁用蓝牙(硬件串口与mini串口映射对换) 3.验证是否交换成功 三、树莓派安装mini串口调试助手 四、树莓派与电脑串口调试 五、树莓派与STM32串口调试 树莓派串口通信与蓝牙模块的基

    2024年02月16日
    浏览(78)
  • STM32CubeMx+MATLAB Simulink串口输出实验,UART/USART串口测试实验

    STM32CubeMx+MATLAB Simulink串口输出实验

    2024年02月21日
    浏览(45)
  • 树莓派与STM32(rt1064)串口通信

    目录 一、树莓派通信 1、硬件连线准备 2、安装Serial和打开树莓派串口 2.1安装Serial 2.2打开树莓派串口 2.3修改串口映射关系 3、树莓派代码 4、上位机 5、运行uart.py代码进行测试 5.1 树莓派发送,上位机接收 5.2上位机发送,树莓派接收  二、STM32通信 6、配置串口 7、测试STM32通

    2024年02月01日
    浏览(86)
  • STM32 UART串口通信IDLE空闲中断的使用步骤

    参考了各路大神的资料,蒙蔽了半天,终于学会了,记录一下,以后忘了可以回来复习参考。 一、首先在stm32cube中配置打开对应uart串口的中断 二、工程main函数调用 __HAL_UART_ENABLE_IT(huart1,UART_IT_IDLE);//hal库宏定义,使能串口空闲中断     HAL_UART_Receive_DMA(huart1,data,sizeof(data));//使

    2024年02月12日
    浏览(44)
  • FPGA与STM32之间的UART通信实验

    目录 1.UART串口介绍 2.实验任务 3.FPGA代码 4.STM32代码 5.总结         UART是一种采用异步串行方式的通用异步收发传输器,在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。         UART串口通信需要两根信号线来实现,

    2024年02月13日
    浏览(45)
  • 【STM32】HAL库UART含校验位的串口通信配置BUG避坑

    【STM32】HAL库UART含校验位的串口通信配置BUG避坑 UART通过一条线就能完成数据的发送 另外一条线则完成数据的接收 所以一共是两条线 TX RX UART在空闲时为低电平 时钟周期由波特率确定 通常是115200bit/s UART协议由四个部分组成: 起始位: 固定低电平 1个时钟周期 数据域: 通常

    2024年01月20日
    浏览(50)
  • stm32基于UART串口实现modbusRTU(软件方式)

     此程序中, 串口通信方式: 115200-n-8-1, modbus协议要求帧与帧之间的间隔必须大于3.5个字符时间间隙作为帧与帧之间的分割.  字符时间计算公式: interval_time = character_interval * 8 / baud_speed * 10 ^ 6 (微秒) 1.1 设置定时器, 超时时间为interval_time. 1.2 设置stm32的uart串口接收数据中断, 每

    2024年02月15日
    浏览(36)
  • STM32CubeMX-HAL库-UART串口接收中断回调函数代码分析

            CubeMx中HAL库函数的调用不同于库函数调用,在学习CubeMx串口通信时,不理解HAL库中的回调函数是怎么被调用的,于是查看每个的定义,参考其他人写的博客,总算弄明白了HAL库中断调用与库函数不同之处。写下这篇博客一是加深自己的理解,二是希望对不理解HA

    2024年02月02日
    浏览(56)
  • STM32学习笔记3 正点原子miniSTM32串口通信实验

    初学者学习总结,如有错误,请大神指正 目的:用 STM32 的串口来发送和接收数据。 ALIENTEK MiniSTM32 V3 版开发板选择的是 STM32F103RCT6 作为 MCU,拥有5 个串口分别为 USART1、USART2、USART3、UART4、UART5, 其中只有USART1挂载在APB2总线上,其余均挂载在APB1总线上 APB1操作速度限于36MHz,A

    2024年02月04日
    浏览(65)
  • UART串口通信实验

    不管是单片机开发还是嵌入式 Linux 开发,串口都是最常用到的外设。 可以通过串口将开发板与电脑相连,然后在电脑上通过串口调试助手来调试程序。 还有很多模块,比如蓝牙、GPS、GPRS等都使用串口与主控进行通信。 串口全称串行接口,通常也叫做COM接口,,串行接口指

    2024年02月08日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包