[其他ST产品] STM32F103C8T6 ADC功能

[复制链接]
2409|10
 楼主| 发给她更好fh 发表于 2023-5-30 15:40 | 显示全部楼层 |阅读模式
12位逐次逼近型ADC,1us转换时间。

输入电压0-3.3v和转化范围0-2^12-1(0-4095)成线性关系。

2个ADC资源,ADC1和ADC2,10个外部通道。

有两种转换单元组:规则组和注入组。

模拟看门狗,会自动检测输入电压范围。

以ADC0809芯片为例:
96766475a86909442.png
通过地址所存和译码控制通道选择开关。通过2分法依次逼近未知测量电压,Vref(+)和Vref(-)即是VCC和GND,决定DAC的比较值和电压对应关系。EOC是转换完成信号,START是起始信号。

 楼主| 发给她更好fh 发表于 2023-5-30 15:41 | 显示全部楼层
STM32ADC
167866475a87e38165.png
规则组最多可以选择16个通道进行数据转化,但是只有1个16位的数据寄存器,根据通道顺序的值会覆盖数据寄存器的值,所以最好用DMA数据转运。


 楼主| 发给她更好fh 发表于 2023-5-30 15:41 | 显示全部楼层
对于注入组,同时可以选择4个通道,因为有4个数据寄存器,所以不必担心数据覆盖问题。

触发ADC数据开始转化的方式有两种:软件写一条代码触发或硬件触发,主要是定时器和中断,如图所示。

ADC时钟来自RCC
456236475a8a048d0e.png
614786475a8a7f1d6d.png
对于初始化的72Mhz,我们只能选择6分频的12Mhz,或者8分频的9Mhz。

如果启动了模拟看门狗,看门狗会自动去比较阈值结果,超过的的话会将AWD位置高位,配置中断后可以申请中断。注入组和规则组转换完成也都会去置标志位。
 楼主| 发给她更好fh 发表于 2023-5-30 15:41 | 显示全部楼层
ADC四种转化模式(单次转换和扫描组合)
1)单次转换,不扫描
173886475a8bbb5a28.png
        触发一次,转换一个序列1内的通道,置转换完成标志位。下次转换依旧还要发开始转换信号
 楼主| 发给她更好fh 发表于 2023-5-30 15:42 | 显示全部楼层
2)连续转换,不扫描
213876475a8cb31985.png
    只发送一次转换信号,然后这个通道就不断转换
 楼主| 发给她更好fh 发表于 2023-5-30 15:42 | 显示全部楼层
3)单次转换,扫描模式
493216475a8da86d7a.png
        一次转换多个通道值,每次转换完后,下一次转换还要再次触发。注意,要指定通道数目。
 楼主| 发给她更好fh 发表于 2023-5-30 15:42 | 显示全部楼层
4)连续转换,扫描模式

224326475a8ee42906.png

和单次不同的是,它会不段扫描通道的值,不需要重新触发开始转换。
 楼主| 发给她更好fh 发表于 2023-5-30 15:42 | 显示全部楼层
数据对齐
ADC的数据只有12位,但是通道的数据寄存器却有12位,可以采用

右对齐方式:低位依次对齐,高位补零(常用),因为它读到的数据就是转换结果。

左对齐方式:高位对齐,低位补零。
 楼主| 发给她更好fh 发表于 2023-5-30 15:43 | 显示全部楼层
ADC转换时间:
AD转换步骤:采样,保持,量化,编码

采样时间可配置。

STM32ADC总转换时间:T=采样时间+12.5个ADC周期

以14M的采样时钟为例:采样时间为1.5个ADC周期时:T=14个周期=1us
 楼主| 发给她更好fh 发表于 2023-5-30 15:43 | 显示全部楼层
ADC校准
ADC内部自带校准,建议每次上电后执行一次校准。启动校准前,ADC必须处于关电状态超过至少2个ADC时钟周期。
 楼主| 发给她更好fh 发表于 2023-5-30 15:43 | 显示全部楼层
STM32单通道程序
ADC单通道初始话程序如下
  1. #include "stm32f10x.h"                  // Device header

  2. void AD_Init(void)
  3. {
  4.         //开时钟
  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  7.        
  8.         RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频=72/6=12Mhz
  9.        
  10.         //GPIO
  11.         GPIO_InitTypeDef GPIO_InitStructure;
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  13.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  14.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  15.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  16.        
  17.         ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//输入通道:选ADC1,通道0,通道放入扫描列表的位置1,采样时间55.5个周期
  18.         //ADC
  19.         ADC_InitTypeDef ADC_InitStruct;
  20.         ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;  
  21.         ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;
  22.         ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
  23.         ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;
  24.         ADC_InitStruct.ADC_NbrOfChannel=1;
  25.         ADC_InitStruct.ADC_ScanConvMode=DISABLE;

  26.         ADC_Init(ADC1,&ADC_InitStruct);
  27.        
  28.         ADC_Cmd(ADC1,ENABLE);
  29.         //ADC校准
  30.         ADC_ResetCalibration(ADC1);//复位校准
  31.         while(ADC_GetResetCalibrationStatus(ADC1)==SET);//等待复位校准完成
  32.         ADC_StartCalibration(ADC1);//开始校准
  33.         while(ADC_GetCalibrationStatus(ADC1)==SET);//等待校准完成
  34. }

  35. uint16_t AD_GetValue(void)
  36. {
  37.         ADC_SoftwareStartConvCmd(ADC1,ENABLE);
  38.         while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==0);//转换完成
  39.         return ADC_GetConversionValue(ADC1);
  40.        
  41. }

主函数中用一个数来收取这个数据即可。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

563

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部
0