先上一个采用串口直接传输的Demo;

此处的思路是完全采用HAL库来实现的,核心是运用HAL_UART_Transmit_IT和HAL_UART_Receive_IT两个函数来实现的,可以作为一个Demo来测试使用;

直接上代码,其串口的配置和上一章完全一致,因此忽略不计:

思路大致是将aTxStartMessage字符串发送出去,接收一个总长度为15个字符的数据到aRxBuffer中,等待接收完毕;

将接收到的aRxBuffer发送出去,等待发送完成,最后将aTxEndMessage发送出去;

uint8_t aTxStartMessage[] = "\r\n ****UART-Hyperterminal communication based on IT ****\r\n Enter 9 characters using keyboard :\r\n";
uint8_t aTxEndMessage[] = "\r\n Example Finished\r\n"; /* Buffer used for reception */
uint8_t aRxBuffer[]; while ()
{
if(HAL_UART_Transmit_IT(&huart2, (uint8_t*)aTxStartMessage, sizeof(aTxStartMessage)) != HAL_OK)
{
while();
}
if(HAL_UART_Receive_IT(&huart2, (uint8_t*)aRxBuffer, ) != HAL_OK)
{
while();
}
while(HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY);
if(HAL_UART_Transmit_IT(&huart2, (uint8_t*)aRxBuffer, ) != HAL_OK)
{
while();
}
while(HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY);
if(HAL_UART_Transmit_IT(&huart2, (uint8_t*)aTxEndMessage, sizeof(aTxEndMessage)) != HAL_OK)
{
while();
}
while(HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY);
}

接下来是也是一个Demo,采用HAL库来实现串口收发中断,思路和C一个一个接收字符然后发送出去是相似的,只不过是采用串口IT中断来实现;

  串口的配置不变,因此在此忽略不计;

uint8_t aRxBuffer;

int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init(); HAL_UART_Receive_IT(&huart3, &aRxBuffer, ); while ()
{}
} void USART2_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart2);
} void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandler)
{
HAL_UART_Transmit(&huart3, &aRxBuffer, , );
HAL_UART_Receive_IT(&huart3, &aRxBuffer, );
}

简要分析以下这个程序的思路:

开头采用HAL_UART_Receive_IT()这个函数和目的不是为了接收数据,而是通过里面的配置开启中断,核心在SET_BIT()这两句话中(开启EIE、PEIE和RXNEIE这三个中断);

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Rx process is not already ongoing */
if(huart->RxState == HAL_UART_STATE_READY)
{
if((pData == NULL ) || (Size == 0U))
{
return HAL_ERROR;
}
/* In case of 9bits/No Parity transfer, pData buffer provided as input paramter
should be aligned on a u16 frontier, as data to be received from RDR will be
handled through a u16 cast. */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
if((((uint32_t)pData)&1U) != 0U)
{
return HAL_ERROR;
}
} /* Process Locked */
__HAL_LOCK(huart); huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->RxXferCount = Size; /* Computation of UART mask to apply to RDR register */
UART_MASK_COMPUTATION(huart); huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX; /* Process Unlocked */
__HAL_UNLOCK(huart); /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
/* Enable the UART Parity Error and Data Register not empty Interrupts */
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

接收数据的过程可以从中断中了解:

当接收到数据后判断ISR寄存器中RXNE中断标志是否置位和CR1寄存器中RXNE中断使能是否开启,然后进入到接收处理函数UART_Receive_IT()中;

在UART_Receive_IT()中,关闭EIE、PEIE和RXNE中断,同时调用回调函数HAL_UART_RxCpltCallback();

