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次之后就会停下来了。