MSPM0L1306例程学习-ADC部分(5)

发布时间:2023年12月26日

MSPM0L1306例程学习系列
使用的TI的官方例程,即SDK里边包含的例程代码。
可以到TI官网下载并且安装SDK: https://www.ti.com.cn/tool/cn/download/MSPM0-SDK/

MCU使用的是MSPM0L1306, 对于ADC部分,有10个例程:
在这里插入图片描述
今天接着讲2个例程,adc12_triggered_by_timer_event和adc12_triggered_by_timer_event_stop,这两个例程都是使用定时器事件去触发ADC转换。两个例程的概述如下:

第一个例程:adc12_triggered_by_timer_event

  1. LFCLK=32kHz,MCLK=ULPCLK=CPUCLK=ADCCLK=32MHz
  2. ADC工作在序列通道、单次转换模式、自动采样、事件触发(定时器);
  3. 使用MEM0~MEM4,都选择ADC通道2(PA25),直接使用电源电压作参考电压;
  4. 采样时长分别采用采样定时器0和采样定时器1 ,采样定时器0设置为25us,采样定时器1设置为12.5us;
  5. 定义订阅定时器事件; 定时器0触发ADC
  6. 定时器工作在单次模式下,周期为1.125s,并定义发布事件1; *
  7. 只转换1回,结果存放到数组gADCResult[]中;
  8. 代码中设有断点语句__BKPT(0),会自动进入断点,查看数据;

第二个例程:adc12_triggered_by_timer_event_stop

  1. LFCLK=32kHz,MCLK=ULPCLK=CPUCLK=ADCCLK=32MHz
  2. ADC工作在单通道、多次转换模式、自动采样、事件触发(定时器);
  3. 使用MEM0,选择ADC通道2(PA25),直接使用电源电压作参考电压;
  4. 采样时长采用采样定时器1,设置为25us;
  5. 启用窗口比较器的功能: 12位AD的转换结果满量程为4095。上限值和下限值都设置为1.5v对应的转换结果ADC12_MONITOR_VALUE 这些值是在代码中设定的,没有在sysconfig图形配置工具中完成;
  6. 定义订阅定时器事件; 定时器0触发ADC
  7. 定时器工作在周期模式下,周期为1s,并定义发布事件1;
  8. PA0引脚连接有LED灯;
  9. 对通道2进行AD采样和转换,系统会自动根据转换结果进行LED的指示操作:
    a.当转换结果小于ADC12_MONITOR_VALUE时,触发窗口比较器下限中断,输出高电平,关闭LED
    b.当转换结果大于ADC12_MONITOR_VALUE时,触发窗口比较器上限中断,输出低电平,点亮LED

第1个例程具体的配置和分析如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第1个例程的注解如下:

/*
 * ADC转换的SDK例程
 * 文件名:adc12_triggered_by_timer_event.c
 * 描述:
 *   ADC模块的事件触发功能演示。
 *   1、LFCLK=32kHz,MCLK=ULPCLK=CPUCLK=ADCCLK=32MHz
 *   2、ADC工作在序列通道、单次转换模式、自动采样、事件触发(定时器);
 *     使用MEM0~MEM4,都选择ADC通道2(PA25),直接使用电源电压作参考电压;
 *   3、采样时长分别采用采样定时器0和采样定时器1
 *     采样定时器0设置为25us,采样定时器1设置为12.5us;
 *   4、定义订阅定时器事件; 定时器0触发ADC
 *   5、定时器工作在单次模式下,周期为1.125s,并定义发布事件1;
 *   6、只转换1回,结果存放到数组gADCResult[]中;
 *   7、代码中设有断点语句__BKPT(0),会自动进入断点,查看数据;
 *
 * 操作描述:
 *   1、下载程序;
 *   2、添加观察变量gADCResult,全速运行;
 *   3、系统会自动停在断点处,查看ADC的采样结果值;
 *
 * 注意事项:
 *   1、ADC的结果的读取就一次,没有在while(1)循环里
 *
 * 思考:
 *   1、为什么要区分采样定时器0和采样定时器1?有特别的意义吗?还是,只是想演示下功能配置
 *
 * 修改:
 *   基于官方的sdk例程增加注释,xie_sx@126.com
 */
#include "ti_msp_dl_config.h"

//标志变量,ADC的转换结果是否已经传输完成;
volatile bool gCheckADC;

//定义16位的数组来存放ADC的转换结果.
volatile uint16_t gADCResult[4];

