MSP430F5438 ADC12学习笔记

发布者:csw520最新更新时间:2020-01-06 来源: eefocus关键字:MSP430F5438  ADC12  学习笔记 手机看文章 扫描二维码
随时随地手机看文章

1.前言

这几天实践了MSP430的ADC12功能,虽然片内AD功能比较简单但是还学出了点“门道”来,这个“门道”便是MSP430F5438A和MSP430F5438的区别。这里通过一个例子说明片内ADC的使用,首先实现UART和定时器1S溢出的功能,在上述功能的基础上每1S打印一次AD转换结果,转换通道定向到通道11,该通道对应AVCC和AVSS插值的一半,由于AVCC和LDO的输出之间只有一个电感连接,可以理解转换的结果为LDO输出电压的一般,若扩大两倍便是LDO的实际输出结果,在本文所用的开发板LDO输出为3.3V,所有打印的结果越接近3.3V越好。


2.代码实现和输出结果

代码实现

// 时钟默认情况

// FLL时钟      FLL选择 XT1

// 辅助时钟     ACLK选择 XT1          32768Hz

// 主系统时钟   MCLK选择 DCOCLKDIV    8000000Hz

// 子系统时钟   SMCLK选择 DCOCLKDIV   8000000Hz

// TA1选择ACLK,最大计数值为32768,中断频率为1HZ

 

#include

#include

#include

void clock_config(void);

void select_xt1(void);

void dco_config(void);

void adc12_config(void);

void uart_config(void);

char second_flag  = 0;                          // 1S标志

 

int main(void)

{

    clock_config();                             // 初始化时钟

    adc12_config();                             // 初始化ADC12

    uart_config();

 

    TA1CCTL0 = CCIE;                            // 使能TA1CCR0,比较匹配中断

    TA1CCR0 = 32768;                            // 初始化最大值,发生比较匹配中断频率 32768/32768 = 1Hz

    TA1CTL = TASSEL_1 + MC_1 + TACLR;           // 选择ACLK,最大值为CCR0,清除计数值

 

    _EINT();                                    // 初始化全局中断

 

    while(1)

    {

        if( second_flag )

        {

            second_flag = 0;                        // 1s时间到

 

            ADC12CTL0 |= ADC12SC;                   // 启动转换

            while ( !(ADC12IFG & BIT0) );           // 等待转换完成

 

            // 被转换的通道为通道11 (AVCC-AVSS)/2;

            // 此时转换的精度为12位——4096

            // AVCC通过一个电感和LDO的输出端连接

            // 打印LDO输出电压,保留3位精度

            float ldo_voltage = ADC12MEM0  / 4096.0 * 3.3 * 2;

            printf("LDO Voltage %.3frn",ldo_voltage);

        }

    }

}

 

void clock_config(void)

{

    WDTCTL = WDTPW + WDTHOLD;                   // 停止看门狗

    select_xt1();                               // 选择XT1

    dco_config();                               // ACLK = XT1 = 32.768K

                                                // MCLK = SMCLK = 8000K

}

 

void select_xt1(void)

{

    // 启动XT1

    P7SEL |= 0x03;                              // P7.0 P7.1 外设功能

    UCSCTL6 &= ~(XT1OFF);                       // XT1打开

    UCSCTL6 |= XCAP_3;                          // 内部电容

    do

    {

        UCSCTL7 &= ~XT1LFOFFG;                  // 清楚XT1错误标记

    }while (UCSCTL7&XT1LFOFFG);                 // 检测XT1错误标记

}

 

void dco_config(void)

{

    __bis_SR_register(SCG0);                    // 禁止FLL功能

    UCSCTL0 = 0x0000;                           // Set lowest possible DCOx, MODx

    UCSCTL1 = DCORSEL_5;                        // DCO最大频率为16MHz

    UCSCTL2 = FLLD_1 + 243;                     // 设置DCO频率为8MHz

                                                // MCLK = SMCLK= Fdcoclkdiv = (N+1)X(Ffllrefclk/n)

                                                // N为唯一需要计算的值

                                                // Ffllrefclk FLL参考时钟,默认为XT1

                                                // n取默认值,此时为1

                                                // (243 + 1) * 32768 = 8MHz

    __bic_SR_register(SCG0);                    // 使能FLL功能

 

    // 必要延时

    __delay_cycles(250000);

 

    // 清楚错误标志位

    do

    {

        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);

                                                // 清除所有振荡器错误标志位

        SFRIFG1 &= ~OFIFG;                      // 清除振荡器错误

    }while (SFRIFG1&OFIFG);                     // 等待清楚完成

}

 

void adc12_config(void)

