打印
[牛人杂谈]

新唐(nuvoton)ARM Cotex-M0 系列ADC运用

[复制链接]
905|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主

1.NUC1xx系列ADC的特点:

+模拟信号输入电压范围:0~Vref(最大5伏)
+12位分辨率,10位精度
+最大8路独立模拟信号输入或者4路差分信号输入
+最快A/D转换时钟频率16MHz
+最快转换率800K次/秒,每次转换时间小于1.25us
+三种操作模式
   --单次模式:单通道A/D转换
   --单次扫描模式:使能的通道连续转换
   --连续扫描模式:使能的通道重复连续转换
+A/D转换的触发方式
   --软件写‘1’到ADST位
   --引脚STADC的外部信号
+每个通道的转换结果保存在各自的数据寄存器中,寄存器可以显示数据是否有效以及转换结果是否被覆盖
+转换结果可以用来与特定的值比较,当转换结果等于比较寄存器的设定时,用户可以选择是否产生中断
+通道7支持3种输入源:外部模拟电压,内部基准电压以及内部温度传感器信号输出
+支持自校正功能,最小化转换误差

2.操作流程
该转换器是一个12位分辨率的逐次逼近型模数转换器,该转换器配备有自校准功能来最小化转换误差,用户可以通过向寄存器ADCALR中CALEN位写‘1’来启动自校准功能,等内部校准完成后CAL_DONE将被置位。A/D转换器支持3种操作模式:单次模式,单次扫描模式,连续扫描模式。在使能模拟信号输入通道或者改变操作模式的时候,为了防止误操作,软件必须将寄存器ADCR中ADST位置‘0’,当ADST为被置‘0’的时候,A/D转换器立即停止当前转换进入空闲状态。

2.1 自校准

      用户可以通过向寄存器ADCALR中CALEN位写‘1’来启动自校准功能,这个操作在内部执行,需要127个时钟周期。CALEN位写‘1’后软件必须等CAL_DONE被内部硬件置位。详细时序如下图:


图1   A/D 转换器自校准时序图
2.2  AD转换时钟产生器
        最大采样率可以达到800KHz,每次转换时间小于1.25us,每次A/D转换需要20个时钟周期。ADC模块通过配置寄存器CLKSEL1[3:2] ADC_S有3个时钟源可选,寄存器CLKDIV[16:23] ADC_N用来设置A/D转换的时钟频率,公式如下:
                      ADC时钟=(ADC时钟源)/(ADC_N+1)
这样,软件通过设置ADC_S和ADC_N可以得到16Mhz左右的时钟频率。

2.3  单次转换模式
        在单次转换模式下,A/D转换只是在设定的通道中执行一次,操作如下:
1.  当寄存器 ADCR 中位ADST 被软件或者外部触发置‘1’后,转换开始
2.  A/D 转换结束后,结果放在相应通道的数据寄存器中
3.  转换结束后,寄存器ADSR 中ADF 位被置‘1’,如果 ADIE 位为‘1’,将会产生一个ADINT 中断
4.  在A/D 转换过程中 ADST 位保持为‘1’,转换结束后ADST 被自动清零,A/D 转换模块进入空闲状态。在转换的过程中如果把ADST位清零,A/D 转换器将立即停止并进入空闲模式注意:如果在单次模式中软件使能了不止一个通道,最小通道将被转换,其他通道被忽略


图2    单次转换模式时序图
2.4    连续扫描转换模式
在连续扫描模式下,A/D转换在由寄存器ADCHER位CHEN使能的通道中(最大8通道)顺序执行,操作流程如下:
1.  当寄存器 ADCR 中位ADST 被软件或者外部触发置‘1’后,A/D 转换从最低的通道开始
2.  当所有被使能的通道转换结束后,结果被顺序存储在相应通道的数据寄存器中
3.  当所有被使能的通道转换结束后,寄存器ADSR 中ADF 位被置‘1’,如果ADIE 位为‘1’,将会产生一个 ADINT 中断
4.  上面第2 步到第3 步重复执行直到ADST 位被清零,ADST 被清零后,A/D 转换模块停止并进入空闲状态。
下图是一个使能(0,2,3,7)通道的连续扫描转换模式的时序图:


图3    连续扫描转换模式时序图


