0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

單片機(jī)DMA驅(qū)動(dòng)串口過程

嵌入式應(yīng)用開發(fā) ? 來源:嵌入式應(yīng)用開發(fā) ? 作者:嵌入式應(yīng)用開發(fā) ? 2022-12-03 14:23 ? 次閱讀

先上代碼:

#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                        //優(yōu)先級(jí)
#define COMM_COM_BaudRate         115200                   //波特率
#define COMM_COM_IRQHandler       USART2_IRQHandler        //中斷函數(shù)接口(見stm32f4xx_it.c)


USART配置:



/************************************************
函數(shù)名稱 :USART_COMM_Configuration
功    能 :通信串口配置
參    數(shù) :無
返 回 值 :無
作    者 :strongerHuang
*************************************************/
void USART_COMM_Configuration(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef  NVIC_InitStructure;  

  /* 時(shí)鐘配置 */
  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);  

  /* 復(fù)用配置 */
  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;                       //復(fù)用模式
  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;        //傳輸位數(shù)
  USART_InitStructure.USART_StopBits = USART_StopBits_1;             //停止位
  USART_InitStructure.USART_Parity = USART_Parity_No ;               //校驗(yàn)位
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收發(fā)功能
  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                        //優(yōu)先級(jí)
#define COMM_TX_DMA_IRQHandler    DMA1_Stream6_IRQHandler  //中斷函數(shù)接口(見stm32f4xx_it.c)
#define COMM_TX_DMA_IT_TCIF       DMA_IT_TCIF6

通訊串口的配置

/************************************************
函數(shù)名稱 :USART_COMM_DMA_Configuration
功    能 :通信串口的DMA配置
參    數(shù) :無
返 回 值 :無
作    者 :strongerHuang
*************************************************/
void USART_COMM_DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;  

  /* 使能時(shí)鐘 */
  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;        //外設(shè)地址
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0;               //內(nèi)存地址(待傳入參數(shù))
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;            //傳輸方向
  DMA_InitStructure.DMA_BufferSize = 0;                              //傳輸長(zhǎng)度(待傳入?yún)?shù))
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;   //外設(shè)遞增
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;            //內(nèi)存遞增
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;    //數(shù)據(jù)寬度
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                      //循環(huán)模式
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;              //優(yōu)先級(jí)
  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接下來實(shí)現(xiàn)數(shù)據(jù)發(fā)送與接收

/************************************************
函數(shù)名稱 :COMM_SendBufByDMA
功    能 :通信串口通過DMA發(fā)送數(shù)據(jù)
參    數(shù) :Buf ------ 數(shù)據(jù)(地址)
            Length --- 數(shù)據(jù)長(zhǎng)度(字節(jié))
返 回 值 :無
作    者 :strongerHuang
*************************************************/
void COMM_SendBufByDMA(uint8_t *Buf, uint16_t Length)
{
  DMA_Cmd(COMM_TX_DMA_STREAM, DISABLE);                              //關(guān)閉DMA
                                                                     //內(nèi)存地址
  DMA_MemoryTargetConfig(COMM_TX_DMA_STREAM, (uint32_t)Buf, DMA_Memory_0);
  DMA_SetCurrDataCounter(COMM_TX_DMA_STREAM, Length);                //設(shè)置DMA傳輸長(zhǎng)度
  DMA_Cmd(COMM_TX_DMA_STREAM, ENABLE);                               //使能DMA
}

DMA是一種在嵌入式實(shí)時(shí)任務(wù)處理中常用的功能。

pYYBAGOJ9qaAPcf0AAEKOSVJNBQ774.png