{

    // 只有在ADC12ENC复位的情况下才可以操作

    // ADC12SHT1X ADC12SHT0X ADC12MSC ADC12REF2_5V ADC12REFON ADC12ON

    ADC12CTL0 &= ~ADC12ENC;

 

    // 设置采样保持时间,最大时间周期以提高转换精度

    // 注意MSP430F5438没有REF模块,片内基准无效

    // 操作ADC12REF2_5V ,ADC12REFON并无意义

    ADC12CTL0 = ADC12SHT0_15 + ADC12SHT1_15 + ADC12ON;

//    ADC12CTL0 = ADC12SHT0_15 + ADC12SHT1_15 + ADC12ON +

//                ADC12REF2_5V + ADC12REFON;

    // 采样保持脉冲来自采样定时器

    ADC12CTL1 = ADC12SHP;

    // 关闭内部内部温度检测以降低功耗,注意或操作否则修改转换精度

    ADC12CTL2 |= ADC12TCOFF ;

    // 基准电压选择AVCC,并选择11通道——(AVCC-AVSS)/2

    ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_11;

 

    __delay_cycles(75);

    // ADC12使能

    ADC12CTL0 |= ADC12ENC;

}

 

void uart_config(void)

{

    P3SEL = 0x30;                               // 选择P3.4和P3.5的复用功能

 

    UCA0CTL1 |= UCSWRST;                        // 软件复位

    UCA0CTL1 |= UCSSEL_1;                       // 选择ACLK时钟

    UCA0BR0 = 3;                                // 查表获得

    UCA0BR1 = 0;                                // UCA0BRX和UCA0MCTL数值

    UCA0MCTL |= UCBRS_3 + UCBRF_0;              //

    UCA0CTL1 &= ~UCSWRST;                       //

 

    UCA0IE |= UCRXIE;                           // 使能接收中断

}

 

int putchar(int ch)

{

UCA0TXBUF = ch;

while(!(UCA0IFG & UCTXIFG));

return ch;

}

 

#pragma vector=TIMER1_A0_VECTOR

__interrupt void TIMER1_A0_ISR(void)

{

    second_flag = 1;

}

图1 参考电压AVCC(3.3V)


3.一些注意点

3.1 提高采样时间

如果条件允许,可以尽可能的提高采样时间,这样转换结果可以更稳定一些。


3.2 MSP430F5438没有REF模块

现在(2013年10月)可以在TI官网上下载得到的示例代码或数据手册参考手册等,都是围绕MSP430F5438A的。但是市面上很多MCU还是MSP430F5438,其实MSP430F5438A和MSP4305438是有区别的,MSP430F5438没有REF模块,所以使用片内的2.5参考电源还是有些不稳定的因素。可以通过以下的实现测试一下,AD转换的目标依然是LDO输出。


需要修改以下几个部分的代码

第一:

ADC12CTL0 = ADC12SHT0_15 + ADC12SHT1_15 + ADC12ON; 修改为

ADC12CTL0 = ADC12SHT0_15 + ADC12SHT1_15 + ADC12ON +

ADC12REF2_5V + ADC12REFON;

使用打开片内2.5V参考电源


第二:

ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_11;修改为

ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_11;

转换参考电压为Vref,即修改1设置的2.5V参考电源


第三:

float ldo_voltage = ADC12MEM0 / 4096.0 * 3.3 * 2;修改为

float ldo_voltage = ADC12MEM0 / 4096.0 * 2.5 * 2;

替换转换公式,参考电压由3.3V变为2.5V


输出结果如下,结果发现LDO的输出电压为3.4V,比实际电压高0.1V。

图2 参考电压VREF(2.5V)

图3 MSP430参考手册说明

关键字:MSP430F5438  ADC12  学习笔记 引用地址:MSP430F5438 ADC12学习笔记

上一篇:msp432记录2-uart 与display的使用
下一篇:MSP430F149的ADC12模块

推荐阅读最新更新时间:2024-11-05 12:44

