#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)の場合は除外され
ます。これで、記事を書くのは初めてです。ネチズンからの批判や批判を歓迎します。これ、お互いから学び、応援!