stm32下f4的adc_dma采集
2016-11-03 13:56
761 查看
网上有很多关于stm32f103的资料,甚至在网上买各种模块商家给你提供的资料都是f103和51的,但是f4的资料相比之下就 比较可怜,当初我写这个程序也是废了不少时间翻了好多资料才写成的,特此拿出来和大家分享一下。
首先是 找到adc的地址,#define ADC1_DR_ADDRESS ((uint32_t)0x4001204C)
由于用的是库函数版本,所以需要引用dma
extern __IO uint16_t ADC1ConvertedValue[6];
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能 ADC1, DMA2 和 GPIO 时钟 ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* DMA2 Stream0 channel0 配置 **************************************/
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //数据流2,通道0
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS; //外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC1ConvertedValue; //内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存
DMA_InitStructure.DMA_BufferSize = 6; //传输4位
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //不增加外设寄存器
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存可增加
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设格式
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存格式
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不用fifo
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //单次突发模式
/*DMA都是为了成批传输数据的,不论单次DMA 和突发DMA。不同的是每次传输一个单元数据(比如使用32bit数据位宽,每单元为32bit;比如使用8bit数据位宽,每单元为8bit)所用的时钟数。突发DMA是每个时钟都传输一个单元数据的连续传输;而单次DMA则不是,需要几个时钟才传输一个数据单元。*/
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//单次突发模式
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
/* 配置ADC1通道3、5引脚为模拟输入模式******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ADC公共部分初始化**********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //分频
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //不配置成直接内存访问
/*先存在adc的寄存器里,在传输出去,所以不直接访问内存*/
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; //两个采样间断之间的延迟
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 初始化 ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //连续扫描模式,多通道必开
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启转换模式
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//没有外部触发,用软件触发
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfConversion = 6;// yuan 2,四个通道
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 规则 channel3、5 配置 *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 4, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 5, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 6, ADC_SampleTime_84Cycles);
/* 使能DMA请求(单ADC模式) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* 使能 ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* 软件启动ADC转换 */
ADC_SoftwareStartConv(ADC1);
}
我开了6个ad如上面代码所示,选择软件开启,调用函数的时候变量里面就有值了。
首先是 找到adc的地址,#define ADC1_DR_ADDRESS ((uint32_t)0x4001204C)
由于用的是库函数版本,所以需要引用dma
extern __IO uint16_t ADC1ConvertedValue[6];
void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能 ADC1, DMA2 和 GPIO 时钟 ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
/* DMA2 Stream0 channel0 配置 **************************************/
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //数据流2,通道0
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS; //外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC1ConvertedValue; //内存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //外设到内存
DMA_InitStructure.DMA_BufferSize = 6; //传输4位
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //不增加外设寄存器
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存可增加
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设格式
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存格式
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不用fifo
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //单次突发模式
/*DMA都是为了成批传输数据的,不论单次DMA 和突发DMA。不同的是每次传输一个单元数据(比如使用32bit数据位宽,每单元为32bit;比如使用8bit数据位宽,每单元为8bit)所用的时钟数。突发DMA是每个时钟都传输一个单元数据的连续传输;而单次DMA则不是,需要几个时钟才传输一个数据单元。*/
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//单次突发模式
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE);
/* 配置ADC1通道3、5引脚为模拟输入模式******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4| GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* ADC公共部分初始化**********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //分频
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //不配置成直接内存访问
/*先存在adc的寄存器里,在传输出去,所以不直接访问内存*/
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles; //两个采样间断之间的延迟
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 初始化 ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //12位模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //连续扫描模式,多通道必开
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //开启转换模式
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//没有外部触发,用软件触发
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //右对齐
ADC_InitStructure.ADC_NbrOfConversion = 6;// yuan 2,四个通道
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 规则 channel3、5 配置 *************************************/
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 4, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 5, ADC_SampleTime_84Cycles);
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 6, ADC_SampleTime_84Cycles);
/* 使能DMA请求(单ADC模式) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* 使能 ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* 使能 ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* 软件启动ADC转换 */
ADC_SoftwareStartConv(ADC1);
}
我开了6个ad如上面代码所示,选择软件开启,调用函数的时候变量里面就有值了。
相关文章推荐
- stm32ADC非DMA模式的多通道采集与注入通道的采集
- 【STM32】用DMA实现多路ADC通道数据采集
- stm32 双adc 采集问题 dma数据有一个没有 adc2为0
- stm32 多通道ADC+DMA采集
- STM32 F4 ADC DMA Temperature Sensor
- STM32 DMA 多通道 ADC 采集
- STM32采集多路ADC到DMA的方法
- STM32的ADC1+ADC3 16路采集 DMA传输 数据不错位
- stm32之TIM+ADC+DMA采集50HZ交流信号
- [置顶] STM32的ADC1采集多条通道,可以不使用DMA功能吗?
- STM32L152 ADC单通道采集模拟量
- STM32F4 ADC采集数据的DMA数据传输【库函数操作】
- STM32之DMA+ADC
- STM32之ADC_2(DMA实例)
- 关于STM32 ADC DMA 使用心得(2)
- stm32之adc双通道的实现dma
- STM32学习笔记-ADC采集-串口2发送至上位机
- STM32 DMA USART ADC
- STM32L073RZ进行两路AD电压信号采集(非DMA方式)
- 11、STM32 的 DMA 使用 - ADC 采用 DMA 模式