当前位置: 首页 > news >正文

dedecms建网站wordpress物流模板

dedecms建网站,wordpress物流模板,网址大全2345 下载这?,信息化网站建设引言文章目录 一、使用中断的步骤二、相关函数分析1、HAL_UART_IRQHandler2、UART_Receive_IT3、HAL_UART_Receive_IT4、UART_Start_Receive_IT5、总结 三、HAL库使用心得 一、使用中断的步骤 1、配置GPIO 2、配置USART1 3、设置UART1中断优先级(不开启手动中断&#x…

文章目录

  • 一、使用中断的步骤
  • 二、相关函数分析
    • 1、HAL_UART_IRQHandler
    • 2、UART_Receive_IT
    • 3、HAL_UART_Receive_IT
    • 4、UART_Start_Receive_IT
    • 5、总结
  • 三、HAL库使用心得

一、使用中断的步骤

1、配置GPIO
2、配置USART1
3、设置UART1中断优先级(不开启手动中断,中断由HAL库给好的函数开启)
4、设置USART1中断服务函数(调用HAL给好的中断服务函数)
5、设置回调函数(HAL定义了一个弱函数,需要用户自己重定义)
6、开启USART1接收中断

二、相关函数分析

1、HAL_UART_IRQHandler

在中断服务函数USART1_IRQHandler中调用,进行USART中断的处理。

void USART1_IRQHandler(void)
{HAL_UART_IRQHandler(&huart1);
}

查看函数源码

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{uint32_t isrflags   = READ_REG(huart->Instance->SR); //#define READ_REG(REG)         ((REG))uint32_t cr1its     = READ_REG(huart->Instance->CR1);uint32_t cr3its     = READ_REG(huart->Instance->CR3);uint32_t errorflags = 0x00U;uint32_t dmarequest = 0x00U;/* If no error occurs */errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));//USART_SR_PE 32位,PE位为1,其余为0,是一个掩码  #define USART_SR_PE   USART_SR_PE_Msk  //  isrflags 时SR的值,与这几位的掩码与,若这些位无置位则结果位0.表示错误位都没有置为,无错误发生if (errorflags == RESET)// == 0 无错误{/* UART in mode Receiver -------------------------------------------------*/if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){//接收数据寄存器非空 且 接收中断使能UART_Receive_IT(huart);//中断接收函数return;}}
//错误发生时/* If some errors occur */if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET)|| ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))){/* UART parity error interrupt occurred ----------------------------------*/if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)){huart->ErrorCode |= HAL_UART_ERROR_PE;}/* UART noise error interrupt occurred -----------------------------------*/if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)){huart->ErrorCode |= HAL_UART_ERROR_NE;}/* UART frame error interrupt occurred -----------------------------------*/if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)){huart->ErrorCode |= HAL_UART_ERROR_FE;}/* UART Over-Run interrupt occurred --------------------------------------*/if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET)|| ((cr3its & USART_CR3_EIE) != RESET))){huart->ErrorCode |= HAL_UART_ERROR_ORE;}/* Call UART Error Call back function if need be --------------------------*/if (huart->ErrorCode != HAL_UART_ERROR_NONE){/* UART in mode Receiver -----------------------------------------------*/if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){UART_Receive_IT(huart);}/* If Overrun error occurs, or if any error occurs in DMA mode reception,consider error as blocking */dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest){/* Blocking error : transfer is abortedSet the UART state ready to be able to start again the process,Disable Rx Interrupts, and disable Rx DMA request, if ongoing */UART_EndRxTransfer(huart);/* Disable the UART DMA Rx request if enabled */if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)){ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);/* Abort the UART DMA Rx channel */if (huart->hdmarx != NULL){/* Set the UART DMA Abort callback :will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK){/* Call Directly XferAbortCallback function in case of error */huart->hdmarx->XferAbortCallback(huart->hdmarx);}}else{/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered error callback*/huart->ErrorCallback(huart);
#else/*Call legacy weak error callback*/HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}}else{/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered error callback*/huart->ErrorCallback(huart);
#else/*Call legacy weak error callback*/HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}}else{/* Non Blocking error : transfer could go on.Error is notified to user through user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered error callback*/huart->ErrorCallback(huart);
#else/*Call legacy weak error callback*/HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */huart->ErrorCode = HAL_UART_ERROR_NONE;}}return;} /* End if some error occurs *//* Check current reception Mode :If Reception till IDLE event has been selected : */if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)&& ((isrflags & USART_SR_IDLE) != 0U)&& ((cr1its & USART_SR_IDLE) != 0U)){__HAL_UART_CLEAR_IDLEFLAG(huart);/* Check if DMA mode is enabled in UART */if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)){/* DMA mode enabled *//* Check received length : If all expected data are received, do nothing,(DMA cplt callback will be called).Otherwise, if at least one data has already been received, IDLE event is to be notified to user */uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);if ((nb_remaining_rx_data > 0U)&& (nb_remaining_rx_data < huart->RxXferSize)){/* Reception is not complete */huart->RxXferCount = nb_remaining_rx_data;/* In Normal mode, end DMA xfer and HAL UART Rx process*/if (huart->hdmarx->Init.Mode != DMA_CIRCULAR){/* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);/* Disable the DMA transfer for the receiver request by resetting the DMAR bitin the UART CR3 register */ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);/* At end of Rx process, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);/* Last bytes received, so no need as the abort is immediate */(void)HAL_DMA_Abort(huart->hdmarx);}/* Initialize type of RxEvent that correspond to RxEvent callback execution;In this case, Rx Event type is Idle Event */huart->RxEventType = HAL_UART_RXEVENT_IDLE;#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx Event callback*/huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#else/*Call legacy weak Rx Event callback*/HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}return;}else{/* DMA mode not enabled *//* Check received length : If all expected data are received, do nothing.Otherwise, if at least one data has already been received, IDLE event is to be notified to user */uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;if ((huart->RxXferCount > 0U)&& (nb_rx_data > 0U)){/* Disable the UART Parity Error Interrupt and RXNE interrupts */ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);/* Rx process is completed, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);/* Initialize type of RxEvent that correspond to RxEvent callback execution;In this case, Rx Event type is Idle Event */huart->RxEventType = HAL_UART_RXEVENT_IDLE;#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx complete callback*/huart->RxEventCallback(huart, nb_rx_data);
#else/*Call legacy weak Rx Event callback*/HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}return;}}/* UART in mode Transmitter ------------------------------------------------*/if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)){UART_Transmit_IT(huart);return;}/* UART in mode Transmitter end --------------------------------------------*/if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)){UART_EndTransmit_IT(huart);return;}
}

2、UART_Receive_IT

中断接收函数,被HAL_UART_IRQHandler 调用

static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{uint8_t  *pdata8bits;uint16_t *pdata16bits;/* Check that a Rx process is ongoing */if (huart->RxState == HAL_UART_STATE_BUSY_RX)//判断接收过程是否任然在进行{if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)){//设置为9位数据而且无校验时的处理pdata8bits  = NULL;pdata16bits = (uint16_t *) huart->pRxBuffPtr;*pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);huart->pRxBuffPtr += 2U;}else{pdata8bits = (uint8_t *) huart->pRxBuffPtr;//pdata16bits  = NULL;if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE))){//设置为8位数据时无校验或9位数据位时的处理*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);//从数据寄存器接收8位数据}else{*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);//从数据寄存器接收7位数据}huart->pRxBuffPtr += 1U;//buff指针加一}if (--huart->RxXferCount == 0U)//此时已经接收了最后一位数据 huart->RxXferCount = 1;{//关闭所有中断,设置usart1 的句柄的各个标志位/* Disable the UART Data Register not empty Interrupt */__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);/* Disable the UART Parity Error Interrupt */__HAL_UART_DISABLE_IT(huart, UART_IT_PE);/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);/* Rx process is completed, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;/* Initialize type of RxEvent to Transfer Complete */huart->RxEventType = HAL_UART_RXEVENT_TC;/* Check current reception Mode :If Reception till IDLE event has been selected : */if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE){//开启了空闲中断,关闭空闲中断/* Set reception type to Standard */huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;/* Disable IDLE interrupt */ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);/* Check if IDLE flag is set */if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)){/* Clear IDLE flag in ISR */__HAL_UART_CLEAR_IDLEFLAG(huart);}
//接收完成,且开启了空闲中断时调用此函数
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx Event callback*/huart->RxEventCallback(huart, huart->RxXferSize);
#else/*Call legacy weak Rx Event callback*/HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}else{/* Standard reception API called *///接收完成,没有开启空闲中断时选择处理的回调函数
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx complete callback*/huart->RxCpltCallback(huart);
#else/*Call legacy weak Rx complete callback*/HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}return HAL_OK;}return HAL_OK;}else{return HAL_BUSY;}
}

3、HAL_UART_Receive_IT

判断USART句柄的接收状态,调用UART_Start_Receive_IT 开启中断。

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)//判断usart状态{if ((pData == NULL) || (Size == 0U))//判断参数是否有效{return HAL_ERROR;}/* Set Reception type to Standard reception */huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;//设置接收状态return (UART_Start_Receive_IT(huart, pData, Size));//调用接收中断开启函数}else{return HAL_BUSY;}
}

