历史上的今天
返回首页

历史上的今天

今天是:2024年10月29日(星期二)

正在发生

2019年10月29日 | STM32 DMA 学习笔记(二)

2019-10-29 来源:eefocus

一、常用DMA库函数

1.DMA初始化(包括通道和参数配置)


void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);

下面就是结构体参数


typedef struct

{

  uint32_t DMA_PeripheralBaseAddr; //外设基地址

  uint32_t DMA_MemoryBaseAddr; //存储器基地址

  uint32_t DMA_DIR;         //数据传输方向

  uint32_t DMA_BufferSize;  //通道传输数据量

  uint32_t DMA_PeripheralInc;//外设增量模式

  uint32_t DMA_MemoryInc;  //存储器增量模式

  uint32_t DMA_PeripheralDataSize; //外设数据宽度

  uint32_t DMA_MemoryDataSize; //存储器数据宽度

  uint32_t DMA_Mode;  //模式:是否循环

  uint32_t DMA_Priority; //优先级

  uint32_t DMA_M2M;    //是否存储器到存储器方式     

}DMA_InitTypeDef;

  2.使能DMA所指示的通道 


void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx,FunctionalState NewState);

3.设置DMA通道的DMA缓存的大小。即数据量 


void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx,uint16_t DataNumber); 

 


 二、配置过程

1.使能DMA时钟:RCC_AHBPeriphClockCmd();

2.初始化DMA通道参数:DMA_Init();

3.使能串口DMA发送,串口DMA使能函数:USART_DMACmd();

4.使能DMA1通道,启动传输:DMA_Cmd();

5.查询DMA传输状态DMA_GetFlagStatus();

6.获取/设置通道当前剩余数据量:DMA_GetCurrDataCounter();              DMA_SetCurrDataCounter();

 


#include "dma.h"

 

u16 DMA1_MEM_LEN;//保存初始化确定的传输数据量,因为初始化只执行一次。

 

void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)//配置DMA1_CHx

{

  

DMA_InitTypeDef DMA_InitStruct;      //定义DMA配置参量结构体

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    //使能DMA1时钟

 

DMA1_MEM_LEN= cndtr; //记录需要传输的数据量

DMA_DeInit(DMA_CHx);  //将DMA的通道1寄存器重设为默认值

DMA_InitStruct.DMA_BufferSize=cndtr;           //DMA通道的DMA缓存的大小,也就是一次传输的数据量

DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设

DMA_InitStruct.DMA_M2M=DMA_M2M_Disable ;       //不将DMA通道x设置为内存到内存传输

DMA_InitStruct.DMA_MemoryBaseAddr=cmar;           //DMA内存基地址

DMA_InitStruct.DMA_MemoryDataSize=  DMA_MemoryDataSize_Byte;      //数据宽度为8位

DMA_InitStruct.DMA_MemoryInc= DMA_MemoryInc_Enable;    //内存地址寄存器递增

DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;        //工作在正常缓存模式,传输一次后就停止传输了

DMA_InitStruct.DMA_PeripheralBaseAddr= cpar;   //DMA外设基地址 

DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;   //数据宽度为8位

DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;   //外设地址寄存器不变

DMA_InitStruct.DMA_Priority=DMA_Priority_VeryHigh;     //DMA通道 x拥有最高优先级

//上面结构体设置的作用是,具体设置DMA某通道的某一功能对应的位,下面的初始化就是将上面的设置相或

  DMA_Init(DMA_CHx,&DMA_InitStruct);       //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器

}

 

 

void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)//使能DMA1_CHx

{

     DMA_Cmd(DMA_CHx,DISABLE); //关闭USART1 TX DMA1 所指示的通道

   DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN);//DMA通道的DMA缓存的大小,因为每次传输完成都要重新开启该函数

   DMA_Cmd(DMA_CHx,ENABLE); //使能USART1 TX DMA1 所指示的通道

 

}

 


四、使用例程 

#include "key.h"

#include "sys.h"

#include "usart.h"  

