博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32F072从零配置工程-基于HAL库的串口UART中断配置
阅读量:4983 次
发布时间:2019-06-12

本文共 5002 字,大约阅读时间需要 16 分钟。

先上一个采用串口直接传输的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[18];    while (1)  {    if(HAL_UART_Transmit_IT(&huart2, (uint8_t*)aTxStartMessage, sizeof(aTxStartMessage)) != HAL_OK)    {        while(1);    }    if(HAL_UART_Receive_IT(&huart2, (uint8_t*)aRxBuffer, 15) != HAL_OK)    {        while(1);    }    while(HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY);    if(HAL_UART_Transmit_IT(&huart2, (uint8_t*)aRxBuffer, 15) != HAL_OK)    {        while(1);    }    while(HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY);    if(HAL_UART_Transmit_IT(&huart2, (uint8_t*)aTxEndMessage, sizeof(aTxEndMessage)) != HAL_OK)    {        while(1);    }    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, 1);    while (1)  {}}void USART2_IRQHandler(void){  HAL_UART_IRQHandler(&huart2);}void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandler){    HAL_UART_Transmit(&huart3, &aRxBuffer, 1, 0);    HAL_UART_Receive_IT(&huart3, &aRxBuffer, 1);}

 

 

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

       开头采用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, 1, 0);    HAL_UART_Receive_IT(&huart3, &aRxBuffer, 1);}

 

 

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

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

 

转载于:https://www.cnblogs.com/lpfdezh/p/11213115.html

你可能感兴趣的文章
VUE-es6
查看>>
MySQL-5.7 高阶语法及流程控制
查看>>
C++学习笔记(十)——向上造型
查看>>
2017/6/16
查看>>
LeetCode 445——两数相加 II
查看>>
预备作业03 20162308马平川
查看>>
【Java】嵌套For循环性能优化案例
查看>>
面试了一个开发人员
查看>>
软件工程及软件项目开发流程
查看>>
关于android4.3 bluetooth4.0的那些事儿
查看>>
嵌入式成长轨迹14 【嵌入式环境及基础】【Linux下的C编程 上】【gcc、gdb和GNU Make】...
查看>>
C语言讲义——变量的输出
查看>>
shell脚本 ----每天学一点shell
查看>>
FZU2150 :Fire Game (双起点BFS)
查看>>
php_常用操作_读取文件_数据库操作
查看>>
Linux中GCC源码编译安装
查看>>
equals与==关于Object覆盖和重载问题
查看>>
KVO
查看>>
js基础教程四之无缝滚动
查看>>
关于C51 keil使用中.c文件的链接心得
查看>>