[MSP-EXP430G2ET] [MSP430G2 LaunchPad入门系列] 第6篇 - 模数转换器

  [复制链接]

17

主题

137

帖子

553

积分

单晶硅锭

Rank: 3Rank: 3

积分
553
查看: 17736回复: 19 发表于 2019-3-1 16:47:06   只看该作者
模/数转换器(ADC)可以称为单片机的“感觉器官”。因为单片机CPU处理的是数字信号,而现实世界中的输入信号往往是模拟量。因此我们必须把这些模拟信号转换成数字信号。有许多ADC芯片可以完成这个功能,但更方便的是使用MSP430中内置的ADC。本章中将介绍MSP430G2系列的10位模/数转换器ADC 10,并通过例程掌握ADC 10的基本用法。


本章目录如下:
章节题目
6.1模/数转换器基础
6.2MSP430 ADC 10 模块及配置
6.3ADC 10例程


MSP430G2 LaunchPad 相关资源链接:

本章内容PDF下载:
第六章-模数转换器.pdf (1.04 MB, 下载次数: 600)

17

主题

137

帖子

553

积分

单晶硅锭

Rank: 3Rank: 3

积分
553
发表于 2019-3-1 16:56:32   只看该作者
6.1 /数转换器基础

模/数转换器是单片机能够感知外部真实世界的一个不可或缺的环节。外部传感器输入进来的信号一般都是模拟信号(电压或电流),而单片机做运算或控制所需的信号一般是数字信号(二进制数),模/数转换器(Analog toDigital Converter,简称ADC)的作用正是将模拟信号转换为数字信号,是单片机能够感知外部世界的桥梁。

正因为ADC如此重要,所以现在很多处理器内部都集成了内部ADC,这样无需外部的ADC电路就可以直接处理电路中的模拟量。

6.1.png

下图中可以很直观的看出模拟信号转换为数字信号的过程。当ADC接收到一个模拟量时(例如电压信号),会自动将其转换成最接近的数字量。由于数字量是离散的,所以转换后的数字量一定是有误差的,误差的大小取决于ADC的分辨率,即下图中“台阶”的数量。分辨率越高,划分的越细,转换的结果与真实值的误差越小。市面上常见的ADC分辨率从8位到24位的都有,MSP430G2系列单片机中内置的ADC分辨率是10位。

6.2.jpg

另外ADC测量的范围是有限的。满量程时对应的模拟电压值就是它的测量范围,这个范围由参考电压(Vref)确定。ADC测量的模拟量范围不能超过这个量程,否则会得到错误的转换结果,甚至损坏单片机。在MSP430G2系列单片机中,Vref有多种选择,其内部有1.5V和2.5V两种预设的参考电压,也可以使用外部参考电压或者单片机供电电压作为参考电压。


6.1.1 采样/保持电路

由于采集的模拟信号是连续的,不会停在那里等ADC采样转换完成后才发生变化,因此ADC内部需要一个采样/保持电路,以保证从开始采样到转换完成这一段时间内输入信号是不变的。

采样/保持电路的核心是一个电容,如下图中的CSH。此电容与S1、S2两个开关配合,当S1闭合S2断开时,输入信号对CSH充电,称为采样;当S1断开S2闭合时,采样电容CSH上的电压维持不变供给ADC转换电路使用,称为保持。

6.3.png

由于给CSH充电的过程不是一瞬间完成的,需要一定的时间,这个充电时间我们称为采样保持时间(sample-and-hold time)。ADC开始转换的时机要与采样保持时间配合好。如果采样保持时间太短,CSH还没来得及完成充电,此时过早开始转换会产生误差;而如果采样保持时间太长,则会活生生把高速ADC拖累成低速ADC,浪费了ADC的性能。

在MSP430G2553的ADC中,可以人工调整采样保持时间,共有4档可以选择,分别为4/8/16/64个ADCCLK周期。通过ADC10CTL0寄存器中的ADC10SHTx位可以选择。

17

主题

137

帖子

553

积分

单晶硅锭

Rank: 3Rank: 3

