Blogs

MSP430 LaunchPad教程 - 第3部分 - ADC

enrico garante.2013年6月25日8评论

在我们进入MSP430的新一集中,我将解释MSP430G2231上的模拟到数字转换的基础。我们将写入将读取ADC通道的程序,并将根据转换结果切换一些LED。 

快速链接

我们将像MSP430G2231的标题文件一样开始,LED文件和将存储转换结果的变量的定义一起开始。我们还声明了一个将初始化ADC模块的函数。
[code c]

本文以PDF格式提供,便于打印

#include“msp430g2231.h”

#define LED0 Bit0. 

#define led1 bit6. 

unsigned int值= 0;

[/代码]

ConfigUreadc功能将设置ADC模块。 
与之 ADC10CTL1. 注册我们选择ADC输入通道和ADC时钟部(来自ADC10内部振荡器,5MHz)。
然后我们选择ADC模块(VCC)的内部电压参考 SREF_0,打开它(ADC10ON.)启用ADC10中断(ADC10ie.)。
最后,我们通过设置来将P1.5连接到ADC模块 ADC10A0. 相应登记。

[码c]

void configureadc(void)

{

   / *配置ADC通道* /

   ADC10CTL1 = inch_5 + ADC10DIV_3; //通道5,ADC10CLK / 4

   ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10ie; // vcc&vss作为参考

   ADC10AE0 |= BIT5; //P1.5 ADC option

}

[/代码]

在主函数中,我们会像往常一样停止看门狗定时器,设置时钟和LED。 

然后我们通过设置adc模块为ADC模块选择输入引脚 P1SEL 登记。之后,我们使用configureadc()初始化ADC并启用ADC中断,这将让我们知道在制作转换时,其结果已准备就绪。

[码c]

void main(空白)

{

   wdtctl = wdtpw + wdthold; //停止WDT.

   bcsctl1 = calbc1_1mhz; //设置范围

   dcoctl = caldco_1mhz;

   BCSCTL2 &= ~(DIVS_3);// smclk = dco = 1MHz

   P1DIR | = LED0 + LED1;

   p1sel | = bit5; // ADC输入引脚P1.5

   P1OUT &= ~(LED0 + LED1);


   ConfigureAdc();

   __enable_interrupt(); //启用中断。

[/代码]

在初始化代码之后,我们等待一些循环使ADC电压参考稳定到稳定的级别,然后我们通过设置来开始转换 ADC10CTL0. register. 

然后我们进入低功耗模式以节省电池汁:我们将在我们的“值”变量中直接转换结果 ADC10MEM 由于ADC10中断注册。然后,中断将返回活动模式并继续主要。 最后,我们简单地根据存储到“值”的数字以Launchpad上的LED(不要忘记我们有一个10位ADC模块,因此最大值为1023)。
您可以进行一些进一步的计算,也许平均结果获得更精确的阅读。

[码c]

   while(1)

   {

      __delay_cycles(1000); //等待ADC Ref解决

      ADC10CTL0 | = ENC + ADC10SC; //抽样和转换开始

      __bis_sr_register(cpuoff + gie); // LPM0启用中断

      value = ADC10MEM;

      if (value>511)

      {

         P1OUT &= ~(LED0 + LED1);

         P1OUT |= LED0;

      }

      else

      {

         P1OUT &= ~(LED0 + LED1);

         P1OUT |= LED1;}

      }

   }

}

[/代码]

正如我们所见为Timera模块所见,下一个是ADC10中断服务例程。 

我们只是退出低功耗模式,让主程序使用ADC的结果进行一些计算。

[码c]

// ADC10中断服务例程

#pragma矢量= adc10_vector

__interrupt void ADC10_ISR(void)

{

   __bic_sr_register_on_exit(cpuoff); //返回活动模式

}

[/代码]

那就是它!非常简单吧?让我们看看更先进的东西。

多次转换

现在我们希望在每个循环中一次从多个输入引脚获得广告转换的结果。

首先,我们定义一个将存储每个频道的转换结果的数组

[码c]

#define adc_channels 5 //我们将为5个频道进行示例 

unsigned int样本[adc_channels]; 

[/代码]

在主循环中,在转换开始之前,我们添加了
[码c]

ADC10CTL0..&= ~ENC;

而(ADC10CTL1.& BUSY);

ADC10SA =(无符号INT)样本;

[/代码]

使用此行我们指定转换结果应在先前创建的数组中自动存储:以此方式,无需访问 ADC10MEM 注册了不起。数据将立即准备好进行计算。 

在这种情况下,Configureadc函数变为

[码c]

