先上一个采用串口直接传输的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. intel汇编笔记

    另一篇汇编学习笔记AT&T Assembly on Linux  (linux下) mov ax,bx     bx到ax 读数据过程:cpu通过地址线发送地址a,控制线向存储器发送读命令,存 ...

  2. 关于EF ORM 框架的使用问题

    1.无法更新 EntitySet“System_UserInfo20140218001”,因为它有一个 DefiningQuery,而 <ModificationFunctionMapping& ...

  3. 想让一个Widget成为模态,我们只需要对其设置setAttribute(Qt::WA_ShowModal, true);

    想让一个Widget成为模态,我们只需要对其设置: setAttribute(Qt::WA_ShowModal, true); 注意:这是QWidget的成员函数 ,也就是说,QWidget可以显示为 ...

  4. 中芯国际在CSTIC上悉数追赶国际先进水平的布局

    作为中国最大.工艺最先进的晶圆厂,中芯国际的一举一动都会受到大家的关注.在由SEMI主办的2017’中国国际半导体技术大会(CSTIC 2017)上,中芯国际CEO邱慈云博士给我们带来了最新的介绍. ...

  5. How To Compile Qt with Visual Studio

    How To Compile Qt with Visual Studio FEBRUARY 1, 2011 This post is a step-by-step guide on how to co ...

  6. 京东sdk商家上架接口调用问题总结

    前言: 最近在做商家发布产品,调用京东sdk,发现问题很多,而且还是在我同事的帮助下完成的,摸索中,菜鸟还请高手门多多提携才好,入正题 首先是引用jd的sdk啦,京东sdk中发布商品需要调用一个 36 ...

  7. 学习Java,值得你留意的问题(1)更名为《学习Java,容易被你忽略的小细节(1)》

    记得大二快要结束的时候,有个女孩子突然问我“你会Java吗,帮我做大作业好吗?” 实话说,那个女孩真的很漂亮,我当时也非常想帮她.但是我从来没有接触过Java,让我在短短的几天内完成Java程序设计课 ...

  8. 深入理解Java G1垃圾收集器

    本文首先简单介绍了垃圾收集的常见方式,然后再分析了G1收集器的收集原理,相比其他垃圾收集器的优势,最后给出了一些调优实践. 一,什么是垃圾回收 首先,在了解G1之前,我们需要清楚的知道,垃圾回收是什么 ...

  9. python网络编程——实现简单聊天

    通过socket建立简单的聊天工具 server.py import socket import threading import time s = socket.socket(socket.AF_I ...

  10. Spring 5.x 、Spring Boot 2.x 、Spring Cloud 与常用技术栈整合

    项目 GitHub 地址:https://github.com/heibaiying/spring-samples-for-all 版本说明: Spring: 5.1.3.RELEASE Spring ...