MSP430的ADC12模块使用及代码(寄存器) 您所在的位置:网站首页 adc文件怎么转换 MSP430的ADC12模块使用及代码(寄存器)

MSP430的ADC12模块使用及代码(寄存器)

2024-07-13 12:12| 来源: 网络整理| 查看: 265

        以我的MSPf5529LP为例,它有A0-A15共计16个输入通道,其中有12个是外部通道。与之相应地,ADC12部分有相当多的各种寄存器,接下来一一介绍,最后依然附上一些代码。

目录

寄存器介绍

ADC12CTLn                ADC12MEMx                ADC12MCTLx

ADC12IE                     ADC12IFG                    ADC12IV

例程

温度传感器                  灰度传感器

总结

寄存器介绍

        由于其为数众多的通道数,ADC12有相当可观数量的寄存器,但是去除重合的一些后只有6个,它们分别负责处理一些功能。

ADC12CTLn

        它分为CTL0、CTL1、CTL2。三者的功能区别也不小,分别介绍一下。然后ADC12CTL0的设置很多,ADC12CT1和ADC12CTL2的操作我用到不多,查到的资料也不多,所以对它的讲解会和机翻很像。

        ADC12CTL0

ADC12SHTnx

这一位寄存器控制采样时间的长度

ADC12SHT1x负责通道8-15,ADC12SHT0x负责通道0-7

二者都是4位的,所以可以写出0-15的所有数字

ADC12SHTnx = xxxx b(四位二进制数),如果将二进制数化为十进制数y

那么采样时间的长度即为2^(2+y)个ADC12CLK时钟周期长度

ADC12MSC

如果机翻的话翻成混合采样,实际上就是连续采样,只在多通道或连续采样时才可用

0  采集到SHI的上升沿信号时触发采样和转换

1  在第一次采集到SHI上升信号后,每次采样转换完成立刻执行下一次

ADC12REF2_5V

控制参考电压(只在下面那个REFON置1时可用)

0  参考电压为1.5V

1  参考电压为2.5V

ADC12REFON

是否选择参考

0  不选择

1  选择使用参考

ADC12ON

打开ADC12_A

0  关闭

1  打开

ADC12OVIE

ADC12MEMx(储存x通道采集到的数据的寄存器,后面会说)的溢出中断使能,如果设置这位的话GIE中断也要配一下

0  失能

1  使能

ADC12TOVIE

ADC12转换超时(时间的“溢出”)使能,如果设置这位的话GIE中断也要配一下

0  失能

1  使能

这一位和上一位用的都很少

ADC12ENC

使能转换,这一位的地位有些特殊

0  失能

1  使能

所有其他寄存器的更改配置操作都要在这一位为0时配置

ADC12SC

启动转换,它会在开始后自动复0,所以要在循环里手动置1

0  不要开始采样

1  开始采样

        ADC12CTL1

ADC12CSTARTADDx数据起始地址,从0到F,对应MEM0-MEM15ADC12SHSx

采样-保持源的选择

00  ADC12SC

01  10  11  这三个取决于具体型号

ADC12SHP

采样-保持 脉冲-模式选择

0  SAPCON信号源自采样输入信号

1  SAMPCON信号源自采样定时器

ADC12ISSH

反转采样信号(0和1反转)

0  不反转

1  反转

ADC12DIVx分频系数。有三位,所以可以1-8分频ADC12SSELx

选择时钟,同样是ACLK和SMCLK更常用

00  ADC12OSC(MODCLK)

01  ACLK

10  MCLK

11  SMCLK

ADC12CONSEQx

转换模式,这个根据实际需要来使用

00  单通道单采集

01  多通道单采集

10  单通道多采集

11  多通道多采集

ADC12BUSY

标志当前是否有操作

0  无操作

1  有操作

        ADC12CTL2

ADC12PDIV

控制时钟预分频系数

0  1分频(不分频)

1  4分频

ADC12TCOFF

控制ADC12外接的温度传感器,不用的话最好关闭省电,置1才是关闭

注意:这一位只有在REFMSTR置0时才可用

0  开启

