MSPM0开发学习笔记:ADC入门

ADC(模数转换器)将传感器上的模拟电压等量测转换成 MCU 可用的数字码字,本篇在 MSPM0 入门语境下简述其基本概念、应用场景,并配合 SysConfig 与示例工程演示一次最简数据采集流程。


MSPM0开发学习笔记

第一章 初步安装与配置
第二章 GPIO
第三章 TIMER
第四章 TIMER-PWM
第五章 ADC入门


一、ADC原理与作用介绍

ADC(模数转换器)是一种将模拟信号转换为数字信号的关键硬件模块,其核心作用是将真实世界的连续模拟量(如电压、温度等)转换为微控制器可处理的数字值。该板块非常庞大也非常的重要,这边暂时只能做一个简单的入门讲解


二、syscfg配置

在这里插入图片描述

ADC的配置主要是在以下几个地方
1、红色部分添加ADC
2、黄色部分选择时钟为ULPCLK
3、绿色是说开始测量的地方 而蓝色的是保存的地方,有可能会冲突报错没配置好的话(因为绿色上面那一行设置的是single)
4、白色部分下面的那个VDDA表示的是测量范围
5、白色的地方重点讲解,这边涉及到ADC的对应问题,我们先记住这边的值ADC选择的是0 然后选择Channel2 这个记为ADC0.2 我们来看原理图
在这里插入图片描述
可以看到第二行的ADC0.2对应的是PA25,所以刚才配置那边的会自动设置到PA25那边去
在这里插入图片描述
剩下的对应
6、红色部分对应准确度
7、Interrupt Configuration那边也要设置触发中断
8、绿色表示对应信息


三、程序设计

具体代码如下:

/* 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) {
        DL_ADC12_startConversion(ADC12_0_INST);

        while (false == gCheckADC) {
        }

        adcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);

        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);
        }

        /* Preparing ADC to trigger new conversion */
        DL_ADC12_stopConversion(ADC12_0_INST);
        gCheckADC = false;
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}

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

值得注意的是 中断函数这边不可以像之前一样因为只有一个中断 就不进行switch的判断,如果这样做的话会导致无法去除标志位,无法第二次进入中断。
DL_ADC12_enableConversions(ADC12_0_INST);需要再每一次再次使能一下

四、多路读取

1、syscfg配置

在这里插入图片描述
其他配置的地方都讲过了,只有这边的single改成sequence,然后会多出来一个选项,表示从0-3,同样可对这四个进行与前面一样的设置

2、程序编写


#include "ti_msp_dl_config.h"

volatile bool gCheckADC;

#define RESULT_SIZE (64)
volatile uint16_t gAdcResult0[RESULT_SIZE];
volatile uint16_t gAdcResult1[RESULT_SIZE];
volatile uint16_t gAdcResult2[RESULT_SIZE];
volatile uint16_t gAdcResult3[RESULT_SIZE];

int main(void)
{
    /* Initialize peripherals and enable interrupts */
    SYSCFG_DL_init();
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    gCheckADC  = false;
    uint16_t i = 0;

    while (1) {
        DL_ADC12_startConversion(ADC12_0_INST);

        /* Wait until all data channels have been loaded. */
        while (gCheckADC == false) {
            __WFE();
        }

        /* Store ADC Results into their respective buffer */
        gAdcResult0[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
        gAdcResult1[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_1);
        gAdcResult2[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_2);
        gAdcResult3[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_3);

        i++;
        gCheckADC = false;
        /* Reset index of buffers, set breakpoint to check buffers. */
        if (i >= RESULT_SIZE) {
            __BKPT(0);
            i = 0;
        } else {
            ; /*No action required*/
        }
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}

/* Check for the last result to be loaded then change boolean */
void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
        case DL_ADC12_IIDX_MEM3_RESULT_LOADED:
            gCheckADC = true;
            break;
        default:
            break;
    }
}

大体思路都是一样的,代码也并没有很复杂,在实现读取64次之后就会停下来了。

MSPM0開發學習筆記:ADC入門