积分
553
发表于 2019-3-1 17:06:19   只看该作者
本帖最后由 Shuyang 于 2019-3-1 17:08 编辑

6.2 MSP430 ADC 10 模块及配置

在MSP430G2553中集成了一个10位ADC,为了与其他MSP430系列中集成的12位ADC区分,我们将它称为ADC 10。在“MSP430x2xx Family User's guide”的第22章中详细介绍了ADC 10的特性及使用。

首先我们来了解一下ADC 10模块的主要特性:

1)    8通道,采样率200ksps,精度10位。
2)     带内部基准1.5V或2.5V,也可外接基准电压。
3)     内置通道可直接对内部温度传感器、芯片供电电压、和外部基准电压采样。
4)     AD采样起始信号可软件触发,也可由Timer_A控制。
5)     单通道单次采样、单通道重复采样、多通道轮流采样、多通道重复采样4种转换模式。
6)     可单独关闭ADC和基准电压源以便降低功耗。
7)     采样数据可自动存储在指定的存储空间中(这个功能比较独特)。

下面我们来具体介绍ADC 10模块的参数配置及使用。


6.2.1 10ADC内核

ADC 10模块的核心部分就是一个10位的模数转换器(ADC),它负责将模拟输入转换成数字量,并将结果储存到ADC10MEM这个寄存器中。模拟量的上限和下限分别由两个可调节的电压VR+和VR-决定,分别对应转换结果数字量1023和0。当输入值等于VR+时,输出的数字量NADC达到最大值1023(16进制值03FFh);当输入值等于VR-时,输出数字量为0。转换结果和输入的关系为:


Capture1.PNG

ADC 10模块通过ADC10CTL0和ADC10CTL1这两个寄存器来配置。当ADC10ON寄存器位置1时,ADC被使能。需要注意的是有一些寄存器位(下图中灰色部分)必须在ENC=0时才能够进行配置,具体定义如下。

6.4.png

6.5.png

请注意上面只给出了部分寄存器位的解释,未列出的部分请参考“MSP430x2xxFamily User's guide”的第22.3节。下面我们将具体介绍这些寄存器位的功能。


6.2.2 时钟选择

ADC10CLK负责为ADC 10提供时钟。通过ADC10SSELx可以选择ADC10CLK的时钟源。共有4种选择,分别为ADC10OCS、ACLK、MCLK和SMCLK。

默认情况下时钟源是ADC10OCS,这是一个内置的5MHz振荡器。选择一个时钟源之后,必须保证在ADC完成转换之前该时钟源保持在活动状态下。如果在转换完成前关闭时钟源,将得到错误的转换结果。


6.2.3 输入配置

ADC 10模块的输入可以来自于A0-A7模拟输入引脚,并且还可以采集内部温度传感器、芯片供电电压、以及外部基准电压采样。通过INCHx寄存器位可以选择输入通道。

当使用A0-A7作为输入时,不要忘记将相应的GPIO配置为ADC输入功能。MSP430G2553共有8个引脚(P1.0-P1.7)可以作为模拟输入端。

6.6.png

从MSP430G2553 datasheet中Port Schematics部分可以看到,只要将ADC10AE.x和INCH.x同时置为1,对应的GPIO就会自动配置为ADC输入功能。而P1DIR、P1SEL和P1SEL2寄存器的值无需关心,但CAPD寄存器(比较模块)必须设为0。

6.7.png


6.2.4
参考电压选择


ADC 10模块内部可以生成一个参考电压,且此参考电压VREF+可以在1.5V和2.5V两档中选择。将REFON设为1即可使能内部参考电压,然后配置REF2_5V可以选择参考电压的数值。REF2_5V=1时参考电压为2.5V,REF2_5V=0时(默认状态)参考电压为1.5V。

如果内部参考电压无法满足要求,也可以使用外部参考电压VeREF。A4和A3两个引脚可以分别作为外部参考电压VR+和VR-的输入端。

在本章中我们曾介绍过ADC输出与输入的关系:

Capture2.PNG