#include "dma.h"

#include "led.h"

#include "delay.h" 

 

 

#define SEND_BUF_SIZE 8200  //发送数据长度,最好等于sizeof(TEXT_TO_SEND)+2的整数倍   因为后面加了两个还行字符n。为了保证打印出来的是完整的句子

 

u8 SendBuff[SEND_BUF_SIZE];//确定发送数据内存空间

 

const u8 TEXT_TO_SEND[]={"Welcom to learn DAM 串口实验"};    //定义一个要传输的内容

 

int main(void)

{

  u16 j,i,mask=0,t;

float pro=0;         //显示传输进度

 

uart_init(115200);  //定义串口波特率为115200

KEY_Init();        //初始化按键

LED_Init();

delay_init();

MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,SEND_BUF_SIZE);//DMA1配置初始化

  j=sizeof(TEXT_TO_SEND);       //求取要传输的字符串长度便于存入一个新的长组数时加入换行符

  for(i=0;i {

   if(t>=j)   //如果一个小数组传输完成

{

if(mask)

{

SendBuff[i]=0x0a;   //换行符ASCII

t=0;

}

else

{  

SendBuff[i]=0x0d;    //回车键ASCII

mask++;

}

}

else

{

mask=0;

SendBuff[i]=TEXT_TO_SEND[t];  //将字符串传进大数组

t++;

}

}  

i=0;

LED0=0;

  while(1)

{

  t=KEY_Scan(0);

if(t==KEY0_PRES)

{

LED1=0; //提示案件进入

  USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);  //使能串口1发送端,等待发送

  MYDMA_Enable(DMA1_Channel4);  //使能DMA1通道4,开始传输

 

while(1)

    {

if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET)    //判断通道4传输完成

{

DMA_ClearFlag(DMA1_FLAG_TC4);  //如果传输完成,那么清除通道4传输完成标志

break; 

    }

 

  pro=DMA_GetCurrDataCounter(DMA1_Channel4);//获取剩余多少数据未传完

pro=1-pro/SEND_BUF_SIZE; //传输进度百分比

pro*=100;            //传输进度

}

}

i++;

delay_ms(10);

if(i==20)

{

LED0=!LED0;//提示系统正在运行

i=0;

}

}

 

 

}



推荐阅读

史海拾趣

FILTRONIC公司的发展小趣事

FILTRONIC公司成立于上世纪90年代初,正值通信技术快速发展的时期。公司初创时便聚焦于滤波器技术的研发与生产,针对当时市场对高性能滤波器的迫切需求,FILTRONIC的研发团队通过不断试验与优化,成功开发出了一款具有创新性的高性能滤波器产品。这款滤波器在频率选择性和插入损耗方面表现出色,迅速获得了市场的认可,为FILTRONIC在电子行业中站稳脚跟奠定了坚实的基础。

E Connector Solutions公司的发展小趣事

随着公司业务的不断发展,E Connector Solutions公司开始积极拓展市场。公司通过参加国际展会、与海外客户建立合作关系等方式,逐步打开了国际市场的大门。同时,公司还积极实施国际化战略,通过设立海外研发中心、生产基地等方式,加强与全球客户的合作与交流。这些举措不仅拓宽了公司的业务范围,还提升了公司的国际竞争力。

DIOTEC公司的发展小趣事

为了进一步完善全球产业布局,DIOTEC于2007年在印度普纳建立了新的生产基地。这座工厂紧邻印度的“门户城市”孟买,为DIOTEC在印度市场的拓展提供了有力支持。印度工厂的投产,不仅加强了DIOTEC在全球市场的竞争力,也进一步巩固了其在亚洲市场的地位。

长运通(CYT)公司的发展小趣事

深圳市长运通光电技术有限公司(简称长运通或CYT)成立于2003年11月,总部设在深圳这座充满创新活力的城市。公司从最初只有几名员工的初创团队,逐步发展成为在电源管理IC和LED光源领域具有影响力的企业。长运通在初创阶段就明确了自身的市场定位,致力于为客户提供高品质的电源解决方案和LED照明产品。通过不断努力,公司逐渐在市场上建立了良好的口碑。

