历史上的今天
返回首页

历史上的今天

今天是:2025年03月14日(星期五)

正在发生

2019年03月14日 | MSP430F5529 ADC参考

2019-03-14 来源:eefocus

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;         //参考电压


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

 3 

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

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<(InitialedChannel_Num-1); 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);         //在指定位置打印


  }

}

推荐阅读

史海拾趣

GSR Technology Ltd公司的发展小趣事

随着技术的成熟和市场的认可,GSR Technology Ltd开始寻求国际合作机会,以进一步扩大其市场影响力。公司与欧洲一家知名雷达制造商达成战略合作,共同开发面向全球市场的先进GSR系统。这一合作不仅提升了公司的产品竞争力,还为公司打开了欧洲市场的大门。随后,公司逐步在北美、亚洲等地设立分支机构,实现了全球化布局。

Econais公司的发展小趣事

Econais公司成立于XXXX年,其创始人是一群在无线通信技术领域拥有深厚背景和丰富经验的工程师。他们看到了物联网(IoT)和机器对机器(M2M)通信的巨大潜力,并希望通过自己的技术,为全球的设备提供高效、稳定的无线连接方案。于是,Econais应运而生,专注于研发超低功耗(ULP)和高性能的无线模块。

Efficient Power Conversion公司的发展小趣事

随着EPC公司氮化镓技术的不断完善和成熟,其产品开始受到市场的广泛认可。无线电源传送、全自动汽车、高速移动通信等领域的企业纷纷采用EPC公司的氮化镓功率半导体器件,以提高其产品的性能和效率。EPC公司的市场份额逐渐扩大,成为氮化镓功率管理技术领域的领军企业。

Bombardier Inc公司的发展小趣事

随着全球航空市场的不断变化,庞巴迪公司在商用航空领域也取得了显著成就。其生产的CRJ系列区域喷气客机和Q系列涡桨飞机在全球范围内广受欢迎。这些飞机配备了先进的电子设备和系统,提供了更高的安全性和舒适性。庞巴迪还推出了C系列单通道中距客机,该机型以其环保、经济和人性化的设计赢得了市场的广泛认可。

柯爱亚(ceaiya)公司的发展小趣事

为了保持技术领先地位,柯爱亚不断加大研发投入,引进先进的研发设备和人才。公司在功率电感、变压器等领域取得了多项技术成果,并申请了多项专利。这些技术成果不仅提升了柯爱亚产品的竞争力,还推动了整个电子行业的发展。

對餘科技(DIOFIT)公司的发展小趣事

随着科技的不断发展,DIOFIT公司始终将技术创新作为发展的核心驱动力。他们不断投入研发资金,引进先进技术和人才,致力于研发具有自主知识产权的电子产品。在物联网、人工智能等前沿领域,DIOFIT公司取得了一系列突破性的成果,推出了一系列具有竞争力的产品,成为行业内的技术创新引领者。

问答坊 | AI 解惑

电感,变压器

请问下滤波电感变压器的原理和作用?,最好能发个图看看,长什么样?谢谢!…

查看全部问答>

信号链基础--运放

信号链基础--运放…

查看全部问答>

寻找RFID及嵌入式开发合作伙伴

本公司寻找有创业激情和梦想的志同道合者,发展方向是RFID及嵌入式开发…

查看全部问答>

现在用得比较多的8位单片机是什么型号的?

现在用得比较多的8位单片机是什么型号的?需要价格比较便宜一点的,带A/D的,I/O比较多的.…

查看全部问答>

怎样使用PB5.0的断点功能

如题,没怎么用过,这次我用的是X86的平台模拟器,在这个基础上想使用断点来跟踪程序请教高手怎么使用这个功能?…

查看全部问答>

关于液晶屏的驱动问题求助?

我有一块ARM7 S3C44B0的开发板,我最近买了一个320X240的液晶屏。 商家提供了320X240.bin的驱动,但是我不知道怎么把驱动加载到开发板的系统中。 我刚开始学这个,我想检验一下这块屏能不能正常使用。哪位高人能不能详细解释一下??…

查看全部问答>

请问做一个USB管理软件的流程?

请问做一个USB管理软件的流程?…

查看全部问答>

请教linux下并口的操作的问题

我向请教下一个问题: 我想对PC机并口进行操作,操作步骤是这样的; 先用ioperm(0x378,3,1);取得控制权,然后 _outp(0x378,0x55); 但是用_inp(0x378)读出的数据是255,是我哪地方用的不对的吗? …

查看全部问答>

Cortex-M3与ARM7TDMI-S内核MCU运算性能比较

还是21IC人气旺,转一篇我在EDN的博文:http://blog.ednchina.com/htjgdw/140162/message.aspx自从STM32推出后,我对它很感兴趣,由于它采用了ARM的Cortex-M3内核,所以很想了解一下其性能和ARM7相比究竟如何?很巧的机会知道了EDNCHINA,参加了EDN ...…

查看全部问答>

用ST的CORTEX-M3,感觉如行云流水阿

                                 IAR + FWLib 那是相当顺手…

查看全部问答>