曰本美女∴一区二区特级A级黄色大片, 国产亚洲精品美女久久久久久2025, 页岩实心砖-高密市宏伟建材有限公司, 午夜小视频在线观看欧美日韩手机在线,国产人妻奶水一区二区,国产玉足,妺妺窝人体色WWW网站孕妇,色综合天天综合网中文伊,成人在线麻豆网观看

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

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

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

如何使用DMA進(jìn)行USART不定長度接收

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

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

USART可以利用DMA連續(xù)通信。Rx緩沖器和Tx緩沖器的DMA請(qǐng)求是分別產(chǎn)生的。參考產(chǎn)品技術(shù)說明以確定是否可用DMA控制器。如果所用產(chǎn)品無DMA功能,發(fā)送器或接收器里所描述的方法使用USART。在USART2_SR寄存器里,可以清零TXE/RXNE標(biāo)志來實(shí)現(xiàn)連續(xù)通信。

利用DMA發(fā)送

使用DMA進(jìn)行發(fā)送,可以通過設(shè)置USART_CR3寄存器上的DMAT位激活。當(dāng)TXE位被置為’1’時(shí),DMA就從指定的SRAM區(qū)傳送數(shù)據(jù)到USART_DR寄存器。為USART的發(fā)送分配一個(gè)DMA通道的步驟如下(x表示通道號(hào)):

在DMA控制寄存器上將USART_DR寄存器地址配置成DMA傳輸?shù)哪康牡刂?。在每個(gè)TXE事件后,數(shù)據(jù)將被傳送到這個(gè)地址;

在DMA控制寄存器上將存儲(chǔ)器地址配置成DMA傳輸?shù)脑吹刂?。在每個(gè)TXE事件后,將從此存儲(chǔ)器區(qū)讀出數(shù)據(jù)并傳送到USART_DR寄存器;

在DMA控制寄存器中配置要傳輸?shù)目偟淖止?jié)數(shù);

在DMA寄存器上配置通道優(yōu)先級(jí);

根據(jù)應(yīng)用程序的要求,配置在傳輸完成一半還是全部完成時(shí)產(chǎn)生DMA中斷;

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

當(dāng)傳輸完成DMA控制器指定的數(shù)據(jù)量時(shí),DMA控制器在該DMA通道的中斷向量上產(chǎn)生一中斷。在發(fā)送模式下,當(dāng)DMA傳輸完所有要發(fā)送的數(shù)據(jù)時(shí),DMA控制器設(shè)置DMA_ISR寄存器的TCIF標(biāo)志;監(jiān)視USART_SR寄存器的TC標(biāo)志可以確認(rèn)USART通信是否結(jié)束,這樣可以在關(guān)閉USART或進(jìn)入停機(jī)模式之前避免破壞最后一次傳輸?shù)臄?shù)據(jù);軟件需要先等待TXE=1,再等待TC=1。

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

圖1 利用DMA發(fā)送

利用DMA接收

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

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

通過DMA控制寄存器把USART_DR寄存器地址配置成傳輸?shù)脑吹刂贰T诿總€(gè)RXNE事件后,將從此地址讀出數(shù)據(jù)并傳輸?shù)酱鎯?chǔ)器;

通過DMA控制寄存器把存儲(chǔ)器地址配置成傳輸?shù)哪康牡刂?。在每個(gè)RXNE事件后,數(shù)據(jù)將從USART_DR傳輸?shù)酱舜鎯?chǔ)器區(qū);

在DMA控制寄存器中配置要傳輸?shù)目偟淖止?jié)數(shù);

在DMA寄存器上配置通道優(yōu)先級(jí);

根據(jù)應(yīng)用程序的要求配置在傳輸完成一半還是全部完成時(shí)產(chǎn)生DMA中斷;

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

當(dāng)接收完成DMA控制器指定的傳輸量時(shí),DMA控制器在該DMA通道的中斷矢量上產(chǎn)生一中斷。

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

圖2 利用DMA接收

DMA通道

在CKS32F107xx DMA章節(jié)中,我們對(duì)DMA進(jìn)行了基本介紹,根據(jù)各通道DMA請(qǐng)求表可以發(fā)現(xiàn),USART1需要使用的DMA通道為DMA1的第4和第5通道。

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

圖3 USART1 DMA通道

USART初始化程序

在該例程中,我們使用USART1,利用DMA接收并發(fā)送不定長度數(shù)據(jù)。

開啟GPIO、USART1、DMA1時(shí)鐘

對(duì)USART引腳進(jìn)行配置,PA9映射TX,PA10映射RX;

初始化DMA1相關(guān)參數(shù);

對(duì)USART參數(shù)進(jìn)行配置,此例程使用USART的IDLE中斷對(duì)不定長度數(shù)據(jù)接收完成進(jìn)行判斷;

對(duì)中斷參數(shù)進(jìn)行配置;

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

