MSPM0L1306例程学习-ADC部分(1)
使用的TI的官方例程,即SDK里边包含的例程代码。
MCU使用的是MSPM0L1306, 对于ADC部分,有10个例程:
ADC的转换有多种工作模式,从最简单的单通道单次转换开始入手,即对特定的某个输入通道,进行一次电压的采样,并且读取ADC的转换结果。
标黑的三个例程,代码结构几乎相同,所使用的参考电压源不同而已。都是对ADC转换的结果,与参考电压的一半进行比较,根据判断结果点亮对应的LED灯。
从这三个例程入手,代码结构如下:
详细代码注释如下,因为代码都涉及到sysconfig图形配置工具,所以把对应的内容也一并截图上传。
详细代码如下:
/*
* 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例程增加注释,xie_sx@126.com
*/
#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;
}
}
详细代码如下:
/*
* 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例程增加注释,xie_sx@126.com
*/
#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;
}
}
详细代码如下:
/*
* 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例程增加注释,xie_sx@126.com
*/
#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;
}
}