炒冷饭系列-STM32F103之DMA

本文深入探讨了STM32F103的DMA功能,详细解析了如何配置和使用DMA进行数据传输,包括设置通道、优先级、传输类型等关键步骤,旨在帮助开发者更高效地利用STM32的外设资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "lsens.h"
#include "adc.h"
#include "dac.h"
//#include "pwmdac.h"


#define SEND_BUF_SIZE 8200
u8 SendBuff[SEND_BUF_SIZE]; //发送数据缓冲区
u16 DMA1_MEM_LEN;//保存 DMA 每次数据传送的长度

const u8 TEXT_TO_SEND[]={"GTXY CHENLEYOU STM32F1 DMA 串口实验"};
void dmaInit(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr);
void dmaEnable(DMA_Channel_TypeDef* DMA_CHx);
 int main(void)
{	
	
//	 u16 pwmval=0;
//	u16 adcx=0;
	 u8 j,mask=0;
	 u8 key=0;
	 u16 i=0;
	float pro=0;//进度
	u8 t=0;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	LED_Init();			     //LED端口初始化
	KEY_Init();
	LCD_Init();
	
	
	dmaInit(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,SEND_BUF_SIZE);
	j=sizeof(TEXT_TO_SEND);	   
	for(i=0;i<j;i++)//填充数据到SendBuff
  {

			SendBuff[i]=TEXT_TO_SEND[i];
  }	

	SendBuff[i+1]=0x0a;		
	SendBuff[i+2]=0x0d;
	
	while(1) 
	{	
		key=KEY_Scan(0);
		if(key==KEY0_PRES)//KEY0按下
		{
			LCD_ShowString(30,150,200,16,16,"Start Transimit....");
			LCD_ShowString(30,170,200,16,16,"   %");//显示百分号
			printf("\r\nDMA DATA:\r\n");
			USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能串口1的DMA发送  
			dmaEnable(DMA1_Channel4);

			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;      //扩大100倍
				LCD_ShowNum(30,170,pro,3,16);	  
			
			}
			
			LCD_ShowNum(30,170,100,3,16);//显示100%	  
			LCD_ShowString(30,150,200,16,16,"Transimit Finished!");//提示传送完成
		}
	}		
}

//DMA1 的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8 位数据宽度/存储器增量模式
//DMA_CHx:DMA 通道 CHx
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量

void dmaInit(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
	
	DMA_InitTypeDef DMA_InitStruct;
	//1、DMA1时钟初始化
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	//2、DMA1配置   DMA1_CH4->USART1_TX
	DMA_DeInit(DMA_CHx);//DMA1_Channel4
	
	
	DMA1_MEM_LEN=cndtr;
	
	//DMA_InitStruct.DMA_PeripheralBaseAddr=;
	DMA_InitStruct.DMA_PeripheralBaseAddr=cpar;//&USART1->DR;//DMA 外设 ADC 基地址
	DMA_InitStruct.DMA_MemoryBaseAddr=cmar;//SendBuff; //DMA 内存基地址
	DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;//数据传输方向内存到外设
	DMA_InitStruct.DMA_BufferSize=cndtr;//SEND_BUF_SIZE;//DMA 通道的 DMA 缓存的大小
	DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址不变
	DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;//内存地址寄存器递增
	DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//数据宽度为 8 位
	DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//数据宽度为 8 位
	
	DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;//工作在正常缓存模式
	DMA_InitStruct.DMA_Priority=DMA_Priority_Medium; //DM 通道拥有中优先级
	DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;//非内存到内存传输
	DMA_Init(DMA_CHx,&DMA_InitStruct);//DMA1_Channel4
}

//开启一次DMA传输
void dmaEnable(DMA_Channel_TypeDef* DMA_CHx)
{
	DMA_Cmd(DMA_CHx,DISABLE);//关闭上一次的传输
	DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN); //设置 DMA 缓存的大小
	DMA_Cmd(DMA_CHx,ENABLE);//开启一次的传输
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值