×
嵌入式 > 技术百科 > 详情

MSP430F5529 ADC参考

发布时间:2020-06-17 发布时间:
|

MSP430F5529 ADC参考笔记


1.ADC12_A初始化参数

typedef struct ADC_MemMap

{

  union

  {

    uint16_t CTL0;

    struct

    {

      uint16_t SC             :1;  /* ADC12 Start Conversion */

      uint16_t ENC            :1;  /* ADC12 Enable Conversion */

      uint16_t TOVIE          :1;  /* ADC12 Timer Overflow interrupt enable */

      uint16_t OVIE           :1;  /* ADC12 Overflow interrupt enable */

      uint16_t ON             :1;  /* ADC12 On/enable */

      uint16_t ADCREFON       :1;  /* ADC12 Reference on */

      uint16_t REF2_5V        :1;  /* ADC12 Ref 0:1.5V / 1:2.5V */

      uint16_t MSC            :1;  /* ADC12 Multiple SampleConversion */

      uint16_t SHT0           :4;  /* ADC12 Sample Hold 0 Select  */

      uint16_t SHT1           :4;  /* ADC12 Sample Hold 1 Select  */

    };

  };

  union

  {

    uint16_t CTL1;

    struct

    {

      uint16_t ADBUSY         :1;    /* ADC12 Busy */

      uint16_t CONSEQ         :2;    /* ADC12 Conversion Sequence Select  */

      uint16_t SSEL           :2;    /* ADC12 Clock Source Select  */

      uint16_t DIV            :3;    /* ADC12 Clock Divider Select  */

      uint16_t ISSH           :1;    /* ADC12 Invert Sample Hold Signal */

      uint16_t SHP            :1;    /* ADC12 Sample/Hold Pulse Mode */

      uint16_t SHS            :2;    /* ADC12 Sample/Hold Source  */

      uint16_t CSTARTADD      :4;    /* ADC12 Conversion Start Address  */

    };

  };

  union

  {

    uint16_t CTL2;

    struct

    {

      uint16_t REFBURST       :1;    /* ADC12+ Reference Burst */

      uint16_t ADCREFOUT      :1;    /* ADC12+ Reference Out */

      uint16_t SR             :1;    /* ADC12+ Sampling Rate */

      uint16_t DF             :1;    /* ADC12+ Data Format */

      uint16_t RES            :2;    /* ADC12+ Resolution  */

      uint16_t TCOFF          :1;    /* ADC12+ Temperature Sensor Off */

      uint16_t PDIV           :1;    /* ADC12+ predivider 0:/1   1:/4 */

    };

  };

  uint16_t RESERVED_1[2];

  uint16_t IFG;

  uint16_t IE;

  uint16_t IV;

  struct

  {

      uint8_t INCH            :4;     /* ADC12 Input Channel Select*/

      uint8_t REF             :3;     /* ADC12 Select Reference  */

      uint8_t EOS             :1;     /* ADC12 End of Sequence */

  }MCTL[16];

  uint16_t MEM[16];

}volatile * ADC_MemMapPtr;


#define ADC12_SSEL_ADC12OSC       0

#define ADC12_SSEL_ACLK           1                   

#define ADC12_SSEL_MCLK           2

#define ADC12_SSEL_SMCLK          3   


#define ADC12_SREF_0            0

#define ADC12_SREF_1            1

#define ADC12_SREF_2            2

#define ADC12_SREF_3            3

#define ADC12_SREF_4            4

#define ADC12_SREF_5            5

#define ADC12_SREF_6            6

#define ADC12_SREF_7            7


#define ADC_BASE_PTR                     ((ADC_MemMapPtr)__MSP430_BASEADDRESS_ADC12_PLUS__)


1.1 初始化的通道及引脚

typedef enum

{

  ADC_CH0        =BIT0,  //P6.0

  ADC_CH1        =BIT1,  //P6.1

  ADC_CH2        =BIT2,  //P6.2

  ADC_CH3        =BIT3,  //P6.3

  ADC_CH4        =BIT4,  //P6.4

  ADC_CH5        =BIT5,  //P6.5

  ADC_CH6        =BIT6,  //P6.6

  ADC_CH7        =BIT7,  //P6.7

  ADC_CH8        =BIT8,  //VeREF+    //外部正基准

  ADC_CH9        =BIT9,  //VeREF-    //外部负基准

  ADC_CH10       =BITA,  //片内温度传感器

  ADC_CH11       =BITB,  //(AVCC-AVSS)/2

  ADC_CH12       =BITC,  //P7.0

  ADC_CH13       =BITD,  //P7.1

  ADC_CH14       =BITE,  //P7.2

  ADC_CH15       =BITF,  //P7.3

  ADC_CH_NUM     =16u,   //通道数量

}ADC_CHn;       //通道


