第三十天-DMA串口实验

一、DMA概述

二、DMA通道

注意,想要往串口中写数据,外部请求信号应该是USARTx_TX,当DR寄存器为空时,产生TX信号,请求DMA。反之,从串口中读数据,外部请求信号应该是USARTx_RX,当DR寄存器满时,产生RX信号,请求DMA。

三、DMA处理过程

四、DMA中断

五、相关寄存器

六、实验部分

1、实验要求

使用DMA,将内存中800个字节发送给串口。

2、详细代码

①dma.c

#include "dma.h"


void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
	//时钟使能
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	
	//初始化
	DMA_DeInit(DMA_CHx);
	DMA_InitTypeDef DMA_InitStruct;
	DMA_InitStruct.DMA_BufferSize = cndtr;
	DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
	DMA_InitStruct.DMA_MemoryBaseAddr =cmar;
	DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStruct.DMA_PeripheralBaseAddr = cpar;
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;
	DMA_Init(DMA1_Channel4, &DMA_InitStruct);
}

void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
	DMA_Cmd(DMA_CHx, DISABLE);
	DMA_SetCurrDataCounter(DMA_CHx,MAXNUM);
	USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
	DMA_Cmd(DMA_CHx, ENABLE);

}

②main.c

#include "stm32f10x.h"
#include "rtc.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "wkup.h"
#include "adc.h"
#include "tsensor.h"
#include "lsensor.h"
#include "dac.h"
#include "key.h"
#include "timer.h"
#include "dma.h"
#include "string.h"


 int main(void)
 {	u16 t = 0;
		char data[MAXNUM + 1] = {0};
	 	 
		char name[] = "我是春春大哥哥\r\n";
 
		for(u16 i = 0;i < MAXNUM / strlen(name);i++)
		{
			strcat(data,name);
		}
	 
		delay_init();
		uart_init(115200);
	 LED_Init();
	 KEY_Init();
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	 RTC_Init();
	 LCD_Init(); 
	 Adc_Init();
	 
		MYDMA_Config(DMA1_Channel4,(u32)&(USART1->DR),(u32)data,MAXNUM);
	
	 LCD_ShowString(60,120,200,24,24,"    -  -  ");
	LCD_ShowString(60,174,200,24,24,"  :  :  ");
	 
	 
	 while(1)
	 {
		 ++t;
		 if(t % 100 == 0)
		 {
			 LED0 =! LED0;
		 }
		 
		 u8 key = KEY_Scan(0);
		 
		 if(key == kup_pres)
		 {
			 MYDMA_Enable(DMA1_Channel4);
		 }
		 
		 delay_ms(10);
	 }
 }

3、代码调试

一定要注意,如果不是循环模式的话,当一次DMA结束后,DMA_BufferSize就会清0,并且该位为0时,DMA不工作。所以,每次使用DMA都要重设该值,并且重设该值之前要DIABLE CMD。

4、实验结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值