MSPM0L1306例程学习-ADC部分(4)
2023-12-21 19:08:05
MSPM0L1306例程学习系列
使用的TI的官方例程,即SDK里边包含的例程代码。
可以到TI官网下载并且安装SDK: https://www.ti.com.cn/tool/cn/download/MSPM0-SDK/
MCU使用的是MSPM0L1306, 对于ADC部分,有10个例程:
今天要讲的例程是adc12_14bit_resolution,12位的ADC内核通过过采样实现14位的分辨率。
相关的要点如下:
- ADC的工作模式选择 单通道 多次转换,选择adc通道2(PA25),这个可以根据实际需要进行修改的;
- 参考电压的选择上,直接使用了电源电压作为基准电压。
- 启用了ADC的硬件均值功能,也就是ADC自带一个硬件功能,可以自动采样指定的次数*(2、4、8、16、32、64、128,仔细看下,都刚好是2的n次方),再将转换结果除以特定的数(1、2、4、8、16、32、64、128,也是2的n次方,可以通过移位直接得出结果)*,最后将计算出来的结果作为这一次ADC转换的结果写入结果存储寄存器。例程的配置中,16次的转换结果,只除以4,相当于提高2位分辨率。
- 使用了DMA传输,没有使用FIFO寄存器。每次直接对ADC的结果存储寄存器进行搬运,每次搬运1个2字节的数据。有新数据写入MEM0时,会触发DMA传输搬运转换结果。 搬运了1024次后,DMA传输完成,进入中断,设置标志位,程序继续往下执行。
例程的注解参考如下:
代码简单注释如下:
/*
* ADC转换的SDK例程
* 文件名:adc12_14bit_resolution.c
* 描述:
* 采用过采样的方式,实现14位分辨率。
* 1、单通道、多次转换、自动采样模式、软件触发;
* 2、使用MEM0,选择ADC通道2(PA25)
* 3、直接使用电源电压做参考电压
* 4、--> 使用硬件均值的功能,每次的转换结果是自动对16次转换求和再除以4的结果;
* 5、转换ADC_SAMPLE_SIZE=1024次,将通过DMA存放到数组gADCSamples[]中;
* 6、代码中设有断点语句__BKPT(0),会自动进入断点,查看数据;
*
* 操作描述:
* 1、下载程序;
* 2、添加观察变量gADCSamples,全速运行;
* 3、系统会自动停在断点处,查看ADC的采样结果值;
*
* 注意事项:
* 1、注意系统时钟的配置,ADC的时钟为32MHz
* 2、在SYSCONFIG图形配置工具中并没有完成所有的DMA参数配置;
* 部分的参数配置,在主程序通过调用库函数的形式进行重新配置;
*
* 思考:
* 1、先增加理论知识,搜下过采样的概念,了解12位分辨率的ADC,怎么才能变成14位分辨率
* 2、从什么样的实现结果,证明14位的分辨率?
* 3、理解分辨率和精度的关系,通过过采样提升了分辨率,不是提升精度,两个概念;
*
* 修改:
* 基于官方的sdk例程增加注释,xie_sx@126.com
*/
#include "ti_msp_dl_config.h"
//宏定义了ADC转换结果的数量(数组的大小)
#define ADC_SAMPLE_SIZE (1024)
//定义16位的数组来存放ADC的转换结果.
uint16_t gADCSamples[ADC_SAMPLE_SIZE];
//标志变量,ADC的转换结果是否已经传输完成;
volatile bool gCheckADC;
int main(void)
{
//器件初始化
SYSCFG_DL_init();
//配置DMA的源地址、目的地址和传输大小
//此处先设置源地址,从MEMRES0读取ADC的转换的结果
//其它参数在while(1)里设置
DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) DL_ADC12_getMemResultAddress(ADC12_0_INST, DL_ADC12_MEM_IDX_0));
//配置器件的中断
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
//ADC12的转换完成标志位清零
gCheckADC = false;
while (1)
{
//在开始新的捕获之前配置DMA的大小和目的地址
//先禁用,修改配置,再使能
//配置DMA搬运的目的地址,数组gADCSamples
//传输大小为转换的次数,ADC_SAMPLE_SIZE
DL_DMA_disableChannel(DMA, DMA_CH0_CHAN_ID);
DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &gADCSamples[0]);
DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, ADC_SAMPLE_SIZE);
DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
//重新启用ADC12的DMA模式,因为每次传输完成时该模式都会被自动清除
DL_ADC12_enableDMA(ADC12_0_INST);
//软件启动ADC12转换
DL_ADC12_startConversion(ADC12_0_INST);
while (false == gCheckADC)
{
__WFE();
}
//ADC12的转换完成标志位清零
gCheckADC = false;
//断点语句,程序运行到此处会自动进入断点,可查看ADC的转换结果
__BKPT(0);
}
}
/*
* ADC12中断处理函数
* 通过DMA传输完成中断来判断ADC转换结束
*
*/
void ADC12_0_INST_IRQHandler(void)
{
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST))
{
case DL_ADC12_IIDX_DMA_DONE:
gCheckADC = true;
break;
default:
break;
}
}
文章来源:https://blog.csdn.net/xie_sx/article/details/135131430
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!