其中VR+和VR-分别是模拟输入的上限和下限。此上/下限可以通过寄存器位SREFx来配置,一般来说我们会令VR+等于内部参考电压或者芯片供电电压Vcc,VR-等于0(即Vss)。例如我们选择VR+=1.5V内部参考电压,那么输入输出关系就变为:

Capture3.PNG

VR+和VR-也可以设为其他模式,具体参考SREFx寄存器位的定义:

6.8.png

在使用内部参考电压时,还需要注意一点,就是参考电压改变之后需要一定的时间来到达稳定状态。根据MSP430G2553 datasheet中的说明,内部参考电压改变后大约需要30us来建立稳定状态。因此程序中改写参考电压之后不要忘记用延时来等待参考电压达到稳态。

6.9.png


6.2.5 ADC 10中断

当AD转换过程完成,数据被载入ADC10MEM寄存器之后,ADC 10模块会产生中断信号,ADC10IFG标志位被置为1。如果ADC10IE使能位和全局中断使能位GIE都被开启,那么ADC10IFG置1时就会进入ADC中断**函数。ADC中断向量名称为ADC10_VECTOR。当中断**函数退出时,ADC10IFG会被自动清零。


6.2.6 单次转换与连续转换

ADC 10共有4种转换方式,可以通过寄存器位CONSEQx来选择。

6.10.png

4种转换方式分别如下:

  • 单次转换:转换一次,完成后即停止。
  • 顺序转换:按顺序转换从Ax(x的值由INCHx寄存器选择)到A0通道依次转换。
  • 重复单次转换:重复对某个通道进行转换。
  • 重复顺序转换:重复进行顺序转换。

各个转换方式的详细执行步骤请参考“MSP430x2xxFamily User's guide”的第22.2.6节。

17

主题

137

帖子

553

积分

单晶硅锭

Rank: 3Rank: 3

积分
553
发表于 2019-3-1 17:11:13   只看该作者
本帖最后由 Shuyang 于 2019-3-1 17:12 编辑

6.3 ADC 10例程

下面我们通过例程来一步一步地演练ADC 10模块的使用。本例程的目标是对A1引脚输入的电压进行转换,并用P1.0连接的LED来表示转换结果。如果结果大于1V,则让LED亮起。

可以用1节干电池作为输入连接到A1引脚,或使用电源提供一个1.5V的电压作为输入。为了采集这个电压,我们使用内部的2.5V参考电压,ADC时钟保持默认。

下面我们来介绍ADC转换的具体实现步骤。


1)    关闭看门狗

与其他程序一样,首先需要关闭看门狗。
  1. #include <msp430.h>

  2. int main(void)
  3. {
  4.   WDTCTL = WDTPW + WDTHOLD;                         // Stop watchdog timer
  5.     …
复制代码


2)    ADC 10模块进行初始化

在初始化语句中需要选择ADC的时钟、输入、参考电压等关键参数。在本例程中我们使用默认时钟,A1引脚作为输入,使用内部2.5V参考电压。注意在改写参考电压之后不要忘记延时,以等待参考电压达到稳定。

输入通过ADC10CTL1和ADC10AE0这两个寄存器来设置;参考电压通过ADC10CTL0寄存器来设置,另外还需要打开ADC10模块,并使能ADC10模块的中断,因为我们后续需要使用中断来进行低功耗模式的切换。
  1.     …
  2.   // Set Ref as internal 2.5V, ADC10ON, enable interrupt
  3.   ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + REF2_5V + ADC10ON + ADC10IE;
  4.   _delay_cycles(30);                // Delay to allow Ref to settle
  5.   ADC10CTL1 = INCH_1;
  6.   ADC10AE0 |= 0x02;             // Set P1.1 as A1 input
  7.     …
复制代码


3)    初始化P1.0

为了使用LED来表示转换结果,需要将P1.0初始化为输出引脚。
  1.     …
  2.   P1DIR |= 0x01;                        // Set P1.0 to output direction
  3.     …
复制代码


4)    编写一个无限循环,在其中进行AD转换,并将转换结果与预设值(1V)进行比较

初始化完成之后,就要开始真正的AD转换过程了。我们使用一个无限循环,在每个循环中进行一次采样和转换,并将转换结果与预设值(1V)进行比较。如果转换结果大于预设值,则点亮LED灯。

