单片机学习小组
直播中

ejlwj

8年用户 904经验值
擅长:处理器/DSP
私信 关注

有关ADC12模块基本知识汇总

ADC12的基本原理是什么?

怎样去设置ADC12的寄存器呢?

ADC12的转换模式有哪几种呢?

回帖(1)

曹利娟

2022-2-11 11:28:38
一,ADC12基本原理




  1.1,参考电压发生器

  所有的 ADC 和 DAC 模块都需要一个基准信号,这个信号就是我们常说的 Vref+,Vref-。 MSP430 的 ADC12 模块内部带有参考电源,通过控制 REFON 信号来启动内部参考电源,并且通过 REF2_5V 控制内部参考电源产生 1.5V 或者 2.5V 的 Vref+。 最后给 ADC 模块转换器的参考电压 Vr+和 Vr-通过 SREF_x 设置 6 种组合方式: Vr+可以在 AVcc(系统模拟电源),Vref+(内部参考电源),Veref+(外部输入的参考电源)之间选择, Vr-可以在 AVss(系统模拟地),Vref-/Veref-(内部或外部参考电源)。
  编者按:说白了在以上流程图可以看到,有两组基准电压选择器(SREF2和SREF1,SREF0)分别控制基准电压的“-”和“+”。
   1.2,时钟发生器

  这部分浩阔各种时钟信号,ADC12CLK 转换时钟,ADC12SSEL 选择内核时钟,ADC12DIV 时钟分频。 产生的ADC12CLK一方面用于转换(12-bit SAR)一方面用于生成采样时间(Sample Timer)。
  1.3,转换结果存储

  ADC12 一共有 12 个转换通道,设置了 16 个转换存储器用于暂时存储转换结果,合理设置后,ADC12 硬件会自动将转换的结果保存到相应的存储器里。
  1.4,具有采样保持功能的 12 位模数转换内核

  转换内核是有一个采样保持器和一个转换器组成。由于 ADC 转换需要一定的时间,对高速变化的信号进行瞬时采样时,不等 ADC 转换完成,外部输入的信号就已经改变。所以在 ADC 转换器前加入了采样保持器,一旦 ADC 开始转换,采样保持器则进行保持,即使现场输入的信号的变化比较快,也不会影响到 ADC 的转换工作。 12位的ADC转换器将Vr+和Vr-之间分割为2^12(4096)等份,然后将输入的模拟信号进行转换,输出0~4095 的数字。如果输入电压 Vin≤ Vr-则结果为 0,Vin≥Vr+结果为 4095。
  编者按:说白了,就是上述的流程图采样保持电路(Sample and Hold)通过前面触发延时控制采样时间,而在没有触发采样时,就完成转换(12-bit SAR)。
  1.5,采样转换时续控制电路

   这部分浩阔各种时钟信号,ADC12CLK 转换时钟,SAMPCON 采样转换信号,SHT 控制采样周期,SHS 控制采样触发来源。 由图可以看出来 SAMPCON 信号高的时候采样,低的时候转换。而 SAMPCON 有 2 个来源,一来自采样 定时器,另一路由用户自己控制,通过 SHP 选择。
  编者按:说白了,就是一个是直接控制(SHP=0)SAMPCON为高电平,转换,中间没有延时,一旦触发立刻采样转换,这样如果是连续采样,可能会导致出错。另个设置触发时间间隔保证采样触发上个电压完成,适合自动采样。
  扩展采样(SHP=0)
  有时序图可以看到,采样直接与触发源同步,这样如果短期再来个触发源时,不就干扰了转换时间。
  
   脉冲采样(SHP=1)
  由时序图可以看到通过采样定时器(Sample Timer)可以达到触发一次,延时采样。这样不会相互干扰。
  
  
