STM32F0 DMA가 UART로부터 데이터를 수신하는 데 문제가 있습니다. 두 개의 DMA 채널 (rx 및 tx 용)을 둘 다 비 원형 모드로 사용하면 rx 채널의 우선 순위가 낮아집니다. Idle Line 인터럽트의 UART 데이터는 DMA 수신 바이트 수를 읽고 처리합니다. 패키지의 바이트 수가 DMA 버퍼 크기보다 작거나 같을 때까지 모든 것이 잘 작동합니다. 그렇지 않으면 DMA가 이상하게 꺼지고 Idle Line 인터럽트를 따라 가면 1, 0, 0, ... DMA 수신 바이트 수를 알 수 있습니다. 여기서 I는 DMA 버퍼가 차면 확인 크기 버퍼 DMA 카운터를 재설정을 시도하는 코드의 한 부분이다 : 상기 제 "오버플로"다음STM32F0 DMA "입력 오버 플로우"
#define S_M_INPUT_CMD_SIZE 20
static char s_m_uart_dma_in_buff[S_M_INPUT_CMD_SIZE + 1];
void USART1_IRQHandler(void)
{
ITStatus reception_status = USART_GetITStatus(USART1, USART_IT_IDLE);
if(reception_status != RESET)
{
int32_t bytes_number = S_M_INPUT_CMD_SIZE - DMA_GetCurrDataCounter(DMA1_Channel3);
if (DMA_GetFlagStatus(DMA1_FLAG_TC3) != RESET)
{
USART_ITConfig(UART_, USART_IT_IDLE, DISABLE);
DMA_Cmd(DMA1_Channel3, DISABLE);
while (DMA1_Channel3->CCR & DMA_CCR_EN);
for (int i = 0; i < S_M_INPUT_CMD_SIZE; i++)
s_m_uart_dma_in_buff[i] = '\0';
DMA_SetCurrDataCounter(DMA1_Channel3, S_M_INPUT_CMD_SIZE);
DMA_Cmd(DMA1_Channel3, ENABLE);
DMA_ClearFlag(DMA1_FLAG_GL3);
}
USART_ClearITPendingBit(UART_, USART_IT_IDLE);
}
}
및 DMA는 활성화 오는 바이트 "크기 + 1 버퍼"그 rx 레지스터에 있었고 나중에 수신 된 바이트 수는 안정적인 0입니다. 내가 뭘 잘못하고있어? 당신이 S_M_INPUT_CMD_SIZE이 코드를 사용하는 것보다 더 큰 크기의 패킷을 수신하려고하면
@alexander 답장을 보내 주셔서 감사합니다. 어쩌면 나는 당신을 이해하지 못한다. 그러나 바이트 수 "0, 0, ..."은 새로운 유휴 인터럽트에서 다음 패키지에 대한 반작용이다. 단지 DMA가 작동하는데 지친 것처럼 보인다. 길은 이상하다.하지만 이것은 최소한의 CPU 비용으로 가변 길이 패키지를 받기 위해 내놓은 유일한 방법이다. 그리고 경주 해줘서 고맙습니다. – Yuriy
@ Yuriy, 그래서 긴 패킷 후에 다른 패킷을 보냅니 까? 그리고 패킷을 추적하는 데'0'을 얻습니다. bytes_number는 어떻게 확인합니까? JTAG이 실제 사진을 손상시킬 수 있으므로 ISR에서 JTAG을 사용하는 프로그램을 중단하지 마십시오. 전역 변수를 사용하여 이벤트를 기록하십시오. 또한 UART와 DMA가 서로 동기화되지 않은 것이 가능합니다 (따라서 UART 또는 DMA를 재설정해야합니다). 또한 UART가 오버플로 플래그를 설정하고이를 지울 때까지 수신을 중지 할 수 있습니다. – alexander
0 bytes_number 검사가 (bytes_number> 0)이면 건너 뜁니다. USART와 DMA를 다시 연결하려고 시도했으며 DMA RCC를 사용 불가능하게 설정하려고했습니다. 전체 재 초기화를 시도하지만 좋지 않습니다. – Yuriy