STM32-USART HAL 라이브러리 수신 임의의 길이 데이터 상세 분석
최근 STM32L152 HAL 라이브러리 직렬 포트에서 임의의 길이 데이터를 받는 프로그램을 디버깅하여 임의의 길이 데이터를 받는 방법을 상세하게 분석하였다.
하드웨어 플랫폼: STM32L152
소프트웨어 플랫폼: keil v5+cubeMX
함수 라이브러리:HAL 라이브러리
STM32L152 —USART
STM32L152 USART의 HAL 라이브러리에서 수신 함수:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
이 함수의 매개 변수는 Size가 고정되어 있어 사용 시 매우 불편하여 고정된 길이의 데이터만 수신할 수 있다.
본고는 HAL 라이브러리 UASRT 수신 함수를 상세하게 분석하여 수신 임의의 길이로 수정합니다.PS: 수신 데이터의 끝에 줄 바꿈 문자 0x0a만 적용되며, 수신 데이터가 다른 형식이면 데이터의 특징에 따라 수정할 수 있습니다.
1.HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 200);
수신 단말기를 시작하여 초기 길이 200을 설정하고 수신하는 임의의 바이트 수가 200보다 크지 않으면 된다.
2. 인터럽트 처리 함수
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
3. HAL에서UART_IRQHandler (&huart1) 의 정의 수신 단말기 함수 찾기: UARTReceive_IT(huart);
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
uint32_t tmp_flag = 0, tmp_it_source = 0;
tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);
/* UART parity error interrupt occurred ------------------------------------*/
if((tmp_flag != RESET) && (tmp_it_source != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_PE;
}
tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
/* UART frame error interrupt occurred -------------------------------------*/
if((tmp_flag != RESET) && (tmp_it_source != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_FE;
}
tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
/* UART noise error interrupt occurred -------------------------------------*/
if((tmp_flag != RESET) && (tmp_it_source != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_NE;
}
tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
/* UART Over-Run interrupt occurred ----------------------------------------*/
if((tmp_flag != RESET) && (tmp_it_source != RESET))
{
huart->ErrorCode |= HAL_UART_ERROR_ORE;
}
tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
/* UART in mode Receiver ---------------------------------------------------*/
if((tmp_flag != RESET) && (tmp_it_source != RESET))
{
UART_Receive_IT(huart);
}
tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE);
tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE);
/* UART in mode Transmitter ------------------------------------------------*/
if((tmp_flag != RESET) && (tmp_it_source != RESET))
{
UART_Transmit_IT(huart);
}
tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC);
tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC);
/* UART in mode Transmitter end --------------------------------------------*/
if((tmp_flag != RESET) && (tmp_it_source != RESET))
{
UART_EndTransmit_IT(huart);
}
if(huart->ErrorCode != HAL_UART_ERROR_NONE)
{
/* Clear all the error flag at once */
__HAL_UART_CLEAR_PEFLAG(huart);
/* Set the UART state ready to be able to start again the process */
huart->State = HAL_UART_STATE_READY;
HAL_UART_ErrorCallback(huart);
}
}.
4. UART 수정Receive_IT(huart) 함수,
u8 flag,Rx_Size;
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t* tmp;
uint32_t tmp_state = 0;
tmp_state = huart->State;
if((tmp_state == HAL_UART_STATE_BUSY_RX) || (tmp_state == HAL_UART_STATE_BUSY_TX_RX))
{
if(huart->Init.WordLength == UART_WORDLENGTH_9B)
{
tmp = (uint16_t*) huart->pRxBuffPtr;
if(huart->Init.Parity == UART_PARITY_NONE)
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
huart->pRxBuffPtr += 2;
}
else
{
*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);
huart->pRxBuffPtr += 1;
}
}
else
{
if(huart->Init.Parity == UART_PARITY_NONE)//
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
if(((uint8_t)(huart->Instance->DR & (uint8_t)0x00FF))==0x0a) flag++; // 0x0A 。
Rx_Size++;
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
}
// if(--huart->RxXferCount == 0) // RxXferCount 0 , , if(flag== 1);
if(flag== 1)
{
flag=0;
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Check if a transmit process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
else
{
/* 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);
huart->State = HAL_UART_STATE_READY;
}
HAL_UART_RxCpltCallback(huart);
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
5. UART 직렬 리셋 함수를 작성하고 수신 중단을 다시 켜고 로고를 정리한다.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
HAL_UART_Transmit(&huart3 ,(uint8_t *)aRxBuffer,Rx_Size ,200);// 3 ,
HAL_UART_Receive_IT(&huart1,(uint8_t *)aRxBuffer, 200);//
for(u8 i=0;i
위의 수정 사항은 0x0a로 끝나는 임의의 길이의 데이터를 수신할 수 있습니다.그러나 HAL 라이브러리를 수정하는 것은 좋은 해결 방법이 아니다.만약 다른 사람이 당신의 프로그램을 이식하려고 한다면, 다른 사람에게 이식 프로그램에 어려움을 가져올 것이다.DMA 방식으로 직렬 수신을 하는 것이 비교적 좋은 방법이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
STM32CubeIDE를 사용해 보자 How To STM32CubeIDE 일본어판 (11) I2C를 사용해 보자 4 Si7020+ssd1306편STM32CubeIDE를 사용해 보자 How To STM32CubeIDE 일본어판 (10) I2C를 사용해 보자 3 ssd1306편의 계속입니다. Nucleo 보드와 Si7020, SSD1306을 연결합니다. 이번에...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.