单片机——ADC采样

[复制链接]
发表于 2026-1-13 17:26:14 | 显示全部楼层 |阅读模式
1、什么是ADC采样?

        ADC是指将模拟信号转换成数字信号的过程。平常明确ADC采样就是收罗电路中的电压,通过数值的方式表现出来。以STM32F103系列为例,它可以反应0~4095,换句话说,它收罗的电压数值上表现为0~4095,也就是12位ADC(2^12)。
2、怎样明确收罗的数值?

        以STM32F103芯片为例,供电电压是3.3V,它能检测的电压也是0~3.3V。这就好明确了,0~3.3V电压对应的是0~4095数值。平常明确为把3.3V分成了4096份,收罗上来多少份占3.3V的比例。
        收罗电压=(收罗数值/4095)*3.3V
3、ADC采样具体知识和步调

3.1、步调

(1)使能用于ADC检测的引脚对应的GPIO口,使能ADC2通道时钟(ADC1也可以,这款芯片有俩个ADC外设)
(2)时钟分频
(3)初始化GPIO引脚并设置成输入模式
(4)设置ADC的工作模式
(5)使能指定的ADC
(6)开启复位校准
注:ADC的输入时钟不得凌驾14MHZ,它是由PCLK2经分频产生。
3.2、 ADC知识讲授

3.2.1、通道选择

         每个 ADC有 18 个通道,此中有16个外部通道(差别引脚数的STM32外部通道数大概有所差别),别的两个是内部通道。

        ADC通道和引脚对应关系如下(STM32F103C8T6为例):

  3.2.2、单次转换和一连转换



  3.2.3、独立模式和多重模式

        独立模式即全部ADC转换器(ADC1、ADC2和ADC3)均独立地工作,互不影响。
        多重模式即多个ADC(如果存在)根据通用寄存器中的设置,按照指定的方式协同工作。
3.2.4、数据对齐


        比如说AD转换后数字量生存在ADCH,ADCL两个寄存器中
        左对齐就是AD值的最高位就是ADCH的最高位了,ADCL的低位就会有的用不到,读出来为0
        右对齐就是AD值的最低位是ADCL的最低位,而ADCH的高位就会有的用不到,读出来也为0
        左对齐:11111111 11110000
        MSB LSB
        右对齐:00001111 11111111
        MSB LSB
3.2.5、注入组和规则组


注:
(1)当完成全部注入通道转换,下个触发启动第1个注入通道的转换。在上述例子中,第四个 触发重新转换第1个注入通道1(2)不能同时利用自动注入和制止模式。(3)必须制止同时为规则和注入组设置制止模式。制止模式只能作用于一组转换。3.2.6、 ADC校准


3.3、代码示例

3.3.1、初始化
  1. void Adc_Init(void)
  2. {
  3.         u8 i;
  4.         ADC_InitTypeDef ADC_InitStructure;
  5.         GPIO_InitTypeDef GPIO_InitStructure;
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC2, ENABLE ); //使能 ADC2 通道时钟
  7.         RCC_ADCCLKConfig(RCC_PCLK2_Div4);                                                                         //设置 ADC 分频因子 6
  8.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
  9.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                                                //模拟输入
  10.         GPIO_Init(GPIOA, &GPIO_InitStructure);                                                                //初始化 GPIOA
  11.        
  12.         ADC_DeInit(ADC2);
  13.         ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                                        //ADC 独立模式
  14.         ADC_InitStructure.ADC_ScanConvMode = DISABLE;                                                //连续多通道模式
  15.         ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                                        //连续转换模式关
  16.         ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        //转换由软件触发
  17.         ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                                //ADC 数据右对齐
  18.         ADC_InitStructure.ADC_NbrOfChannel = 1;                                                                //顺序进行规则转换的ADC通道的数目
  19.         ADC_Init(ADC2, &ADC_InitStructure);                                                                        //根据指定的参数初始化外设 ADCx
  20.        
  21.         ADC_Cmd(ADC2, ENABLE);                                                                                                //使能指定的 ADC2
  22.         for(i=0;i<100;i++);
  23.         ADC_ResetCalibration(ADC2);                                                                                         //开启复位校准
  24.         while(ADC_GetResetCalibrationStatus(ADC2));                                                        //等待复位校准结束
  25.         ADC_StartCalibration(ADC2);                                                                                        //开启 AD 校准
  26.         while(ADC_GetCalibrationStatus(ADC2));                                                                //等待校准结束
  27. }
复制代码
3.3.2、获取ADC数值
  1. u16 Get_Adc1(void)
  2. {
  3.         ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5); //通道1
  4.         ADC_SoftwareStartConvCmd(ADC2, ENABLE);                                                        //使能指定的 ADC2 的软件转换功能
  5.         while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));                                        //等待转换结束
  6.         return ADC_GetConversionValue(ADC2);                                                        //返回最近一次 ADC2 规则组的转换结果
  7. }
  8. u16 Get_Adc2(void)
  9. {
  10.         ADC_RegularChannelConfig(ADC2, ADC_Channel_2, 1, ADC_SampleTime_239Cycles5); //通道2
  11.         ADC_SoftwareStartConvCmd(ADC2, ENABLE);                                                        //使能指定的 ADC2 的软件转换功能
  12.         while(!ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC ));                                        //等待转换结束
  13.         return ADC_GetConversionValue(ADC2);                                                        //返回最近一次 ADC2 规则组的转换结果
  14. }
复制代码
3.3.3、主函数
  1. u8 Val;
  2. u8 ADC;
  3. int main(void)
  4. {
  5.            Adc_Init();                        //ADC初始化
  6.         while (1)
  7.         {       
  8.         ADC = Get_Adc1();                //将1通道检测的数值传给ADC变量
  9.         Val = (ADC*3.3)/4095             //计算得到1通道检测的电压
  10.         }
  11.        
  12. }
复制代码
注:上述设置下, 多通道收罗时,俩个通道收罗之间要有肯定的隔断。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表