在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何使用DMA進行USART不定長度接收

中科芯MCU ? 來源:中科芯MCU ? 2025-02-18 17:01 ? 次閱讀

在上一講中,我們對USART進行了簡單介紹,并講解了如何在不使用DMA的情況下進行不定長度數據接收,本講將著重講解如何使用DMA進行USART不定長度接收。

USART可以利用DMA連續通信。Rx緩沖器和Tx緩沖器的DMA請求是分別產生的。參考產品技術說明以確定是否可用DMA控制器。如果所用產品無DMA功能,發送器或接收器里所描述的方法使用USART。在USART2_SR寄存器里,可以清零TXE/RXNE標志來實現連續通信。

利用DMA發送

使用DMA進行發送,可以通過設置USART_CR3寄存器上的DMAT位激活。當TXE位被置為’1’時,DMA就從指定的SRAM區傳送數據到USART_DR寄存器。為USART的發送分配一個DMA通道的步驟如下(x表示通道號):

在DMA控制寄存器上將USART_DR寄存器地址配置成DMA傳輸的目的地址。在每個TXE事件后,數據將被傳送到這個地址;

在DMA控制寄存器上將存儲器地址配置成DMA傳輸的源地址。在每個TXE事件后,將從此存儲器區讀出數據并傳送到USART_DR寄存器;

在DMA控制寄存器中配置要傳輸的總的字節數;

在DMA寄存器上配置通道優先級;

根據應用程序的要求,配置在傳輸完成一半還是全部完成時產生DMA中斷;

在DMA寄存器上激活該通道。

當傳輸完成DMA控制器指定的數據量時,DMA控制器在該DMA通道的中斷向量上產生一中斷。在發送模式下,當DMA傳輸完所有要發送的數據時,DMA控制器設置DMA_ISR寄存器的TCIF標志;監視USART_SR寄存器的TC標志可以確認USART通信是否結束,這樣可以在關閉USART或進入停機模式之前避免破壞最后一次傳輸的數據;軟件需要先等待TXE=1,再等待TC=1。

175ab9a8-edd4-11ef-9310-92fbcf53809c.png

圖1 利用DMA發送

利用DMA接收

可以通過設置USART_CR3寄存器的DMAR位激活使用DMA進行接收,每次接收到一個字節,DMA控制器就就把數據從USART_DR寄存器傳送到指定的SRAM區(參考DMA相關說明)。

為USART的接收分配一個DMA通道的步驟如下(x表示通道號):

通過DMA控制寄存器把USART_DR寄存器地址配置成傳輸的源地址。在每個RXNE事件后,將從此地址讀出數據并傳輸到存儲器;

通過DMA控制寄存器把存儲器地址配置成傳輸的目的地址。在每個RXNE事件后,數據將從USART_DR傳輸到此存儲器區;

在DMA控制寄存器中配置要傳輸的總的字節數;

在DMA寄存器上配置通道優先級;

根據應用程序的要求配置在傳輸完成一半還是全部完成時產生DMA中斷;

在DMA控制寄存器上激活該通道。

當接收完成DMA控制器指定的傳輸量時,DMA控制器在該DMA通道的中斷矢量上產生一中斷。

17a2e6ba-edd4-11ef-9310-92fbcf53809c.png

圖2 利用DMA接收

DMA通道

在CKS32F107xx DMA章節中,我們對DMA進行了基本介紹,根據各通道DMA請求表可以發現,USART1需要使用的DMA通道為DMA1的第4和第5通道。

17e1777c-edd4-11ef-9310-92fbcf53809c.png

圖3 USART1 DMA通道

USART初始化程序

在該例程中,我們使用USART1,利用DMA接收并發送不定長度數據。

開啟GPIO、USART1、DMA1時鐘

對USART引腳進行配置,PA9映射TX,PA10映射RX;

初始化DMA1相關參數

對USART參數進行配置,此例程使用USART的IDLE中斷對不定長度數據接收完成進行判斷;

對中斷參數進行配置;

/*******************************************************************************

* Function Name : USART_Configuration

* Description : Configure USART1

* Input : None

* Output : None

* Return : None

* Attention : None

*******************************************************************************/

void CKS_USART_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/*USART1_TX -> PA9 , USART1_RX -> PA10*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* DMA configuration ----------------------------------------------*/

/* USART1_RX DMA Init */

DMA_DeInit(DMA1_Channel5);

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)CKS_Uart_Rx;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize = CKS_UART_TX_RX_BUFF;

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_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel5, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel5, ENABLE);

/* USART1_TX DMA Init */

