MSPM0L1306例程学习-ADC部分(1)

MSPM0L1306例程学习笔记。
直接使用TI的官方例程,即MSPM0 SDK里边包含的例程。
准备工作:
1、需要下载并安装MSPM0 SDK: https://www.ti.com.cn/tool/cn/download/MSPM0-SDK
2、会例程的导入。例如在CCS中导入例程。

MCU使用的是MSPM0L1306, 对于ADC部分,有10个例程,分成6篇文章。所有例程的代码也添加了注释,可直接拷贝到原文件中使用:
MSPM0L1306例程学习-ADC部分(1)_第1张图片

例程理解

ADC的转换有多种工作模式,从最简单的单通道单次转换开始入手,即对特定的某个输入通道,进行一次电压的采样,并且读取ADC的转换结果。

标黑的三个例程,代码结构几乎相同,所使用的参考电压源不同而已。都是对ADC转换的结果,与参考电压的一半进行比较,根据判断结果点亮对应的LED灯。

  • adc12_single_conversion :单通道单次转换,直接使用AVCC作为参考电压源;
  • adc12_single_conversion_vref_internal:单通道单次转换,使用内部参考电压源,配置VREF为2.5V;
  • adc12_single_conversion_vref_external:单通道单次转换,使用外部参考电压源,需要外接参考电压到VREF+引脚;

从这三个例程入手,代码结构如下:
MSPM0L1306例程学习-ADC部分(1)_第2张图片
MSPM0L1306例程学习-ADC部分(1)_第3张图片

详细代码注释如下,因为代码都涉及到sysconfig图形配置工具,所以把对应的内容也一并截图上传。

  • GPIO部分,相同的配置,配置了一个GPIO口,用于点亮LED灯操作;
  • ADC部分,也基本相同的配置,时钟,分频;单通道单次转换,使用MEM0,自动采样,软件触发;
  • 在参考电压的选择上,是最大的区别,3个例程分别选择了不同的参考电压,如果选择了vref,还需要在vref模块中对电压进行配置。

adc12_single_conversion

MSPM0L1306例程学习-ADC部分(1)_第4张图片
MSPM0L1306例程学习-ADC部分(1)_第5张图片
MSPM0L1306例程学习-ADC部分(1)_第6张图片
详细代码如下:

/*
 * ADC转换的SDK例程
 * 文件名:adc12_single_conversion.c
 *
 * 描述:
 *   1、单通道单次转换、自动采样模式、软件触发;
 *   2、使用MEM0,通道0(PA27),直接用电源电压作为参考电压
 *   3、PA0引脚连接有LED灯;
 *   4、对通道0进行AD采样和转换,根据转换结果进行LED的指示操作:
 *     a.当转换结果小于0x7ff时,LED灭; 否则,点亮LED
 *
 * 操作描述:
 *   1、下载程序,全速运行;
 *   2、引脚PA27通过杜邦线连接VCC或GND
 *     a. 连接到VCC时,红色LED点亮;
 *     b. 连接到GND时,红色LED熄灭.
 * 注意事项:
 *   1、如果使用的是LP-MSPM0L1306, PA27引脚默认通过跳线帽连接三色LED2;
 *
 * 思考:
 *   给输入引脚上施加一个电压,看测量值是否符合预取结果。
 *
 * 修改:
 *   基于官方的sdk例程增加注释,[email protected]
 */

#include "ti_msp_dl_config.h"

//ADC转换完成的标识,在ADC的中断里设为有效;
volatile bool gCheckADC;

volatile uint16_t gAdcResult;

int main(void)
{
    //初始化配置
    SYSCFG_DL_init();

    //使能中断
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    //标志位清零
    gCheckADC = false;

    while (1)
    {
        //软件开启ADC转换,SC=1
        DL_ADC12_startConversion(ADC12_0_INST);

        //等待转换完成
        //如果标志位gCheckADC不是true,程序在while循环等待
        //gCheckADC=true后,程序继续往下执行
        while (false == gCheckADC)
        {
            __WFE();
        }


        //读取ADC12的转换结果
        gAdcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);

        //对ADC12的转换结果进行处理
        if (gAdcResult > 0x7ff)
        {
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        }
        else
        {
            DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        }

        //ADC12的转换标志位清零
        gCheckADC = false;

        //使能ADC转换,即ENC=1,等待触发信号
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}


/*
 * ADC12中断处理函数
 *
 * 中断里边只设置标志位gCheckADC
 *
 */

void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST))
    {
        case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
            //结果存储寄存器有更新
            gCheckADC = true;
            break;
        default:
            break;
    }
}

adc12_single_conversion_vref_internal

MSPM0L1306例程学习-ADC部分(1)_第7张图片
MSPM0L1306例程学习-ADC部分(1)_第8张图片

MSPM0L1306例程学习-ADC部分(1)_第9张图片

MSPM0L1306例程学习-ADC部分(1)_第10张图片
详细代码如下:

/*
 * ADC转换的SDK例程
 * 文件名:adc12_single_conversion_vref_internal.c
 * 描述:
 *   1、单通道单次转换、自动采样模式、软件触发;
 *   2、使用MEM0,通道2(PA25),使用内部参考电压,2.5V
 *   3、PA0引脚连接有LED灯;
 *   4、对通道0进行AD采样和转换,根据转换结果进行LED的指示操作:
 *     a.当转换结果小于0x7ff时,LED灭; 否则,点亮LED
 *
 * 操作描述:
 *   1、下载程序,全速运行;
 *   2、引脚PA25通过杜邦线连接VCC或GND
 *     a. 连接到VCC时,红色LED点亮;
 *     b. 连接到GND时,红色LED熄灭.
 * 注意事项:
 *   1、如果使用的是LP-MSPM0L1306, PA25引脚默认接有跳线帽J4;
 *
 * 思考:
 *   给输入引脚上施加一个电压,看测量值是否符合预取结果。
 *
 * 修改:
 *   基于官方的sdk例程增加注释,[email protected]
 */