1  关闭

ADC12RES

这个位定义了转换结果分辨率

00  8位(9个时钟周期转换时间)

01  9位(11个时钟周期转换时间)

10  10位(13个时钟周期转换时间)

11  保留(就是暂时先不用)

ADC12DF

数据回读格式

0  无符号

1  有符号

ADC12SR

配置采样率

0  最高约200kps

1  最高约50kps

ADC12REFOUT

参考输出,只在REFMSTR置0时有效

0  关闭

1  开启

ADC12REFBURST

设置缓冲器的

0  持续打开缓冲器

1  只在采样转换时打开缓冲器

ADC12MEMx

         就是通过前面ADC12CSTARTADDx那一位寄存器控制送到这些寄存器里以供使用。

ADC12MCTLx

ADC12EOS

表明是采样序列的最后一个,这样说可能有些抽象,看一下代码就清楚了

0  不是结尾

1  是结尾

ADC12SREFx选择参考,一共有8个,全部贴出来太多了ADC12INCHx选择输入通道,四位对应到A0-A7,内部参考,A13-A15共计十五个通道 ADC12IE

        看着很哈人,但是实际上只要使能你需要的通道就可以了,并不麻烦。

ADC12IFG

         当对应的通道号引起中断后,对应IFG置1。

ADC12IV

         类似于TAxIV,它也可以记录到底是哪一位引起了中断。

例程

        有关寄存器的介绍终于算是结束了,这么多的内容可能对阅读不那么友好,接下来跟着例程看寄存器怎么配置,AD采集的例子不多,全部都是抽象的也不太好,结合具体的外设来看。我介绍两个,一个温度传感器,一个灰度传感器,正好契合一个单通道采集和一个多通道采集。

温度传感器

        这个传温度的传感器跳动可能比较大,我自己测的时候一直在27℃-29℃跳变。具体想要查看温度数值的话可以debug,在观察窗口里面看,或者添加一个OLED也可以,我自己是加了OLED的,但是因为本篇的篇幅太长了,于是将之删去。

#include #define CALADC12_15V_30C *((unsigned int *)0x1A1A) #define CALADC12_15V_85C *((unsigned int *)0x1A1C) //这两个宏定义用于温度校准使用,不必在意,校准30和85 #define REF_30C CALADC12_15V_30C #define REF_85C CALADC12_15V_85C unsigned int temp; volatile float temperatureDegC; volatile float temperatureDegF; //volatile类型的变量主要是因为单片机访问机制的问题,如果不加上这一位可能导致读取的数据不变 int main(void) { WDTCTL = WDTPW + WDTHOLD; REFCTL0 &= ~REFMSTR; // 将REFMSTR置0以设置参考 ADC12CTL0 = ADC12ON + ADC12SHT0_8 + ADC12REFON ; //打开ADC12;设置采样时间;开启参考(未设置ADC12REF2_5V位,故参考电压1.5V) ADC12CTL1 = ADC12SHP; // 以采样定时器为SAMPCON信号源 ADC12IE = 0x001; // 使能MEM0的IFG中断 __delay_cycles(100); // 等待ref设置完成 ADC12CTL0 |= ADC12ENC; while(1) { ADC12CTL0 &= ~ADC12SC; // 手动停止上一次采集 ADC12CTL0 |= ADC12SC; // 重新开始新的一次 __bis_SR_register(LPM4_bits + GIE); // 进入低功耗模式4并使能中断(等待采样完成) //在中断结束后会自动退出低功耗模式,就进入了下面的计算 temperatureDegC=(float)(((long)temp-REF_30C)*(85 - 30))/(REF_85C - REF_30C)+30.0f; temperatureDegF = temperatureDegC * 9.0f / 5.0f + 32.0f; } } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC12_VECTOR __interrupt void ADC12ISR (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(ADC12IV,34)) { case 0: break; // Vector 0: 无 case 2: break; // Vector 2: ADC 溢出 case 4: break; // Vector 4: ADC 超时 case 6: // Vector 6: ADC12IFG0 temp = ADC12MEM0; __bic_SR_register_on_exit(LPM4_bits); break; case 8: break; // Vector 8: ADC12IFG1 case 10: break; // Vector 10: ADC12IFG2 case 12: break; // Vector 12: ADC12IFG3 case 14: break; // Vector 14: ADC12IFG4 case 16: break; // Vector 16: ADC12IFG5 case 18: break; // Vector 18: ADC12IFG6 case 20: break; // Vector 20: ADC12IFG7 case 22: break; // Vector 22: ADC12IFG8 case 24: break; // Vector 24: ADC12IFG9 case 26: break; // Vector 26: ADC12IFG10 case 28: break; // Vector 28: ADC12IFG11 case 30: break; // Vector 30: ADC12IFG12 case 32: break; // Vector 32: ADC12IFG13 case 34: break; // Vector 34: ADC12IFG14 default: break; } } 灰度传感器

        是P6.0到P6.4五个引脚,对应五路灰度传感器。

