完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32F4 DMA(直接内存存取)
DMA原理 DMA即Direct Memory Access 直接存储器访问:将数据从一个地址复制到另一个地址,当CPU初始化DMA控制器后,传输动作由DMA控制器实现和完成 优点:无需CPU控制 或 中断压栈-出栈过程,让RAM与IO设备间可快速传输数据,减少CPU负载 stm32f4资源
对每个DMA数据流,在
2.重新使能数据流 3.设置外设端口寄存器地址 4.设置存储器地址 5.配置要传输的数据项总数,每出现一次外设时间或一个节拍的突发传输,该值就会递减 6.选择DMA通道 7.设置外设用作流控制器 8.配置数据流优先级 9.配置FIFO使用情况 10.配置数据传输方向 11.配置外设和存储器模式、突发事件、数据宽度、循环模式、双缓冲区模式、特殊情况中断等 12.使能数据流 只要使能数据流后即可响应连接到数据流的外设发出的任何DMA请求
2.初始化DMA通道参数 3.使能串口DMA发送 4.查询DMA的EN位,确保数据流就绪,可以配置 5.设置通道当前剩余数据量 6.使能DMA1通道,启动传输 7.查询DMA传输状态 8.获取/设置通道当前剩余数据量 dma.c #include "dma.h" //DMA_Streamx表示DMA数据流,只能选择DMA1或DMA2 //chx表示通道数 //par表示外设地址 //mar表示存储器地址 //ndtr表示数据传输量 void DMA_config(DMA_Stream_TypeDef* DMA_streamx,u32 chx,u32 par,u32 mar,u16 ndtr) { DMA_InitTypeDef DMA_InitStructure; //得到当前stream属于DMA1还是DMA2 if((u32)DMA_streamx>(u32)DMA2) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE); else RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE); //1. 将先前的数据块DMA传输在状态寄存器中置1的所有数据流专用的位 置0 DMA_DeInit(DMA_streamx); //2. 查询DMA的EN位,确保数据流就绪,等待配置 while(DMA_GetCmdStatus(DMA_streamx)!=DISABLE){} //3. 设置DMA属性 DMA_InitStructure.DMA_Channel=chx;//选择通道 DMA_InitStructure.DMA_PeripheralBaseAddr=par;//外设地址 DMA_InitStructure.DMA_Memory0BaseAddr=mar;//DMA 存储器0地址 DMA_InitStructure.DMA_DIR=DMA_DIR_MemoryToPeripheral;//选择模式:存储器mar>>外设par DMA_InitStructure.DMA_BufferSize=ndtr;//数据传输量 DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设增量模式关闭 DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;;//存储器增量模式开启 DMA_InitStructure.DMA_MemoryDataSize=DMA_PeripheralDataSize_Byte;//存储器数据长度:字节模式(8位) DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//普通模式 DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;//中等优先级 DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Disable;//FIFO模式:不使用FIFO DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_Full;//FIFO阈值设置:全满时停止加入FIFO DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;//存储器突发单次传输 DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;//外设突发单次传输 //应用设置 DMA_Init(DMA_streamx,&DMA_InitStructure); } void DMA_enable(DMA_Stream_TypeDef* DMA_streamx,u16 ndtr) { //4. 关闭DMA传输 DMA_Cmd(DMA_streamx,DISABLE); //5. 等待DMA可以被设置 while(DMA_GetCmdStatus(DMA_streamx)!=DISABLE){} //6. 设置数据传输量 DMA_SetCurrDataCounter(DMA_streamx,ndtr); //7. 开启DMA传输 DMA_Cmd(DMA_streamx,ENABLE); } dma.h #ifndef __DMA_H #define __DMA_H #include "sys.h" void DMA_config(DMA_Stream_TypeDef* DMA_streamx,u32 chx,u32 par,u32 mar,u16 ndtr);//DMA配置函数 void DMA_enable(DMA_Stream_TypeDef* DMA_streamx,u16 ndtr);//DMA使能函数 #endif main.c #include "sys.h" #include "delay.h" #include "usart.h" #include "dac.h" #include "dht11.h" #include "dma.h" #define SEND_BUF_SIZE 8200 //发送数据长度,最好等于sizeof(TEXT_TOSEND)+2的整数倍 u8 send_buff[SEND_BUF_SIZE]; const u8 TEXT_TO_SEND[]={"DMA test!"}; int main(void) { u16 i; u8 t=0; u8 j,mask=0; float process=0;//进度 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168);//初始化延时函数 uart_init(115200);//初始化串口波特率115200 LED_init(); LCD_init(); KEY_init(); //设置DMA:USART->DR >>DMA_Channel_4>> send_buff DMA_config(DMA2_Stream7,DMA_Channel_4,(u32)&USART1->DR,(u32)send_buff,SEND_BUF_SIZE); j=sizeof(TEXT_TO_SEND) //填充TEXT_TO_SEND到send_buff[] for(i=0;i if(t>=j)//加入换行符 { if(mask) { send_buff=0x0a; t=0; } else { send_buff=0x0d; mask++; } } else { mask=0; send_buff=TEXT_TO_SEND[t]; t++; } } i=0; while(1) { t=KEY_scan(0); if(t==KEY0_PRES)//KEY0按下 { printf("rnDMA DATA:rn"); LCD_ShowString(20,150,200,16,16,"Start Transimit..."); LCD_ShowString(30,170,200,16,16,"%");//显示进度百分号 //开启一次DMA传输 USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //等待DMA传输完成,在此期间可以执行其他任务 while(1) { if(DMA_GetCmdStatus(DMA2_Stream7,DMA_FLAG_TCIF7)!=RESET) { DMA_ClearFlag(DMA2_Stream7,DMA_FLAG_TCIF7); break; } process=DMA_GetCurrDataCounter(DMA2_Stream7);//得到当前剩余数据数量 process=1-process/SEND_BUF_SIZE;//得到百分比 process*=100;//扩大100倍进行显示 LCD_ShowNum(30,170,100,3,16); } LCD_ShowNum(30,170,100,3,16);//显示100% LCD_ShowString(20,150,200,16,16,"Tansimit Finished!");//提示传输完成 } i++; delay_ms(10); if(i==20) { LED0=!LED0; i=0; } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1561 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1501 浏览 1 评论
933 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
665 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1555 浏览 2 评论
1848浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
610浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
504浏览 3评论
508浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
489浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 17:15 , Processed in 0.498312 second(s), Total 44, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号