#include "ti_msp_dl_config.h"

volatile bool gCheckADC;
volatile uint16_t adcResult;

int main(void)
{
    //初始化配置
    SYSCFG_DL_init();

    //使能中断
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    gCheckADC = false;

    //在启动ADC12转换之前,先确认参考电压VREF已稳定
    while (DL_VREF_CTL1_READY_NOTRDY == DL_VREF_getStatus(VREF));

    while (1)
    {
        //软件开启ADC转换,SC=1
        DL_ADC12_startConversion(ADC12_0_INST);

        //等待转换完成
        //如果标志位gCheckADC不是true,程序在while循环等待
        //gCheckADC=true后,程序继续往下执行
        while (false == gCheckADC)
        {
            __WFE();
        }

        //读取ADC12的转换结果
        adcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);

        //对ADC12的转换结果进行处理
        if (adcResult > 0x7ff)
        {
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        }
        else
        {
            DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        }

        //ADC12的转换标志位清零
        gCheckADC = false;

        //使能ADC转换,即ENC=1,等待触发信号
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}



/*
 * ADC12中断处理函数
 *
 * 中断里边只设置标志位gCheckADC
 *
 */

void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST))
    {
        case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
            gCheckADC = true;
            break;
        default:
            break;
    }
}

adc12_single_conversion_vref_external

MSPM0L1306例程学习-ADC部分(1)_第11张图片

MSPM0L1306例程学习-ADC部分(1)_第12张图片

MSPM0L1306例程学习-ADC部分(1)_第13张图片
MSPM0L1306例程学习-ADC部分(1)_第14张图片
详细代码如下:

/*
 * ADC转换的SDK例程
 * 文件名:adc12_single_conversion_vref_external.c
 * 描述:
 *   1、单通道单次转换、自动采样模式、软件触发;
 *   2、使用MEM0,通道2(PA25),使用内部参考电压,2.5V
 *   3、PA0引脚连接有LED灯;
 *   4、对通道0进行AD采样和转换,根据转换结果进行LED的指示操作:
 *     a.当转换结果小于0x7ff时,LED灭; 否则,点亮LED
 *
 * 操作描述:
 *   1、下载程序,全速运行;
 *   2、引脚PA25通过杜邦线连接VCC或GND
 *     a. 连接到VCC时,红色LED点亮;
 *     b. 连接到GND时,红色LED熄灭.
 * 注意事项:
 *   1、如果使用的是LP-MSPM0L1306, PA25引脚默认接有跳线帽J4;
 *   2、需要VREF+引脚外接参考电压
 *
 * 思考:
 *   给输入引脚上施加一个电压,看测量值是否符合预取结果。
 *
 * 修改:
 *   基于官方的sdk例程增加注释,[email protected]
 */

#include "ti_msp_dl_config.h"

/* 宏定义配置
 * 先定义了外部参考电压ADC12_EXTERNAL_REF_VOLTAGE, 取参考电压的一半为监测比较的电压ADC12_MONITOR_VOLTAGE
 * 因为ADC位数为12位,通过宏定义的方式计算出了参考电压的一半值所对应的ADC转换结果ADC12_MONITOR_VALUE
 *
 * 实际上ADC12_MONITOR_VALUE,可以直接计算出来的。 2的12次方的一半,2048,即12位ADC满量程的一半;
 * 如果是10位AD,一半为512
 */
/* clang-format off */
#define ADC12_BIT_RESOLUTION          (12)
#define ADC12_EXTERNAL_REF_VOLTAGE    (3.3)
#define ADC12_MONITOR_VOLTAGE         (ADC12_EXTERNAL_REF_VOLTAGE / 2)
#define ADC12_MONITOR_VALUE           ((1 << ADC12_BIT_RESOLUTION) * (ADC12_MONITOR_VOLTAGE / (ADC12_EXTERNAL_REF_VOLTAGE)))
/* clang-format on */

volatile bool gCheckADC;

int main(void)
{
    uint16_t adcResult;

    //初始化配置
    SYSCFG_DL_init();

    //使能中断
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    gCheckADC = false;

    while (1)
    {
        //软件开启ADC转换,SC=1
        DL_ADC12_startConversion(ADC12_0_INST);

        //等待转换完成
        //如果标志位gCheckADC不是true,程序在while循环等待
        //gCheckADC=true后,程序继续往下执行
        while (false == gCheckADC)
        {
            __WFE();
        }

        //读取ADC12的转换结果
        adcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);

        //对ADC12的转换结果进行处理
        if (adcResult > ADC12_MONITOR_VALUE)
        {
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        }
        else
        {
            DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
        }

        //?这一句没太必要,多余的
        DL_ADC12_stopConversion(ADC12_0_INST);

        //ADC12的转换标志位清零
        gCheckADC = false;

        //使能ADC转换,即ENC=1,等待触发信号
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}


/*
 * ADC12中断处理函数
 *
 * 中断里边只设置标志位gCheckADC
 *
 */

void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST))
    {
        case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
            gCheckADC = true;
            break;
        default:
            break;
    }
}

你可能感兴趣的:(MSPM0L1306,TI,MSPM0,MCU,学习,mspm0l1306,电赛,LP-MSPM0L1306,launchpad,mspm0g3507)