ADC(模數轉換器)將感測器上的類比電壓等量測轉成 MCU 可用的數位碼字,本篇在 MSPM0 入門語境下簡述其基本概念、應用場景,並搭配 SysConfig 與示例工程演示一次最簡資料擷取流程。

來源:https://blog.csdn.net/2403_87969572/article/details/148122737

抓取時間(ISO本地):2026-05-18 05:17:00


MSPM0開發學習筆記

第一章 初步安裝與配置
第二章 GPIO
第三章 TIMER
第四章 TIMER-PWM
第五章 ADC入門


文章目錄


一、ADC原理與作用介紹

ADC(模數轉換器)是一種將模擬信號轉換為數字信號的關鍵硬件模塊,其核心作用是將真實世界的連續模擬量(如電壓、溫度等)轉換為微控制器可處理的數字值。該板塊非常龐大也非常的重要,這邊暫時只能做一個簡單的入門講解


二、syscfg配置

在這裡插入圖片描述

ADC的配置主要是在以下幾個地方
1、紅色部分添加ADC
2、黃色部分選擇時鐘為ULPCLK
3、綠色是說開始測量的地方 而藍色的是保存的地方,有可能會衝突報錯沒配置好的話(因為綠色上面那一行設置的是single)
4、白色部分下面的那個VDDA表示的是測量範圍
5、白色的地方重點講解,這邊涉及到ADC的對應問題,我們先記住這邊的值ADC選擇的是0 然後選擇Channel2 這個記為ADC0.2 我們來看原理圖
在這裡插入圖片描述
可以看到第二行的ADC0.2對應的是PA25,所以剛才配置那邊的會自動設置到PA25那邊去
在這裡插入圖片描述
剩下的對應
6、紅色部分對應準確度
7、Interrupt Configuration那邊也要設置觸發中斷
8、綠色表示對應信息


三、程序設計

具體代碼如下:

/* 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) {
        DL_ADC12_startConversion(ADC12_0_INST);

        while (false == gCheckADC) {
        }

        adcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);

        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);
        }

        /* Preparing ADC to trigger new conversion */
        DL_ADC12_stopConversion(ADC12_0_INST);
        gCheckADC = false;
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}

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

值得注意的是 中斷函數這邊不可以像之前一樣因為只有一箇中斷 就不進行switch的判斷,如果這樣做的話會導致無法去除標誌位,無法第二次進入中斷。
DL_ADC12_enableConversions(ADC12_0_INST);需要再每一次再次使能一下

四、多路讀取

1、syscfg配置

在這裡插入圖片描述
其他配置的地方都講過了,只有這邊的single改成sequence,然後會多出來一個選項,表示從0-3,同樣可對這四個進行與前面一樣的設置

2、程序編寫


#include "ti_msp_dl_config.h"

volatile bool gCheckADC;

#define RESULT_SIZE (64)
volatile uint16_t gAdcResult0[RESULT_SIZE];
volatile uint16_t gAdcResult1[RESULT_SIZE];
volatile uint16_t gAdcResult2[RESULT_SIZE];
volatile uint16_t gAdcResult3[RESULT_SIZE];

int main(void)
{
    /* Initialize peripherals and enable interrupts */
    SYSCFG_DL_init();
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    gCheckADC  = false;
    uint16_t i = 0;

    while (1) {
        DL_ADC12_startConversion(ADC12_0_INST);

        /* Wait until all data channels have been loaded. */
        while (gCheckADC == false) {
            __WFE();
        }

        /* Store ADC Results into their respective buffer */
        gAdcResult0[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
        gAdcResult1[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_1);
        gAdcResult2[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_2);
        gAdcResult3[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_3);

        i++;
        gCheckADC = false;
        /* Reset index of buffers, set breakpoint to check buffers. */
        if (i >= RESULT_SIZE) {
            __BKPT(0);
            i = 0;
        } else {
            ; /*No action required*/
        }
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}

/* Check for the last result to be loaded then change boolean */
void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
        case DL_ADC12_IIDX_MEM3_RESULT_LOADED:
            gCheckADC = true;
            break;
        default:
            break;
    }
}

大體思路都是一樣的,代碼也並沒有很複雜,在實現讀取64次之後就會停下來了。

