ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM32f103Hal库学习笔记

2021-09-08 20:29:50  阅读:187  来源: 互联网

标签:DMA HAL 函数 UART STM32f103Hal 笔记 学习 中断 串口


STM32f103Hal库学习笔记–USART

文章目录

前言

因为参加学校的航模队需要用到一些单片机,大一下的时候就自学了51,后来大二上的寒假总算是入门了stm32的标准库,大二下因为很多原因搁置了stm32,转战arduino,大二下的寒假开始了解hal库;今天上午想用标准库写一个串口中断收发,结果发现自己连新建工程都不记得怎么操作了(嫌弃自己),所以突发奇想想通过学习笔记来记录学习hal库的过程,第一次写文章,外加半路出家学习单片机,难免会有有一些错误,所以仅供参考。(再次嫌弃)


一、串口是什么?

大致就是一种用于单片机间通信的东西,网上太多介绍的了,反正我也是在网上学的,所以不懂就百度吧。

二、Hal库串口通信

1.中断模式

(1)CubeMx配置

时钟选择,默认选择内部高速时钟
时钟选择,默认选择内部高速时钟(偷懒不想配置时钟)
打开串口,配置串口以及打开中断
打开串口,配置串口以及打开中断
配置工程
配置工程
配置工程

(2)函数相互调用逻辑

串口收发数据(中断模式)主要运用到四个函数
首先是HAL_UART_Recive_IT(中断接收函数),在stm32f1xx_hal_uart.c中,官方描述为使用阻塞模式接收数据,然鹅这里用于中断模式,我自己把这个函数理解为使能中断。
函数本身
第二个函数是USART1_IRQHandler(中断服务函数),在stm32f1xx_it.c文件中,串口接收到数据,产生中断时立即调用。
中断服务函数
第三个是HAL_UART_IRQHandler(中断处理函数),串口产生中断后调用USART1_IRQHandler中断服务函数,中断服务函数调用中断处理函数,该函数用于判断产生中断的来源(收到数据还是发送数据),然后根据来源判断是调用UART_Recive_IT还是UART_Transmit_IT函数。
第四个是UART_Recive_IT(接收函数)(以收到数据产生中断为例),接收发来的数据并储存,然后调用HAL_UART_RxCpltCallBack(中断回调函数),中断回调函数用于用户自行编写产生中断后单片机的动作,记得再次开启接收函数中断,即再次调用HAL_UART_Recive_IT(中断接收函数)。

(3)需要自己添加的代码

//main.c
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define RXBUFFERSIZE  256     //最大接收字节数
char RxBuffer[RXBUFFERSIZE];   //接收数据
uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0;		//接收缓冲计数
/* USER CODE END PD */

/* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
/* USER CODE END 2 */

//stm32f1xx_it.c
/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	HAL_UART_Transmit(&huart1, (uint8_t *)&aRxBuffer, 1, 10000);//将接收到的数据发送
	HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_15);
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
}
/* USER CODE END 1 */

(4)总结

串口中断模式收发函数总的来说程序逻辑顺序就是:
HAL_UART_Recive_IT (中断接收函数)//开启中断
USART1_IRQHandler(中断服务函数)//产生中断即调用
HAL_UART_IRQHandler(中断处理函数)//服务函数调用,判断中断源
UART_Recive_IT(接收函数)//根据不同中断源调用不同回调函数
HAL_UART_RxCpltCallBack(中断回调函数)//用户赋予中断执行动作
函数间跳来跳去的确实有点绕,但是绕着绕着还是能大概绕明白的

2.DMA模式

有一说一DMA还没怎么学懂,不过应该现在做的项目还比较基础,后面需要用到了再加深了解也不晚,毕竟还是为了学而学更有动力。

(1)CubeMx配置

老规矩,跟前面的配置差不多,不太重要不细说。
中断配置
中断配置,默认开启DMA中断了,但不太清楚开不开启串口中断
DMA配置
DMA配置

(2)函数相互调用逻辑

MX-DMA-INIT
首先是程序最先调用main函数里面MX-DMA-Init函数,进去看看函数原型MX-DMA-Init函数原型
很简单就是配置中断优先级,开启中断
HAL-DMA-Ini
紧接着再HAL-UART-MspInit里面看到了HAL-DMA-Init和__HAL-LINKDMA,再进去看看两个函数原型
HAL-DMA-Init
HAL-DMA-Init函数原型,官方描述是初始化函数,看原型也确实是配置DMA所需的寄存器
__HAL-LINKDMA
顾名思义就是把串口的tx或者rx连接到DMA上
这里完了之后,DMA的配置就大致结束了,然后再通过HAL-UART-Transmit-DMA来通过DMA方式传输数据(也可以是Recive),下面是函数原型

HAL-UART-Transmit-DMA
官方给的描述是通过DMA的方式发送数据,里面比较重要的函数是HAL-DMA-START-IT,再进去看看HAL-DMA-START-IT
官方给的描述是开启中断,不过还可以看到可以将DMA传输源和传输目标的地址作为形参传入,再看回来,HAL-Transmit-DMA调用HAL-START-DMA-IT,传输源为HAL-Transmit-DMA的形参(uint8_t *pData),目标地址为tx的DR(数据)寄存器。

(3)还没有搞懂的地方

然后函数HAL-Transmit-DMA就被执行完了,然后好像数据就被发送了?我也不是很清楚。(笑死了,自己都没搞清楚就写这篇文章,不过作为一篇自己的笔记,不管搞没搞懂都把它记下来,后面也好再继续学习,也防止自己搞忘)
不过好像还有一个地方没有搞懂,就是DMA说是可以不占用CPU资源的情况下进行数据传输,但是我看好像无论是DMA传输还是中断传输,都是把数据放入tx的DR寄存器,然后再发送出去,难道是DMA传输只需要DMA控制器跟外设都产生了应答就可以传输数据,而不需要跟CPU发出指令吗?那也就是说数据只要放进了DR寄存器就相当于发出去了(或者接受到了)?

标签:DMA,HAL,函数,UART,STM32f103Hal,笔记,学习,中断,串口
来源: https://blog.csdn.net/weixin_45872915/article/details/120140100

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有