ADC数模转换器

📅 2026/7/13 22:21:53
ADC数模转换器
ADC简介ADC采样量化编码EOC:结束转换信号START:开始转换给一个输入脉冲开始转换CLOCK:是ADC时钟这是一种不断进行二分比较最终确定电压值的方法。例如这里高位先行如果输入的是一个0.9V的电压那么如果DAC将第一位置1即20481.65V进行比较发现比0.9V大所以第一位置0接着如果第二位置1即10240.825V进行比较发现比0.9V小所以第二位置1接着第三位…以此类推最终填满12位。这就是12位逐渐逼近行ADC。配置ADC的结构:本节暂时不会用到看门狗和中断输出控制等部分 本节演示的是软件触发、规则组单次转换、非扫描模式的ADC转换。这里规则组是可以输入16个数据但可以看到AD数据寄存器中规则组结果只有一个所以只能放一个数据如果输入16个数据那么前15个数据就会被覆盖掉所以这里可以配合使用DMA数据转运使用。输入通道由于该芯片只有10个外部输入通道所以只有通道0到通道9这10个引脚可用于输入模拟量。初始化配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//ADC都是挂载在APB2总线上RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//配置ADC时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择6分频 ADC时钟最大频率为14MHzGPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_ModeGPIO_Mode_AIN;//选择模拟输入模式 ADC专属GPIO_InitStructure.GPIO_PinGPIO_Pin_0;GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//配置ADC规则通道组参数分别是选择ADCACD指定通道序列位置指定通道采样时间ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//初始化ADCADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_ModeADC_Mode_Independent;//选择独立模式还是双ADC模式ADC_InitStructure.ADC_DataAlignADC_DataAlign_Right;//选择数据对齐方式ADC_InitStructure.ADC_ExternalTrigConvADC_ExternalTrigConv_None;//外部触发转换选择(触发控制的触发源选择)ADC_InitStructure.ADC_ContinuousConvModeDISABLE;//选择单次转换ADC_InitStructure.ADC_ScanConvModeDISABLE;//选择非扫描模式ADC_InitStructure.ADC_NbrOfChannel1;//选择通道数目(1~16)ADC_Init(ADC1,ADC_InitStructure);//上电ADCADC_Cmd(ADC1,ENABLE);//对ADC进行校准ADC_ResetCalibration(ADC1);//这里会将复位校准状态标志位置1while(ADC_GetResetCalibrationStatus(ADC1));//获取复位校准状态复位校准完后状态位标志为0跳出循环ADC_StartCalibration(ADC1);//开始校准while(ADC_GetCalibrationStatus(ADC1));//等待校准完成注意我们这里选择的是软件触发所以还要调用ADC_SoftwareStartConvCmd函数才能转换数据每调用一次这函数就触发一次ADC转换。由上图可知ADC_RegularChannelConfig是配置ADC规则通道组的因为GPIO口选择P0口所以ADC通道选择通道0其中第三个参数的序列如下图由图可知我们选择的是单次转换非扫描模式所以每次将转换数据放到数据寄存器中后还要再触发一次才能进行下一次转换。最后根据手册建议我们还要对ADC进行校准减少误差。接下来如果需要读取转换数据可以调用下面函数uint16_tADC_GetValue(uint8_tADC_Channel){ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);//设置指定的ADC规则组通道设置它们的转换数据和采样时间ADC_SoftwareStartConvCmd(ADC1,ENABLE);//调用软件触发while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)RESET);//转换完成会置EOC标志位所以这里等待标志位returnADC_GetConversionValue(ADC1);//读取数据}由图可知我们调用 ADC_GetConversionValue函数时就是读取ADC_DR的值所以不用再手动对EOC清零。连续扫描非扫描模式如果想选择连续转换非扫描模式只需要将模板里的ADC_InitStructure.ADC_ContinuousConvModeDISABLE;//选择单次转换改为ENABLE就是选择连续转换模式了。这里与单次转换非扫描模式不同的是它在一次转换完成后不会停止下来而是进行下一次转换然后一直持续下去所以只要手动触发一次它就能一直转换下去想要读ADC值时直接从数据寄存器读取就行了。常用函数RCC_ADCCLKConfig配置ADCCLK分频器ADC_SoftwareStartConvCmd软件触发ADC_GetFlagStatus获取标志位状态判断EOCADC_RegularChannelConfig规则组通道配置ADC_ExternalTrigConvCmd外部触发转换控制就是是否允许外部触发转换ADC_GetConversionValueADC获取转换值