MSPM0开发学习笔记:ADC入门

This primer explains how MSPM0’s analog‑to‑digital converter turns real‑world analog voltages into digital samples the CPU can process, sketches typical use‑cases such as metering temperature or joystick inputs on a microcontroller, then walks through a minimal SysConfig plus driverlib example for taking the first readings.


MSPM0开发学习笔记

第一章 初步安装与配置
第二章 GPIO
第三章 TIMER
第四章 TIMER-PWM
第五章 ADC入门


一、ADC原理与作用介绍

ADC(模数转换器)是一种将模拟信号转换为数字信号的关键硬件模块,其核心作用是将真实世界的连续模拟量(如电压、温度等)转换为微控制器可处理的数字值。该板块非常庞大也非常的重要,这边暂时只能做一个简单的入门讲解


二、syscfg配置

在这里插入图片描述

ADC的配置主要是在以下几个地方
1、红色部分添加ADC
2、黄色部分选择时钟为ULPCLK
3、绿色是说开始测量的地方 而蓝色的是保存的地方,有可能会冲突报错没配置好的话(因为绿色上面那一行设置的是single)
4、白色部分下面的那个VDDA表示的是测量范围
5、白色的地方重点讲解,这边涉及到ADC的对应问题,我们先记住这边的值ADC选择的是0 然后选择Channel2 这个记为ADC0.2 我们来看原理图
在这里插入图片描述
可以看到第二行的ADC0.2对应的是PA25,所以刚才配置那边的会自动设置到PA25那边去
在这里插入图片描述
剩下的对应
6、红色部分对应准确度
7、Interrupt Configuration那边也要设置触发中断
8、绿色表示对应信息


三、程序设计

具体代码如下:

/* 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) {
        DL_ADC12_startConversion(ADC12_0_INST);

        while (false == gCheckADC) {
        }

        adcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);

        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);
        }

        /* Preparing ADC to trigger new conversion */
        DL_ADC12_stopConversion(ADC12_0_INST);
        gCheckADC = false;
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}

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

值得注意的是 中断函数这边不可以像之前一样因为只有一个中断 就不进行switch的判断,如果这样做的话会导致无法去除标志位,无法第二次进入中断。
DL_ADC12_enableConversions(ADC12_0_INST);需要再每一次再次使能一下

四、多路读取

1、syscfg配置

在这里插入图片描述
其他配置的地方都讲过了,只有这边的single改成sequence,然后会多出来一个选项,表示从0-3,同样可对这四个进行与前面一样的设置

2、程序编写


#include "ti_msp_dl_config.h"

volatile bool gCheckADC;

#define RESULT_SIZE (64)
volatile uint16_t gAdcResult0[RESULT_SIZE];
volatile uint16_t gAdcResult1[RESULT_SIZE];
volatile uint16_t gAdcResult2[RESULT_SIZE];
volatile uint16_t gAdcResult3[RESULT_SIZE];

int main(void)
{
    /* Initialize peripherals and enable interrupts */
    SYSCFG_DL_init();
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    gCheckADC  = false;
    uint16_t i = 0;

    while (1) {
        DL_ADC12_startConversion(ADC12_0_INST);

        /* Wait until all data channels have been loaded. */
        while (gCheckADC == false) {
            __WFE();
        }

        /* Store ADC Results into their respective buffer */
        gAdcResult0[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
        gAdcResult1[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_1);
        gAdcResult2[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_2);
        gAdcResult3[i] =
            DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_3);

        i++;
        gCheckADC = false;
        /* Reset index of buffers, set breakpoint to check buffers. */
        if (i >= RESULT_SIZE) {
            __BKPT(0);
            i = 0;
        } else {
            ; /*No action required*/
        }
        DL_ADC12_enableConversions(ADC12_0_INST);
    }
}

/* Check for the last result to be loaded then change boolean */
void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
        case DL_ADC12_IIDX_MEM3_RESULT_LOADED:
            gCheckADC = true;
            break;
        default:
            break;
    }
}

大体思路都是一样的,代码也并没有很复杂,在实现读取64次之后就会停下来了。