私は、STM32F0 DMAのUARTからのデータ受信に問題があります。私は2つのDMAチャンネル(rxとtxの両方)を非円形モードで使用し、rxチャンネルは低い優先順位を持っています。 UARTからのデータは、アイドルライン割り込みで処理されます。ここで、DMA受信バイト数を読み取り、処理します。パッケージ内のバイト数がDMAバッファサイズ以下になるまで、すべてうまく動作します。さもなければ、DMAが不意にオフになり、アイドルライン割り込みに続いて、1,0,0、...、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をバッファリング」に復帰した後:ここではDMAバッファがいっぱいとサイズをバッファリングするためにDMAカウンタをリセットしようとした場合、私はチェックコードの一部は、 rxレジスタにあり、後で受信バイト数が安定してゼロになりました。私は間違っているの?あなたのコード使用してS_M_INPUT_CMD_SIZEよりも大きなサイズのパケットを受信しようとするとどうなるかをここで
ご返信ありがとうございます@alexander。たぶん私はあなたを理解していないが、バイト番号 "0、0、..."を受け取った新しいアイドル中の割り込みで次のパッケージの反応は、ちょうど作業に疲れてDMAのようだ。 方法は奇妙ですが、これは私が最小のCPUコストで可変長パッケージを受け取るために思いついた唯一の方法です。 レースに感謝します。 – Yuriy
@Yuriy、長いパケットの後に別のパケットを送りますか?そして、あなたはパケットをフォローするに '0'を得ますか? bytes_numberはどうやってチェックしますか? JTAGが実際の画像を壊す可能性があるので、ISRの内部でJTAGを使用してプログラムを停止することはできません。グローバル変数を使用してイベントを記録します。また、UARTとDMAが互いに同期していないこともあります(UARTやDMAをリセットする必要があります)。 UARTがオーバフローフラグをセットし、それをクリアするまで受信を停止することも可能です。 – alexander
(bytes_number> 0)の場合、ゼロbytes_numberのチェックはスキップされます。 USARTとDMAを再接続しようとしましたが、DMA RCCを無効/有効にしようとしました。私は完全な再初期化を試みますが、それは良く見えません。 – Yuriy