#include volatile unsigned int A0results; volatile unsigned int A1results; volatile unsigned int A2results; volatile unsigned int A3results; volatile unsigned int A4results; int main(void) { WDTCTL = WDTPW + WDTHOLD; P6SEL = BIT0 + BIT1 + BIT2 + BIT3 + BIT4; // 使能 ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT0_8; //打开ADC12 在第一个SHI信号后自动采样 设置采样时间 ADC12CTL1 = ADC12SHP + ADC12CONSEQ_3; // 使用定时器作为采样信号源, 多通道采集 ADC12MCTL0 = ADC12INCH_0; // A0 ADC12MCTL1 = ADC12INCH_1; // A1 ADC12MCTL2 = ADC12INCH_2; // A2 ADC12MCTL3 = ADC12INCH_3; // A3 ADC12IE = 0x08; // 使能IFG3 ADC12CTL0 |= ADC12ENC; // 使能转换 while(1) { ADC12CTL0 |= ADC12SC; // SC这一位会自动复0,要手动置1 __bis_SR_register(LPM0_bits + GIE); // 低功耗0, 使能中断 } } #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC12_VECTOR __interrupt void ADC12ISR (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(ADC12_VECTOR))) ADC12ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(ADC12IV,34)) { case 0: break; // Vector 0: 无 case 2: break; // Vector 2: ADC溢出 case 4: break; // Vector 4: ADC超时 case 6: break; // Vector 6: ADC12IFG0 case 8: break; // Vector 8: ADC12IFG1 case 10: break; // Vector 10: ADC12IFG2 case 12: // Vector 12: ADC12IFG3 A0results = ADC12MEM0; A1results = ADC12MEM1; A2results = ADC12MEM2; A3results = ADC12MEM3; A4results = ADC12MEM4; __bic_SR_register_on_exit(LPM0_bits); case 14: break; // Vector 14: ADC12IFG4 case 16: break; // Vector 16: ADC12IFG5 case 18: break; // Vector 18: ADC12IFG6 case 20: break; // Vector 20: ADC12IFG7 case 22: break; // Vector 22: ADC12IFG8 case 24: break; // Vector 24: ADC12IFG9 case 26: break; // Vector 26: ADC12IFG10 case 28: break; // Vector 28: ADC12IFG11 case 30: break; // Vector 30: ADC12IFG12 case 32: break; // Vector 32: ADC12IFG13 case 34: break; // Vector 34: ADC12IFG14 default: break; } } 总结

        ADC12的寄存器特别多,配置起来也很复杂,尤其是工程比较大时配置得很让人头疼,这也是大多数人选择不用寄存器的主要原因。但是就一般情况来说,配置还是有迹可循的。在大多数情况下只需要如下配置。

ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT0_8;

打开ADC ,自动采样,选择采样时间

ADC12CTL1 = ADC12SHP + ADC12CONSEQ_x;

选择采样源,根据需要选择采集方式

ADC12MCTLx = ADC12INCH_x;

选择输入通道

ADC12IE = BITx;

使能对应输入通道对应的IFG

ADC12CTL0 |= ADC12ENC;

最后再使能转换,注意这条一定在最后



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有