IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于STM32F407的DMA解析-ADC单通道DMA读取数据 -> 正文阅读

[嵌入式]基于STM32F407的DMA解析-ADC单通道DMA读取数据

目录

一:什么是DMA??

1.DMA简介:

2.DMA数据流与通道:

3.工作原理 :

二:实验代码及实验效果

2.1? ADC基本配置:

2.2 DMA基本配置:

2.3 主函数:

2.4 实验结果——串口接收数据

?三:DMA代码详细解及注意事项

?3.1 ADC代码段:

3.2DMA代码段:


?

一:什么是DMA??

1.DMA简介:

?????? DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。

????? STM32F407ZGT6 有 2 个 DMA 控制器(DMA1 和 DMA2),共 16 个数据流(每个控制器 8 个),每一个 DMA 控制器都用于管理一个或多个外设的存储器访问请求。每个数据流有 8个通道(或称请求)。每个数据流通道都有一个仲裁器,用于处理 DMA 请求间的优先级。

2.DMA数据流与通道:

????? 每个DMA有八个数据流,而8个数据流中的每一个都连接到专用硬件 DMA 通道(请求),DMA 数据流请求之间的优先级可用软件编程(4 个级别:非常高、高、中、低),在软件优先级相同的情况下可以通过硬件决定优先级(例如,请求 0 的优先级高于请求 1),每个数据流也支持通过软件触发存储器到存储器的传输(仅限 DMA2 控制器),可供每个数据流选择的通道请求多达 8 个。此选择可由软件配置,允许几个外设启动 DMA请求。

????? 在设置DMA数据流与通道的时候要按照数据手册当中的对应关系进行配置。

3.工作原理 :

?????? 在产生事件后,外设会向 DMA 控制器发送请求信号。DMA 控制器根据通道优先级处理该请求。只要 DMA 控制器访问外设,DMA 控制器就会向外设发送确认信号。外设获得 DMA 控制器的确认信号后,便会立即释放其请求。一旦外设使请求失效,DMA 控制器就会释放确认信号。如果有更多请求,外设可以启动下一个事务。?

二:实验代码及实验效果

2.1? ADC基本配置:

#include "adc.h"
#include "delay.h"		 


//初始化ADC															   
void  Adc_Init(void)
{    
    GPIO_InitTypeDef  GPIO_InitStructure;
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	ADC_InitTypeDef       ADC_InitStructure;
	
    /*使能 GPIOA ADC1 时钟*/
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 

    /*先初始化ADC1通道5 IO口*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);	  
	RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);	 
 
	/*ADC基本配置*/
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //DMA失能
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;//预分频4分频
    ADC_CommonInit(&ADC_CommonInitStructure);//初始化
	
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式	
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//关闭连续转换
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐	
    ADC_InitStructure.ADC_NbrOfConversion = 1;//1个转换在规则序列中 也就是只转换规则序列1 
    ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化
	ADC_Cmd(ADC1, ENABLE);//开启AD转换器	


    /*ADC1,ADC通道,480个周期,提高采样时间可以提高精确度*/
	ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_480Cycles );
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
    ADC_DMACmd(ADC1, ENABLE);
    /*使能指定的ADC1的软件转换启动功能	*/
	ADC_SoftwareStartConv(ADC1);	

}				  

2.2 DMA基本配置:

u32 ADC_ConvertedValue;

void Dma_Init(void)
{
    DMA_InitTypeDef DMA_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); 
	/*外设基址为:ADC 数据寄存器地址*/
	DMA_InitStructure.DMA_PeripheralBaseAddr = ((u32)ADC1+0x4c);	
    /*存储器地址,实际上就是一个内部SRAM的变量*/
	DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&ADC_ConvertedValue;  
    / 数据传输方向为外设到存储器*/
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;	
	/* 缓冲区大小为,指一次传输的数据量*/
	DMA_InitStructure.DMA_BufferSize = 1;	
	/*外设寄存器只有一个,地址不用递增*/
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    /*存储器地址固定*/
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 
    /*外设数据大小为半字,即两个字节*/
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 
    /*存储器数据大小也为半字,跟外设数据大小相同*/
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;	
	/*循环传输模式*/
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    /*DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响*/
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    /*禁止DMA FIFO,使用直连模式*/
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;  
    /*FIFO 大小,FIFO模式禁止时,这个不用配置*/	
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
	/* 选择 DMA 通道,通道存在于流中*/
    DMA_InitStructure.DMA_Channel = DMA_Channel_0; 
    /*初始化DMA流,流相当于一个大的管道,管道里面有很多通道*/
	DMA_Init(DMA2_Stream0, &DMA_InitStructure);
	/*使能DMA流*/
    DMA_Cmd(DMA2_Stream0, ENABLE);

}

2.3 主函数:

int main(void)
{ 
	extern u32 ADC_ConvertedValue;
	float temp;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);    //初始化延时函数
	uart_init(115200);	//初始化串口波特率为115200
	Adc_Init();         //初始化ADC
    Dma_Init();   
	while(1)
	{ 
    printf ("V:%d\r\n",ADC_ConvertedValue);
		delay_ms(500);	
	}
}

2.4 实验结果——串口接收数据

分别对应引脚悬空、连接GND、连接3v3时的输出数据

?

?三:DMA代码详细解及注意事项

?3.1 ADC代码段:

相比无DMA的ADC配置代码,这里要多配置以下代码:

/*开启ADC DMA 请求*/
ADC_DMACmd(ADC1, ENABLE);
/*启用或禁用上次传输后的ADC DMA请求*/
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

3.2DMA代码段:

?????? 首先要关注传输方向,这里我们需要将ADC转换完成的数据传递到cpu内部寄存器,所以为外设到寄存器。

/*数据传输方向为外设到存储器*/	
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;	

?????? 其次要关注寄存器地址与外设地址,寄存器地址在这里为变量,所以取地址。

/*存储器地址,实际上就是一个内部SRAM的变量	*/
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&ADC_ConvertedValue;  

?????? 外设在这里有对应的寄存器,地址为基地址+偏移地址,如果要更改ADC通道,要修改相应的寄存器地址,可以在中文参考手册里查找。

/*外设基址为:ADC 数据寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = ((u32)ADC1+0x4c);	

?????? 寄存器地址与外设地址,在这里我们只传递了ADC1的数据,单对单,所以两个地址都不需要递增

/*外设寄存器只有一个,地址不用递增*/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
/*存储器地址固定*/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; 

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-23 16:51:02  更:2021-08-23 16:53:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:43:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码