序文
オリジナル:https://blog.csdn.net/u014470361/article/details/79206352
エンドは0x0Aを受信したときに受けたと考えられているUSARTデータは、任意の長さのデータは0x0Aの受信側で達成することができ、HALライブラリが変更されたために、達成することができ受ける任意の長さのための私の以前の記事では、リンクを参照してください:HAL USARTを任意の長さを受け取ります。
しかし、この方法は、上記には適していません。この方法は望ましくないので、HALライブラリを変更していない一般的な原理は、他の人ではない容易な移行プログラムは、このプログラムは、非常に悪い習慣をあるライブラリーの適用可能性を減少させ。
学習データ+開始シリアルこのようにDMA任意の長さを受け取るように受信した後、STM32が情報を確認することを任意の長さのデータはまた、DMAシリアル方法によって実現されてもよいです。
cubeMXソフトウェアの設定プロセス
まず、最初のステップは、図に示すように、クロックツリー、構成されたクロック・システム、チップクロック周波数の異なるコンフィギュレーションを設定することです。
次に、USART1構成は、非同期非同期、ソフトウェアを自動的に構成PA9およびPA10ピンを選択します。
その後、DMA USART1に残りのデフォルトを送受信するために追加していきます。
次に、有効割り込みUSART1をご確認ください。
最後に、プログラムMDK-ARM V5のバージョンの環境。
UASRTシリアルプログラム
//添加变量,为什么用关键字volatile见链接:[链接](http://blog.csdn.net/u014470361/article/details/78830147)
volatile uint8_t rx_len=0;
volatile uint8_t recv_end_flag=0;
uint8_t rx_buffer[200];
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
//上面的usart配置代码为cubemx自动生成的,在下方添加使能idle中断和打开串口DMA接收语句
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//使能idle中断
HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//打开DMA接收,数据存入rx_buffer数组中。
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
そして、シリアルポート割り込み機能を変更します。
void USART1_IRQHandler(void)
{
uint32_t tmp_flag = 0;
uint32_t temp;
tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
if((tmp_flag != RESET))//idle标志被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
temp = huart1.Instance->SR; //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
temp = huart1.Instance->DR; //读取数据寄存器中的数据
HAL_UART_DMAStop(&huart1); //
temp = hdma_usart1_rx.Instance->NDTR;// 获取DMA中未传输的数据个数,NDTR寄存器分析见下面
rx_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
recv_end_flag = 1; // 接受完成标志位置1
}
HAL_UART_IRQHandler(&huart1);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
DMAチャネル構造は、それが送信されていない理由NDTRレジスタ、数値データは定義された、STM32中国のマニュアルは、レジスタの詳細な説明を提供します。
typedef struct
{
__IO uint32_t CR; /*!< DMA stream x configuration register */
__IO uint32_t NDTR; /*!< DMA stream x **number of data register** */
__IO uint32_t PAR; /*!< DMA stream x peripheral address register */
__IO uint32_t M0AR; /*!< DMA stream x memory 0 address register */
__IO uint32_t M1AR; /*!< DMA stream x memory 1 address register */
__IO uint32_t FCR; /*!< DMA stream x FIFO control register */
} DMA_Stream_TypeDef;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
そして、書き込みハンドラシリアルポート割り込みの主な機能。
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
while (1)
{
if(recv_end_flag ==1)
{
printf("rx_len=%d\r\n",rx_len);//打印接收长度
HAL_UART_Transmit(&huart1,rx_buffer, rx_len,200);接收数据打印出来
for(uint8_t i=0;i<rx_len;i++)
{
rx_buffer[i]=0;//清接收缓存
}
rx_len=0;//清除计数
recv_end_flag=0;//清除接收结束标志位
}
HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重新打开DMA接收
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
次の図に示されているエフェクトプログラムを実行して、任意の長さの入力データは、受信データアウトシリアルの印刷データ及び印刷の長さが受信されます。受信が最大長を本BUFFER_SIZE 200のプログラムによって設定され、受信された長いデータの場合、配列の長さを変更し、大BUFFER_SIZEできます。
### DMA関数パラメータ及び分析
次の記事を分析するための理論的根拠DMA、パラメータおよび分析機能(リンク)。
この記事のソースコードをダウンロードしてください:https://download.csdn.net/download/u014470361/10234803