为了进行比较,需要将预设值进行换算。因为参考电压为2.5V,对应转换结果为1023。那么预设值1V所对应的转换结果应为409。故我们将采集来的电压所转换的结果与409进行比较,若小于409则LED熄灭,若大于409则LED点亮。

同时置位ENC和ADC10SC,则ADC开始进行转换。由于转换需要一定的时间,我们在不知道具体需要多久的情况下可以先令单片机进入低功耗模式,并留下中断入口。当转换完成后会自动进入ADC中断**函数,在中断**函数中退出低功耗模式,就可以回到主程序执行比较语句。
  1.     …
  2.   for (;;)
  3.   {
  4.     ADC10CTL0 |= ENC + ADC10SC;                // Sampling and conversion start
  5.     __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exi
  6.     if (ADC10MEM < 409)                        // ADC10MEM = A1 > 1.0V?
  7.       P1OUT &= ~0x01;                        // Clear P1.0 LED off
  8.     else
  9.       P1OUT |= 0x01;                        // Set P1.0 LED on
  10.   }
  11.     …
复制代码


5)    利用ADC中断强制退出低功耗模式

如上一步中所解释,ADC中断**函数的任务是等待转换完成,并退出低功耗模式。因此中断**函数中的代码很简单,只有一句退出低功耗模式的语句。

ADC 10模块的中断向量名称是ADC10_VECTOR。
  1. // ADC10 interrupt ** routine
  2. #pragma vector=ADC10_VECTOR
  3. __interrupt void ADC10_ISR (void)
  4. {
  5.   __bic_SR_register_on_exit(CPUOFF);                // Clear CPUOFF bit from 0(SR)
  6. }
复制代码


6)    总结