modelsim仿真学习笔记(精华篇)
1、 仿真的目的:   在软件环境下,验证电路的行为和设想中的是否一致。   2、 仿真的分类:   a) 功能仿真:在RTL层进行的仿真,其特点是不考虑构成电路的逻辑和门的时间延迟,着重考虑电路在理想环境下的行为和设计构想的一致性;   b) 时序仿真:又称为后仿真,是在电路已经映射到特定的工艺环境后,将电路的路径延迟和门延迟考虑进对电路行为的影响后,来比较电路的行为是否还能够在一定条件下满足设计构想。   3、 功能仿真的目的:   a) 设计出能工作的电路:因此功能仿真不是一个孤立的过程,其和综合、时序分析等形成一个反馈工作过程,只有这个过程收敛,各个环节才有意义。而孤立的功能仿真通过是没有意义的,如果在时序分
[模拟电子]
modelsim仿真<font color='red'>学习</font><font color='red'>笔记</font>(精华篇)
STM32学习笔记之GPIO(二)
首文提到了GPIO拥有八种工作方式: 4种输入模式: 输入浮空 输入上拉 输入下拉 模拟输入 4种输出模式: 开漏输出 开漏复用功能 推挽式输出 推挽式复用功能 3种最大翻转速度: -2MHZ -10MHz -50MHz 八种模式介绍及电路详解 输入浮空模式: 由于浮空输入一般多用于外部按键输入,结合图上的输入部分电路,我理解为浮空输入状态下,IO 的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的。 输入上拉模式: 上拉输入/下拉输入/模拟输入:这几个概念很好理解,从字面便能轻易读懂。 输入下拉模式: 模拟模式: 开漏输出: 只可以输出强低电平,高电平得靠外部电阻拉高。输出端
[单片机]
STM32<font color='red'>学习</font><font color='red'>笔记</font>之GPIO(二)
STM32学习笔记:通用定时器输出PWM
脉冲宽度调制,简称PWM(Pulse Width Modulation)是利用微处理器的数字输出 对模拟电路进行控制的一种非常有效的控制技术,常用于控制Led灯的亮度、电机转速等。 STM32 的定时器除了 TIM6 和 7,其他的定时器都可以用来产生 PWM 输出。其中高级定时器TIM1和TIM8可以同时产生高达7路的PWM输出,通用定时器TIM2~TIM5可以同时产生4路PWM输出。 使用通用定时器输出PWM同样需要4步配置,由于输出PWM信号时,不需要定时器中断,所以不需要配置NVIC,但是需要配置TIM_OCInitStructure。下面已配置TIM2为例: (1)开启系统时钟 RCC_APB1PeriphClockCm
[单片机]
51学习笔记之以总线方式实现1602与8051连接
//以总线方式实现8051与1602的通信 //这个程序主要实现功能是向1602发送一串字符串,并显示出来 #include reg52.h #include absacc.h #define uchar unsigned char #define uint unsigned int #define LCDDDATA XBYTE //读数据地址 #define LCDXDATA XBYTE //写数据地址 #define LCDDCOM XBYTE //读命令 #define LCDXCOM XBYTE //写命令 uchar idata s_GOOD ={'W','D',
[单片机]
51<font color='red'>学习</font><font color='red'>笔记</font>之以总线方式实现1602与8051连接
LCD实验学习笔记(四):系统时钟
一般CPU频率(FCLK)高于内存、网卡等设备频率(HCLK),而串口、USB、I2C等设备频率(PCLK)更低。 系统时钟:   系统时钟源为晶振,初始频率12MHz。   通过设置MPLLCON寄存器的MDIV、PDIV、SDIV(s3c2440手册上有时钟设置取值表),可设置系统时钟FCLK。    设置MDIV, 设置PDIV, 设置SDIV。   设置公式:     * S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)     * S3C2410: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)     * 其中: m = MDIV + 8, p = PDI
[单片机]
51单片机学习笔记(一)_总记
单片机电路仿真软件Proteus;编程软件Keil; 在Proteus中设计好电路图、在Keil中编写程序编译生成十六进制文件。 在电路图中载入该十六进制文件通过相应的程序控制电路。 51hei单片机+Proteus视频+实例+开发工具包 http://download.csdn.net/detail/leytton/7658297 http://www.51hei.com/ 文章阅读 http://www.51hei.com/mcuteach/252.html http://www.51hei.com/mcuteach/150.html 视频教程 http://www.51hei.com/sp/
[单片机]
51单片机<font color='red'>学习</font><font color='red'>笔记</font>(一)_总记
51单片机学习笔记,简易时钟
使用芯片STC89C52RC, 2个锁存器 6个带小数点共阴极数码管显示一个24时制时钟 没有时钟芯片,所以掉电后时间会复位 原理图为TX-1C开发板 暂时显示了半小时,一秒不差, 未验证有无其他bug,代码贴上来,欢迎高手指点 ============================== 最终显示的 时.分.秒 是 16.31.37 形式 C代码 #include reg52.h #include MY51.H void show(); uint8 shi=15; //初始时间15:45:00 按复位按钮对时 uint8 fen=45; uint8 miao=0; vo
[单片机]
51单片机<font color='red'>学习</font><font color='red'>笔记</font>,简易时钟
arm学习笔记五(c/c++与arm汇编混合编程)
常见方式: 1 在c/c++程序中嵌入汇编指令 语法格式: __asm { 汇编语言程序 } 2 在汇编程序中访问c/c++定义的全局变量 示例代码如下: test.c #include stdio.h int gVar_1=12; extern asmDouble(void) int main(void){ printf( original value of gVar_1 is %d ,gVar_1); admDouble(); printf( modified value of gVar_1 is %d ,gVar_1); return 0; } test.s AREA asmfil
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved