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

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

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

直接存儲器存取(DMA)簡介及程序設(shè)計

嵌入式技術(shù) ? 來源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-06-01 09:01 ? 次閱讀

1.DMA簡介

直接存儲器存取(DMA)用來提供在外設(shè)和存儲器之間或者存儲器和存儲器之間的高速數(shù)據(jù)傳輸。無須CPU干預(yù),數(shù)據(jù)可以通過DMA快速地移動,這就節(jié)省了CPU的資源來做其他操作。
STM32F10x中有兩個DMA控制器(DMA1有7個通道,DMA2有5個通道)每個通道專門用來管理來自于一個或多個外設(shè)對存儲器訪問的請求。還有一個仲裁器來協(xié)調(diào)各個DMA請求的優(yōu)先權(quán)。

DMA1請求映像
??USART1_TX – DMA1_Chnanel4
??USART1_RC – DMA1_Channel5
??利用DMA功能完成串口數(shù)據(jù)處理,無需CPU干預(yù),減少CPU占用。

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ1MzY5NA==,size_16,color_FFFFFF,t_70#pic_center

2.程序設(shè)計

?1.DMA1_CH4配置

/******DMA配合串口1發(fā)送數(shù)據(jù)************
**形參:u32 cpar -- 外設(shè)地址
**
**例:DMA_CH4_Init(&USART1->DR,buff)
**外設(shè)地址:USART1->DR的地址
**					buff的地址
**************************************/
void DMA_CH4_Init(u32 cpar)
{
	RCC->AHBENR|=1<<0;//dma1時鐘使能
	DMA1_Channel4->CCR&=~(1<<14);//非存儲器到存儲器模式
	DMA1_Channel4->CCR|=0x3<<12;//設(shè)置CH4優(yōu)先級為最高
	DMA1_Channel4->CCR&=~(0x3<<10);//存儲器數(shù)據(jù)寬度8位
	DMA1_Channel4->CCR&=~(0x3<<8);//外設(shè)數(shù)據(jù)寬度8位	
	DMA1_Channel4->CCR|=1<<7;//存儲器地址增量
	DMA1_Channel4->CCR&=~(1<<6);//外設(shè)地址不增量
	DMA1_Channel4->CCR&=~(1<<5);//不執(zhí)行循環(huán)操作
	DMA1_Channel4->CCR|=1<<4;//從存儲器讀
	DMA1_Channel4->CPAR=cpar;//外設(shè)地址
}
/**********開啟DMA1_CH4數(shù)據(jù)傳輸*************
***
***形參:u16 data_len -- DMA要傳輸數(shù)目
***********************************************/
void DMA_CH4_Start(u8 *buff,u16 data_len)
{
	DMA1_Channel4->CMAR=(u32)buff;//存儲器地址
	DMA1_Channel4->CCR&=~(1<<0);//關(guān)閉通道傳輸
	DMA1_Channel4->CNDTR=data_len;//設(shè)置傳輸數(shù)量
	DMA1_Channel4->CCR|=1<<0;//開啟通道傳輸
}

??2.DMA1_CH5配置

/******DMA配合串口1接收數(shù)據(jù)************
**形參:u32 cpar -- 外設(shè)地址
**			u32 cmar -- 存儲器地址
**
**例:DMA_CH5_Init(&USART1->DR,buff)
**外設(shè)地址:USART1->DR的地址
**					buff的地址
**************************************/
void DMA_CH5_Init(u32 cpar,u32 cmar)
{
	RCC->AHBENR|=1<<0;//dma1時鐘使能
	DMA1_Channel5->CCR&=~(1<<14);//非存儲器到存儲器模式
	DMA1_Channel5->CCR|=0x3<<12;//設(shè)置CH4優(yōu)先級為最高
	DMA1_Channel5->CCR&=~(0x3<<10);//存儲器數(shù)據(jù)寬度8位
	DMA1_Channel5->CCR&=~(0x3<<8);//外設(shè)數(shù)據(jù)寬度8位	
	DMA1_Channel5->CCR|=1<<7;//存儲器地址增量
	DMA1_Channel5->CCR&=~(1<<6);//外設(shè)地址不增量
	DMA1_Channel5->CCR&=~(1<<5);//執(zhí)行循環(huán)操作
	DMA1_Channel5->CCR&=~(1<<4);//從外設(shè)讀
	DMA1_Channel5->CPAR=cpar;//外設(shè)地址
	DMA1_Channel5->CMAR=cmar;//存儲器地址
	DMA1_Channel5->CCR&=~(1<<0);//關(guān)閉通道傳輸
	DMA1_Channel5->CNDTR=1024;//設(shè)置傳輸數(shù)量
	DMA1_Channel5->CCR|=1<<0;//開啟通道傳輸
}