沙发
zhuomuniao110|  楼主 | 2016-8-27 22:09 | 只看该作者
2.5    单次扫描模式
在单次扫描转换模式中,A/D转换将从低到高在使能的通道中执行一次,操作流程如下:
1.  当寄存器 ADCR 中位ADST 被软件或者外部触发置‘1’后,A/D 转换从使能的最低的通道开始
2.  当所有被使能的通道转换结束后,结果被顺序存储在相应通道的数据寄存器中
3.  当所有被使能的通道转换结束后,寄存器ADSR 中ADF 位被置‘1’,如果ADIE 位为‘1’,将会产生一个 ADINT 中断
4.  A/D 转换结束后ADST 被自动清零,A/D 转换模块进入空闲状态。在转换的过程中如果把ADST 位清零,A/D 转换器将立即停止并进入空闲模式
下图是一个使能(0,2,3,7)通道的单次扫描转换模式的时序图:


图4    单次扫描转换模式时序图
2.6    输入采样和A/D转换时间
A/D转换模块内置一个采样保持电路,在寄存器ADCR中位ADST被置‘1’并经过A/D转换开始延时时间(Td)后,采样保持电路用来采样模拟输入信号。由于ADC时钟是由PCLK/(N+1)产生的,所以从APB写寄存器到A/D转换器开始采样模拟信号的最大时间是2N PCLK时钟周期,开始延时时间如下图所示:

图5    转换开始延时时序图
A/D转换可以通过外部引脚来触发,寄存器ADCR.TRGEN置高用来使能外部触发功能,设置TRGS[1:0]为2’b00 用来选择从STADC引脚输入外部触发信号。软件可以设置TRGCOND[1:0]来选择触发条件为上升/下降沿或者高/低电平触发,如果选择了电平触发,一个8位的采样计数器被用来去尖峰脉冲,STADC引脚必须在特定的状态保持8个PCLK才能有效触发,ADST位将在第9个PCKL被置‘1’,然后开始转换。在电平触发模式中,外部触发保持特定电平的时候,A/D转换连续进行,触发电平消失将停止转换。如果选择了边沿触发,高/低电平必须保持至少4 PCLK时钟周期,小于4 PCLK的脉冲信号将被忽略,其他单次和扫描模式下的操作也是一样的

图6   外部A/D转换触发时序图




使用特权

评论回复
板凳
zhuomuniao110|  楼主 | 2016-8-27 22:12 | 只看该作者
2.7    比较模式下的A/D转换结果监控
NUC1xx控制器提供了2个比较寄存器ADCMPR0,ADCMPR1,用来监控A/D转换模块特定通道的转换结果,如下图。软件可以通过设定CMPCH[2:0]来选择被监控的通道,CMPCOND位用来检测转换结果小于或者大于/等于CMPD[11:0]中设定的值。当比较结果符合设定条件,内部计数器将加1,当内部计数器达到CMPMATCNT设定的值时,CMPF位将被置‘1’,此时如果CMPIE位也为‘1’,将产生ADINT中断请求。在扫描模式下,软件不用做额外工作就可以通过比较器来监控外部模拟输入脚的电压变化。详细逻辑框图如下:

图7    A/D转换结果监控逻辑图
2.8    中断源
A/D转换结束后寄存器ADSR中ADF位被置‘1’,如果ADIE位为‘1’,将会产生一个ADINT中断。如果CMPIE被使能,当A/D转换结果符合ADCMPR寄存器的设定时,ADINT和监控中断将产生,CPU可以清除CMPF和ADF来停止中断请求。

图8    A/D控制器中断
2.9    外围设备DMA请求
当A/D转换结束的时候,转换结果被存储在ADDR寄存器中VALID位被置‘1’。如果ADCR.PTEN被置‘1’,A/D控制器将产生PDMA请求(P_nDRQ)来传输数据,PDMA通过回应P_nDRQ请求来读走A/D转换的数据,以此达到CPU无干预情况下的连续A/D转换。


使用特权

