先上一个采用串口直接传输的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. C# Excel导入Access

    /// <summary> /// 导入 /// </summary> private void btn_In_Click(object sender, EventArgs e ...

  2. /\B(?=(?:\d{3})+$)/g 一条令人费解的正则表达式

    网上浏览博客看到要用JavaScript正则表达式解决一个功能, 要在数字中间插入逗号, 用来表示书面的金额写法. JS代码是这样子的 let test1 = '1234567890' let for ...

  3. .net core 利用Selenium和PhantomJS后台生成EChart图片

    1.引用 NuGet安装: Selenium.Support Selenium.WebDriver Selenium.WebDriver.PhantomJS.CrossPlatform  (分布Lin ...

  4. 什么是Android NDK

    1.NDK是一系列工具的集合. NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk.这些工具对开发者的帮助是巨大的. NDK集成了交叉编译 ...

  5. “多团队大规模”开发模式 - 基于SAP HANA平台的多团队产品研发

    应用SAP HANA “官方”开发模式的伙伴们在转到“多团队大规模”开发模式时会遇到各式各样的心理不适应的状况,各种纠结.比如GIT Repository和HANA Repository冲突什么的. ...

  6. Java 函数传入参数后,究竟发生了什么?java函数传参数原理解析

    JAVA函数在传入参数A时,会在函数作用周期内生成一个与参数相同类型的局部变量B. B与A指向同一块内存区域,并且具有相同的名字如param. 在函数内所有对param的操作都是对B的操作.对B进行赋 ...

  7. C语言实现常用数据结构——堆

    #include<stdio.h> #include<stdlib.h> #define CAPACITY 20 /*堆有两个性质: * 1.结构性:堆必须是一颗完全二叉树 * ...

  8. Nodejs操作MySQL - 增删改查

    先安装npm模块项目 npm init 安装mysql npm install mysql --save Nodejs 连接msyql // 导入mysql const mysql = require ...

  9. Eclipse远程代码调试

    前提:远程服务器上运行的WEB项目class对应的源码与本地项目中必须保持一致 也就是远程tomcat部署的项目就是本机项目打包过去的,而本机项目没有发生变动. 1.配置$tomcat_home/bi ...

  10. php+mysql新无线级分类

    create table cat( id int unsigned not null primary key auto_increment, pid , path ) not null default ...