先上代碼:
#define COMM_COM USART2
#define COMM_COM_CLK RCC_APB1Periph_USART2
#define COMM_COM_TX_GPIO_CLK RCC_AHB1Periph_GPIOD //UART TX
#define COMM_COM_TX_PIN GPIO_Pin_5
#define COMM_COM_TX_GPIO_PORT GPIOD
#define COMM_COM_TX_SOURCE GPIO_PinSource5
#define COMM_COM_TX_AF GPIO_AF_USART2
#define COMM_COM_RX_GPIO_CLK RCC_AHB1Periph_GPIOD //UART RX
#define COMM_COM_RX_PIN GPIO_Pin_6
#define COMM_COM_RX_GPIO_PORT GPIOD
#define COMM_COM_RX_SOURCE GPIO_PinSource6
#define COMM_COM_RX_AF GPIO_AF_USART2
#define COMM_COM_IRQn USART2_IRQn
#define COMM_COM_Priority 9 //優先級
#define COMM_COM_BaudRate 115200 //波特率
#define COMM_COM_IRQHandler USART2_IRQHandler //中斷函數接口(見stm32f4xx_it.c)
USART配置:
/************************************************
函數名稱 :USART_COMM_Configuration
功 能 :通信串口配置
參 數 :無
返 回 值 :無
作 者 :strongerHuang
*************************************************/
void USART_COMM_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 時鐘配置 */
RCC_AHB1PeriphClockCmd(COMM_COM_TX_GPIO_CLK | COMM_COM_RX_GPIO_CLK, ENABLE);
if((USART1 == COMM_COM) || (USART6 == COMM_COM))
RCC_APB2PeriphClockCmd(COMM_COM_CLK, ENABLE);
else
RCC_APB1PeriphClockCmd(COMM_COM_CLK, ENABLE);
/* 復用配置 */
GPIO_PinAFConfig(COMM_COM_TX_GPIO_PORT, COMM_COM_TX_SOURCE, COMM_COM_TX_AF);
GPIO_PinAFConfig(COMM_COM_RX_GPIO_PORT, COMM_COM_RX_SOURCE, COMM_COM_RX_AF);
/* 引腳配置 */
GPIO_InitStructure.GPIO_Pin = COMM_COM_TX_PIN; //USART Tx
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //復用模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(COMM_COM_TX_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = COMM_COM_RX_PIN; //USART Rx
GPIO_Init(COMM_COM_RX_GPIO_PORT, &GPIO_InitStructure);
/* NVIC配置 */
NVIC_InitStructure.NVIC_IRQChannel = COMM_COM_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = COMM_COM_Priority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* USART配置 */
USART_InitStructure.USART_BaudRate = COMM_COM_BaudRate; //波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //傳輸位數
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位
USART_InitStructure.USART_Parity = USART_Parity_No ; //校驗位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收發功能
USART_Init(COMM_COM, &USART_InitStructure);
USART_ClearFlag(COMM_COM, USART_FLAG_RXNE | USART_FLAG_TC);
USART_ITConfig(COMM_COM, USART_IT_RXNE, ENABLE); //接收中斷
USART_DMACmd(COMM_COM, USART_DMAReq_Tx, ENABLE); //使能DMA
USART_Cmd(COMM_COM, ENABLE); //使能USART
}
DMA配置中的宏定義:
#define COMM_DR_ADDRESS ((uint32_t)USART2 + 0x04)
#define COMM_DMA DMA1
#define COMM_DMA_CLK RCC_AHB1Periph_DMA1
#define COMM_TX_DMA_CHANNEL DMA_Channel_4
#define COMM_TX_DMA_STREAM DMA1_Stream6
#define COMM_TX_DMA_FLAG_TCIF DMA_FLAG_TCIF6
#define COMM_TX_DMA_IRQn DMA1_Stream6_IRQn
#define COMM_TX_DMA_Priority 8 //優先級
#define COMM_TX_DMA_IRQHandler DMA1_Stream6_IRQHandler //中斷函數接口(見stm32f4xx_it.c)
#define COMM_TX_DMA_IT_TCIF DMA_IT_TCIF6
通訊串口的配置
/************************************************
函數名稱 :USART_COMM_DMA_Configuration
功 能 :通信串口的DMA配置
參 數 :無
返 回 值 :無
作 者 :strongerHuang
*************************************************/
void USART_COMM_DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 使能時鐘 */
RCC_AHB1PeriphClockCmd(COMM_DMA_CLK, ENABLE);
/* NVIC配置 */
NVIC_InitStructure.NVIC_IRQChannel = COMM_TX_DMA_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = COMM_TX_DMA_Priority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* DMA配置 */
DMA_DeInit(COMM_TX_DMA_STREAM);
DMA_InitStructure.DMA_Channel = COMM_TX_DMA_CHANNEL; //DMA通道
DMA_InitStructure.DMA_PeripheralBaseAddr = COMM_DR_ADDRESS; //外設地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; //內存地址(待傳入參數)
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //傳輸方向
DMA_InitStructure.DMA_BufferSize = 0; //傳輸長度(待傳入參數)
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設遞增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存遞增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //數據寬度
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //循環模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //優先級
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(COMM_TX_DMA_STREAM, &DMA_InitStructure);
DMA_ClearFlag(COMM_TX_DMA_STREAM, COMM_TX_DMA_FLAG_TCIF);
DMA_ITConfig(COMM_TX_DMA_STREAM, DMA_IT_TC, ENABLE); //使能DMA傳輸完成中斷
DMA_Cmd(COMM_TX_DMA_STREAM, DISABLE); //初始化禁止
}
j接下來實現數據發送與接收
/************************************************
函數名稱 :COMM_SendBufByDMA
功 能 :通信串口通過DMA發送數據
參 數 :Buf ------ 數據(地址)
Length --- 數據長度(字節)
返 回 值 :無
作 者 :strongerHuang
*************************************************/
void COMM_SendBufByDMA(uint8_t *Buf, uint16_t Length)
{
DMA_Cmd(COMM_TX_DMA_STREAM, DISABLE); //關閉DMA
//內存地址
DMA_MemoryTargetConfig(COMM_TX_DMA_STREAM, (uint32_t)Buf, DMA_Memory_0);
DMA_SetCurrDataCounter(COMM_TX_DMA_STREAM, Length); //設置DMA傳輸長度
DMA_Cmd(COMM_TX_DMA_STREAM, ENABLE); //使能DMA
}
DMA是一種在嵌入式實時任務處理中常用的功能。
而UART發送數據包,使用DMA方式能大量減輕CPU處理的時間,使其CPU資源不被大量浪費,尤其在UART收發大量數據包(如高頻率收發指令)時具有明顯優勢。
審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
單片機
+關注
關注
6032文章
44525瀏覽量
633261 -
STM32
+關注
關注
2266文章
10876瀏覽量
354928 -
串口
+關注
關注
14文章
1547瀏覽量
76231 -
dma
+關注
關注
3文章
559瀏覽量
100446
發布評論請先 登錄
相關推薦
基于單片機虛擬串口驅動LCD1602的電路仿真
基于M ult isim 10 仿真軟件, 設計單片機的虛擬串口驅動LCD1602 液晶電路。實現了虛擬串口擴展并行輸出的功能。該設計適用單片機
發表于 08-16 17:28
?116次下載
單片機控制系統中labVIEW與單片機實現串口通信的設計過程
首先利用單片機STC89C54通過串口發送“你好,LabVIEW”,LabVIEW將單片機發送到數據進行顯示。通過這個實例來了解LabVIEW的串口通信設計。
發表于 07-25 09:30
?2.7w次閱讀
單片機的串口實驗 串口介紹 串口原理
文章目錄1 串口的硬件初步認識2 中間橋梁芯片硬件電路3 電腦如何識別 中間橋梁芯片4 串口調試助手5 為什么需要CH340模塊6 CH340模塊可以換成別的嗎7 單片機開發版設計理念18 單
發表于 11-10 20:20
?16次下載
C語言條件編譯語句and單片機DMA的介紹
C語言條件編譯語句and單片機DMA的介紹C語言條件編譯:這里面介紹的很詳細,也有歷程。DMA的介紹:介紹了單片機中為什么要使用DMA,以及
發表于 11-29 10:36
?3次下載
STM32單片機串口空閑中斷+DMA接收不定長數據
在上一篇文章STM32單片機串口空閑中斷接收不定長數據中介紹了利用串口空閑中斷接收不定長數據,這種方式有一個問題就是串口每接收到一個字節就會進入一次中斷,如果發送的數據比較頻繁,那么
發表于 12-27 19:24
?18次下載
STM32單片機實現DMA+ADC+UART功能
。于是想到了ADC采樣的數據用DMA功能存儲,并通過串口打印。但是串口打印依然要占用單片機時間,那能不能串口數據的輸出也采用
發表于 12-28 19:25
?34次下載
單片機接收不定長的數據,最優解是DMA+串口空閑中斷
如果單片機不支持串口空閑中斷和DMA,可以參考之前寫的,串口只用接收中斷,完成不定長的分包。這里以stm32L4的單片機舉例,思路可拓展到G
發表于 12-28 19:26
?25次下載
評論