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