STM32 CubeMX Halk Library의 일부 구멍
10647 단어 stm32
STM32 CubeMX Halk Library의 일부 구멍
stm32f103V1을 사용합니다.40 버전 라이브러리
UART DMA에서 보낸 질문
발송 함수발송이 끝난 후 성공한 리셋 함수도 정상이지만 다시 발송할 때 보낼 수 없습니다.오류가 계속 반환됩니다.이 함수의 코드를 봅시다.
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
uint32_t tmp_state = 0;
tmp_state = huart->State;
if((tmp_state == HAL_UART_STATE_READY) || (tmp_state == HAL_UART_STATE_BUSY_RX))
{
if((pData == NULL ) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Check if a receive process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_RX)
{
huart->State = HAL_UART_STATE_BUSY_TX_RX;
}
else
{
huart->State = HAL_UART_STATE_BUSY_TX;
}
/* Set the UART DMA transfer complete callback */
huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
/* Set the UART DMA Half transfer complete callback */
huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
/* Set the DMA error callback */
huart->hdmatx->XferErrorCallback = UART_DMAError;
/* Enable the UART transmit DMA channel */
tmp = (uint32_t*)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t*)tmp, (uint32_t)&huart->Instance->DR, Size);
/* Clear the TC flag in the SR register by writing 0 to it */
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
/* Enable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Process Unlocked */
__HAL_UNLOCK(huart);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
코드를 보면 보내기 전에 상태 표시를 먼저 판단하고 발송 상태에서 보내는 것이 아니라는 것도 정상이다.그러나 한 번 발송하면 상태가 발송 상태로 바뀌고 발송 완료도 명확하지 않아 다음에 다시 발송하고 바쁘다고 판단하면 발송이 안 된다.우리는 그가 보낸 성공적인 처리 부분을 보았다.
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal mode*/
if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
{
huart->TxXferCount = 0;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
}
/* DMA Circular mode */
else
{
HAL_UART_TxCpltCallback(huart);
}
}
코드에서 볼 수 있듯이 발송 상태를 지우지 않았기 때문에 다음 발송에 성공하지 못할 문제가 생겼다.직접 보내기 전에 상태를 지우는 것은 라이브러리 함수의 본뜻이 아닐 것 같습니다.우리 는 수신 성공 이 어떻게 처리되었는지 비교해 보았다
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal mode*/
if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
{
huart->RxXferCount = 0;
/* Disable the DMA transfer for the receiver request by setting the DMAR bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
/* 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
{
huart->State = HAL_UART_STATE_READY;
}
}
HAL_UART_RxCpltCallback(huart);
}
수신 성공 후 상태 표시를 정확하게 지우면 발송 성공도 마찬가지이기 때문에 빠뜨린 것 같습니다.우리는 더하면 된다
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
/* DMA Normal mode*/
if ( HAL_IS_BIT_CLR(hdma->Instance->CCR, DMA_CCR_CIRC) )
{
huart->TxXferCount = 0;
/* Disable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
/* Enable the UART Transmit Complete Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
/* Check if a transmit process is ongoing or not */
if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
{
huart->State = HAL_UART_STATE_BUSY_RX;
}
else
{
huart->State = HAL_UART_STATE_READY;
}
}
/* DMA Circular mode */
else
{
HAL_UART_TxCpltCallback(huart);
}
}
테스트, 정상적으로 발송 가능...
Flash 읽기/쓰기 보호
HAL의 라이브러리 flash는 표준 라이브러리에 비해 변화가 매우 커서 이 부분을 보호하기 위해 수동으로 설정해야 한다.부호를 붙이다
FLASH_OBProgramInitTypeDef obProgram;
__HAL_FLASH_PREFETCH_BUFFER_DISABLE();
HAL_FLASHEx_OBGetConfig(&obProgram);
if (obProgram.RDPLevel == OB_RDP_LEVEL_0)
{
obProgram.OptionType = OPTIONBYTE_WRP; //
obProgram.WRPState = OB_WRPSTATE_ENABLE; //
obProgram.WRPPage = OB_WRP_ALLPAGES; //
obProgram.Banks = FLASH_BANK_1;
obProgram.RDPLevel = OB_RDP_LEVEL_1;
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBProgram(&obProgram);
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
}
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
error: #136: struct ""has no field "AHBSTR"RL-TCPNet을 이식할 때 공식 이더넷 DP83848칩의 구동을 추가하여 컴파일할 때 계속 오류를 보고하였다 error: #136: struct ""has no field "AHBSTR" 사용한 것은 처음에 #...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.