STM32halライブラリはシリアルポート+ DMA受信データを解決します

STM32F407シリアルポートアイドル割り込み+ DMA受信、DJIDT7ワイヤレスリモコンに適用

#stm32CubeIDE STM32F4HALライブラリDJIDT7シリアルポート+ DMA()

1.ハードウェアの設計
まず反転回路を作る必要があります、ここに写真の説明を挿入してください
、図に示すように、DJIレシーバーによって送信されるシリアルポートデータの信号タイプを理解します。次に示すように、反転回路を作成する必要があります。
ここに画像の説明を挿入

写真はインターネットから撮影したものです。これらはインターネットで見つけることができます。プルアップ抵抗を忘れずに用意してください。外部がない場合は、MCU USARTのRXのGPIOを使用して
プル後に送信れるように構成できます。 -upリモートコントロールを受信します。これは外部シリアルポートのTXに相当します。マイクロコンピュータのRXに接続します。

次はソフトウェアの部分です。STM32CubeIDEを使用し、最初に環境を構成します。1。RCC
クロックを構成します。これについては詳しく説明しません
できない場合は、コメント領域に2.ここに画像の説明を挿入
シリアルポートデータを構成します。GPIOモード構成
ここに画像の説明を挿入を受信するようにシリアルポートDMAを
ここに画像の説明を挿入
構成し、
最後に、シリアルポートが割り込みを受信できるように
ここに画像の説明を挿入
します。10msのタイマー割り込みを使用して、割り込みではなくタイマーでデータを処理しました。割り込みはデータの受信にのみ使用されます。タイマーの設定についてはあまり言いません

ここに画像の説明を挿入
写真、
以下コードを追加します

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); //使能串口空闲中断
  HAL_UART_Receive_DMA(&huart1, receive_buff,18);//开启串口DMA接收
  HAL_TIM_Base_Start_IT(&htim2);//开启1定时器中断
  /* USER CODE END 2 */

uint8_t receive_buff [18];これは定義された受信配列です
receive_buffは受信配列です。受信データはここに配置されます。18は一度に18バイトを受信することを表します。
次に、stm32f4xx_it.cファイルを見つけます。

 * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);  //这个可有可无
  /* USER CODE BEGIN USART1_IRQn 1 */
  if(USART1==huart1.Instance)  //判断是否为串口1的中断
  {
  if( __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)!=RESET )                /判断是否为空闲中断
  			   {
  				__HAL_UART_CLEAR_IDLEFLAG(&huart1);        //  如果是空闲中断清除空闲中断标志
  				HAL_UART_DMAStop(&huart1);                 // 关闭串口的DMA接收
  				DMA2_Stream2->NDTR=(uint16_t)(RC_FRAME_LENGTH);  //  这个参考的大疆DT7历程,重置DMA存储指针到起始位置
  				HAL_UART_Receive_DMA(&huart1, (uint8_t*) receive_buff, 18); //再开启接收
  				HAL_Delay(25);    //为什么加延时呢,见后面
              if(__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)==0&&receive_buff[17]==4)  // 见后面
                {
                memcpy(data_Handle, receive_buff, 18);      //复制到其他数组方便处理
      
                }
  			   }
  }
  /* USER CODE END USART1_IRQn 1 */
}
/**

説明します。文__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)は、現在のDMAストリーム送信の残りのデータユニットの数を意味します。つまり、受信がオンになった後、データを処理する前に受信が完了するのを待つ必要があります。 、__ HAL_DMA_GET_COUNTER(&hdma_usart1_rx)これはゼロに等しい。これは、18バイトすべてが受信されたことを意味します。
このマクロ定義は、HALライブラリで確認できます#define __HAL_DMA_GET_COUNTER(HANDLE)((HANDLE)-> Instance-> NDTR)および次に
、STドキュメントのNDTRレジスタの意味を確認します。これで、
ここに画像の説明を挿入
私はHAL_UART_Receive_DMA(&huart1、(uint8_t *)receive_buff、18);にいます。受信をオンにした後、受信が完了するまで20分待つ必要があります。それ以外の場合、デバッグ中にブレークポイントを設定しても、次の場合は入力されません。まだ残っているため、0に等しくなりません。
&& receive_buff [17] == 4について、これは私のデータ受信の特性である必要があります。ルート。データの正確性を向上させるために判断条件を追加しました。
率直に言って、この文は受信データの長さチェックに加えて、データ内のデータの特徴によりデータの正確性を保証できます。データは混沌としているため
、(__ HAL_DMA_GET_COUNTER(&hdma_usart1_rx)== 0 && receive_buff [17] == 4)の場合は除外され
ます。これで、記事を書くのは初めてです。ネチズンからの批判や批判を歓迎します。これ、お互いから学び、応援!

おすすめ

転載: blog.csdn.net/m0_49933527/article/details/114187881