APM32F103ZE-外部引脚信号触发AD转换
ADC触发方式介绍
ADC触发有三种方式
- 片上定时器信号触发
- 外部引脚信号触发
- 软件触发
其中外部引脚信号触发AD转换有两种方式;分别是规则通道外部触发EINT11、注入通道外部触发EINT15;
外部引脚信号触发AD转换使用的资源
ADC IO :PC.01、PC.02、PC.04、PA.04
EINT IO:PE.11、PE.15
DMA1通道1
ADC1
外部引脚信号触发AD转换配置流程
- NVIC配置
- 时钟配置
- DMA配置
- EINT IO配置
- ADC IO配置
- ADC配置
- ADC中断服务函数编写
NVIC配置
配置NVIC是为了ADC1注入组中断
//NVIC配置
NVIC_EnableIRQRequest(ADC1_2_IRQn,2,2);
时钟配置
使用ADC IO(PC.01、PC.02、PC.04、PA.04)、EINT IO(PE.11、PE.15)、ADC1、DMA1通道1;所以需要开启GPIOC、GPIOA、GPIOE、ADC1时钟;因为配置外部引脚信号触发AD转换,还需要配置EINT,所以还需要开启AFIO时钟;再有配置ADC时钟,需要保证ADC时钟小于等于14MHz,配置ADC时钟6分频;总结下来代码见下:
//时钟配置
RCM_ConfigADCCLK(RCM_PCLK2_DIV_6);
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOC | RCM_APB2_PERIPH_GPIOE | RCM_APB2_PERIPH_AFIO | RCM_APB2_PERIPH_ADC1);
DMA配置
配置DMA加快ADC数据的采集(ADC1_DR_Address对应ADC1数据寄存器地址)
其中外设配置:ADC1_DR_Address、DMA_PERIPHERAL_DATA_SIZE_HALFWORD(半字)、DMA_PERIPHERAL_INC_DISABLE(不自增)
其中存储器配置:(uint32_t)ADC_RegularConvertedValueTab、DMA_MEMORY_DATA_SIZE_HALFWORD(半字)、DMA_MEMORY_INC_ENABLE(自增)
方向:外设->存储器、循环模式、优先级高、失能M2M,数据量20、
//DMA配置
/* DMA1 通道1 配置*/
DMA_Config_T DMA_Configure;
DMA_Configure.loopMode = DMA_MODE_CIRCULAR;
DMA_Configure.bufferSize = 20;
DMA_Configure.M2M = DMA_M2MEN_DISABLE;
DMA_Configure.priority = DMA_PRIORITY_HIGH;
DMA_Configure.dir = DMA_DIR_PERIPHERAL_SRC;
DMA_Configure.memoryBaseAddr = (uint32_t)ADC_RegularConvertedValueTab;
DMA_Configure.memoryDataSize = DMA_MEMORY_DATA_SIZE_HALFWORD;
DMA_Configure.memoryInc = DMA_MEMORY_INC_ENABLE;
DMA_Configure.peripheralBaseAddr = ADC1_DR_Address;
DMA_Configure.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_HALFWORD;
DMA_Configure.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
DMA_Config(DMA1_Channel1,&DMA_Configure);
DMA_Enable(DMA1_Channel1);
EINT IO配置
初始化EINT IO(配置浮空输入)
配置EINT:EINTLine源配置、EINT初始化(事件模式)
//EXTI IO 配置
/* EXTI line11 配置、EXTI line15 配置 */
GPIO_Config_T GPIO_Configure;
GPIO_Configure.mode = GPIO_MODE_IN_FLOATING;
GPIO_Configure.pin = GPIO_PIN_11 | GPIO_PIN_15;
GPIO_Config(GPIOE,&GPIO_Configure);
EINT_Config_T EINT_Configure;
GPIO_ConfigEINTLine(GPIO_PORT_SOURCE_E,GPIO_PIN_SOURCE_15);
EINT_Configure.line = EINT_LINE_15;
EINT_Configure.lineCmd = ENABLE;
EINT_Configure.mode = EINT_MODE_EVENT;
EINT_Configure.trigger = EINT_TRIGGER_RISING;
EINT_Config(&EINT_Configure);
GPIO_ConfigEINTLine(GPIO_PORT_SOURCE_E,GPIO_PIN_SOURCE_11);
EINT_Configure.line = EINT_LINE_11;
EINT_Configure.lineCmd = ENABLE;
EINT_Configure.mode = EINT_MODE_EVENT;
EINT_Configure.trigger = EINT_TRIGGER_RISING;
EINT_Config(&EINT_Configure);
ADC IO配置
ADC IO配置为模拟输入
//ADC IO 配置
/* PC.01, PC.02 and PC.04 (ADC Channel11, Channel12 and Channel14) */
GPIO_Configure.mode = GPIO_MODE_ANALOG;
GPIO_Configure.pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4;
GPIO_Config(GPIOC,&GPIO_Configure);
/* PA.04 (ADC Channel4) */
GPIO_Configure.mode = GPIO_MODE_ANALOG;
GPIO_Configure.pin = GPIO_PIN_4;
GPIO_Config(GPIOA,&GPIO_Configure);
ADC配置
ADC配置:独立模式、数据右对齐、外部EINT11触发、通道数2、扫描模式使能、连续模式失能
ADC规则组通道配置、使能规则组外部触发
ADC注入组配置:注入组转换序列长度、注入组通道配置、注入组外部触发配置、使能注入组外部触发
ADC中断配置:清除ADC中断标志、使能ADC中断
ADC DMA使能
ADC使能、ADC校准
//ADC 配置
/* ADC1 配置 */
ADC_Config_T ADC_Configure;
ADC_Configure.continuosConvMode = DISABLE;
ADC_Configure.dataAlign = ADC_DATA_ALIGN_RIGHT;
ADC_Configure.externalTrigConv = ADC_EXT_TRIG_CONV_EINT11_T8_TRGO;
ADC_Configure.mode = ADC_MODE_INDEPENDENT;
ADC_Configure.nbrOfChannel = 2;
ADC_Configure.scanConvMode = ENABLE;
ADC_Config(ADC1,&ADC_Configure);
/* ADC1 规则组通道配置 */
ADC_ConfigRegularChannel(ADC1,ADC_CHANNEL_4,1,ADC_SAMPLETIME_28CYCLES5);
ADC_ConfigRegularChannel(ADC1,ADC_CHANNEL_14,2,ADC_SAMPLETIME_28CYCLES5);
/* 使能ADC1 规则组通道外部触发 */
ADC_EnableExternalTrigConv(ADC1);
//ADC1 注入组通道配置
/* 设置注入组转换顺序长度 */
ADC_ConfigInjectedSequencerLength(ADC1,2);
/* ADC1 注入组通道配置 */
ADC_ConfigInjectedChannel(ADC1,ADC_CHANNEL_11,1,ADC_SAMPLETIME_28CYCLES5);
ADC_ConfigInjectedChannel(ADC1,ADC_CHANNEL_12,2,ADC_SAMPLETIME_28CYCLES5);
/* ADC1 注入组外部触发配置 */
ADC_ConfigExternalTrigInjectedConv(ADC1,ADC_EXT_TRIG_INJEC_CONV_EINT15_T8_CC4);
/* 使能ADC1 注入组通道外部触发 */
ADC_EnableExternalTrigInjectedConv(ADC1);
/* ADC1 JEOC 中断使能 */
ADC_ClearStatusFlag(ADC1,ADC_FLAG_INJEOC);
ADC_EnableInterrupt(ADC1,ADC_INT_INJEOC);
/* ADC1 DMA使能 */
ADC_EnableDMA(ADC1);
/* ADC1 使能、ADC1校准 */
ADC_Enable(ADC1);
ADC_ResetCalibration(ADC1);
while(ADC_ReadResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_ReadCalibrationStartFlag(ADC1));
ADC中断服务函数编写
编写ADC中断服务函数采集ADC注入组的数据
void ADC1_2_IRQHandler(void)
{
if(ADC_ReadIntFlag(ADC1,ADC_INT_INJEOC) == SET)
{
ADC_ClearIntFlag(ADC1, ADC_INT_INJEOC);
ADC_InjectedConvertedValueTab[Index++] = ADC_ReadInjectedConversionValue(ADC1,ADC_INJEC_CHANNEL_1);
ADC_InjectedConvertedValueTab[Index++] = ADC_ReadInjectedConversionValue(ADC1,ADC_INJEC_CHANNEL_2);
if (Index == 10)
{
Index = 0;
}
}
}
ADC外部触发测试情况
最后提供外部引脚信号触发AD转换的demo
附件:外部引脚信号触发AD转换.zip