1.采集到的值如何转化计算?
在STM32系列芯片大都是12位只有少部分是16位的,如:F373芯片。
12位分辨率意味着我们采集电压的精度可以达到:Vref / 4096。
采集电压= Vref * ADC_DR / 4096;
VREF:参考电压
ADC_DR:读取到ADC数据寄存器的值
2.什么是通道扫描模式?
扫描模式用于多通道采集时,一轮采集为根据通道设定的顺序依次采集每个开启的通道。但要注意的是每个通道采集到的值都是存放在寄存器ADCx-> DR中,而只有当一轮采集完即所有设定的通道都采集完后采集完成标志才会被置位,所以不使用DMA传输方式的时候会出现采集到的数据被覆盖的现象。
3.采集周期,转换周期
转换时间=采样时间+12.5个时钟周期;
采样时间根据ADC_RegularChannelConfig()配置。
4.连续转换模式
将所有开启的通道采集转换完一轮后自动开启下一轮的采集转换。
5.一次采集完成后会触发中断吗?
ADC使能中断的话当通道规则组都采集转化完成一轮后会产生中断ADC1_2_IRQHandler(void)
1.什么是DMA循环模式?
完成一轮DMA传输后自动开启下一轮传输。
2.怎么算一轮DMA传输完成?
3.ADC怎么触发DMA?
传输请求函数触发
例如:
ADC_DMACmd(ADC1,Enable);
4.DMA有哪些传输方向?
内存 到 内存
内存 到 外设
外设 到 内存
5.DMA传输会触发哪些中断?
void adc_gpio_init(void) { GPIO_InitTypeDef t_gpio; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);//使能 GPIOA GPIOB GPIOC 时钟 t_gpio.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//GPIOA t_gpio.GPIO_Mode=GPIO_Mode_AIN;//模拟输入模式 GPIO_Init(GPIOA,&t_gpio);//初始化GPIOA t_gpio.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;//GPIOB GPIO_Init(GPIOB,&t_gpio);//初始化GPIOB t_gpio.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//GPIOC GPIO_Init(GPIOC,&t_gpio);//初始化GPIOC } void adc_init(void) { ADC_InitTypeDef t_adc; RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//使能ADC1时钟 t_adc.ADC_Mode = ADC_Mode_Independent; //独立模式:ADC1与ADC2独立 t_adc.ADC_ScanConvMode = DISABLE; //禁用通道扫描 t_adc.ADC_ContinuousConvMode = DISABLE; //禁用连续转换 t_adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部触发 t_adc.ADC_DataAlign = ADC_DataAlign_Right; //数据位右对齐 t_adc.ADC_NbrOfChannel = 1; //转换通道数为1 ADC_Init(ADC1,&t_adc); //初始化ADC1 RCC_ADCCLKConfig(RCC_PCLK2_Div8);//配置ADC时钟为PCLK2的8分频 ADC_Cmd(ADC1,ENABLE); //使能ADC1 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); //校准 while(ADC_GetCalibrationStatus(ADC1)){}; } uint16_t read_adc_value(uint8_t ch) { uint16_t adc_value = 0; ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_7Cycles5 ); //设置ADC1通道ch的转换周期为7.5个采样周期,采样次序为1 ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能软件触发 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )){};//等待转换完成 adc_value = ADC_GetConversionValue(ADC1); //获取转换值 return adc_value; }
void ADC_Multichannel_Config(void) { ADC_InitTypeDef ADC_InitStructure; ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值 /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//ADC工作模式:ADC1和ADC2工作在独立模式 ADC_InitStructure.ADC_ScanConvMode =ENABLE; //ADC为扫描模式 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //ADC为连续转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发转换关闭 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 4; //顺序进行规则转换的ADC通道的数目 ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器 /* ADC1 regular channel11 configuration */ //设置指定ADC的规则组通道,设置它们的转化顺序和采样时间 //ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5 ); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5 ); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_239Cycles5 ); ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 4, ADC_SampleTime_239Cycles5); // 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数) ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1 /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); //复位指定的ADC1的校准寄存器 /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); //复位指定的ADC1的校准寄存器 /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); //开始指定ADC1的校准状态 /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待 }
void DMA_Configuration(void) { /* ADC1 DMA1 Channel Config */ DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA时钟 DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值:ADC1连接DMA通道1 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_Value; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地 DMA_InitStructure.DMA_BufferSize = N*4; //此值为完整一轮DMA传输的次数 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据位宽度16位,即DMA传输尺寸 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度16位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式,一轮结束后自动开始下轮传输 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x禁止内存到内存 DMA_Init(DMA1_Channel1, &DMA_InitStructure); //根据DMA_InitStruct中参数DMA通道 }