4、UART_Start_Receive_IT

HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{huart->pRxBuffPtr = pData;//缓冲区指针初始化huart->RxXferSize = Size;//缓冲区大小初始化huart->RxXferCount = Size;//接收数据总大小初始化  会在接收时减小huart->ErrorCode = HAL_UART_ERROR_NONE;//错误码设置huart->RxState = HAL_UART_STATE_BUSY_RX;//接收状态设置if (huart->Init.Parity != UART_PARITY_NONE){/* Enable the UART Parity Error Interrupt */__HAL_UART_ENABLE_IT(huart, UART_IT_PE);}//开启错误中断和接收中断/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);/* Enable the UART Data Register not empty Interrupt */__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);return HAL_OK;
}

5、总结

在使用标准库时需要我们先初始化GPIO再初始化USART,然后设置中断优先级并开启中断。在HAL库中,只需要我们初始化GPIO和USART并设置中断优先级,中断的开启和数据的接收都在HAL中封装好了函数,并使用回调函数的方式在接收完成后对数据进行处理。需要注意的是,USART的中断在HAL_UART_Receive_IT中调用UART_Start_Receive_IT开启相关中断,在ISR函数中只需调用HAL_UART_IRQHander函数。每次接收完成后相关的中断都会关闭,需要再次调用HAL_UART_Receive_IT函数开启中断,这也是刚开始用HAL库时常常疑惑的地方,为什么要在初始化时调用一次HAL_UART_Receive_IT函数,在接收完成后的处理函数中要调用HAL_UART_Receive_IT?
当然我们也可以自己调用相关的宏开启中断在ISR中写自己的处理函数,但是这样就不能够调用HAL库提供的函数接收数据了,因为在HAL库中,将外设抽象为句柄,在其中有许多的标志位,我们一旦自己自己调用中断操作后面又使用HAL库的API就会因为外设句柄中的标志位与实际不符而返回错误状态,导致程序卡死。