评论回复
地板
zhuomuniao110|  楼主 | 2016-8-27 22:16 | 只看该作者
3     A/D转换编程方法
3.1    单次A/D转换下的程序流程
1. 设置被选为A/D转换功能的GPIOA口为输入模式
2. 根据需要设置寄存器CLKSEL1中的ADC_S位和CLKDIV中的ADC_N,然后设置寄存器APBCLK中的ADC_EN位来使能ADC时钟源
3. 根据操作模式设定寄存器ADCR中的ADEN,DIFF,ADMD位
4. 设置ADCHER寄存器CHEN位来选择A/D转换通道
5. 设置ADCR寄存器中ADIE位和NVIC_ISER寄存器来使能中断
6. 设置ADCR寄存器中ADST开始A/D转换


使用特权

评论回复
5
zhuomuniao110|  楼主 | 2016-8-27 22:17 | 只看该作者
3.2    示例程序
#include <stdio.h>         
#include "NUC1xx.h"

/*----------------------------------------------------------------------------
  Define variable
  ----------------------------------------------------------------------------*/
static uint32_t ADCTemp=0;
/*----------------------------------------------------------------------------
  Function subroutine
  ----------------------------------------------------------------------------*/
void Delay(uint32_t delayCnt)
{
    while(delayCnt--)
    {
        __NOP();
        __NOP();
    }
}
/*----------------------------------------------------------------------------

Interrupt subroutine
  ----------------------------------------------------------------------------*/
void ADC_IRQHandler(void) // Timer0 interrupt subroutine  
{
ADC->ADSR.ADF=1;
ADCTemp=ADC->ADDR[1].RSLT;     
}
/*----------------------------------------------------------------------------
  MAIN function
  ----------------------------------------------------------------------------*/
int32_t main (void)
{
   
NVIC_DisableIRQ(ADC_IRQn); //Disable ADC interrupt
outpw(&ADC->ADCR ,0 );  //Disable ADC  
                             
  /* Step 1. GPIO initial */  
GPIOA->PMD.PMD1=0;    //Set input mode
GPIOA->SCH|=0x00020000;   //Disable digital input path
SYS->GPAMFP.ADC1=1;   //Set ADC function  
     
  /* Step 2. Enable and Select ADC clock source, and then enable ADC module */           
SYSCLK->CLKSEL1.ADC_S = 2; //Select 22Mhz for ADC
SYSCLK->CLKDIV.ADC_N = 1;  //ADC clock source = 22Mhz/2 =11Mhz;
SYSCLK->APBCLK.ADC_EN = 1; //Enable clock source

  /* Step 3. Select Operation mode */
ADC->ADCR.ADEN = 1;  //Enable ADC module
ADC->ADCR.DIFF = 0;       //single end input
ADC->ADCR.ADMD = 0;       //single mode


  /* Step 4. Select ADC channel */
ADC->ADCHER.CHEN = 0x02;
    /* Step 5. Enable ADC interrupt */
ADC->ADSR.ADF =1;       //clear the A/D interrupt flags for safe  
ADC->ADCR.ADIE = 1;
NVIC_EnableIRQ(ADC_IRQn);
  
  /* Step 6. Conversion start  */
ADC->ADCR.ADST=1;
while(1)
{
  if (ADC->ADSR.BUSY==0) ADC->ADCR.ADST=1;
  ADCTemp=ADC->ADSR.CHANNEL;
}
}


使用特权

评论回复
6
天灵灵地灵灵| | 2016-8-28 16:38 | 只看该作者
时序图有点类似SPI时序图的感觉。

使用特权

评论回复
7
说书先生| | 2016-8-28 22:27 | 只看该作者
不错不错,赞一个!

使用特权

评论回复
8
zhuotuzi| | 2016-8-28 23:13 | 只看该作者
ADC有很多种模式组合,比如只搞一次的,一个通道连续搞的,多个通道搞一次的,多个通道轮番搞的。

使用特权

评论回复
9
zhuomuniao110|  楼主 | 2016-8-30 18:48 | 只看该作者
结构图很重要,如果官方能把结构图的注释搞详细点,会学起来很轻松。

使用特权

评论回复
10
wahahaheihei| | 2016-8-30 21:52 | 只看该作者
看到这些时序,让我想起了SPI 的时序结构。

使用特权

评论回复
11
捉虫天师| | 2016-8-30 22:19 | 只看该作者
一个12位分辨率的逐次逼近型模数转换器,该转换器配备有自校准功能来最小化转换误差

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

206

主题

3359

帖子

10

粉丝