??3.USART1配置

/********************串口初始化函數(shù)封裝*********************
****硬件接口:USART1_TX -- PA9(發(fā)送)
**						USART1-RX --PA10(接收)
**						USART2_TX -- PA2(發(fā)送)
**						USART2-RX --PA3(接收)
**						USART3_TX -- PB10(發(fā)送)
**						USART3_RX -- PB11(接收)
形參:USART_TypeDef *USARTx -- 要配置的哪個串口
**			u32 baud  --波特率
**			u32 sysclk --時鐘頻率(USART1 --72MHZ ,USAT2USART3 --36MHZ)
**
***********************************************************/
void Usartx_Init(USART_TypeDef *USARTx,u32 baud,u32 sysclk)
{
	if(USART1 == USARTx)
	{
			/*1.開時鐘*/
		RCC->APB2ENR|=1<<2;//PA時鐘
		RCC->APB2ENR|=1<<14;//串口時鐘
		RCC->APB2RSTR|=1<<14;//串口復(fù)位
		RCC->APB2RSTR&=~(1<<14);//取消復(fù)位
		/*2.配置GPIO口*/
		GPIOA->CRH&=0xFFFFF00F;
		GPIOA->CRH|=0x000008B0;//上下拉輸入,復(fù)用推挽輸出	
		USART1->CR3|=1<<7;//DMA發(fā)送
		USART1->CR3|=1<<6;//DMA接收
		USART1->CR1|=1<<4;//IDLE(空閑幀中斷)
		STM32_NVIC_SetPriority(USART1_IRQn,0,1);//設(shè)置優(yōu)先級
	}
	else if(USART2 == USARTx)
	{
		/*1.開時鐘*/
		RCC->APB2ENR|=1<<2;//PA時鐘
		RCC->APB1ENR|=1<<17;//USART2時鐘
		RCC->APB1RSTR|=1<<17;//開復(fù)位時鐘
		RCC->APB1RSTR&=~(1<<17);//取消復(fù)位
		/*2.配置GPIO口*/
		GPIOA->CRL&=0xFFFF00FF;//清除原來寄存器中的值
		GPIOA->CRL|=0x00008B00;		
		#ifdef USART2_IRQ
			USART2->CR1|=1<<5;//串口2接收中斷
			STM32_NVIC_SetPriority(USART2_IRQn,1,2);//設(shè)置優(yōu)先級
		#endif
	}
	else if(USART3 == USARTx)
	{
		/*1.開時鐘*/
		RCC->APB2ENR|=1<<3;//PB時鐘
		RCC->APB1ENR|=1<<18;//USART3時鐘
		RCC->APB1RSTR|=1<<18;//開復(fù)位時鐘
		RCC->APB1RSTR&=~(1<<18);//取消復(fù)位
		/*2.配置GPIO口*/
		GPIOB->CRH&=0xFFFF00FF;
		GPIOB->CRH|=0x00008B00;	
		#ifdef USART3_IRQ
			USART3->CR1|=1<<5;//開啟接收中斷
			STM32_NVIC_SetPriority(USART3_IRQn,0,0);//設(shè)置優(yōu)先級
		#endif
	}
	else return;
	/*3.配置串口核心寄存器*/
	USARTx->BRR=sysclk*1000000/baud;//設(shè)置波特率
	USARTx->CR1|=1<<2;//接收使能
	USARTx->CR1|=1<<3;//發(fā)送使能
	USARTx->CR1|=1<<13;//使能串口3
	#ifdef DMA_USART1_SEND //利用DMA完成數(shù)據(jù)收發(fā)
		DMA_CH5_Init((u32 )&USART1->DR,(u32 )usart1_rx_buff);//DMA配合串口1接收數(shù)據(jù)
		DMA_CH4_Init((u32 )&USART1->DR);
	#endif
}