void configureadc(void)

{

   / *配置ADC通道* /

   ADC10CTL1 = inch_4 + ADC10DIV_0 + CONSEQ_3 + SHS_0; //从通道5开始的多通道重复转换

   ADC10CTL0 = SREF_0 + ADC10SHT_2 + MSC + ADC10ON + ADC10IE;

   ADC10AE0 = Bit4 + Bit3 + Bit2 + Bit1 + Bit0;

   ADC10DTC1 = ADC_CHANNELS; // adc_channels定义为5

}

[/代码]

CONSEQ_3. 启用多通道重复的转换模式。
INCH_4 我们选择起始频道(在这种情况下,我们从通道5开始,然后我们将通道4一直到通道0)。我们将ADC与那些带有的销钉 ADC10A0. 登记。
MSC. 启用多通道转换。
ADC10DTC1. 定义我们转移到我们以前创建的数组ADC_CHANCELS的数据块(每个通道转换的块)。

可变观察

这是一个图像,它将解释如何在调试时使用CCS观看变量(单击它以缩放)。通过这种方式,我们可以在每个程序循环中读取广告转换的值。

可变观看CCS

在下一个剧集中,我们将学习使用UART连接,所以保持调整!


[]
评论 Xavier_A.2016年11月14日

非常感谢您的帮助,它适用于MSPG2553 !!来自México的问候语

[]
评论 Mik232014年11月23日
你好。
谢谢你的良好教程,到目前为止,他们已经救世了。
我对此有一些麻烦,我不知道从哪里开始寻找问题。

授予我正在使用2553而不是2231,我缺少修复了一个用于使第一个教程在他的2553上工作的人,但没有结果。

你能告诉我正确的方向寻找修复吗?谢谢。
[]
评论 Mik232014年11月23日
没关系,我只是不知道我必须将芯片连接到相同的GND电压发生器连接到。
这是一个解决了一切。

如果可以的话,我会删除以前的评论,但如果我将来有人像我一样愚蠢,我就不能把它发布。
[]
评论 istemihan2015年4月25日
嗨,这个教程绝对是惊人的。但是,在本章中我收到了这个错误:

// -------代码下面
P1OUT &= ~(LED0 + LED1);

P1OUT |= LED1;}

}

}

} ///这是我第一次错误的地方:#171预计宣言

// ADC10中断服务例程

#pragma矢量= adc10_vector //这是第二个错误:#609这个Pragma必须在声明之前立即

__interrupt void ADC10_ISR(void)

{

__bic_sr_register_on_exit(cpuoff); //返回活动模式

}
// --------代码结束


我使用G2553,但是,我检查了寄存器名称和细节。它们大多是同样的,那里没有问题。你能给我任何建议吗?谢谢。
[]
评论 istemihan2015年4月25日
嗨,我认为你忘记了额外的“}”终点的一线,几乎不可能注意到:)

引用:

P1OUT.|= LED1;}

[]
评论 Cravisjan97 @ Gmai.5月22日2015年5月22日
感谢您的教程。我想在找到ADC值的时间来扩展代码>511.
这是我的代码片段和if(t<3000000) is always 执行。请 help me.
如果(价值>511)
TA1R=0;
//将ADC10MEM中的值分配给名为ADC_VALUE的整数

else
{
t=TA1R;

if(t<3000000)
{P1OUT&=~(BIT0+BIT6);
P1OUT|=BIT0;
}
else
{P1OUT&=~(BIT0+BIT6);
P1OUT|=BIT6;

}

}
[]
评论 Cravisjan97 @ Gmai.5月22日2015年5月22日
感谢您的教程。我想在找到ADC值的时间来扩展代码>511.
这是我的代码 片段 if(t<3000000)总是被执行。请帮助我。

如果(价值>511)
TA1R=0;

else
{
t=TA1R;

if(t<3000000)
{P1OUT&=~(BIT0+BIT6);
P1OUT|=BIT0;
}
else
{P1OUT&=~(BIT0+BIT6);
P1OUT|=BIT6;

}

}
[]
评论 Yara222015年11月2日
你的教程很棒!但我特别有问题。如果我必须向PIN 5发送电压以进行转换,我只是不确定性;我的意思是,连接电压发生器或类似的东西。

要发布回复评论,请单击连接到每个注释的“回复”按钮。发布新的评论(不是回复评论),请在评论的顶部查看“写评论”选项卡。

注册将允许您参加所有相关网站的论坛,并为您提供所有PDF下载。

注册

我同意 使用条款隐私政策.

尝试我们偶尔但流行的时事通讯。非常容易取消订阅。
或登录