MSPM0L1306例程学习-ADC部分(1)
MSPM0L1306例程学习
使用的TI的官方例程,即SDK里边包含的例程代码。
MCU使用的是MSPM0L1306, 对于ADC部分,有10个例程:
例程理解
ADC的转换有多种工作模式,从最简单的单通道单次转换开始入手,即对特定的某个输入通道,进行一次电压的采样,并且读取ADC的转换结果。
标黑的三个例程,代码结构几乎相同,所使用的参考电压源不同而已。都是对ADC转换的结果,与参考电压的一半进行比较,根据判断结果点亮对应的LED灯。
- adc12_single_conversion :单通道单次转换,直接使用AVCC作为参考电压源;
- adc12_single_conversion_vref_internal:单通道单次转换,使用内部参考电压源,配置VREF为2.5V;
- adc12_single_conversion_vref_external:单通道单次转换,使用外部参考电压源,需要外接参考电压到VREF+引脚;
从这三个例程入手,代码结构如下:
详细代码注释如下,因为代码都涉及到sysconfig图形配置工具,所以把对应的内容也一并截图上传。
- GPIO部分,相同的配置,配置了一个GPIO口,用于点亮LED灯操作;
- ADC部分,也基本相同的配置,时钟,分频;单通道单次转换,使用MEM0,自动采样,软件触发;
- 在参考电压的选择上,是最大的区别,3个例程分别选择了不同的参考电压,如果选择了vref,还需要在vref模块中对电压进行配置。
adc12_single_conversion
详细代码如下:
/** 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=1DL_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
详细代码如下:
/** 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=1DL_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
详细代码如下:
/** 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=1DL_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;}
}