STM32F0的UART虽然支持LIN模式,但是在HAL库中却缺少LIN总线相关的API函数。
基于对总线协议的研究,将USART HAL库进行改写,实现了LIN通信。- 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;
- }
- }
复制代码- void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
- {
- uint32_t isrflags = READ_REG(huart->Instance->ISR);
- uint32_t cr1its = READ_REG(huart->Instance->CR1);
- uint32_t cr3its;
- uint32_t errorflags;
- uint16_t ore_rdr_data;
- /* If no error occurs */
- errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));
- if (errorflags == RESET)
- {
-
- /* UART in ¿ÕÏÐÖжϣ¬½ÓÊÕÊý¾ÝÍê³É ---------------------------------------------------*/
- if(((isrflags & USART_ISR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
- {
-
- __HAL_UART_CLEAR_IT(huart, UART_CLEAR_IDLEF);
-
- /* 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);
-
- /* ½ûÖ¹IDLEIEÖÐ¶Ï */
- CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);
- /* Rx process is completed, restore huart->RxState to Ready */
- huart->RxState = HAL_UART_STATE_READY;
- HAL_UART_RxCpltCallback(huart);
- //UART_Receive_IT(huart);
- return;
- }
-
- /* UART in mode Receiver ---------------------------------------------------*/
- if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
- {
- UART_Receive_IT(huart);
- return;
- }
- }
- /* 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)) )
- {
- /* UART parity error interrupt occurred -------------------------------------*/
- if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
- {
- __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF);
- huart->ErrorCode |= HAL_UART_ERROR_PE;
- }
- /* UART frame error interrupt occurred --------------------------------------*/
- if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF);
- __HAL_UART_CLEAR_IT(huart, UART_CLEAR_IDLEF); //Çå³ý¿ÕÏбêÖ¾
- huart->RxXferCount = huart->RxXferSize;
- //HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
- SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);//ʹÄܽÓÊÕÖжÏ
- SET_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);//ʹÄÜ¿ÕÏÐÖжÏ
- huart->ErrorCode |= HAL_UART_ERROR_FE;
- }
- /* UART noise error interrupt occurred --------------------------------------*/
- if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
- {
- __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF);
- huart->ErrorCode |= HAL_UART_ERROR_NE;
- }
-
- /* UART Over-Run interrupt occurred -----------------------------------------*/
- if(((isrflags & USART_ISR_ORE) != RESET) &&
- (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
- {
- __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF);
- huart->ErrorCode |= HAL_UART_ERROR_ORE;
- }
- /* Call UART Error Call back function if need be --------------------------*/
- if(huart->ErrorCode != HAL_UART_ERROR_NONE)
- {
- ore_rdr_data = (uint16_t) READ_REG(huart->Instance->RDR); //¶ÁÈ¡Êý¾Ý¼Ä´æÆ÷£¬ÇåÁã
- /* UART in mode Receiver ---------------------------------------------------*/
- if(((isrflags & USART_ISR_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 */
- if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) ||
- (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)))
- {
- /* Blocking error : transfer is aborted
- Set 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))
- {
- 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;
- /* Abort DMA RX */
- if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
- {
- /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
- huart->hdmarx->XferAbortCallback(huart->hdmarx);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_UART_ErrorCallback(huart);
- }
- }
- else
- {
- /* Call user error callback */
- HAL_UART_ErrorCallback(huart);
- }
- }
- else
- {
- /* Non Blocking error : transfer could go on.
- Error is notified to user through user error callback */
- HAL_UART_ErrorCallback(huart);
- huart->ErrorCode = HAL_UART_ERROR_NONE;
- }
- }
- return;
- } /* End if some error occurs */
- #if !defined(STM32F030x6) && !defined(STM32F030x8)&& !defined(STM32F070xB)&& !defined(STM32F070x6)&& !defined(STM32F030xC)
- /* UART wakeup from Stop mode interrupt occurred ---------------------------*/
- if(((isrflags & USART_ISR_WUF) != RESET) && ((cr3its & USART_CR3_WUFIE) != RESET))
- {
- __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF);
- /* Set the UART state ready to be able to start again the process */
- huart->gState = HAL_UART_STATE_READY;
- huart->RxState = HAL_UART_STATE_READY;
- HAL_UARTEx_WakeupCallback(huart);
- return;
- }
- #endif /* !defined(STM32F030x6) && !defined(STM32F030x8)&& !defined(STM32F070xB)&& !defined(STM32F070x6)&& !defined(STM32F030xC) */
- /* UART in mode Transmitter ------------------------------------------------*/
- if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
- {
- UART_Transmit_IT(huart);
- return;
- }
- /* UART in mode Transmitter (transmission end) -----------------------------*/
- if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
- {
- UART_EndTransmit_IT(huart);
- return;
- }
- }
复制代码
|