一、微项目实现目标:
由于ADC多通道采集在规则组中只有一个寄存器CR,实际上在多通道采集时刻,需要把每一个同都的数据及时传出,否则上一个通道的数据会被当前通道的数据给覆盖掉。
二、微项目硬件配置需求:
stm32F103C8T6核心板一块
0.96寸OLED显示,用于显示计数
三、前置知识:
1,传输数据流:
外部GPIO采集----ADC转化执行-----存放到CR寄存器中-----触发DMA转移信号----DMA硬件触发开始转移数据-----从外设寄存器DR转移到SRAM的数组中
2,
四、代码逻辑分析:
① 启动GPIO时钟、启动DMA1时钟、启动ADC1时钟(由于ADC最大14MHZ,还需要进行一次分频处理);
②初始化GPIO模块,本实验采用4路,分别是PA0-PA3上;配置模拟输入模式
③配置ADC输入通道开启,使用ADC_Channel_0到ADC_Channel_3,分别放置在规则组1-3通道上;
④配置ADC模块,
需要注意:1)触发模式---硬件触发;2)开启循环模式,转化完成后,重新开下一轮转化;3)开启扫描模式,表示转化序列组中依次进行转化;4)转化通道数配置4
⑤DMA通道配置。
需要注意:1)数据源起始地址选择(uint32_t)&ADC1->DR;2)数据源采用16位的半字传输;3)不自增模式,即一直在这寄存器内取数据;
4)接受方地址选择(uint32_t)arr,存放到SRAM数组中;5)接收方采用16位半字接受;6)启动自增模式;
7)配置计数器值4位;8)传输模式,采用循环传输;其余正常配置
⑥开启ADC触发DMA通道,以完成一个通道后,产生DMA转移的硬件请求信号;
⑦开启ADC电源和DMA电源
⑧配置ADC校准
⑨软件触发启动ADC
五、代码示例:
① 启动GPIO时钟、启动DMA1时钟、启动ADC1时钟(由于ADC最大14MHZ,还需要进行一次分频处理);
//打开ADC1时钟 和GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//配置ADC1的分频,ADC最高支持14mhz
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//打开DMA1时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
②初始化GPIO模块,本实验采用4路,分别是PA0-PA3上;配置模拟输入模式
/初始化GPIO模块,模拟输入模式
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0 |GPIO_Pin_1 |GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
③配置ADC输入通道开启,使用ADC_Channel_0到ADC_Channel_3,分别放置在规则组1-3通道上;
//配置ad输入通道
ADC_RegularChannelConfig( ADC1, ADC_Channel_0 , 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig( ADC1, ADC_Channel_1 , 2, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig( ADC1, ADC_Channel_2 , 3, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig( ADC1, ADC_Channel_3 , 4, ADC_SampleTime_55Cycles5);
④配置ADC模块,
需要注意:1)触发模式---硬件触发;2)开启循环模式,转化完成后,重新开下一轮转化;3)开启扫描模式,表示转化序列组中依次进行转化;4)转化通道数配置4
//初始化AD模块
ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.ADC_ContinuousConvMode=ENABLE;//循环模式
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right ;//转化后在寄存器内右对齐
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None ;//软件触发,不使用硬件触发转化
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//独立模式
ADC_InitStruct.ADC_NbrOfChannel=4;
ADC_InitStruct.ADC_ScanConvMode=ENABLE;//扫描模式
ADC_Init( ADC1, &ADC_InitStruct);
⑤DMA通道配置。
需要注意:1)数据源起始地址选择(uint32_t)&ADC1->DR;2)数据源采用16位的半字传输;3)不自增模式,即一直在这寄存器内取数据;
4)接受方地址选择(uint32_t)arr,存放到SRAM数组中;5)接收方采用16位半字接受;6)启动自增模式;
7)配置计数器值4位;8)传输模式,采用循环传输;其余正常配置
/DMA初始化
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)&ADC1->DR;
DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)arr;
DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord ;
DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_BufferSize=4;//传输计数器的值
DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC ;//方向
DMA_InitStruct.DMA_M2M=DMA_M2M_Disable ;//存储器到存储器、存储器到外设
DMA_InitStruct.DMA_Mode=DMA_Mode_Circular ;
//是否循环传输;在存储器到存储器模式下,不可循环传输
DMA_InitStruct.DMA_Priority=DMA_Priority_Medium ;
DMA_Init( DMA1_Channel1, &DMA_InitStruct);
⑥开启ADC触发DMA通道,以完成一个通道后,产生DMA转移的硬件请求信号;
//开启ADC-DMA硬件触发
ADC_DMACmd( ADC1,ENABLE);
⑦开启ADC电源和DMA电源
//开启adc电源
ADC_Cmd(ADC1,ENABLE);
//开启DMA电源
DMA_Cmd(DMA1_Channel1, ENABLE);
⑧配置ADC校准文章来源:https://www.toymoban.com/news/detail-598427.html
//ADC校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1)==SET);//完成后会被硬件置为reset
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1)==SET);
⑨软件触发启动ADC文章来源地址https://www.toymoban.com/news/detail-598427.html
ADC_SoftwareStartConvCmd( ADC1, ENABLE);//软件触发ADC转换
到了这里,关于STM32-微项目10-ADC多通道采集+DMA数据转移的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!