二,寄存器设置


  

  • 12 位转换精度,1 位非线形误差,1 位非线形积分误差
  • 多种时钟源给 ADC12 模块,切本身自带时钟发生器
  • 内置温度传感器
  • TimerA/TimerB 硬件触发器
  • 8 路外部通道和 4 路内部通道
  • 内置参考电压源和 6 种参考电压组合
  • 4 种模式的模数转换
  • 16bit 的转换缓存
  • ADC12 关闭支持超低功耗
  • 采用速度快,最高 200Kbps
  • 自动扫描
  • DMA 使能

   2.1,ADC12CTL0

  
   ADC12ON:

  ADC12 内核控制 0 关闭 ADC12 内核实现低功耗             1 开启 ADC12 内核
  REFON:

  内部基准电压发生器控制 0 关闭内部基准电压发生器 1 开启内部基准电压发生器
  REF2_5V:

  内部基准电压选择 1.5V/2.5V 0 选择 1.5V 内部参考电压 1 选择 2.5V 内部参考电压
  SHT0x:

  0~7 通道的采样保持器时间控制 定义了 ADC12MEM0~7 中转换采样时序与采样时钟的关系 保持时间越短,采样速度越快,反映电压波动明显 Tsample= 4×TADC12CLK×N(N13 时,N=256)
  SHT1x:

  8~15 通道的采样保持器时间控制 定义了 ADC12MEM8~15 中转换采样时序与采样时钟的关系 保持时间越短,采样速度越快,反映电压波动明显 Tsample= 4×TADC12CLK×N(N13 时,N=256)
  MSC:

  多次采样/转换控制位
  当 SHP=1,CONSEQ≠0 时,MSC 位才能生效 (因为在多次采样时,必然要用采样定时进行延时,否则会出现转换数据错误,这也就是脉冲采样,然后似乎扩展采样多余的:为什么会有扩展采样,因为这是为了提高msp430的优越性,当有了扩展采样,在我们想要采样可以直接改变触发源,采样一次,而不是重复采样,节约能量)
  0 每次转换需要 SHI 信号的上升沿出发采样定时器
  1 首次转换需要 SHI 信号的上升沿出发采样定时器, 以后每次转换在前一次转换结束后立即进行
  ADC12SC:(软件触发)

  采样转换控制位  
  在 ENC=1,ISSH=0 的情况下:
  SHP=1 时:ADC12SC 由 0 变 1 时,启动 A/D 转换,转换完成后 ADC12SC 自动复位 SHP=0 时:ADC12SC 高电平时采样,ADC12SC 复位启动一次转换
  其中 ENC=1 表示转换允许,ISSH 表示输入信号为同相输入信号(一般默认为同向信号), SHP=1 表示采 样信号 SAMPCON 来自于采样定时器, SHP=0 表示 SAMPCON 采样有 ADC12SC 直接控制。
  注意:当软件启动一次 A/D 转换时,ADC12SC 和 ENC 要在一条语句内完成设置。
  ENC:

  转换允许位 0 ADC12 为初始状态,不能启动 A/D 转换 1 首次转换由 SAMPCON 的上升沿启动
  注意: [1]在 CONSEQ=0(单通道单次转换)的情况下,当 ADC12BUSY=1 时, ENC=0 则会结束转换进程,并且得到错误结果。 [2]在 CONSEQ≠0(非单通道单次转换)的情况下,当 ADC12BUSY=1 时, ENC=0 则转换正常结束,得到正确结果
  ADC12TVIE:

  转换时间溢出中断允许(多次采样请求) 当前转换还没有完成时,又得到一次采样请求,如果 ADC12TVIE 允许的话,会产生中断。 0 允许发生转换时间溢出产生中断 1 禁止发生转换时间溢出产生中断
  ADC12OVIE:

  溢出中断允许(ADC12MEMx 多次写入) 当 ADC12MEMx 还没有被读出的时候,而又有新的数据要求写入 ADC12MEMx 时, 如果允许则会产生中断 0 允许溢出中断 1 禁止溢出中断
  
    2.2,ADC12CTL1

  0
   ADC12SSELx:

  ADC12 时钟选择 0 ADC12OSC(ADC12 内部时钟源) 1 ACLK 2 MCLK 3 SMCLK
  ADC12DIVx:

  ADC12 时钟分频控制 ADC12 时钟源的分频因子选择位,分频因子为(x+1)
  ISSH:

  采样触发信号同向/反向 0 采样信号为同相输入 1 采样信号为反相输入
  SHP:

  采样信号 SAMPCON 选择 0 SAMPCON 信号来自采样触发输入信号 1 SAMPCON 信号来自采样定时器,由采样输入信号的上升沿触发
  SHSx:

  采样触发源选择 0 ADC12SC 1 TimerA.OUT1 2 TimerB.OUT1 3 TimerB.OUT2
  CSTARTADD:

  单通道模式转换通道/多通道模式守通道 定义单次转换的启始地址或者序列通道转换的首地址。
  COMSEQx:

  转换模式
  0 单通道单次转换 1 序列通道单次转换 2 单通道多次转换 3 序列通道多次转换
  ADC12BUSY:

  忙标志(转换中...) 0 表示 ADC12 没有活动的操作 1 ADC12 正在采样/转换期间,忙~~
  2.3,ADC12MCTLX

   EOS:

  多通道转换末通道标志 0 序列没有结束 1 该序列中最后一次转换
  SREFx:

  基准源选择 0 Vr+=AVcc, Vr-=AVss 1 Vr+=Vref+, Vr-=AVss 2,3 Vr+=Veref+, Vr-=AVss 4 Vr+=AVcc, Vr-=Vref-/Veref5 Vr+=AVcc, Vr-=Vref-/Veref6,7 Vr+=AVcc, Vr-=Vref-/Vere
  INCHx:

  所对应的模拟电压输入通道 0~7 A0~A7 8 Veref+ 9 Veref-/Vref10 片内温度传感器 11~15 (AVcc-AVss)/2
   2.4,ADC12MEMX

  
   该组寄存器为 12 位寄存器,用来存放 A/D 转换结果,其中只用到了低 12 位,高 4 位为 0。
  2.5,有关中断寄存器

  ADC12IFG 中断标志寄存器

   ADC12IFGx:中断标志位 对应于 ADC12MEMx,当 A/D 转换完成后,数据被存入 ADC12MEMx,此时 ADC12IFGx 标志置位。
  [6] ADC12IE 中断控制寄存器

  
  ADC12IEx:中断允许位 对应于 ADC12IFGx,如果 ADC12IEx 允许,则当 ADC12IFGx 置位时会进入 ADC12 的中断服务程序