int main(void)
{
    //SysConfig图形配置工具初始化配置函数
    SYSCFG_DL_init();

    //使能ADC12的中断
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);

    //ADC12的转换完成标志位清零
    gCheckADC = false;

    //启动定时器
    DL_TimerG_startCounter(TIMER_0_INST);

    while (false == gCheckADC)
    {
        //等待结果存储寄存器MEM3加载新数据
        __WFE();
    }

    //读取结果存储寄存器MEM0、MEM1、MEM2、MEM3的数据,存放到数组中
    gADCResult[0] = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
    gADCResult[1] = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_1);
    gADCResult[2] = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_2);
    gADCResult[3] = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_3);

    //断点语句,程序运行到此处会自动进入断点,可查看ADC的转换结果
    __BKPT(0);

    while (1)
    {
        __WFI();
    }
}

/*
 * ADC12中断处理函数
 * 通过转换结果存储寄存器MEM3加载新数据中断来判断ADC转换结束
 *
 */
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;
    }
}

第2个例程具体的配置和分析如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第2个例程的注解如下:

/*
 * ADC转换的SDK例程
 * 文件名:adc12_triggered_by_timer_event_stop.c
 * 描述:
 *   ADC模块的事件触发功能演示。
 *   1、LFCLK=32kHz,MCLK=ULPCLK=CPUCLK=ADCCLK=32MHz
 *   2、ADC工作在单通道、多次转换模式、自动采样、事件触发(定时器);
 *     使用MEM0,选择ADC通道2(PA25),直接使用电源电压作参考电压;
 *     采样时长采用采样定时器1,设置为25us;
 *   4、启用窗口比较器的功能:
 *     12位AD的转换结果满量程为4095. 上限值和下限值都设置为1.5v对应的转换结果ADC12_MONITOR_VALUE
 *     这些值是在代码中设定的,没有在sysconfig图形配置工具中完成;
 *   3、定义订阅定时器事件; 定时器0触发ADC
 *   4、定时器工作在周期模式下,周期为1s,并定义发布事件1;
 *   5、PA0引脚连接有LED灯;
 *   6、对通道2进行AD采样和转换,系统会自动根据转换结果进行LED的指示操作:
 *     a.当转换结果小于ADC12_MONITOR_VALUE时,触发窗口比较器下限中断,输出高电平,关闭LED
 *     b.当转换结果大于ADC12_MONITOR_VALUE时,触发窗口比较器上限中断,输出低电平,点亮LED
 *
 * 操作描述:
 *   1、下载程序,全速运行;
 *   2、测量通道2(PA25)的输入电压,偷懒点,输入可直接接3.3V或者Gnd;
 *   3、查看板卡上LED灯的状态
 * 注意事项:
 *   1、AD输入的引脚不要错接5V电压,会烧坏引脚;
 *
 * 思考:
 *   1、暂无
 *
 * 修改:
 *   基于官方的sdk例程增加注释,xie_sx@126.com
 */

#include "ti_msp_dl_config.h"

/*
 * 下边这段宏定义的作用:
 * 通过宏定义的方式,自动计算出某个电压值对应的ADC转换结果计算式ADC12_MONITOR_VALUE
 * 即根据目标电压,反算ADC转换的结果数值;
 *
 * ADC12_BIT_RESOLUTION位AD的最大量程值:  (1 << ADC12_BIT_RESOLUTION) --》12位的AD,2的12次方;
 * ADC12_MONITOR_VOLTAGE / ADC12_REF_VOLTAGE : 目标电压和参考电压的比值
 * 两者相乘,就自动计算出 目标电压对应的ADC转换的结果数值;
 */
#define ADC12_BIT_RESOLUTION (12)
#define ADC12_REF_VOLTAGE (3.3)
#define ADC12_MONITOR_VOLTAGE (1.5)
#define ADC12_MONITOR_VALUE \
    ((1 << ADC12_BIT_RESOLUTION) * (ADC12_MONITOR_VOLTAGE / ADC12_REF_VOLTAGE))

int main(void)
{
    //SysConfig图形配置工具初始化配置函数
    SYSCFG_DL_init();

    //配置窗口比较器的限值,上下限都设置为ADC12_MONITOR_VALUE
    DL_ADC12_configWinCompHighThld(ADC12_0_INST, (uint16_t) ADC12_MONITOR_VALUE);
    DL_ADC12_configWinCompLowThld(ADC12_0_INST, (uint16_t) ADC12_MONITOR_VALUE);

    //使能ADC12的中断
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
    //启动定时器
    DL_TimerG_startCounter(TIMER_0_INST);

    while (1)
    {
        __WFI();
    }
}

/*
 * ADC12中断处理函数
 * 窗口比较器的上限、下限中断
 * --高于上限值,输出低电平,点亮LED;
 * --低于下限值,输出高电平,关闭LED
 *
 */
void ADC12_0_INST_IRQHandler(void)
{
    switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST))
    {
        case DL_ADC12_IIDX_WINDOW_COMP_HIGH:
            DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            break;
        case DL_ADC12_IIDX_WINDOW_COMP_LOW:
            DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            break;
        default:
            break;
    }
}

文章来源:https://blog.csdn.net/xie_sx/article/details/135131461
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。