金牌会员
 
- 积分
- 1554
- 金钱
- 1554
- 注册时间
- 2017-10-9
- 在线时间
- 131 小时
|
本帖最后由 千湖 于 2020-6-23 14:42 编辑
ADC1:CH0、CH1
ADC2:CH2、CH3
双重规则模式,12Bit,右对齐,采样时间为28cycle[可修改],转换周期固定为12cycle;采样时钟21MHz,得到一个数据的时间为:(28+12)/21MHz = 1.9us,
采集到的数据存放在定义的数组中
uint16_t ADC_ConVal[MAX_LEN * (ADC1_CHN + ADC2_CHN)] = {0}; // ADC存储数据
使用DMA2流0通带0进行传输,软件触发转换!
/**
* @brief ADC采集数据存放的位置
* (n*i+ 0)的下标存放 CH0数据
* (n*i+ 1)的下标存放 CH2数据
* (n*i+ 2)的下标存放 CH1数据
* (n*i+ 3)的下标存放 CH3 数据
*/
uint16_t ADC_ConVal[MAX_LEN * (ADC1_CHN + ADC2_CHN)] = {0}; // ADC存储数据
/*====================单个ADC需要转换的通道数========*/
/**
* @brief ADC需要转换的通道数
*/
#define ADC1_CHN 2 // ADC1转换的通道数
#define ADC2_CHN 2 // ADC2转换的通道数
/*********************************************************/
/*==============一个周期内采集的次数========*/
/**
* @brief 一个周期内采集的次数
*/
#define MAX_LEN 1500
/*********************************************************/
/**
* @brief ADC初始化 采集上下行数据
* @param None
* @retval None
*/
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
/*=============================配置ADC对应的GPIO=============================*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); // 初始化GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; // PA0,PA1,PA2,PA3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; // 模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; // 不带上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*=============================DMA初始化=============================*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // 使能DMA2时钟
DMA_InitStructure.DMA_Channel = DMA_Channel_0; // 选择通道0
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC->CDR); // ADC->CDR寄存器的地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&(ADC_ConVal); // 存储数据的地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; // 外设到存储器
DMA_InitStructure.DMA_BufferSize = MAX_LEN * (ADC1_CHN + ADC2_CHN); // DMA缓存大小
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优先级,高优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; // 不用FIFO
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; // FIFO阈值
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // 存储器突发、单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 外设突发、单次传输
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream0, ENABLE); // 使能DMA2_Stream0流
/*=============================ADC时钟使能=============================*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 使能ADC1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); // 使能ADC2时钟
RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE); // ADC1复位
RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE); // 复位结束
RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC2, ENABLE); // ADC2复位
RCC_AHB2PeriphResetCmd(RCC_APB2Periph_ADC2, DISABLE); // 复位结束
/*=============================ADC公共部分配置=============================*/
ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult; // 双重模式多通道
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; // ADC采样时钟21MHz
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; // DMA模式1
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; // 两个采样延时5个Tadcclk,此配置仅在交替模式中生效
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 = ADC1_CHN; // 转换通道2个 /****此处ADC1和ADC2通道数一样,可以不用再修改,若两个通道数不相同,在2处添加ADC2的通道数*********/
/*=============================ADC1部分配置=============================*/
ADC_Init(ADC1, &ADC_InitStructure);
/*=============================ADC1转换顺序=============================*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles); // ADC1_CHANNEL0,第一个转换,采样时间位28个周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_28Cycles); // ADC1_CHANNEL1,第二个转换,采样时间位28个周期
/*=============================ADC2部分配置=============================*/
ADC_InitStructure.ADC_NbrOfConversion = ADC2_CHN; /**********2**********/
ADC_Init(ADC2, &ADC_InitStructure);
/*=============================ADC2转换顺序=============================*/
ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 1, ADC_SampleTime_28Cycles); // ADC1_CHANNEL2,第一个转换,采样时间位28个周期
ADC_RegularChannelConfig(ADC2, ADC_Channel_3, 2, ADC_SampleTime_28Cycles); // ADC1_CHANNEL3,第二个转换,采样时间位28个周期
ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); // 使能DMA请求 (多ADC模式)
ADC_Cmd(ADC1, ENABLE); // 使能ADC1
ADC_Cmd(ADC2, ENABLE); // 使能ADC2
ADC_SoftwareStartConv(ADC1); // 开启ADC1转换
}
/**寄存器版的若需要,请留言,我后面补上**/
|
|