/** ****************************************************************************** * File Name : USART.c * Description : This file provides code for the configuration * of the USART instances. ****************************************************************************** * @attention * *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include #include #include #include #include #include #include "usart.h" #include "utilities.h" #include "tim.h" #include "board_common.h" UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; static uint8_t aRxBuffer[UART_RINGBUF_SIZE] = {0}; static uint8_t aTxBuffer[UART_RINGBUF_SIZE] = {0}; static UartBuffer_t UartRev; static UartBuffer_t UartSnd; static uint8_t RxBuffer = 0; static char TxBuffer[UART_RINGBUF_SIZE]; /* buffer write index*/ static __IO uint16_t iw=0; /* buffer read index*/ Uart_Rxbuffer_t Debug_Rxbuffer; void Board_USART2RX_Enable(void); /* USART1 init function */ void Board_USART1Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } } void Board_USART1DeInit(void) { HAL_UART_DeInit(&huart1); } void Board_USART1RX_Enable(void) { HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); //再开启接收中断 } void Board_USART1RX_Disable(void) { CLEAR_BIT(USART1->CR1, USART_CR1_RXNEIE); } static void Board_USART2BufferInit(void) { /* * 初始化缓存 * 两个指针指向相同的地址空间 */ memset(aRxBuffer, 0, sizeof(aRxBuffer)); memset(aTxBuffer, 0, sizeof(aTxBuffer)); UartRev.pFront = aRxBuffer; UartRev.pRear = aRxBuffer; UartSnd.pFront = aTxBuffer; UartSnd.pRear = aTxBuffer; //两个指针指向相同的地址空间 } /* USART3 init function */ void Board_USART2Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } Board_USART2BufferInit(); Board_USART2RX_Enable(); } void Board_USART2DeInit(void) { HAL_UART_DeInit(&huart2); } void Board_USART2RX_Enable(void) { HAL_UART_Receive_IT(&huart2, (uint8_t *)aRxBuffer, 1); //再开启接收中断 } void Board_USART2RX_Disable(void) { CLEAR_BIT(USART2->CR1, USART_CR1_RXNEIE); } void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspInit 0 */ /* USER CODE END USART1_MspInit 0 */ /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 interrupt Init */ HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); HAL_NVIC_EnableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */ } else if (uartHandle->Instance==USART2) { __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART2 interrupt Init */ HAL_NVIC_SetPriority(USART2_IRQn, 1, 0); HAL_NVIC_EnableIRQ(USART2_IRQn); } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* USER CODE BEGIN USART1_MspDeInit 0 */ /* USER CODE END USART1_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USART1 interrupt Deinit */ HAL_NVIC_DisableIRQ(USART1_IRQn); /* USER CODE BEGIN USART1_MspDeInit 1 */ /* USER CODE END USART1_MspDeInit 1 */ } else if (uartHandle->Instance==USART2) { __HAL_RCC_USART2_CLK_DISABLE(); /**USART2 GPIO Configuration PA2 ------> USART2_TX PA3 ------> USART2_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Pin = GPIO_PIN_2 ; HW_GPIO_Init( GPIOA, GPIO_PIN_2, &GPIO_InitStruct ); HW_GPIO_Write( GPIOA, GPIO_PIN_2, 1); //GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pin = GPIO_PIN_3 ; HW_GPIO_Init(GPIOA, GPIO_PIN_3, &GPIO_InitStruct ); HW_GPIO_Write(GPIOA, GPIO_PIN_3, 1); /* USART2 interrupt Deinit */ HAL_NVIC_DisableIRQ(USART2_IRQn); } } /* modifes only ir*/ void VcomPrint( void) { static uint16_t ir=0; char* CurChar; while(((iw+UART_RINGBUF_SIZE-ir)%UART_RINGBUF_SIZE) > 0) { BACKUP_PRIMASK(); DISABLE_IRQ(); CurChar = &TxBuffer[ir]; ir= (ir+1) %UART_RINGBUF_SIZE; RESTORE_PRIMASK(); HAL_UART_Transmit(&huart1, (uint8_t *) CurChar, 1, 300); } HAL_NVIC_ClearPendingIRQ(USART1_IRQn); } void VcomSend( char *format, ... ) { va_list args; va_start(args, format); uint8_t len; uint8_t lenTop; char tempBuff[255]; BACKUP_PRIMASK(); DISABLE_IRQ(); /*convert into string at buff[0] of length iw*/ len = vsprintf(&tempBuff[0], format, args); if (iw+len= (aRxBuffer+UART_RINGBUF_SIZE)) UartRev.pFront = aRxBuffer; return 0; } u16TimeOut--; } return -1; } /********************************************************************** 函数:Uart2SendChar() 函数作用:发送一个字节数据 参数: uint8_t *pFmt--------------------------------需要发送的数据 返回值: 上一版本:无 当前版本:1.0 作者: 最后修改时间:2015-04-08 说明: **********************************************************************/ static void Uart2SendChar(uint8_t u8Fmt) { uint8_t u8Ret = HAL_OK; if(UartSnd.pRear == UartSnd.pFront) { //队首指针和队尾指针相等表明当前没有数据需要发送,这里需要手动开启发送请求 *UartSnd.pRear = u8Fmt; UartSnd.pRear++; if(UartSnd.pRear >= aTxBuffer + UART_RINGBUF_SIZE) UartSnd.pRear = aTxBuffer; do { u8Ret = HAL_UART_Transmit_IT(&huart2, UartSnd.pFront, 1);//请求发送下一个数据 }while(u8Ret != HAL_OK); } else { *UartSnd.pRear = u8Fmt; UartSnd.pRear++; if(UartSnd.pRear >= aTxBuffer + UART_RINGBUF_SIZE) UartSnd.pRear = aTxBuffer; } } int8_t Board_USART2Send(const uint8_t *pFmt, uint8_t u8Len) { while(u8Len) { Uart2SendChar(*pFmt); pFmt++; u8Len--; } //HAL_Delay(10); return 0; } //#define DATA_OVERFLOW "Buffer locked or data overflow.\r\n" #define DATA_OVERFLOW "122.\r\n" void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { /* * 溢出判断 */ if (Debug_Rxbuffer.Locked || (Debug_Rxbuffer.RxSize >= sizeof(Debug_Rxbuffer.RxBuffer))) { //HAL_UART_Transmit(&huart1, (uint8_t *)DATA_OVERFLOW, strlen(DATA_OVERFLOW), 0xFFFF); //将收到的信息发送出去 //while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束 FreeUart1Buffer(); // 清除buffer HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); //再开启接收中断 return ; } /* * 取数据 */ Debug_Rxbuffer.RxBuffer[Debug_Rxbuffer.RxSize++] = RxBuffer; Debug_Rxbuffer.Time = jiffies; /* * 判断结束 */ if ((Debug_Rxbuffer.RxBuffer[Debug_Rxbuffer.RxSize-1] == 0x0A) && (Debug_Rxbuffer.RxBuffer[Debug_Rxbuffer.RxSize-2] == 0x0D)) { //HAL_UART_Transmit(&huart1, (uint8_t *)Uart1_Rxbuffer.RxBuffer, Uart1_Rxbuffer.RxSize, 0xFFFF); //将收到的信息发送出去 // while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束 Debug_Rxbuffer.Locked = 1; } HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer, 1); //再开启接收中断 } else if(huart->Instance == USART2) { uint8_t u8Ret = HAL_OK; //PRINTF("--%d-\r\n", __LINE__); UartRev.pRear++; if(UartRev.pRear >= (aRxBuffer + UART_RINGBUF_SIZE)) /* 判断队列是否满*/ UartRev.pRear = aRxBuffer; /* 从头开始存储*/ do { u8Ret= HAL_UART_Receive_IT(huart, UartRev.pRear, 1); }while(u8Ret != HAL_OK); } } void HAL_UART_TxCpltCallback(UART_HandleTypeDef *pHuart) { uint8_t u8Ret = HAL_OK; UartSnd.pFront++; /* 更新rear指针*/ if(UartSnd.pFront >= (aTxBuffer + UART_RINGBUF_SIZE)) UartSnd.pFront = aTxBuffer; if(UartSnd.pFront != UartSnd.pRear) { /* 如果队首指针和队尾指针不同表明缓冲区中有数据还未发送*/ do { u8Ret = HAL_UART_Transmit_IT(pHuart, UartSnd.pFront, 1);/* 请求发送下一个数据*/ }while(u8Ret != HAL_OK); } } #if 0 int8_t Board_USART2Test(void) { uint8_t u8Rx = 0; uint32_t u32TestTimeOut = jiffies + 5000; uint32_t u32RecvTimeOut = jiffies + 200; const uint8_t u8SendBuffer[32] = "Recv OK\r\n"; uint8_t u8RecvBuffer[32] = {0}; uint8_t u8Index = 0; //RS485_RX_ENABLE(); //Board_RS485RecvEnable(); while(1) { while( !Timeout_Happened(u32RecvTimeOut)) { if (!Board_USART2Recv(&u8Rx, 200)) { PRINTF("--%d-\r\n", __LINE__); u8RecvBuffer[u8Index] = u8Rx; if (u8Index <= (sizeof(u8RecvBuffer)-1)) u8Index++; else break; } } //if(strstr((char *)u8RecvBuffer, (const char *)u8SendBuffer)) if(u8Index > 0) { PRINTF("--%d-\r\n", __LINE__); Board_USART2Send(u8SendBuffer, strlen((const char *)u8SendBuffer)); //return 0; } u8Index = 0; memset(u8RecvBuffer, 0, sizeof(u8RecvBuffer)); u32RecvTimeOut = jiffies + 200; } return -1; } #endif /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/