* 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函數(shù)

我們利用USART的IDLE進(jìn)行不定長度數(shù)據(jù)接收完成判斷,當(dāng)USART被IDLE中斷觸發(fā)后,即標(biāo)志著本次數(shù)據(jù)流已完成傳輸。

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

* 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發(fā)送程序

發(fā)送程序通過DMA發(fā)送長度為lenth的CKS_Uart_Tx數(shù)組。

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

* 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);

}

聲明:本文內(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)投訴
  • 控制器
    +關(guān)注

    關(guān)注

    114

    文章

    16876

    瀏覽量

    182449
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5403

    瀏覽量

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

    關(guān)注

    3

    文章

    569

    瀏覽量

    102115
  • USART
    +關(guān)注

    關(guān)注

    1

    文章

    198

    瀏覽量

    31543

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

文章出處:【微信號(hào):中科芯MCU,微信公眾號(hào):中科芯MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    FreeRTOS串口DMA收發(fā)不定長數(shù)據(jù)

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

    stm32串口怎么用DMA接收不定長數(shù)據(jù)?

    stm32串口怎么用DMA接收不定長數(shù)據(jù),求大神點(diǎn)播1. 網(wǎng)上查到,空閑中斷+DMA可以接收不定長
    發(fā)表于 08-21 09:21

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

    經(jīng)??吹接腥嗽趩栍?b class='flag-5'>DMA接收不定長包的問題,由于STM32DMA的特殊性,使其對(duì)接收不定長的數(shù)據(jù)
    發(fā)表于 12-26 08:48

    STM32之串口DMA接收不定長數(shù)據(jù)

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

    DMA如何接收不定長的數(shù)據(jù)?

    STM32串口DMA如何接收不定長的數(shù)據(jù)呢?
    發(fā)表于 12-21 07:39

    stm32串口是如何實(shí)現(xiàn)接收不定長度數(shù)據(jù)的呢

    1.不定長度數(shù)據(jù)為什么會(huì)存在串口接收不定長度數(shù)據(jù)呢?首先,在通信雙方進(jìn)行數(shù)據(jù)傳輸?shù)臅r(shí)候,由于不同的設(shè)備在實(shí)現(xiàn)控制,數(shù)據(jù)采樣時(shí),發(fā)送的數(shù)據(jù)指令字節(jié)數(shù)量存在著差異,就產(chǎn)生了串口
    發(fā)表于 08-11 08:18

    STM32 HAL DMA串口接收不定長度的實(shí)現(xiàn)方法

    STM32 HAL DMA串口接收不定長度的實(shí)現(xiàn)方法
    發(fā)表于 12-08 07:59

    基于DMA接收利用空閑模式接收不定長數(shù)據(jù)

    STM32L051 HAL庫非DMA模式使用空閑中斷接收不定長數(shù)據(jù)因項(xiàng)目中的上位機(jī)與單片機(jī)之間的通信協(xié)議采用非標(biāo)準(zhǔn)協(xié)議,上位機(jī)發(fā)送的數(shù)據(jù)長度不定
    發(fā)表于 01-12 07:44

    STM32F072使用DMA+IDLE進(jìn)行串口接收不定長數(shù)據(jù)有問題,改為DMA+RTO接收正常。

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

    stm32 串口接收不定長度數(shù)據(jù)及黏包處理 + 串口DMA接收

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

    STM32 DMA串口接收不定長數(shù)據(jù)

    STM32 DMA串口接收不定長數(shù)據(jù)
    發(fā)表于 12-24 18:50 ?41次下載
    STM32  <b class='flag-5'>DMA</b>串口<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)

    STM32之串口DMA接收不定長數(shù)據(jù)

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

    STM32F429 標(biāo)準(zhǔn)庫 串口完成中斷+DMA 接收不定長數(shù)據(jù)

    之前寫過STM32F103的串口+DMA不定長數(shù)據(jù)接收驅(qū)動(dòng),近期在設(shè)計(jì)STM32F429系列單片機(jī)標(biāo)準(zhǔn)庫函數(shù) 串口+DAM 接收不定長數(shù)據(jù)驅(qū)
    發(fā)表于 12-24 19:03 ?21次下載
    STM32F429 標(biāo)準(zhǔn)庫  串口完成中斷+<b class='flag-5'>DMA</b>  <b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)

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

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

    STM32CubeMX之串口接收不定長數(shù)據(jù)

    基本串口通信通常只能接收定長數(shù)據(jù),無法穩(wěn)定接收不定長數(shù)據(jù),本章介紹利用STM32單片機(jī)的IDLE空閑中斷,接收
    的頭像 發(fā)表于 05-11 09:59 ?3914次閱讀
    STM32CubeMX之串口<b class='flag-5'>接收</b><b class='flag-5'>不定長</b>數(shù)據(jù)