1.2 参考电压

typedef enum

{

  ADC_VREF_1_5V         ,  //内部1.5V

  ADC_VREF_2_5V         ,  //内部2.5V

  ADC_VREF_3_3V         ,  //供电电压作为参考电压

  ADC_VREF_External     ,  //使用外部提供参考电压

}ADC_VREF;         //参考电压


值得注意的是,参考手册里面解释如下 

  

单片机的采样电压是不允许超过参考电压: 

Nadc=4095∗Vin−VR−VR+−VR−

Nadc=4095∗Vin−VR−VR+−VR−


从参考公式来看,必须小于参考电压,如果超过参考电压,输出只能到最大参考电压,并且还会可能烧坏单片机。

1.3 转换精度

typedef enum

{

  ADC_8bit              ,  //8 位精度,最大值256-1

  ADC_10bit             ,  //10位精度,最大值1024-1

  ADC_12bit             ,  //12位精度,最大值4096-1

}ADC_Resolution;   //精度


2 初始化

/*******************************************************************************

*  函数名称:ADC_Init(uint16_t ch,ADC_VREF Vref,ADC_Resolution nBit)

*  功能说明:ADC初始化一个或多个ADC通道

*  参数说明:

            uint16_t ch     :要初始化的通道

            ADCVREF Vref    :参考电压

            ADC_Resolution nBit   :转换精度

*  函数返回:无

********************************************************************************/

void ADC_Init(uint16_t ch,ADC_VREF Vref,ADC_Resolution nBit)

