历史上的今天
今天是: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; } } }
史海拾趣
|
禁产品在远古时代就已经存在,它作为人身财产安全防范的首道防线,是人们生活、工作的必备品。从一把锁、一道门等机械产品发展到网络化、集成化、智能化的现代门禁产品,可谓经历了千锤百炼,才练就出如今的本领。 今天的门禁产品,已经从单纯 ...… 查看全部问答> |
|
最近在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 ...… 查看全部问答> |
|
买板送的资料,里面详细介绍寄存器的每位,类似于51,avr和stm32的资料,配合149的中文头文件看,入门不难。请看下面几行,有个印象再看配合看电子书和149的中文头文件。 int main(void) { WDTCTL = WDT ...… 查看全部问答> |
|
三防漆固化后的线路板还有可能会返修,这就需要把漆膜去除掉,然后才能更换元件。这里列举几种常见三防漆的去除方法。 一,加热法,不到万不得已不建议采用此方法。加热法的具体操作是,一般采用 ...… 查看全部问答> |
|
ALTERA Cyclone Ⅲ板子上能否将输入变成输出?? 现在手里有一个 板子 上面有5*8个按键开关 请问下 是否能将开关焊下 接上LED灯 如果可以 能在Quartus 软件上改么 ?… 查看全部问答> |




