MSP430的ADC12模块使用及代码(寄存器) | 您所在的位置:网站首页 › adc文件怎么转换 › MSP430的ADC12模块使用及代码(寄存器) |
以我的MSPf5529LP为例,它有A0-A15共计16个输入通道,其中有12个是外部通道。与之相应地,ADC12部分有相当多的各种寄存器,接下来一一介绍,最后依然附上一些代码。 目录 寄存器介绍 ADC12CTLn ADC12MEMx ADC12MCTLx ADC12IE ADC12IFG ADC12IV 例程 温度传感器 灰度传感器 总结 寄存器介绍由于其为数众多的通道数,ADC12有相当可观数量的寄存器,但是去除重合的一些后只有6个,它们分别负责处理一些功能。 ADC12CTLn它分为CTL0、CTL1、CTL2。三者的功能区别也不小,分别介绍一下。然后ADC12CTL0的设置很多,ADC12CT1和ADC12CTL2的操作我用到不多,查到的资料也不多,所以对它的讲解会和机翻很像。 ADC12CTL0这一位寄存器控制采样时间的长度 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 打开 ADC12OVIEADC12MEMx(储存x通道采集到的数据的寄存器,后面会说)的溢出中断使能,如果设置这位的话GIE中断也要配一下 0 失能 1 使能 ADC12TOVIEADC12转换超时(时间的“溢出”)使能,如果设置这位的话GIE中断也要配一下 0 失能 1 使能 这一位和上一位用的都很少 ADC12ENC使能转换,这一位的地位有些特殊 0 失能 1 使能 所有其他寄存器的更改配置操作都要在这一位为0时配置 ADC12SC启动转换,它会在开始后自动复0,所以要在循环里手动置1 0 不要开始采样 1 开始采样 ADC12CTL1采样-保持源的选择 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控制时钟预分频系数 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表明是采样序列的最后一个,这样说可能有些抽象,看一下代码就清楚了 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 实验室设备网 版权所有 |