一位萌新为参加robomaster所做的前期准备–stm32基础(四)(DMA串口发送)

一位萌新为参加robomaster所做的前期准备–stm32基础(四)(DMA串口发送)


一、 实验目的:通过按键来控制DMA向串口发送数据,并将数据在pc端打印出来。DMA作用:为CPU减负(串口的发送不需要经过cpu)。
二、 方案:
① 实验需要运用按键,故需配置按键相关引脚(结构体,时钟,参数等)
② 需要串口发送,故需配置串口相关信息(打开串口时钟及发送时钟,串口的相关参数,使能串口)
③ 需要调试DMA相关参数(打开DMA时钟,外设基址,内存基址,传输大小,使能DMA等)
三、 流程图

在这里插入图片描述
四、 相关函数

//主函数
 int main(void){
	key_init();   //配置按键参数,打开按键
	port_init();    //配置串口参数,打开串口
	MYDMA_Config();   //配置DMA参数
	while(1){
		if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)==0){
			sw_delay_ms(250);
			USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
//打开串口的DMA发送功能
			DMA_Enable();   //打开DMA传送
		}
	}
}

//DMA相关参数配置函数
u8 TEXT_TO_SEND[]={"Hello world!"}; 
//设置一个数组来存放内存数据
#define TEXT_LENTH  sizeof(TEXT_TO_SEND)   
       //设置变量来储存数据长度
void MYDMA_Config(){
	DMA_InitTypeDef DMA_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	//打开DMA时钟
		DMA_DeInit(DMA1_Channel4);   
//将 DMA 的通道 1 寄存器重设为缺省值(可以省去)
	DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&USART1->DR;  
// DMA 外设基地址:(u32)&USART1->DR
	DMA_InitStructure.DMA_MemoryBaseAddr=(u32)TEXT_TO_SEND;
// DMA 内存基地址(发送缓冲区首地址)
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;
//数据传输方向:内存到外设
	DMA_InitStructure.DMA_BufferSize=TEXT_LENTH;
// DMA 通道的 DMA 缓存的大小(需要发送的字节数)
	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
//外设地址不变
	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
//内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
//外设数据宽度8位
	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
//内存数据宽度8位
	DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
    //模式:单次传输模式,不循环 
	DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;
//优先级设置(中级)
	DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
//非内存到内存传输
	
	DMA_Init(DMA1_Channel4,&DMA_InitStructure);
//初始化 DMA 的通道
}

void DMA_Enable(void){    //打开DMA
	DMA_Cmd(DMA1_Channel4,DISABLE);   
//先关闭DMA传送(先设置 DMA 缓存的大小,要关闭通道)
	DMA_SetCurrDataCounter(DMA1_Channel4,TEXT_LENTH);
    //设置 DMA 缓存的大小
	DMA_Cmd(DMA1_Channel4,ENABLE); 
    //使能 USART1 TX DMA1 所指示的通道
}

五、相关知识
① STM32 最多有 2 个 DMA 控制器(DMA2 仅存在大容量产品中), DMA1 有 7 个通道。 DMA2 有 5个通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁起来协调各个 DMA 请求的优先权。在七个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低)
② 独立的源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程,源和目标地址必须按数据传输宽度对齐。
③ 每个通道都有 3 个事件标志(DMA 半传输, DMA 传输完成和 DMA 传输出错),这 3 个事件标志逻辑或成为一个单独的中断请求。(该实验没有使用)

在这里插入图片描述

1)数据传输的目的地和来源
在这里插入图片描述
2)定义DMA通道的DMA缓存的大小
3)外设地址寄存器递增与否
在这里插入图片描述
4)内存地址寄存器递增与否
在这里插入图片描述
5)设定了外设数据宽度
在这里插入图片描述
6)设定了内存数据宽度
在这里插入图片描述
7)设置了DMA的工作模式
在这里插入图片描述
8)DMA通道的软件优先级
在这里插入图片描述
9)使能或关闭DMA通道的内存到内存传输
在这里插入图片描述
⑥DMA常用库函数
void DMA_Init()
//初始化DMA
void DMA_Cmd()
//打开DMA通道
void DMA_ITConfig()
//打开DMA中断通道
DMA_SetCurrDataCounter()
//返回当前 DMA 通道 x 剩余的待传输数据数目
USART_DMACmd()
//打开串口的DMA功能
六、 总结
本次实验主要了解了DMA的工作原理,熟悉DMA向串口发送数据的流程及相关配置,本实验关键在于对DMA的参数进行相关配置(外设地址,内存地址,传输大小,传输模式等)
DMA配置程序过程:
① 使能DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
② 初始化DMA通道参数
DMA_Init(DMA1_Channel4,&DMA_InitStructure);
③ 使能串口DMA1发送,串口DMA使能函数
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
④ 使能DMA1通道,启动传输
DMA_Cmd(DMA1_Channel4,ENABLE);

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值