串口通信 HAL库+cubeMX

news2024/11/24 9:03:34

一.通信的基本概念

1.串行通信和并行通信

2.全双工、半双工和单工 

3.针对串行通信的同步通信和异步通信 

 4.通信速率

二.UART配置

UART常用HAL库函数 

//UART_HandleTypeDef *huart是句柄

typedef struct
{
     //初始化看前面两个就可以了
     USART_TypeDef *Instance; /* UART 寄存器基地址 */
     UART_InitTypeDef Init; /* UART 通信参数 */

     uint8_t *pTxBuffPtr; /* 指向 UART 发送缓冲区 */
     uint16_t TxXferSize; /* UART 发送数据的大小 */
     __IO uint16_t TxXferCount; /* UART 发送数据的个数 */
     uint8_t *pRxBuffPtr; /* 指向 UART 接收缓冲区 */
     uint16_t RxXferSize; /* UART 接收数据大小 */
     __IO uint16_t RxXferCount; /* UART 接收数据的个数 */
     DMA_HandleTypeDef *hdmatx; /* UART 发送参数设置(DMA) */
     DMA_HandleTypeDef *hdmarx; /* UART 接收参数设置(DMA) */
     HAL_LockTypeDef Lock; /* 锁定对象 */
     __IO HAL_UART_StateTypeDef gState; /* UART 发送状态结构体 */
     __IO HAL_UART_StateTypeDef RxState; /* UART 接收状态结构体 */
     __IO uint32_t ErrorCode; /* UART 操作错误信息 */
}UART_HandleTypeDef;


typedef struct
{
     uint32_t BaudRate; /* 波特率 */
     uint32_t WordLength; /* 字长 */
     uint32_t StopBits; /* 停止位 */
     uint32_t Parity; /* 校验位 */
     uint32_t Mode; /* UART 模式 */
     uint32_t HwFlowCtl; /* 硬件流设置 */
     uint32_t OverSampling; /* 过采样设置 */
}UART_InitTypeDef;


typedef enum
{
  HAL_OK       = 0x00U,//初始化完成
  HAL_ERROR    = 0x01U,//初始化错误
  HAL_BUSY     = 0x02U,//忙
  HAL_TIMEOUT  = 0x03U //超时
} HAL_StatusTypeDef;

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);//用于开启以中断(干完了跟我说,中途可以干其他事情)的方式接收指定字节。数据接收在中断处理函数里面实现。

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);//用阻塞(干不完不准出来)的方式发送指定字节数据

void HAL_UART_MspInit(UART_HandleTypeDef *huart)  /* 串口MSP回调函数 */

HAL库对USART的初始化流程 

uint8_t g_rx_buffer[1];          /* HAL库使用的串口接收数据缓冲区 */
uint8_t g_usart1_rx_flag = 0;    /* 串口接收到数据标志 */

UART_HandleTypeDef g_uart1_handle;  /* UART句柄 */

/* 串口1初始化函数 */
void usart_init(uint32_t baudrate)
{
    g_uart1_handle.Instance = USART1;
    g_uart1_handle.Init.BaudRate = baudrate;
    g_uart1_handle.Init.WordLength = UART_WORDLENGTH_8B;
    g_uart1_handle.Init.StopBits = UART_STOPBITS_1;
    g_uart1_handle.Init.Parity = UART_PARITY_NONE;
    g_uart1_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    g_uart1_handle.Init.Mode = UART_MODE_TX_RX;
    HAL_UART_Init(&g_uart1_handle);
    
    HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);
}

/* 串口MSP回调函数 HAL_UART_MspInit 函数来完成对串口底层的初始化,包括:串口
及 GPIO 时钟使能、GPIO 模式设置、中断设置等。 */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    GPIO_InitTypeDef gpio_init_struct;
    if(huart->Instance == USART1)                /* 如果是串口1,进行串口1 MSP初始化 */
    {
        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();

        gpio_init_struct.Pin = GPIO_PIN_9;
        gpio_init_struct.Mode = GPIO_MODE_AF_PP;            /* 推挽式复用输出 */
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;      /* 高速 */
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);            /* 初始化串口1的TX引脚 */
        
        gpio_init_struct.Pin = GPIO_PIN_10;
        gpio_init_struct.Mode = GPIO_MODE_AF_INPUT;         /* 输入 */
        gpio_init_struct.Pull = GPIO_PULLUP;                /* 上拉 */
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);            /* 初始化串口1的RX引脚 */
        
        HAL_NVIC_SetPriority(USART1_IRQn, 3, 3);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
    }
}

