ADC模数转换
本文档参考讲师熊家余老师的文档,因原理讲解还是老师讲的详细,就直接搬过来了,后面根据老师的例程设置我自己做的ADC模数转换。
1.介绍本章我们来学习一下T5L芯片内部的ADC模数转换外设,有一点需要注意的是此ADC外设不属于C51核,而是属于GUI核,ADC外设相关的底层硬件驱动程序已被GUI核中的DGUS II系统给封装好了,让我们开发者不用去管更多的底层细节,使用起来更方便,但是换一句话来说,我们也就失去了对ADC外设进行自定制的能力,比如说在C51代码中能不能实现设置ADC外设的采样周期以及分辨率呢?可以明确地告诉大家,目前是不能的,因为ADC外设被DGUS II系统给封装之后,并没有给我们开发者提供相关的接口,它就只给我们提供了一个读取ADC转换结果的接口,但这都不重要,因为一般情况下,我们不需要去设置这些ADC参数,所以看待一个事物,一定要理性,整体上来说T5L芯片内部的ADC外设还是不错的,使用起来相当简单,而且采样数据还比较稳定,缺点就是转换速度慢.
T5L芯片内部的ADC外设总共具有ADC0-ADC7这8个采样通道,采样分辨率固定为12位,在T5L芯片上电稳定之后,这8个采样通道都是被强制开启的,没办法被关闭的,8个采样通道之间依次循环转换,转换好的结果被保存到了”DGUS存储器”上,更为具体一点地说就是被保存到了”系统变量接口”上,此ADC外设的默认参考电压为3.3V,你可以通过T5L芯片上的VREF引脚来连接你想要的参考电压,如下图所示:
图1.1 VREF参考电压引脚
前面说到我们的C51代码要想读取ADC的转换结果,就必须得通过”系统变量接口”来进行访问,”系统变量接口”还给我们提供了很多其他的功能,在本章节中,我们只关心ADC相关的功能,如下图所示:
从官方文档描述可知,我们只需要通过sys_read_vp函数从0x32起始地址处读取数据即可,读取到的数据就是相应ADC通道的转换结果.
电压 = AD值*3300/4095 mV
2.例程设计2.1功能简介我们C51代码中读取ADC0通道的转换结果,然后通过一个简单的平均滤波算法,最后把稳定之后的AD值和电压值显示到界面上
2.2 GUI界面设计 主要是用到了2个”数据变量显示控件”,一个用来显示AD值,一个用来显示电压值,然后启动界面的整体设计如下图所示:
图2.2.1 启动界面的设计(第1个数据变量显示控件)
图2.2.2 启动界面的设计(第2个数据变量显示控件)
2.3 C51代码设计我们可以直接利用在第1章节中已经创建好的C51项目工程模板,然后在此基础上进行修改,我们在HARDWARE文件夹下创建ADC子文件夹,接着在ADC子文件夹下创建adc.c和adc.h驱动文件
(1) adc.c文件的代码如下:
#include "adc.h"
#define ADC_START_ADDR 0x32
//读取通道的ad值,不需要启动命令,屏幕上电之后,直接读取就行
//chn:0-7
u16 adc_get(u16 chn)
{
sys_read_vp(ADC_START_ADDR+chn,(u8*)&chn,1);
return chn;
}
//读取通道的平均ad值
//chn:0-7
//avg_cnt:平均次数
//返回稳定之后的ad值
u16 adc_get_avg(u16 chn,u16 avg_cnt)
{
u16 cnt;
u16 ad;
u16 max_ad = 0;
u16 min_ad = 0xFFFF;
float ad_sum = 0;
{
//注意,因为我们T5L中的ADC采样速度慢,差不多80ms出一个采样结果,而且T5L也没有
//给我们提供任何判断ADC转换完毕的标志位,所以这里只能采用大约延时了,当然了你可以
//采用定时器的方式来做,好处就是不会造成程序堵塞,如果不延时直接读取的话,
//那读取到的是上次的转换结果,这样我们的平均滤波算法就失去意义了
sys_delay_ms(100);
ad = adc_get(chn);
ad_sum += ad;//计算总和
if(ad>max_ad)
max_ad = ad;//找出最大ad值
if(ad
min_ad = ad;//找出最小ad值
}
if(avg_cnt>2)
{
ad_sum = ad_sum-max_ad-min_ad;//从总和中去掉最大值和最小值
avg_cnt -= 2;
}
ad = (u16)(ad_sum/avg_cnt+0.5f);//加0.5f是为了四舍五入取整
return ad;
}
(2) main.c文件的代码如下:
#include "sys.h"
#include "adc.h"
void main(void)
{
u16 ad;
float vol;
sys_init();//系统初始化
while(1)
{
//1.读取通道0的ad值
ad = adc_get_avg(ADC_CHANNEL0,10);
//2.计算得到电压,单位mV
vol = ad*(3300.0f/4095);
//3.把ad值和电压显示到界面上
sys_write_vp(0x2000,(u8*)&ad,1);//更新ad值
sys_write_vp(0x2001,(u8*)&vol,2);//更新电压值
}
}
2.3 C51代码编译bin文件配置首先下载文件,我在网上找的,忘记了。感谢。网上方法也不少,我来说一下我的方法吧。
(1) 准备文件:
如图所示,在USER文件夹内新建DOWNLOAD文件夹,存储最终生成bin文件。在USER文件内新建两个bat文件。如下图所示。
2.3.1 准备文件夹及文件
2.3.2 生成bin文件bat文件
2.3.3 清除中间文件
(2)
配置keil options内的User:
在Options配置界面里,点击User,将After Build/Rebuild的Run#1选中,并填入.AfterBuildRun.bat命令,保存即可。
2.3.4 设置keil
(3) 编译生成:
点击keil中编译生成bin文件,出现问题。根据提示修改文件,重新编译成功。如下图所示。
2.3.5 生成bin文件
2.3.6 修改bat文件
2.3.7 最终生成bin文件
2.4下载程序将GUI文件DWIN_SET文件夹文件和T5L51.bin拷贝到TF卡的DWIN_SET文件夹内,下载程序。
断电,插入TF卡,上电,等待刷新程序OK。断电,拔下TF卡,重新上电ok。如视频所示。
TF卡内的汉字库和CFG文件需要自己生成。
问题:供电电源为5V,adc显示电压为啥高于5V?