{

  ADC12->ENC = DISABLE; //先对该位复位,否则置位后有些寄存器不能再进行操作

  uint16_t SREF_RegValue = 0u;

  switch(Vref)           //选择参考电压

  {

  case ADC_VREF_1_5V:

    REFCTL0 &=~ REFMSTR;                //把REF参考电压控制权交给ADC

    ADC12->ADCREFON = BIT_SET;

    ADC12->REF2_5V = RESET;

    SREF_RegValue = ADC12_SREF_1;       //使用内部提供的参考电压

    break;

  case ADC_VREF_2_5V:

    REFCTL0 &=~ REFMSTR;

    ADC12->ADCREFON = BIT_SET;

    ADC12->REF2_5V = BIT_SET;

    SREF_RegValue = ADC12_SREF_1;       //使用内部提供的参考电压

    break;

  case ADC_VREF_External:      

    P5SEL |= BIT0;       //VeREF+

    P5SEL |= BIT1;       //VeREF-

    SREF_RegValue = ADC12_SREF_2;       //使用外部参考电压

  case ADC_VREF_3_3V:

    SREF_RegValue = ADC12_SREF_0;       //使用电源电压作为参考电压,

    break;

  default :break;

  }

  //初始化通道

  uint16_t CH_Mask = 0x01;

  for(uint8_t CH_Num=0; CH_Num < ADC_CH_NUM; CH_Num++)

  {

    if(ch & CH_Mask)   //要初始化的通道

    {

      if((CH_Mask & InitialedChannel_Bit) == 0)   //如果该通道未被初始化过               

      {

        ADC12->MCTL[InitialedChannel_Num].INCH = CH_Num;

        ADC12->MCTL[InitialedChannel_Num].REF  = SREF_RegValue;//参考电压选择,通道设置

        ADC_Channel_Bit[InitialedChannel_Num] = CH_Mask;//将该通道初始化标志置位                                                 InitialedChannel_Bit |= CH_Mask; //置位已初始化的通道标志位

        InitialedChannel_Num ++;//初始化的通道数加1

      }

      else //如果是之前已经初始化过的通道,则要在这里从新设置一下,只设置通道参考电压

      {

        ADC12->MCTL[ADC_GetChanelNum((ADC_CHn)CH_Mask)].REF = SREF_RegValue;//改变参考电压            

      }

    }

    CH_Mask <<= 1;

  }

  if(InitialedChannel_Num > 1)                 //有多个通道时要加上序列通道结束位

  {

    for(int i=0; i

    {

      ADC12->MCTL[i].EOS = RESET;

    }

    ADC12->MCTL[InitialedChannel_Num-1].EOS = BIT_SET;  //最后一通道加上序列通道转换结束位

  }

  //一般配置

  ADC12->SHT0 = M0_M7_SAMPLE_HOLD_TIME; //0-7通道采样与保持时间

  ADC12->SHT1 = M8_M15_SAMPLE_HOLD_TIME;//8-15通道采样与保持时间

  ADC12->ON = BIT_SET;/ 采样时间,AD内核开启

  ADC12->MSC = BIT_SET;

  ADC12->SSEL = ADC12_SSEL_ADC12OSC;//时钟选择

  ADC12->SHP = BIT_SET;

  //有多个通道时设为序列通道单次转换模式,单个通道时设为单通道单次转换模式   

  ADC12->CONSEQ = (InitialedChannel_Num > 1) ? BIT_SET : RESET;        

  //设置ADC精度

  ADC12->RES = nBit;    

  //开启时钟

  UCS->MODOSC_REQEN = BIT_SET; //ADC使用的是MODCLK 所以在这里配置该时钟,约5MHz左右

  //配置通道为第二功能

  if(ch & 0x00ff)

  {

     GPIO_MultiBits_Init(P6,(ch & 0x00ff),GPI | SEL);

  }

  if(ch & 0xf000)

  {

     GPIO_MultiBits_Init(P7,((ch & 0xf000)>>12),GPI | SEL);

  }

  if(ch & ADC_CH10) //如果使用了温度传感器通道,则开启温度传感器

  {

    ADC12->TCOFF = RESET;

  }

  ADC12->ENC = ENABLE;     //该位必须在初始化完成后再置位

  //DELAY_MS(5);     //延时等待参考电压建立

}


这里采样与保持间隔


//宏定义ADC12MEM8 to ADC12MEM15采样与保持时间  0-15

#define M8_M15_SAMPLE_HOLD_TIME  3

//宏定义ADC12MEM0 to ADC12MEM7 采样与保持时间  0-15

#define M0_M7_SAMPLE_HOLD_TIME   3


注意点 

1. 初始化后所有通道精度相同,即所有通道转换精度只取决于最后一次配置的精度 

2. 所有通道内部参考电压只能使用1.5或2.5V中的一种


使用示例:


ADC_Init(ADC_CH1+ADC_CH3,ADC_VREF_1_5V,ADC_10bit);        

//同时初始化两个通道,使用内部提供的1.5V参考电压,10位精度

1

2

3.采样实例

/*!

*     COPYRIGHT NOTICE

*     Copyright (c) 2016,CTGU-GB

*     All rights reserved.

*

*

* @file       main.c

* @brief      MSP430F5529 平台主程序


* @author     CTGU-GB

* @version    v2.7

* @date       2016-11-26

*/

#include "include.h"

double adcDataTest[20];

/*******************************************************************************

*  函数名称:ADC_Filter(u32 num,double *adcDataStorage)

*  功能说明:ADC滤波函数

*  作者:klaus 邮箱:xcf2016a@outlook.com

*  参数说明:uint8_t num 输入滤波数据个数

*            double *adcDataStorage:滤波数组

*  函数返回:滤波结果

********************************************************************************/

double ADC_Filter(uint8_t num,double *adcDataStorage)

{

  uint8_t i,j,k;

  uint8_t noswap=1;

  double adc_sum_tmp=0,adc_ave_tmp=0;


  for(i=0;i

      for(j=0;j

      {

          if(adcDataStorage[j]>adcDataStorage[j+1]){

              adcDataStorage[j]=adcDataStorage[j]+adcDataStorage[j+1];

              adcDataStorage[j+1]=adcDataStorage[j]-adcDataStorage[j+1];

              adcDataStorage[j]=adcDataStorage[j]-adcDataStorage[j+1];

              noswap=0;

          }

       }

      if(noswap) break;

  }

  for(k=2;k

  //adc_sum_tmp -= (adcDataStorage[0]+adcDataStorage[1]+adcDataStorage[num-2]+adcDataStorage[num-1]);    

  adc_ave_tmp=adc_sum_tmp/(num-4);

  adc_sum_tmp=0;


  return adc_ave_tmp;

}


void main()

{

  DisableInterrupts();          //禁止总中断


  LED_Init(LED_ALL);              //LED灯初始化

  OLED_Init();


  ADC_Init(ADC_CH2,ADC_VREF_3_3V,ADC_10bit);       //初始化通道,P6.1


  while(1)

  {  


    int i;

    for(i=0;i<20;i++)

    {

      adcDataTest[i]=ADC_ReadChanelOnce(ADC_CH2)*3.3/1023;

      DELAY_MS(10);

    }

    double ad = ADC_Filter(20,adcDataTest);

    OLED_PrintfAt(FONT_ASCII_8X16,0,0,"ADValue:\n%.3f V",ad);         //在指定位置打印


  }


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
实时控制.安全.如何加速实现未来工厂落地?