/* 串口1中断服务函数 */
void USART1_IRQHandler(void)
{
    HAL_UART_IRQHandler(&g_uart1_handle);//这个函数会清除中断
    HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1);//重新使能
}

/* 串口数据接收完成回调函数 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART1)
    {
        g_usart1_rx_flag = 1;
    }
}
int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    usart_init(115200);                         /* 波特率设为115200 */
    
    printf("请输入一个英文字符:\r\n\r\n");
    while(1)
    {
        if(g_usart1_rx_flag == 1)//判断串口接收到数据标志
        {
            printf("您输入的字符为:\r\n");
            HAL_UART_Transmit(&g_uart1_handle, (uint8_t*)g_rx_buffer, 1, 1000);
            while(__HAL_UART_GET_FLAG(&g_uart1_handle, UART_FLAG_TC) != 1);
            printf("\r\n");
            g_usart1_rx_flag = 0;
        }
        else
        {
            delay_ms(10);
        }
    }
}

三.cubeMX配置USART

Asynchronous   异步                                                                                                              Synchronous 同步                                                                                                                     single wire 单线                                                                                                                            IrDA 红外数据传输

参数配置

使能和配置中断 

HAL_UART_Transmit();串口发送数据,使用超时管理机制 
HAL_UART_Receive();串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();串口中断模式发送  
HAL_UART_Receive_IT();串口中断模式接收
HAL_UART_Transmit_DMA();串口DMA模式发送
HAL_UART_Transmit_DMA();串口DMA模式接收

发送数据是主观上的,所以用HAL_UART_Transmit();,接收数据是被动的,一般利用中断完成接收。

//stm32f1xx_it.c里面有中断服务函数的代码(可以配置各部分的中断服务函数)
uint8_t StaMessages[] = "Please enter 10 characters:\r\n";
uint8_t RxBuffer[20];
 
int main(void)
{
  /*其余代码省略*/
    MX_GPIO_Init();
    MX_USART1_UART_Init();
 
    HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)StaMessages,sizeof(StaMessages));
    //发送完成产生中断,执行中断回调
    HAL_UART_Receive_IT(&huart1,(uint8_t*)RxBuffer,10);
    while(1){}
}
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
    HAL_UART_Transmit(&huart1,(uint8_t*)RxBuffer,10,0xFFFF);
    HAL_UART_Receive_IT(&huart1,(uint8_t*)RxBuffer,10);//重新使能
}

四.制定协议

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1258740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件提示vcruntime140_1.dll文件丢失解决方法,和vcruntime140_1.dll丢失原因分析

vcruntime140_1.dll是Visual C Redistributable Packages的一部分,它是Microsoft Visual C 2015 Update 3运行时库文件。它包含了许多C标准库函数的实现,这些函数在运行使用C编写的程序时会被调用。所以我们在打开运行软件时候如果计算机中的vcruntime14…

(十三)Flask之特殊装饰器详解

目录: Flask中用作装饰器的特殊的函数第一部分:before_request和after_request一、 before_request装饰器:二、after_request装饰器:三、多个before_request和after_request执行流程分析: 首先—理论讲解:然…

Java核心知识点整理大全18-笔记

Java核心知识点整理大全-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全2-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全3-笔记_希斯奎的博客-CSDN博客 Java核心知识点整理大全4-笔记-CSDN博客 Java核心知识点整理大全5-笔记-CSDN博客 Java核心知识点整理大全6…

沈阳陪诊系统|陪诊软件开发功能

陪诊小程序的出现它可以帮助患者或家属解决就医过程中的各种问题。根据数据显示,2021年中国陪诊市场规模约为36.7亿元,预计到2025年将达到100亿元。同时,在医疗行业数字化转型的大背景下,陪诊微信小程序作为一种创新的医疗服务模式…

ABAP: JSON 报文解析——/ui2/cl_json

1、JSON数组 报文格式如下,是JSON 数组类型的。 [{"I_TYPE":"V","I_BUSINESSSCOPE":"1001"},{"I_TYPE":"V","I_BUSINESSSCOPE":"1002"} ] json转换为SAP内表: TYP…

二 使用GPIO的复用功能 利用USART 实现printf()

参考这篇: STM32串口通信详解 1. 关于USART USART ( universal synchronous / asynchronous receiver /transmitter) 是一种串行通讯协议 , 允许设备通过串行端口进行数据传输, USART 能够以同步或者异步的方式进行工作,在实际的运用中&…