而UART發(fā)送數(shù)據(jù)包,使用DMA方式能大量減輕CPU處理的時(shí)間,使其CPU資源不被大量浪費(fèi),尤其在UART收發(fā)大量數(shù)據(jù)包(如高頻率收發(fā)指令)時(shí)具有明顯優(yōu)勢(shì)。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6023

    文章

    44378

    瀏覽量

    628605
  • STM32
    +關(guān)注

    關(guān)注

    2258

    文章

    10828

    瀏覽量

    352546
  • 串口
    +關(guān)注

    關(guān)注

    14

    文章

    1534

    瀏覽量

    75478
  • dma
    dma
    +關(guān)注

    關(guān)注

    3

    文章

    552

    瀏覽量

    99954
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    51單片機(jī)串口通信原理與應(yīng)用

    本文我們主要講單片機(jī)串口的工作原理和如何通過程序來對(duì)串口進(jìn)行設(shè)置,以及根據(jù)所給出的實(shí)例實(shí)現(xiàn)與PC 機(jī)通信。
    發(fā)表于 01-08 13:51 ?9545次閱讀

    基于單片機(jī)虛擬串口驅(qū)動(dòng)LCD1602的電路仿真

    基于M ult isim 10 仿真軟件, 設(shè)計(jì)單片機(jī)的虛擬串口驅(qū)動(dòng)LCD1602 液晶電路。實(shí)現(xiàn)了虛擬串口擴(kuò)展并行輸出的功能。該設(shè)計(jì)適用單片機(jī)
    發(fā)表于 08-16 17:28 ?116次下載

    基于單片機(jī)串口雙機(jī)通訊的圖解

    單片機(jī)串口作用非常重要,如果您設(shè)計(jì)需要也上位機(jī)(PC)通訊,最放方便的還是串口。因?yàn)镻C本身就有串口,不需要寫任何
    發(fā)表于 09-15 15:24 ?0次下載
    基于<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>串口</b>雙機(jī)通訊的圖解

    單片機(jī)控制系統(tǒng)中l(wèi)abVIEW與單片機(jī)實(shí)現(xiàn)串口通信的設(shè)計(jì)過程

    首先利用單片機(jī)STC89C54通過串口發(fā)送“你好,LabVIEW”,LabVIEW將單片機(jī)發(fā)送到數(shù)據(jù)進(jìn)行顯示。通過這個(gè)實(shí)例來了解LabVIEW的串口通信設(shè)計(jì)。
    發(fā)表于 07-25 09:30 ?2.7w次閱讀
    <b class='flag-5'>單片機(jī)</b>控制系統(tǒng)中l(wèi)abVIEW與<b class='flag-5'>單片機(jī)</b>實(shí)現(xiàn)<b class='flag-5'>串口</b>通信的設(shè)計(jì)<b class='flag-5'>過程</b>

    什么是單片機(jī)串口通信?

    串口通信是單片機(jī)一個(gè)重要的部分,單片機(jī)和PC,單片機(jī)單片機(jī)之間的通信大都用串口。
    發(fā)表于 07-25 07:36 ?6.1w次閱讀
    什么是<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>串口</b>通信?

    單片機(jī)串口實(shí)驗(yàn) 串口介紹 串口原理

    文章目錄1 串口的硬件初步認(rèn)識(shí)2 中間橋梁芯片硬件電路3 電腦如何識(shí)別 中間橋梁芯片4 串口調(diào)試助手5 為什么需要CH340模塊6 CH340模塊可以換成別的嗎7 單片機(jī)開發(fā)版設(shè)計(jì)理念18
    發(fā)表于 11-10 20:20 ?16次下載
    <b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>串口</b>實(shí)驗(yàn) <b class='flag-5'>串口</b>介紹 <b class='flag-5'>串口</b>原理

    PIC單片機(jī)DMA和ADC

    PIC單片機(jī)DMA和ADC
    發(fā)表于 11-16 11:21 ?32次下載
    PIC<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>DMA</b>和ADC

    單片機(jī)串口調(diào)試丟包驗(yàn)證過程記錄 已解決

    單片機(jī)串口調(diào)試丟包驗(yàn)證過程記錄 已解決
    發(fā)表于 11-16 15:36 ?80次下載
    <b class='flag-5'>單片機(jī)</b><b class='flag-5'>串口</b>調(diào)試丟包驗(yàn)證<b class='flag-5'>過程</b>記錄 已解決

    51單片機(jī)串口通信

    51單片機(jī)串口通信文章目錄51單片機(jī)串口通信串口介紹硬件電路電平標(biāo)準(zhǔn)常見通信接口比較相關(guān)術(shù)語51單片機(jī)
    發(fā)表于 11-18 14:06 ?22次下載
    51<b class='flag-5'>單片機(jī)</b><b class='flag-5'>串口</b>通信

    51單片機(jī)串口通信

    51單片機(jī)串口通信文章目錄51單片機(jī)串口通信串口介紹硬件電路電平標(biāo)準(zhǔn)常見通信接口比較相關(guān)術(shù)語51單片機(jī)
    發(fā)表于 11-21 20:36 ?62次下載
    51<b class='flag-5'>單片機(jī)</b><b class='flag-5'>串口</b>通信

    C語言條件編譯語句and單片機(jī)DMA的介紹

    C語言條件編譯語句and單片機(jī)DMA的介紹C語言條件編譯:這里面介紹的很詳細(xì),也有歷程。DMA的介紹:介紹了單片機(jī)中為什么要使用DMA,以及
    發(fā)表于 11-29 10:36 ?3次下載
    C語言條件編譯語句and<b class='flag-5'>單片機(jī)</b><b class='flag-5'>DMA</b>的介紹

    STM32單片機(jī)串口空閑中斷+DMA接收不定長(zhǎng)數(shù)據(jù)

    在上一篇文章STM32單片機(jī)串口空閑中斷接收不定長(zhǎng)數(shù)據(jù)中介紹了利用串口空閑中斷接收不定長(zhǎng)數(shù)據(jù),這種方式有一個(gè)問題就是串口每接收到一個(gè)字節(jié)就會(huì)進(jìn)入一次中斷,如果發(fā)送的數(shù)據(jù)比較頻繁,那么
    發(fā)表于 12-27 19:24 ?18次下載
    STM32<b class='flag-5'>單片機(jī)</b><b class='flag-5'>串口</b>空閑中斷+<b class='flag-5'>DMA</b>接收不定長(zhǎng)數(shù)據(jù)

    STM32單片機(jī)實(shí)現(xiàn)DMA+ADC+UART功能

    。于是想到了ADC采樣的數(shù)據(jù)用DMA功能存儲(chǔ),并通過串口打印。但是串口打印依然要占用單片機(jī)時(shí)間,那能不能串口數(shù)據(jù)的輸出也采用
    發(fā)表于 12-28 19:25 ?32次下載
    STM32<b class='flag-5'>單片機(jī)</b>實(shí)現(xiàn)<b class='flag-5'>DMA</b>+ADC+UART功能

    單片機(jī)接收不定長(zhǎng)的數(shù)據(jù),最優(yōu)解是DMA+串口空閑中斷

    如果單片機(jī)不支持串口空閑中斷和DMA,可以參考之前寫的,串口只用接收中斷,完成不定長(zhǎng)的分包。這里以stm32L4的單片機(jī)舉例,思路可拓展到G
    發(fā)表于 12-28 19:26 ?23次下載
    <b class='flag-5'>單片機(jī)</b>接收不定長(zhǎng)的數(shù)據(jù),最優(yōu)解是<b class='flag-5'>DMA</b>+<b class='flag-5'>串口</b>空閑中斷

    基于STM32單片機(jī)DMA使用庫文件設(shè)計(jì)源代碼

    基于STM32單片機(jī)DMA使用庫文件設(shè)計(jì)源代碼)
    發(fā)表于 04-26 15:03 ?2次下載