三,代码


   ADC12 模块一共提供了 4 钟转换模式
  

  • 单通道单次转换
  • 序列通道单次转换
  • 单通道多次转换
  • 序列通道多次转换

注意这里的代码都是用脉冲模式,因为这样直接封装,主函数不用手调触发
   3.1,单通道模式

  
  
  查询方式

void ADC12_Init_0()
{
   // 内核开启, 启动内部基准,选择 2.5V 基准,设置采样保持时间
   //一般情况设置ADC12CTL0都是这样设置,至于那两个中断一般不设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2;//这里是脉冲模式
  // 时钟源为内部5M振荡器, 触发采样为ADC12SC 且上升沿有效
//采样来自采样定时器, 转换地址为 ADC12MCTL4
ADC12CTL1 = ADC12SSEL_0 + SHP +  CONSEQ_0+CSTARTADD_4;
// 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
ADC12MCTL4 = SREF_1 + INCH_0;

ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
  
while((ADC12IFG & 0x0010) == 0); // 软件查询中断标志, 等待转换结束
  /*  写处理程序   */
}
中断

  unsigned int TEMP;
void ADC12_Init_0()
{
   // 内核开启, 启动内部基准,选择 2.5V 基准,设置采样保持时间
   //一般情况设置ADC12CTL0都是这样设置,至于那两个中断一般不设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2;//这里是脉冲模式
  // 时钟源为内部5M振荡器, 触发采样为ADC12SC 且上升沿有效
//采样来自采样定时器, 转换地址为 ADC12MCTL4
ADC12CTL1 = ADC12SSEL_0 + SHP +  CONSEQ_0+CSTARTADD_4;
// 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
ADC12MCTL4 = SREF_1 + INCH_0;

  // 中断允许
ADC12IE = 0x0010; //因为我们存储数据在ADC12MCTL4
_EINT();

ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换

}

