STM32之DMA

该代码示例展示了如何在STM32中配置DMA进行内存到外设(MtM)、外设到内存(PtM)以及串口发送和接收的数据传输。程序初始化了不同的DMA通道,如DMA1_Channel4和DMA1_Channel6,用于串口的发送和接收。在内存到串口的传输中,数据从内存数组发送到串口的数据寄存器。同时,还启用了串口的DMA传输功能。
摘要由CSDN通过智能技术生成
void MtM_DMA(void)
{
	DMA_InitTypeDef DMA_InitStrcut;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	DMA_InitStrcut.DMA_PeripheralBaseAddr = (uint32_t)A1S;
	DMA_InitStrcut.DMA_MemoryBaseAddr = (uint32_t)A2D;
	DMA_InitStrcut.DMA_DIR = DMA_DIR_PeripheralSRC;
	
	DMA_InitStrcut.DMA_BufferSize = BUFFER_SIZE;
	DMA_InitStrcut.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
	DMA_InitStrcut.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
	
	DMA_InitStrcut.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStrcut.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
	
	DMA_InitStrcut.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStrcut.DMA_Priority = DMA_Priority_High;
	DMA_InitStrcut.DMA_M2M = DMA_M2M_Enable;
	
	DMA_Init(DMA1_Channel6, &DMA_InitStrcut);
	DMA_Cmd(DMA1_Channel6, ENABLE);
	
}



void PtM_DMA(void)//此情况是串口发给内存(串口是作为发送方SRC)
{
	DMA_InitTypeDef DMA_InitStrcut;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	DMA_DeInit(DMA1_Channel4);
	DMA_InitStrcut.DMA_PeripheralBaseAddr = (uint32_t)USART_DR_ADDRESS;
	DMA_InitStrcut.DMA_MemoryBaseAddr = (uint32_t)REData;
	DMA_InitStrcut.DMA_DIR = DMA_DIR_PeripheralSRC;
	
	DMA_InitStrcut.DMA_BufferSize = 1;
	DMA_InitStrcut.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStrcut.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	
	DMA_InitStrcut.DMA_MemoryInc = DMA_MemoryInc_Disable;
	DMA_InitStrcut.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	
	DMA_InitStrcut.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStrcut.DMA_Priority = DMA_Priority_High;
	DMA_InitStrcut.DMA_M2M = DMA_M2M_Disable;
	
	DMA_Init(DMA1_Channel4, &DMA_InitStrcut);
	DMA_ClearFlag(DMA1_FLAG_TC4);
	DMA_Cmd(DMA1_Channel4, ENABLE);//串口1的RX通道(接收)
	
}

值得注意的是串口是与相应的DMA通道对应的,使能的时候要注意。
在这里插入图片描述
在这里插入图片描述
可以从表中看到,串口1的发送是在DMA1的通道4,而接收通道是在DMA1的通道5
最后需要使能串口的DMA命令

USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

这样就可以使用DMA通道了。

内存到外设

#include "dma.h"
extern int Data[100];
void MtP_DMA(void)//此情况是内存发给串口(串口是作为接收方DST)
{
	DMA_InitTypeDef DMA_InitStrcut;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	DMA_DeInit(DMA1_Channel4);
	DMA_InitStrcut.DMA_PeripheralBaseAddr = (uint32_t)(USART1_BASE+0x04);//串口1的数据寄存器的地址
	DMA_InitStrcut.DMA_MemoryBaseAddr = (uint32_t)Data1;
	DMA_InitStrcut.DMA_DIR = DMA_DIR_PeripheralDST;
	
	DMA_InitStrcut.DMA_BufferSize = 100;
	DMA_InitStrcut.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStrcut.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	
	DMA_InitStrcut.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStrcut.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	
	DMA_InitStrcut.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStrcut.DMA_Priority = DMA_Priority_High;
	DMA_InitStrcut.DMA_M2M = DMA_M2M_Disable;
	
	DMA_Init(DMA1_Channel4, &DMA_InitStrcut);
	DMA_ClearFlag(DMA1_FLAG_TC4);
	DMA_Cmd(DMA1_Channel4, ENABLE);//DMA1的通道4与串口1的TX通道连接(发送)
}

main.c文件

#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "systick.h"
#include "dma.h"
#include "uart.h"
#include <math.h>

int Data[100];

int main(void)
{
	int i = 0;
	key_init();
	led_init();
	
	USART1_Init(9600);
	for(i=0;i<100;i++)
	{
		Data[i] = 100*sin(2*3.14*0.01*i);
	}
	
	MtP_DMA();//在数据的下方
	USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
	while(1)
	{
		
		GPIO_SetBits(GPIOB, GPIO_Pin_0);
		GPIO_ResetBits(GPIOB, GPIO_Pin_1);
		delay_nms(500);
		GPIO_SetBits(GPIOB, GPIO_Pin_1);
		GPIO_ResetBits(GPIOB, GPIO_Pin_0);
		delay_nms(500);
	}


}

串口:

#include "uart.h"

//串口1初始化并启动
void USART1_Init(u32 bound)
	{ 
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
		USART_InitTypeDef USART_InitStructure;
		NVIC_InitTypeDef NVIC_InitStructure;	 
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);	//使能USART1,GPIOA时钟
		USART_DeInit(USART1);  //复位串口1
     //USART1_TX   PA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);  
    //USART1_RX	  PA.10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure); 
	
   //Usart1 NVIC 配置
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级1
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//子优先级1
		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
		NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器 
   //USART 初始化设置
		USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
		USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
		USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
		USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
		USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
		USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
    USART_Init(USART1, &USART_InitStructure); //初始化串口
		
		
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启ENABLE/关闭DISABLE中断
    USART_Cmd(USART1, ENABLE);                    //使能串口 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值