DMA_DeInit(DMA1_Channel4);

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)CKS_Uart_Tx;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

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_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel4, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel4, DISABLE);

USART_InitStructure.USART_BaudRate = 115200;

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(USART1, &USART_InitStructure);

USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);

/* USART1 interrupt configuration ----------------------------------------------*/

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

USART_Cmd(USART1, ENABLE);

}

USART_IRQHandler函數

我們利用USART的IDLE進行不定長度數據接收完成判斷,當USART被IDLE中斷觸發后,即標志著本次數據流已完成傳輸。

/*******************************************************************************

* Function Name : USART1_IRQHandler

* Description : This function handles USART1 global interrupt request.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void USART1_IRQHandler(void)

{

if(USART_GetFlagStatus(USART1, USART_FLAG_IDLE) != RESET)

{

DMA_Cmd(DMA1_Channel5, DISABLE);

uint8_t i = USART1->SR;

i = USART1->DR;

CKS_Uart_Rx_Data_Lenth = CKS_UART_TX_RX_BUFF - DMA_GetCurrDataCounter(DMA1_Channel5);

DMA1_Channel5->CNDTR = CKS_UART_TX_RX_BUFF;

CKS_Uart_Tx_Data_Lenth = CKS_Uart_Rx_Data_Lenth;

memcpy(CKS_Uart_Tx, CKS_Uart_Rx, CKS_Uart_Rx_Data_Lenth);

memset(CKS_Uart_Rx, 0x00, sizeof(CKS_Uart_Rx));

DMA_Cmd(DMA1_Channel5, ENABLE);

CKS_Uart_Transmite_With_DMA(CKS_Uart_Tx_Data_Lenth);

}

USART_ClearFlag(USART1, USART_IT_RXNE);

}

USART發送程序

發送程序通過DMA發送長度為lenth的CKS_Uart_Tx數組。

/*******************************************************************************

* Function Name : CKS_Uart_Transmite_With_DMA

* Description : transmite data.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void CKS_Uart_Transmite_With_DMA(uint32_t lenth)

{

DMA1_Channel4->CNDTR = lenth;

DMA_Cmd(DMA1_Channel4, ENABLE);

while(!DMA_GetFlagStatus(DMA1_FLAG_TC4)){}

DMA_ClearFlag(DMA1_FLAG_TC4);

memset(CKS_Uart_Tx, 0x00, sizeof(CKS_Uart_Tx));

CKS_Uart_Tx_Data_Lenth = 0x00;

DMA_Cmd(DMA1_Channel4, DISABLE);

}

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 控制器
    +關注

    關注

    113

    文章

    16505

    瀏覽量

    179925
  • 寄存器
    +關注

    關注

    31

    文章

    5386

    瀏覽量

    121459
  • dma
    dma
    +關注

    關注

    3

    文章

    568

    瀏覽量

    101186
  • USART
    +關注

    關注

    1

    文章

    198

    瀏覽量

    31035

原文標題:MCU微課堂|CKS32F107xx USART(二)

文章出處:【微信號:中科芯MCU,微信公眾號:中科芯MCU】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    FreeRTOS串口DMA收發不定長數據

    FreeRTOS例程,介紹串口DMA收發不定長數據
    的頭像 發表于 09-26 09:08 ?4824次閱讀
    FreeRTOS串口<b class='flag-5'>DMA</b>收發<b class='flag-5'>不定長</b>數據

    stm32串口怎么用DMA接收不定長數據?

    stm32串口怎么用DMA接收不定長數據,求大神點播1. 網上查到,空閑中斷+DMA可以接收不定長
    發表于 08-21 09:21

    用串口DMA傳輸不定長度包的方式

    經常看到有人在問用DMA接收不定長包的問題,由于STM32DMA的特殊性,使其對接收不定長的數據
    發表于 12-26 08:48

    STM32之串口DMA接收不定長數據

      STM32之串口DMA接收不定長數據引言  在使用stm32或者其他單片機的時候,會經常使用到串口通訊,那么如何有效地接收數據呢?假如這段數據是
    發表于 09-05 16:52

    DMA如何接收不定長的數據?

    STM32串口DMA如何接收不定長的數據呢?
    發表于 12-21 07:39

    stm32串口是如何實現接收不定長度數據的呢

    1.不定長度數據為什么會存在串口接收不定長度數據呢?首先,在通信雙方進行數據傳輸的時候,由于不同的設備在實現控制,數據采樣時,發送的數據指令字節數量存在著差異,就產生了串口
    發表于 08-11 08:18

    STM32 HAL DMA串口接收不定長度的實現方法

    STM32 HAL DMA串口接收不定長度的實現方法
    發表于 12-08 07:59

    基于DMA接收利用空閑模式接收不定長數據

    STM32L051 HAL庫非DMA模式使用空閑中斷接收不定長數據因項目中的上位機與單片機之間的通信協議采用非標準協議,上位機發送的數據長度不定
    發表于 01-12 07:44

    STM32F072使用DMA+IDLE進行串口接收不定長數據有問題,改為DMA+RTO接收正常。

    把調試STM32F072串口過程中,出現了一小點問題,記錄下來,F0的串口寄存器有些增加的功能以前沒用到,F0增加了modbus協議之類的接收超時處理,完美實現了不定長數據包的幀接收。本次
    發表于 12-03 09:21 ?11次下載
    STM32F072使用<b class='flag-5'>DMA</b>+IDLE<b class='flag-5'>進行</b>串口<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數據有問題,改為<b class='flag-5'>DMA</b>+RTO<b class='flag-5'>接收</b>正常。

    stm32 串口接收不定長度數據及黏包處理 + 串口DMA接收

    1.不定長度數據 為什么會存在串口接收不定長度數據呢?首先,在通信雙方進行數據傳輸的時候,由于不同的設備在實現控制,數據采樣時,發送的數據指令字節數量存在著差異,就產生了串口
    發表于 12-23 19:09 ?27次下載
    stm32 串口<b class='flag-5'>接收</b><b class='flag-5'>不定長度</b>數據及黏包處理 + 串口<b class='flag-5'>DMA</b><b class='flag-5'>接收</b>

    STM32 DMA串口接收不定長數據

    STM32 DMA串口接收不定長數據
    發表于 12-24 18:50 ?40次下載
    STM32  <b class='flag-5'>DMA</b>串口<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數據

    STM32之串口DMA接收不定長數據

    目錄STM32之串口DMA接收不定長數據引言DMA簡介什么是DMA在STM32的DMA資源
    發表于 12-24 19:03 ?30次下載
    STM32之串口<b class='flag-5'>DMA</b><b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數據

    STM32F429 標準庫 串口完成中斷+DMA 接收不定長數據

    之前寫過STM32F103的串口+DMA不定長數據接收驅動,近期在設計STM32F429系列單片機標準庫函數 串口+DAM 接收不定長數據驅
    發表于 12-24 19:03 ?21次下載
    STM32F429 標準庫  串口完成中斷+<b class='flag-5'>DMA</b>  <b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數據

    STM32CUBEMX(8)--USART通過定時器中斷方式接收不定長數據

    本文利用中斷實現串口不定長接收(非DMA),使用HAL庫,將接收的數據打印出去。
    的頭像 發表于 11-14 16:31 ?1502次閱讀
    STM32CUBEMX(8)--<b class='flag-5'>USART</b>通過定時器中斷方式<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數據

    STM32CubeMX之串口接收不定長數據

    基本串口通信通常只能接收定長數據,無法穩定接收不定長數據,本章介紹利用STM32單片機的IDLE空閑中斷,接收
    的頭像 發表于 05-11 09:59 ?3627次閱讀
    STM32CubeMX之串口<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數據
    主站蜘蛛池模板: 亚洲一区二区三区四区在线观看 | 久久h| 午夜国产精品福利在线观看 | 天天操天天干天天舔 | www.xxx国产| 人人艹人人射 | 午夜影院观看 | 亚洲精品亚洲人成人网 | yy4080午夜理论一级毛片 | 羞涩妩媚玉腿呻吟嗯啊销魂迎合 | 色视频日本 | 亚洲激情视频网站 | 天天综合欧美 | www四虎| 亚洲一区在线视频观看 | 午夜骚| 夜夜操夜夜骑 | 有坂深雪在线 | 美女被草视频在线观看 | 欧美日韩视频综合一区无弹窗 | 国产精品一区二区综合 | 国产高清小视频 | 久久综合狠狠综合久久 | 天天操天天艹 | 天天爽天天操 | 四虎影视最新网址 | 欧美不卡视频 | 免费欧美黄色网址 | 色婷婷777| 午夜免费啪 | 校园 春色 欧美 另类 小说 | 午夜视频在线免费播放 | 天天插天天透 | 精品国产污网站在线观看15 | 免费视频爰爱太爽了 | 欧美精品专区55页 | aa国产| 欧美专区一区二区三区 | 欧美成人自拍视频 | 床上激情四射 | 日本不卡免费高清视频 |