Defender Security公司的发展小趣事

随着网络安全问题的全球化趋势日益明显,Defender Security公司开始积极拓展国际市场。他们与多家国际知名的网络安全企业建立了合作关系,共同应对全球网络安全挑战。通过技术交流和合作研发,Defender Security不断提升自己的国际竞争力,逐渐成为了全球网络安全领域的重要力量。

Deutron Electronics Corp公司的发展小趣事

随着环保意识的日益提高,Deutron Electronics Corp也积极响应环保号召,致力于实现绿色生产和可持续发展。公司采用环保材料和生产工艺,减少了对环境的污染。同时,公司还加大了对节能减排的投入,提高了资源利用效率。这些努力使得Deutron Electronics Corp在行业内树立了良好的环保形象,也为公司的长期发展奠定了坚实基础。

问答坊 | AI 解惑

请问谁有labview8.2的安装软件啊?

如题,请问谁有labview8.2的安装软件啊?我刚开始学,网上看到的下载网址都打不开,谁有的给我共享一下,谢谢。…

查看全部问答>

谁有51内核无线模块NRF905或NRF2401 C程序

谁有51内核无线模块NRF905或NRF2401 C程序…

查看全部问答>

空调语音解决方案

本帖最后由 jameswangsynnex 于 2015-3-3 19:58 编辑 空调语音解决方案 空调是我们每个人都不可缺少的生活用品,在竞争激烈的今天,怎样做出一款更适应市场的好空调,则是每个厂商苦恼的问题,更新和创新是一个企业发展和生存的源泉动力,市面 ...…

查看全部问答>

门禁系统技术与应用浅析

禁产品在远古时代就已经存在,它作为人身财产安全防范的首道防线,是人们生活、工作的必备品。从一把锁、一道门等机械产品发展到网络化、集成化、智能化的现代门禁产品,可谓经历了千锤百炼,才练就出如今的本领。   今天的门禁产品,已经从单纯 ...…

查看全部问答>

stm32f103+ucosII2.88运行一段时间后死机

最近在stm32f103VE上跑官方移植的ucosII2.88 ,刚开始运行的时候,系统一切正常,各个任务正常调度,大概可以持续5~7小时。但是>14小时连续运行之后,系统就不正常了,现象是:各个中断可以正常进入(通过观察led),但是有些任务已经不运行了 ...…

查看全部问答>

uboot-2009.08.tar.bz2移植到TQ2440

依据上几次搭建的环境进行uboot的移植,出现了一些错误,我特此做出一些总结,已经将编译器转换到旧一点的arm-linux-gcc-4.3.2,具体的原因是为什么,我查找了天嵌的网站说需要转换到3.4版本的编译器,因此我改用了友善之臂的uboot-2009.08.tar.bz2 ...…

查看全部问答>

《MSP430系列常用模块应用原理》 入门不难

买板送的资料,里面详细介绍寄存器的每位,类似于51,avr和stm32的资料,配合149的中文头文件看,入门不难。请看下面几行,有个印象再看配合看电子书和149的中文头文件。   int main(void) {       WDTCTL = WDT ...…

查看全部问答>

常见三防漆固化后的去除方法

三防漆固化后的线路板还有可能会返修,这就需要把漆膜去除掉,然后才能更换元件。这里列举几种常见三防漆的去除方法。         一,加热法,不到万不得已不建议采用此方法。加热法的具体操作是,一般采用 ...…

查看全部问答>

ALTERA Cyclone Ⅲ板子上能否将输入变成输出??

现在手里有一个 板子 上面有5*8个按键开关 请问下 是否能将开关焊下 接上LED灯 如果可以 能在Quartus 软件上改么 ?…

查看全部问答>

LED照明调光器

这LED调光器一般是调电流还是电压也,是一个什么过程或是原理也。…

查看全部问答>