三、HAL库使用心得

http://www.yayakq.cn/news/948412/

相关文章:

  • 免费自己生成网站淘宝手机网站模板下载安装
  • 网站界面尺寸大小蓝色的网站登录页面模版
  • 贵阳门户网站建设wordpress 自己写
  • 东莞网站新网网站
  • 哪个网站可以做代练门户网站做等保需要备案哪些
  • 无锡网络公司有哪些济南优化网站排名
  • 自己电脑做服务器搭网站如何自己制作一个软件
  • 有没有网站教做美食的新品发布会视频
  • 建设网站的发布与推广网站开发团队职能
  • 基层网站建设作用五金配件店 东莞网站建设
  • 梅州住房和建设局网站wordpress 代码分享
  • 电信网站空间如何开发wap网站
  • 做网站需要备案几次家里做服务器开网站
  • 网站产品展示单页模板网站开发有关书籍
  • 美团外卖网站开发网络营销论文怎么写
  • 网站开发的实训报告中国企业集成网电子商务
  • ie6 网站模板做网站投广告攻略
  • 重庆本地建站昆明网站优化建设
  • 成都网络运营公司烟台网站的优化
  • php网站怎么修改后台地址营销网站制作企业
  • 韩国化妆品网站模板郑州信盈达嵌入式培训
  • 网站 展示网站建设基础服务
  • wordpress幻灯片回收站在哪网站开发自我介绍代码
  • 网上做网站aso优化方法
  • 做商铺最好的网站wordpress 加入搜索引擎
  • 关于手机的网站有哪些内容推广网站方案
  • 任经理++徐州网站建设wordpress弹幕功能
  • 百度权重查询爱站网网站设计 佛山
  • asp网站开发框架爱做网站外国
  • 做网站的风险分析直播开放平台登陆