4.串口1中斷,DMA數(shù)據(jù)接收數(shù)據(jù)

u8 usart1_rx_buff[1024];//串口1接收數(shù)據(jù)緩沖區(qū)
u16 usart1_cnt=0;//保存數(shù)組下班
u8 usart1_flag;//接收完成標(biāo)志符
void USART1_IRQHandler(void)
{
	U8 C;
	//清除標(biāo)志:先讀USART_SR,再讀USART_DR
	if(USART1->SR&1<<4)//空閑幀
	{
		C=USART1->DR;
		C=c;
       // USART1->DR=c;
		Usart1_Receive_Data();//接收數(shù)據(jù)處理函數(shù)
	}
	USART1->SR=0;//清除標(biāo)志位
}

/*************************串口接收數(shù)據(jù)函數(shù)********************/
void Usart1_Receive_Data(void)
{
	DMA1_Channel5->CCR&=~(1<<0);//關(guān)閉通道傳輸
	usart1_cnt=1024-DMA1_Channel5->CNDTR;//獲取接收到是字符長度
	if(usart1_cnt>=1024)usart1_cnt=0;
	DMA1->IFCR|=1<<17;//清除標(biāo)志位
	DMA1_Channel5->CNDTR=1024;//從新賦值
	DMA1_Channel5->CCR|=1<<0;//開啟通道傳輸
	usart1_flag=1;
}

??5.串口數(shù)據(jù)發(fā)送

/****************串口發(fā)送字符串*****************************/
void Usart1_SendStr(u8 *str)
{
	#ifdef DMA_USART1_SEND
		DMA_CH4_Start(str,strlen((char *)str));
	#else
		while(*str!='?')
		{
			USART1->DR=*str++;
			while(!(USART1->SR&1<<7));
		}
	#endif
}

6.硬件初始化,DMA配合串口調(diào)試

int main()
{
	u8 key;
	Beep_Init();//蜂鳴器初始化
	Led_Init();//LED初始化
	Key_Init();//按鍵初始化
	Usartx_Init(USART1,115200,72);
	while(1)
	{
		key=Key_Scan();
		if(key)
		{
			Usart1_SendStr((u8 *)"DMA1配合串口收發(fā)數(shù)據(jù)不定長測試234556789rn");
		}
		if(usart1_flag)
		{
			usart1_rx_buff[usart1_cnt]='?';
			printf("%srn",usart1_rx_buff);
			usart1_flag=0;
		}
	}
}

7.運行效果

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDQ1MzY5NA==,size_16,color_FFFFFF,t_70#pic_center

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

    關(guān)注

    38

    文章

    7366

    瀏覽量

    163091
  • STM32F10x
    +關(guān)注

    關(guān)注

    1

    文章

    81

    瀏覽量

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

    關(guān)注

    3

    文章

    552

    瀏覽量

    99928