#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR(void)
{
  
  TEMP = ADC12MEM4;                     //读取ADC转换值

}
  3.2,序列通道模式

  
  
   查询方式

    void ADC_Init_1(void)
{
// ADC12 控制寄存器设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V+MSC + SHT0_6+SHT1_6;
// CONSEQ_1 表示当前模式为序列通道单次转换, 起始地址为 ADC12MCTL4, 结束地址 ADC12MCTL6
ADC12CTL1 = ADC12SSEL_0 + SHP + CONSEQ_1 + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_0; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
ADC12MCTL5 = SREF_1 + INCH_1; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A1
ADC12MCTL6 = SREF_1 + INCH_10 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:片内温度传感器
// 启动转换
  //ADC12IE = 0x0040;
// _EINT();
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
while((ADC12IFG & 0x0040) == 0); // 等待转换结束也就是ADC12MCTL6中断标志
  TEMP = ADC12MEM4;
}
中断

  void ADC_Init_1(void)
{
// ADC12 控制寄存器设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V+MSC + SHT0_6+SHT1_6;
// CONSEQ_1 表示当前模式为序列通道单次转换, 起始地址为 ADC12MCTL4, 结束地址 ADC12MCTL6
ADC12CTL1 = ADC12SSEL_0 + SHP + CONSEQ_1 + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_0; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
ADC12MCTL5 = SREF_1 + INCH_1; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A1
ADC12MCTL6 = SREF_1 + INCH_10 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:片内温度传感器
// 启动转换
  ADC12IE = 0x0040;
_EINT();
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
// while((ADC12IFG & 0x0040) == 0); // 等待转换结束也就是ADC12MCTL6中断标志
  //TEMP = ADC12MEM4;
}

#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR(void)
{
  
  TEMP=ADC12MEM6;
                     //读取ADC转换值
  
}
  3.3,单通道重复模式

  
   中断

void ADC_Init_3(void)
{
// ADC12 控制寄存器设置
// 对于多次转换需要设置 MSC
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2 + MSC;
// CONSEQ_2 表示当前模式为单通道多次转换, 转换地址为 ADC12MCTL4
ADC12CTL1 = ADC12SSEL_0 + SHP + CONSEQ_2 + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_0 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A0
// 中断允许
ADC12IE = 0x0010;
_EINT();
// 启动转换
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
}

#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR(void)
{

  TEMP=ADC12MEM4;
                     //读取ADC转换值


}
  3.4,多通道循环

  
  中断

  void ADC_Init(void)
{
// ADC12 控制寄存器设置
ADC12CTL0 = ADC12ON + REFON + REF2_5V + SHT0_2 +SHT1_2+ MSC;
ADC12CTL1 = ADC12SSEL_0 + SHP + CONSEQ_3 + CSTARTADD_4;
// 转换通道设置
ADC12MCTL4 = SREF_1 + INCH_0 ; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A4
ADC12MCTL5 = SREF_1 + INCH_10 ; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A5
ADC12MCTL6 = SREF_1 + INCH_11 + EOS; // 参考电压:V+=Vref+,V-=AVss ADC 通道:A6
// 中断允许
ADC12IE = 0x0040;
_EINT();
// 启动转换
ADC12CTL0 |= ENC + ADC12SC; // 转换使能开始转换
}

#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR(void)
{

  TEMP=ADC12MEM6;
                     //读取ADC转换值

}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分