将上述步骤总结起来,可以得到完整的ADC例程。
  1. #include <msp430.h>

  2. int main(void)
  3. {
  4.   WDTCTL = WDTPW + WDTHOLD;                         // Stop watchdog timer

  5.   // Set Ref as internal 2.5V, ADC10ON, enable interrupt
  6.   ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + REF2_5V + ADC10ON + ADC10IE;
  7.   _delay_cycles(30);                // Delay to allow Ref to settle
  8.   ADC10CTL1 = INCH_1;
  9.   ADC10AE0 |= 0x02;             // Set P1.1 as A1 input

  10.   P1DIR |= 0x01;                        // Set P1.0 to output direction
  11.   for (;;)
  12.   {
  13.     ADC10CTL0 |= ENC + ADC10SC;                // Sampling and conversion start
  14.     __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exi
  15.     if (ADC10MEM < 409)                        // ADC10MEM = A1 > 1.0V?
  16.       P1OUT &= ~0x01;                        // Clear P1.0 LED off
  17.     else
  18.       P1OUT |= 0x01;                        // Set P1.0 LED on
  19.   }

  20. // ADC10 interrupt ** routine
  21. #pragma vector=ADC10_VECTOR
  22. __interrupt void ADC10_ISR (void)
  23. {
  24.   __bic_SR_register_on_exit(CPUOFF);                // Clear CPUOFF bit from 0(SR)
  25. }
复制代码


17

主题

137

帖子

553

积分

单晶硅锭

Rank: 3Rank: 3

积分
553
发表于 2019-3-5 12:28:52   只看该作者
本章参考资料:     
  
1.     《从零开启大学生电子设计之路--基于MSP430 LaunchPad口袋实验平台》,杨艳,傅强编著,北京航空航天大学出版社,2014年8月第1版。
2.     “MSP Design Workshop” by TexasInstruments, Version 4.60, May 2016, http://processors.wiki.ti.com/index.php/MSP_Design_Workshop
3.     “Getting Started with the MSP430G2553Value-Line LaunchPad Workshop” by Texas Instruments, Version 2.22, July 2013, http://processors.wiki.ti.com/in ... _LaunchPad_Workshop
4.     MSP430G2553 datasheet (Rev.J), May2013, http://www.ti.com/mcu/docs/litab ... 2&familyId=1937
5.     MSP430x2xxFamily User's Guide, SLAU144J, http://www.ti.com/cn/lit/pdf/slau144
6.     MSP-EXP430G2LaunchPad Evaluation Kit User's Guide, SLAU318G, March 2016, http://www.ti.com/cn/lit/pdf/slau318

0

主题

24

帖子

8

积分

一粒轻沙

Rank: 1

积分
8
发表于 2019-3-12 22:22:08   只看该作者
太棒了,超级实用非常好

0

主题

7

帖子

80

积分

一粒轻沙

Rank: 1

积分
80
发表于 2019-3-26 13:36:34   只看该作者
Shuyang 发表于 2019-3-1 17:11
6.3 ADC 10例程

下面我们通过例程来一步一步地演练ADC 10模块的使用。本例程的目标是对A1引脚输入的电压进 ...

顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶

0

主题

14

帖子

53

积分

一粒轻沙

Rank: 1

积分
53
发表于 2019-4-21 18:36:40   只看该作者
好!谢谢分享

0

主题

3

帖子

57

积分

一粒轻沙

Rank: 1

积分
57
发表于 2019-5-18 16:12:01   只看该作者
Shuyang 发表于 2019-3-1 17:11
6.3 ADC 10例程

下面我们通过例程来一步一步地演练ADC 10模块的使用。本例程的目标是对A1引脚输入的电压进 ...

受益匪浅

0

主题

24

帖子

20

积分

一粒轻沙

Rank: 1

积分
20
发表于 2019-7-10 20:25:24   只看该作者
好,我鼓掌

0

主题

6

帖子

232

积分

二氧化硅

Rank: 2

积分
232
发表于 2019-7-17 09:27:56   只看该作者
非常感谢

0

主题

14

帖子

6

积分

一粒轻沙

Rank: 1

积分
6
发表于 2019-7-24 10:28:50   只看该作者
谢谢分享

0

主题

2

帖子

1

积分

一粒轻沙

Rank: 1

积分
1
发表于 2019-7-24 10:39:03   只看该作者
Arduino 发表于 2019-3-12 22:22
太棒了,超级实用非常好


太棒了,超级实用非常好

0

主题

2

帖子

1

积分

一粒轻沙

Rank: 1

积分
1
发表于 2019-7-24 10:41:28   只看该作者

谢谢!!

0

主题

1

帖子

2

积分

一粒轻沙

Rank: 1

积分
2
发表于 2019-8-5 14:40:30   只看该作者
Shuyang 发表于 2019-3-1 17:06
6.2 MSP430 ADC 10 模块及配置

在MSP430G2553中集成了一个10位ADC,为了与其他MSP430系列中集成的12位ADC ...

很好,正好很需要这份资料

0

主题

1

帖子

54

积分

一粒轻沙

Rank: 1

积分
54
发表于 2019-8-7 22:42:21   只看该作者
请问msg432p401如何产生模拟量输出,输出一个1.5v的电压。可以吗?还有我想问一下,为什么这个板子高电平是3.3v,是所以引脚都这样吗,还是可以切换,谢谢了

0

主题

2

帖子

68

积分

一粒轻沙

Rank: 1

积分
68
发表于 2019-8-7 22:52:18   只看该作者
楼主讲的很详细

0

主题

2

帖子

102

积分

二氧化硅

Rank: 2

积分
102
发表于 2020-7-31 16:04:33   只看该作者
谢谢分享!!!

0

主题

1

帖子

50

积分

一粒轻沙

Rank: 1

积分
50
发表于 2020-8-8 12:04:25   只看该作者
于昊言 发表于 2019-8-7 22:42
请问msg432p401如何产生模拟量输出,输出一个1.5v的电压。可以吗?还有我想问一下,为什么这个板子高电平是 ...

这个·板子只有模数转换(就是AD)模块,没有DA模块哦。

0

主题

1

帖子

8

积分

一粒轻沙

Rank: 1

积分
8
发表于 2020-9-20 20:18:45   只看该作者
请问外部参考电压的大小有范围限制吗 还是必须要在板子的工作电压之间?谢谢
快速回复 返回顶部 返回列表