void USART2_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart2);
} void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{ /* If some errors occur */
cr3its = READ_REG(huart->Instance->CR3);
if( (errorflags != RESET)
&& ( ((cr3its & USART_CR3_EIE) != RESET)
|| ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)) )
{ /* Call UART Error Call back function if need be --------------------------*/
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* UART in mode Receiver ---------------------------------------------------*/
if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
UART_Receive_IT(huart);
}
}
return;
} /* End if some error occurs */
} HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
/* Check that a Rx process is ongoing */
if(huart->RxState == HAL_UART_STATE_BUSY_RX)
{
if(--huart->RxXferCount == 0U)
{
/* Disable the UART Parity Error Interrupt and RXNE interrupt*/
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); /* Rx process is completed, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY; HAL_UART_RxCpltCallback(huart); return HAL_OK;
}
}
}

在主函数中执行重写的回调函数:

将接收到的一个字符发送出去,同时开启接收中断准备接收下一个字符;

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandler)
{
HAL_UART_Transmit(&huart3, &aRxBuffer, , );
HAL_UART_Receive_IT(&huart3, &aRxBuffer, );
}

其实现的功能可以和以下C语言实现的相似:

int c;
while((c = getchar()) != EOF)
{
putchar(c);
}

STM32F072从零配置工程-基于HAL库的串口UART中断配置的更多相关文章

  1. 基于zynq 7020的串口UART中断实验

    1.参考 UG585,P1790[JokerのZYNQ7020]UART学会Zynq(27)UART中断驱动模式示例 2.理论知识 在ZYNQ的中断中有一个IOP的中断集,它包几个外设的中断,其中包含 ...

  2. 【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&CubeMX工程)

    说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...

  3. STM32基于HAL库通过DMA读写SDIO

    通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...

  4. (4)STM32使用HAL库实现串口通讯——理论讲解

    一.查询模式 1. 二.中断模式 1.中断接收. 1.1先看中断接收的流程(以 USART2 为例) 在启动文件中找到中断向量 USART2_IRQHandler 找到USART2_IRQHandle ...

  5. STM32F0_HAL库驱动描述——基于F1的USART串口IT中断实现解析

    从原子F103 HAL库基础串口例程来看HAL程序结构: 从main函数开始,首先是HAL库两个函数的初始化: HAL_Init(): Stm32_Clock_Init(RCC_PLL_MUL9); ...

  6. 基于HAL库的STM32的DSP库详解(附FFT应用)

    1 . 建立工程,生成代码时选择包含所有库.   2. 打开 option for target 选择 Target 标签,在code generatio中,将floating point hardw ...

  7. STM32串口接收中断——基于HAL库

    写在前面 最近需要使用一款STM32L4系列的芯片进行开发,需要学习使用HAL库.在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考. 1.UART相关的头文件引用错误 由于本人直接使用 ...

  8. STM32 ADC详细篇(基于HAL库)

    一.基础认识 ADC就是模数转换,即将模拟量转换为数字量 l  分辨率,读出的数据的长度,如8位就是最大值为255的意思,即范围[0,255],12位就是最大值为4096,即范围[0,4096] l  ...

  9. STM32 HAL库之串口详细篇

    一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...

随机推荐

  1. GIS基础软件及操作(八)

    原文 GIS基础软件及操作(八) 练习八.地理建模 地理建模:Model Builder 土壤侵蚀危险性建模分析 认识ModelBuilder操作界面 1: 添加硬盘上的数据或工具到模型中,数据也可以 ...

  2. mysql 更改root密码

    mysql 更改root密码,有很多种,网上也有很多记录,这里只是做个记录,以后可以看看,只记录两种自己常用的方法. 1.改表法,登录到数据库,切换到:mysql数据库,update user set ...

  3. Windows Mount NFS Share from e.g. Linux

    Note: Not Stable, so steps below are for reference only ************ Linux Configuration NFS Share 1 ...

  4. 第四章 .net core做一个简单的登录

    项目目标部署环境:CentOS 7+ 项目技术点:.netcore2.0 + Autofac +webAPI + NHibernate5.1 + mysql5.6 + nginx 开源地址:https ...

  5. Spring 注解编程之模式注解

    Spring 框架中有很多可用的注解,其中有一类注解称模式注解(Stereotype Annotations),包括 @Component, @Service,@Controller,@Reposit ...

  6. 分享Sql Server 2008 r2 数据备份,同步服务器数据(二.本地发布,订阅)

    上一篇文章中写到了数据库的本地备份,这一篇主要分享一下关于不同服务器的数据备份,主要是使用sql server中的本地发布,本地订阅功能,在数据库的读写分离中,也会经常性的用到这个功能. 复制-> ...

  7. 我与微软的不解之缘 - 我的Insider Dev Tour 2019讲师之旅

    标题:我与微软的不解之缘 - 我的Insider Dev Tour 2019讲师之旅 作者:Lamond Lu 大家好,我是陆楠,来自北京盛安德青岛分公司,今年非常有幸作为讲师参加了微软Insider ...

  8. Redis 密码设置和查看密码(二)

    Redis 密码设置和查看密码 redis没有实现访问控制这个功能,但是它提供了一个轻量级的认证方式,可以编辑redis.conf配置来启用认证. 1.初始化Redis密码: 在配置文件中有个参数: ...

  9. 你需要知道的c# Timer 的垃圾回收机制。

    通常我们需要定时执行一段任务的时候,我们就需要定时器,这时我们就可以使用c# System.Threading空间中的 Timer定时器;他是个异步定时器,时间到时每次都是在线程池中分配一个线程去执行 ...

  10. 数据结构与算法---查找算法(Search Algorithm)

    查找算法介绍 在java中,我们常用的查找有四种: 顺序(线性)查找 二分查找/折半查找 插值查找 斐波那契查找 1)线性查找算法 示例: 有一个数列: {1,8, 10, 89, 1000, 123 ...