一、样例展示
通过ADC0触发单次采样,如果采样结果大于0.5倍的VDD,就点亮LED 否则熄灭LED
编译加载运行这个历程,提供一个电压到A0_2引脚上,电压范围在0-VCC之间同时观察LED1.在上电后,默认将ADC配置到正确的引脚模式,因此没有必要调用这个函数来设置了
烧录之后观察现象,可以看到,现在的结果是led点亮,满足大于二分之一VDD的条件
#include "ti_msp_dl_config.h"
volatile bool gCheckADC;//不要对变量进行编译优化
volatile uint16_t gAdcResult;
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
gCheckADC = false;
while (1) {
DL_ADC12_startConversion(ADC12_0_INST);
while (false == gCheckADC)//等待完成ADC转换
{
}
//读取ADC的值
gAdcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
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);
}
gCheckADC = false;
DL_ADC12_enableConversions(ADC12_0_INST);//每一轮执行后会关闭掉,执行后需再次打开
}
}
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;
}
}
二、 syscfg 配置
1.名称 选择的外设
2. 基础设置
01 用32兆时钟,进行8分频
02 采样模式配置
当前为 single 为单一转换,因为当前只测量了一个引脚的值
当需要进行多个通道的测量,就可以选用sequence
从哪里开始测量,当前为memory 0
重复模式,不需要用
测量模式 自动和手动
自动模式的采样时间直接设置好的,通过sample timr0设置好后,自动控制
软件里进行转换,所以选择第一个,否则也可以进行事件驱动
转换的数据格式(当前为无符号二进制数)
选择将结果保存到哪一个内存当中,共有12个内存,
关于内存空间的配置
channel和pin是关联的
接下来查看手册,对这两个的关系进行查找
可以看到 ADC0.2对应就是PA25引脚
下面是选择参考电压为VDDA,VDDA是3.3v的电压,这样的话,输入电压范围就是0-3.3V
选择时钟源为timer 0,这个与上面的auto相关联
这个不需要去修改
3.高级设置
本身加ADC12,就说明是12bit的精度,也就是说明,最终输出的数字是0-4095
fifo未启用
power down mode
选择手动或自动模式,这里选择手动模式,在这个模式下,用到sample time 0,设置采样时间,时间越长,结果越准
中断
测量流程:先开启测量,等待测量完成,测量完成后,将结果存到memory 0里面,存入后触发中断,触发中断就说明结果已经测量完成然后将标志位设置为true
所以要使能中断
DMA和EVENT不做配置,PIN保持默认
pin mux,可以选择是ADC0还是ADC1
三、空白模板自己编写
1、配置
添加ADC12
基础功能不需要修改,只需要改需要的引脚即可
高级设置改为手动,配置为125us
中断设置为memory 0中断
2.代码编写
01使能中断ADC12_0_INST_INT_IRQN
找到中断函数名(编译后可打开.h文件)
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
02编写中断服务函数
找到中断服务函数名(编译后可打开.h文件)
用到了Switch语句,通过这个函数获取最高优先级
DL_ADC12_getPendingInterrupt(ADC12_0_INST)
这个函数有两个作用,一是判断找到最高优先级中断,二是清除最高优先级中断标志位标志位
查找数据手册
对应这一节
手册中说明,软件应用程序可以读取这个寄存器,来判断和清除(中断标志位)最高优先级的外设中断,读取会返回当前最高优先级的中断,这个读取同时也会清除RIS和MIS(最高优先级中断标志位)
3.完整代码
#include "ti_msp_dl_config.h"
volatile bool ADC_Flag;//中断标志位
volatile uint16_t ADC_Val;//采样值
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
while (1)
{
ADC_Flag=false ;
DL_ADC12_startConversion(ADC12_0_INST);//开始采样变换
while(ADC_Flag==false);//等待转换完成,如果退出,说明已经弄好了
ADC_Val== DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);//读取结果
DL_ADC12_enableConversions(ADC12_0_INST);//再次使能中断,因为每次执行完就关闭了
}
}
void ADC12_0_INST_IRQHandler (void)
{
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
ADC_Flag = true;
break;
default:
break;
}
}
4.查看结果
添加到watch窗口中
四、多路读取
1.样例工程 (序列转换)
配置ADC0触发4路通道采集,并且保存到不同的buffer里面
编译加载运行这个历程,提供一个0-VCC的电压到ADC通道上,浮空的引脚不保证是0
#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;
}
}
2.配置
sequence
end address 由于有4个内存空间
使能中断 因为到3结束,只需要使能到3就可以了
3.空白模版配置
添加ADC,更改模式为sequence,始末地址为 0 1,
配置两路的引脚
手动设置时间是40us
使能中断1
4.代码编写
定义中断标志位,定义变量接收采集的数据
volatile bool ADC_Flag;
volatile uint16_t ADC_Val1,ADC_Val2;
使能中断
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
设置中断标志位为false
ADC_Flag=false;
开始转换,由于是对ADC0进行转换,启动一次就是序列转换,所以只写一次就行
DL_ADC12_startConversion(ADC12_0_INST);
while循环等待转换
编写中断服务函数,在头文件去找
ADC12_0_INST_IRQHandler
完整代码
#include "ti_msp_dl_config.h"
#include <stdbool.h>
volatile bool ADC_Flag;
volatile uint16_t ADC_Val1,ADC_Val2;
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
while (1) {
ADC_Flag=false;
DL_ADC12_startConversion(ADC12_0_INST);
while (ADC_Flag==false);
ADC_Val1 =
DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
ADC_Val2 =
DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_1);
DL_ADC12_enableConversions(ADC12_0_INST);
}
}
void ADC12_0_INST_IRQHandler(void)
{
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
case DL_ADC12_IIDX_MEM1_RESULT_LOADED:
ADC_Flag = true;
break;
default:
break;
}
}
五、DAC的学习
1、配置
使能
最高和最低参考电压
使能输出
默认值设置为0即可,因为上电后会手动配置
2.高级配置
可以选择12位还是8位的模式,12位就是到4095,8位是到255
二进制输入,选择到on
3.空白模版编写
添加dac模块
使能MFPCLK时钟
设为默认
使能输出,默认值为0
这里只修改为on
代码
#include "ti_msp_dl_config.h"
int main(void)
{
SYSCFG_DL_init();
DL_DAC12_output12(DAC0, 4095);
DL_DAC12_enable(DAC0);
while (1) {
}
}