STM32F072从零配置工程-基于HAL库的串口UART中断配置
先上一个采用串口直接传输的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中断配置的更多相关文章
- 基于zynq 7020的串口UART中断实验
1.参考 UG585,P1790[JokerのZYNQ7020]UART学会Zynq(27)UART中断驱动模式示例 2.理论知识 在ZYNQ的中断中有一个IOP的中断集,它包几个外设的中断,其中包含 ...
- 【GMT43智能液晶模块】基于HAL库的SDRAM和LCD驱动例程(MDK工程&CubeMX工程)
说明: 1.该工程基于HAL库实现动态存储器SDRAM驱动以及液晶控制器LCD驱动. 2.工程通过STM32CubeMX(Version 4.22.0)配置生成,可直接打开进行配置. 3.KEIL M ...
- STM32基于HAL库通过DMA读写SDIO
通过STM32CUBEMX生成DMA读写sdio的工程,再读写过程中总会卡死在DMA中断等待读写完成的while中,最终发现while等待的标志在SDIO的中断里置位的,而SDIO中断优先级如果小于或 ...
- (4)STM32使用HAL库实现串口通讯——理论讲解
一.查询模式 1. 二.中断模式 1.中断接收. 1.1先看中断接收的流程(以 USART2 为例) 在启动文件中找到中断向量 USART2_IRQHandler 找到USART2_IRQHandle ...
- STM32F0_HAL库驱动描述——基于F1的USART串口IT中断实现解析
从原子F103 HAL库基础串口例程来看HAL程序结构: 从main函数开始,首先是HAL库两个函数的初始化: HAL_Init(): Stm32_Clock_Init(RCC_PLL_MUL9); ...
- 基于HAL库的STM32的DSP库详解(附FFT应用)
1 . 建立工程,生成代码时选择包含所有库. 2. 打开 option for target 选择 Target 标签,在code generatio中,将floating point hardw ...
- STM32串口接收中断——基于HAL库
写在前面 最近需要使用一款STM32L4系列的芯片进行开发,需要学习使用HAL库.在进行串口中断使用的时候遇到了一些小麻烦,写下解决方案供大家参考. 1.UART相关的头文件引用错误 由于本人直接使用 ...
- STM32 ADC详细篇(基于HAL库)
一.基础认识 ADC就是模数转换,即将模拟量转换为数字量 l 分辨率,读出的数据的长度,如8位就是最大值为255的意思,即范围[0,255],12位就是最大值为4096,即范围[0,4096] l ...
- STM32 HAL库之串口详细篇
一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...
随机推荐
- 微信小程序把玩(二十五)loading组件
原文:微信小程序把玩(二十五)loading组件 loading通常使用在请求网络数据时的一种方式,通过hidden属性设置显示与否 主要属性: wxml <!----> <butt ...
- Android零基础入门第88节:Fragment显示和隐藏、绑定和解绑
在上一期我们学习了FragmentManager和FragmentTransaction的作用,并用案例学习了Fragment的添加.移除和替换,本期一起来学习Fragment显示和隐藏.绑定和解绑. ...
- 为DataGridTemplateColumn设置快捷菜单
<DataGrid.ContextMenu> <ContextMenu> <MenuItem Command="{x:Static ApplicationCom ...
- 论文阅读计划2(Deep Joint Rain Detection and Removal from a Single Image)
Deep Joint Rain Detection and Removal from a Single Image[1] 简介:多任务全卷积从单张图片中去除雨迹.本文在现有的模型上,开发了一种多任务深 ...
- C++数组指针、指针数组、函数指针的核心概念
1.什么叫数组指针? 数组指针:一个指向一维或者多维数组的指针. 比如:int * b=new int[10];指向一维数组的指针b ; 注意,这个时候释放空间一定要delete [] ,否则会造成内 ...
- IntelliJ IDEA Maven工程保证JDK版本不变
创建maven项目后修改pom文件idea会默认将jdk版本调回到1.5,这是因为没有在pom里面设置项目的jdk版本 解决方法: 在pom文件中设定jdk版本即可,以下这种写法会自动更新idea中的 ...
- nginx 配置https并自签名证书
2016-10-28 转载请注明出处:http://daodaoliang.com/ 作者: daodaoliang 版本: V1.0.1 邮箱: daodaoliang@yeah.net 参考链接: ...
- 用Go语言异常机制模拟TryCatch异常捕捉1
有的同学看到Go和TryCatch一起出现,心里可能会说,难道Go语言升级了,加入了try...catch语句.哈哈,其实Go语言从创建之初就没打算加入try...catch语句,因为创建Go的那帮大 ...
- linux程序机制入门
GCC环境 类debian系统运行 apt-get install build-essential 安装gcc环境. 编写c语言程序后,运行 gcc ./hello.c 会得到一个名为 a.out 的 ...
- 你真的懂printf么?
自从你进入程序员的世界,就开始照着书本编写着各种helloworld,大笔一挥: printf("Hello World!\n"); 于是控制台神奇地出现了一行字符串,计算机一句温 ...