机器学习的复习笔记4-岭回归与多项式回归

一、岭回归 在简单的线性回归中,一味追求平方误差最小化,R2值尽可能大,可能会受到噪声的严重干扰。噪声,即偶发的错误的值。 如图,若为满足所有点的拟合(虚线),表面上看R2值小&…

虚拟偶像的商业化

虚拟偶像的商业化主要通过以下几种方式实现: 直播与内容:虚拟主播在各大平台进行直播,提供音乐、游戏、教育等内容。收益主要包括Super Chat(直播打赏)、收费会员(支付月费后成为该频道会员,可…

如何使用WMS仓储管理系统实现流程优化

随着企业对于物流管理的需求日益增长,自动化WMS仓储管理系统已经成为了现代企业的核心工具之一。通过引入信息化技术,我们可以实现仓库管理流程的不断调整和优化,从而更好地满足客户的多样化需求。 一、信息化技术的引领 在现代仓库管理中&a…

Docker和Kubernetes:区别与优势对比

在现代软件开发和部署中,Docker和Kubernetes是两个备受关注的技术。本文将对Docker和Kubernetes进行比较,探讨它们的区别和各自的优势。 引言 在过去的几年中,容器技术得到了迅速的发展,并且在现代软件交付和部署中扮演着越来越重…

如何获取抖音订单列表

怎么获取订单列表接口 请求地址:响应参数以及示例

为什么我用 AI 做不出好看的图?好说给你划重点

最近一个月,我们介绍了些实用的 AI 绘画教程,不知道看过的你是学会了吗?有不少朋友和小编说,有了这些教程,用好说 AI 的指令做起图来比 SD 方便了不少。 不过也有朋友就和小编抱怨:“你教程里的和我做出来…

Flask 实现Token认证机制

在Flask框架中,实现Token认证机制并不是一件复杂的事情。除了使用官方提供的flask_httpauth模块或者第三方模块flask-jwt,我们还可以考虑自己实现一个简易版的Token认证工具。自定义Token认证机制的本质是生成一个令牌(Token)&…

dubbo框架技术文档-《spring-boot整合dubbo框架搭建+配置文件》框架的本地基础搭建

阿丹: 目前流行的微服务更多的就是dubbo和springcould微服务。之前阿丹没有出过dubbo相关的文章,因为之前接触springcould的微服务概念比较多一点,但是相对于springcould来说,springcould服务之间的调用是大多是使用了nacos&#…

Cascader 级联选择器动态加载数据的回显

如果后端没有只返回第三级的id,而是同时把第三级的名字一起返回了,那么就可以通过下面的方法来实现 1.在级联选择器里面加上这句代码 placeholder"请选择" 2.注册一个字符串 pleasett:"" 3.赋值 如过后端返回的有第三级的选项名 直接进行赋…

记录一个mqtt错误

在vue-admin-template 中引入mqtt 安装不报错,引入试过 import mqtt from mqtt import * as mqtt from mqtt/dist/mqtt.min; import {connect} from mqtt 一直报错: 就表示不理解,网上也没查到相应的资料,请告诉我我不是第一个遇…

pytest系列——pytest_runtest_makereport钩子函数获取测试用例执行结果

前言 pytest测试框架提供的很多钩子函数方便我们对测试框架进行二次开发,可以根据自己的需求进行改造。 例如:钩子方法:pytest_runtest_makereport ,可以更清晰的了解测试用例的执行过程,并获取到每个测试用例的执行…

Python基础:字符串(String)详解

1. 字符串定义 在Python中,字符串是一种数据类型,用于表示文本数据。字符串是由字符组成的序列,可以包含字母、数字、符号和空格等字符。在Python中,你可以使用单引号()或双引号("&#xf…

【Python】巧用tkinter设计秒表计时器

秒表计时器是一种用于计算时间间隔的计时器。它通常由一个开始按钮、一个停止按钮和一个重置按钮组成。 使用方法: 单击“开始”按钮开始计时。单击“停止”按钮停止计时。单击“重置”按钮将计时器归零。 注意事项: 没有对计时器误差进行校准&#…

【密码学】【多方安全计算】不经意传输(Oblivious Transfer,OT)

文章目录 不经意传输(oblivious transfer)定义不经意传输的实例(1 out 2,二选一不经意传输)基于RSA的1 out 2 不经意传输疑问 不经意传输(oblivious transfer)定义 不经意传输(obli…