电子说
1.前言说明
1.1. 本章内容
本MCU带12bit 4.5Msps ADC,这在通用MCU中采样率是比较高的,适合做模拟前端。
本文先对ADC模块进行简单介绍,然后搭建基于MDK和RT-Thread的开发环境,实现ADC信号采集,最终实现虚拟示波器的Demo。
1.2. 模块介绍
参考《CN_UM_N32L40x Series User Manual_V2.pdf》的《17 模拟数字转换( ADC)》
1 个 ADC,支持单端输入和差分输入 ,12 位逐次逼近型。
19 个通道,可测量 16 个外部和 3 个内部信号源
内部通道支持 TempSensor、 VREFINT(内部 1.2V BG)、 VREFBUFF(2.048V)
每个通道的 A/D 转换有四种执行模式:单次、连续、扫描或间断
带内嵌数据一致性的数据对齐。 ADC 转换值存储(左对齐/右对齐)在 16 位数据寄存器中
可以通过模拟看门狗检测输入电压是否在用户定义的高/低阈值内
ADC的输入时钟的最大频率为 64MHz。
支持 12 位、 10 位、 8 位、 6 位分辨率。
12bit 分辨率下最高采样速率 4.57MSPS。
10bit 分辨率下最高采样速率 5.33MSPS。
8bit 分辨率下最高采样速率 6.4MSPS。
6bit 分辨率下最高采样速率 8MSPS。
支持触发采样,包括 EXTI/TIMER。
各通道的采样时间间隔可编程。
支持自校准。
支持 DMA
中断生成:转换结束,注入转换结束,模拟看门狗事件
支持内部参考电压(2.048V)
ADC 支持转换的电压在 VREF-和 VREF+之间。
ADC 的工作电压在 1.8V 到 3.6V 之间。
可以外部触发注入转换和规则转换。
其框图如下
其他相关信息可以参考手册不再赘述。
1.3. 开发软件
开发环境:MDK+RT-Thread
下载工具:板载NsLink
2.步骤说明
2.1. 导入ADC测试工程
下载ftp://58.250.18.138/1-Microcontrollers/N32L40xxx_V2.1.0.zip解压
双击N32L40xxx_V2.1.06-软件开发套件(Software Development Kit)Nationstech.N32L40x_DFP.1.0.0.pack
打开
N32L40xxx_V2.1.06-软件开发套件(Software Development Kit)Nationstech.N32L40x_Library.1.2.1projectsn32l40x_EVALexamplesRT_ThreadRT_Thread12_ADC_DEVICE_REGISTERMDK-ARMADC_DEVICE_REGISTER.uvprojx
选择device
如果提示找不到文件context_rvds.S是因为工程路径中文的原因,工程路径放在英文路径即可。
选择仿真器烧录算法
下载程序可以看到,串口打印如下(串口参数115200-8-n-1)
2.2. ADC代码介绍
ADC驱动使用的是RT-Thread的设备框架。
我们从main.c的main函数入口,可以看到创建了两个线程
test0_thread_entry和test1_thread_entry其中test1_thread_entry线程用于进行ADC采集。
代码如下:
static void test1_thread_entry(void* parameter)
{
rt_adc_device_t adc_dev;
rt_uint32_t adc_converted_value = 0;
adc_dev = (rt_adc_device_t)rt_device_find("adc");
rt_adc_enable(adc_dev, ADC_CH_6_PA5);
rt_adc_enable(adc_dev, ADC_CH_7_PA6);
if(adc_dev)
{
while(1)
{
adc_converted_value = rt_adc_read(adc_dev, ADC_CH_6_PA5);
rt_kprintf("the PA5 voltage value is %drn", adc_converted_value);
rt_thread_delay(50); //delay 500ms
adc_converted_value = rt_adc_read(adc_dev, ADC_CH_7_PA6);
rt_kprintf("the PA6 voltage value is %drn", adc_converted_value);
rt_thread_delay(50); //delay 500ms
}
}
}
可以看到由于使用了驱动框架代码很简单。
rt_adc_device_t adc_dev; 定义设备变量
rt_uint32_t adc_converted_value = 0; 定义变量用于获取采样值
adc_dev = (rt_adc_device_t)rt_device_find(“adc”);查找设备
rt_adc_enable(adc_dev, ADC_CH_6_PA5);
rt_adc_enable(adc_dev, ADC_CH_7_PA6); 使能这两个通道
如果查找到了设备adc_dev则循环采样
adc_converted_value = rt_adc_read(adc_dev, ADC_CH_6_PA5); 采样
再打印延时继续ADC_CH_7_PA6通道的采样。
相关API可以参考RT-Thread官网这里不再赘述。
3.基于ADC实现虚拟示波器
上一节我们实现了ADC的采集,基于此我们可以实现一些有意思的项目,比如将上述采集到的信号发送到PC端进行处理显示,那么就可以实现示波器的功能,这一篇就来实现该Demo。
3.1 代码实现
先将采集到的信号按照一定的格式发送到PC端
上报格式为 “/ 数据,数据 /” 的形式
修改如下,两路采集后一起上报。
static void test1_thread_entry(void* parameter)
{
rt_adc_device_t adc_dev;
rt_uint32_t adc_converted_value1 = 0;
rt_uint32_t adc_converted_value2 = 0;
adc_dev = (rt_adc_device_t)rt_device_find("adc");
rt_adc_enable(adc_dev, ADC_CH_6_PA5);
rt_adc_enable(adc_dev, ADC_CH_7_PA6);
if(adc_dev)
{
while(1)
{
adc_converted_value1 = rt_adc_read(adc_dev, ADC_CH_6_PA5);
//rt_kprintf("the PA5 voltage value is %drn", adc_converted_value);
//rt_thread_delay(50); //delay 500ms
adc_converted_value2 = rt_adc_read(adc_dev, ADC_CH_7_PA6);
//rt_kprintf("the PA6 voltage value is %drn", adc_converted_value);
//rt_thread_delay(50); //delay 500ms
rt_kprintf("/%d,%d/rn", adc_converted_value1,adc_converted_value2);
rt_thread_delay(1); // 上报速率为约1kHz(没有考虑采样和发送时间)
}
}
}
3.2 上位机配置
我们可以使用一款比较好用的开源的串口可视化工具Serial Studio,可以从以下地址下载安装,安装过程很简单,不再赘述。
打开Serial Studio软件,按照如下过程配置
点击控制台标签,先配置串口参数,点击连接,可以看到串口打印信息
点击json编辑器,创建新项目,设置如下的信息
名字为osc,分割符号为,
开始介乎是符号为/和/ ,对应我们的上报格式 “/ 数据,数据 /” 的形式
点击拯救(翻译的问题)
保存文件
3.3 测试
使用变阻器分压接到PA5和PA6模拟电压变化,进行测试。
点击仪表盘可以看到曲线显示:
改变变阻器位置,可以看到曲线的变化。
得益于ADC的精度和采样率都比较高,可以实现具备使用价值的虚拟示波器。目前的代码仅作延时,实际上如果产品化更具备实用价值我们可以实用DMA方式采集,保存到缓存区然后通过USB高速接口发送到PC端进行解析显示,这样就可以达到ADC的最大带宽8MSPS。这个采样率已经可以比肩一般手持示波器了。
4.章节总结
以上完成了ADC的测试,并实现了一个有一定实用价值的Demo. 从以上可以看出从应用程序开发角度来说,使用RT-Thread的设备框架非常方便,几行简单的代码即可完成ADC采集。
另外Nation的文档和例程也是做的比较好和规范的,所以使用起来也比较简单。
全部0条评论
快来发表一下你的评论吧 !