收藏 人收藏

    評論

    相關(guān)推薦

    DMA簡介

    DMA直接存儲器訪問)目錄文章目錄DMA直接存儲器訪問)一、
    發(fā)表于 07-28 08:59

    DMA簡介

    1. DMA簡介直接存儲器存取(DMA,Direct Memory Access)用來提供在外設(shè)
    發(fā)表于 08-16 08:30

    DMA直接存儲器存取的主要功能是什么

    DMA 簡介DMA(Direct Memory Access) —— 直接存儲器存取,是單片機(jī)的
    發(fā)表于 01-26 06:35

    STM32的DMA簡介

    1、DMA簡介DMA(Direct Memory Access) :直接存儲器存取,是單片機(jī)的一
    發(fā)表于 01-26 08:27

    DMA直接存儲器訪問與配置流程簡介

    DMA配置流程三、DMA應(yīng)用簡單實例1. 存儲器存儲器(M2M)2. 存儲器到USART串口(M2P)一、
    發(fā)表于 01-26 07:54

    STM32F2技術(shù)培訓(xùn)_直接存儲器訪問_DMA

    STM32F2技術(shù)培訓(xùn)_直接存儲器訪問_DMA
    發(fā)表于 12-03 17:51 ?0次下載

    DMA直接內(nèi)存存取

    【*】程序簡介 -工程名稱:DMA直接內(nèi)存存取 -實驗平臺: 秉火STM32 F429 開發(fā)板 -MDK版本:5.16 -ST固件庫版本:1
    發(fā)表于 12-13 15:09 ?9次下載

    TMS320VC5505DSP直接存儲器存取DMA)控制特點和操作的概述

     該文檔描述了在TMS3VC5505/5504數(shù)字信號處理(DSP)上可用的直接存儲器存取DMA)控制
    發(fā)表于 04-26 10:34 ?3次下載
    TMS320VC5505DSP<b class='flag-5'>直接</b><b class='flag-5'>存儲器</b><b class='flag-5'>存取</b>(<b class='flag-5'>DMA</b>)控制<b class='flag-5'>器</b>特點和操作的概述

    TMS320VC5501和TMS320VC5502DSP直接存儲器存取DMA)控制詳細(xì)描述

    本文描述了TMS320VC5501/TMS320VC5502數(shù)字信號處理(DSPS)的直接存儲器存取DMA)控制
    發(fā)表于 04-26 15:41 ?10次下載
    TMS320VC5501和TMS320VC5502DSP<b class='flag-5'>直接</b><b class='flag-5'>存儲器</b><b class='flag-5'>存取</b>(<b class='flag-5'>DMA</b>)控制<b class='flag-5'>器</b>詳細(xì)描述

    MSP430教程Chapt11-直接存儲器存取DMA

    MSP430系列中的一些設(shè)備支持多通道直接存儲器地址(DMA)控制,可以在沒有CPU干預(yù)的情況下將數(shù)據(jù)從一個位置移動到另一個位置。
    發(fā)表于 05-07 09:30 ?2次下載
    MSP430教程Chapt11-<b class='flag-5'>直接</b><b class='flag-5'>存儲器</b><b class='flag-5'>存取</b>(<b class='flag-5'>DMA</b>)

    隨機(jī)存取存儲器為什么叫隨機(jī)存取存儲器(結(jié)構(gòu)、特點、分類、優(yōu)缺點)

    隨機(jī)存取存儲器(random access memory,RAM)又稱作“隨機(jī)存儲器”,是與CPU直接交換數(shù)據(jù)的內(nèi)部存儲器,也叫主存(內(nèi)存)。它可以隨時讀寫,而且速度很快,通常作為操作
    發(fā)表于 05-17 17:04 ?2.1w次閱讀

    隨機(jī)存取存儲器的最大特點

    隨機(jī)存取存儲器(randomaccessmemory,RAM)又稱作“隨機(jī)存儲器”,是與CPU直接交換數(shù)據(jù)的內(nèi)部存儲器,也叫主存(內(nèi)存)。它可以隨時讀寫,而且速度很快,通常作為操作系統(tǒng)
    的頭像 發(fā)表于 11-24 10:59 ?4.4w次閱讀

    靜態(tài)隨機(jī)存取存儲器簡介及應(yīng)用

    SRAM(Static Random Access Memory),即靜態(tài)隨機(jī)存取存儲器。它是一種具有靜止存取功能的內(nèi)存,不需要刷新電路即能保存它內(nèi)部存儲的數(shù)據(jù)
    發(fā)表于 07-16 10:44 ?5174次閱讀
    靜態(tài)隨機(jī)<b class='flag-5'>存取存儲器</b><b class='flag-5'>簡介</b>及應(yīng)用

    STM32學(xué)習(xí)筆記(7)——DMA直接存儲器訪問

    DMA配置流程三、DMA應(yīng)用簡單實例1. 存儲器存儲器(M2M)2. 存儲器到USART串口(M2P)一、
    發(fā)表于 12-02 14:06 ?3次下載
    STM32學(xué)習(xí)筆記(7)——<b class='flag-5'>DMA</b><b class='flag-5'>直接</b><b class='flag-5'>存儲器</b>訪問

    STM32F103 中級篇 22 DMA 直接存儲器訪問

    22.1直接存儲器訪問22.1.1 DMA功能框圖講解DMA(Direct Memory Access)—直接
    發(fā)表于 12-16 16:59 ?2次下載
    STM32F103 中級篇 22 <b class='flag-5'>DMA</b> <b class='flag-5'>直接</b><b class='flag-5'>存儲器</b>訪問