切换到宽版
  • 76947阅读
  • 143回复

[C51]谈谈stc15系列单片机adc第九通道BandGap(内部带隙电压基准)使用问题 [复制链接]

上一主题 下一主题
离线2545889167
 

发帖
13268
M币
20754
专家
302
粉丝
4860
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2016-04-27
— 本帖被 香瑶 设置为精华,作者+3000M币+5专家(2016-04-28) —
大家都知道,stc单片机的adc(模数转换器)的基准是基于基于供电电源电压的,这样就造成了一个问题,如果供电电压发生变化,adc读得的值也会发生变化,就出现了测不准的现象,所以大家普遍的用法就是在adc的一个通道外接一个电压基准,类似tl431,通过读电压基准和测量值,换算出真实测量电压,但这样就会带来个问题,要占用一路adc通道,占用一个io,付出tl431的成本,外接还要处理电路,麻烦。所以stc15系列的单片机给我们提供了内部的基准,名字叫BandGap(内部带隙电压基准)。
这两天要搞adc的应用,想到stc内部有基准,于是研读了数据手册,然而数据手册说的很不清楚,内容还分布在不同的地方,于是就搜索了下。但是在百度上的有用搜索结果很少,有一个本坛的帖子,点进去看了大部分人也是没搞懂

甚至大家都不太懂stc还有第九通道

还有人继续提tl431外部基准法

之前也看到有坛友在抱怨内部基准是垃圾,居然会随供电电压变化,完全没用什么的。



无法只好自己研究了,经过一下午的研究,终于搞了个明白,遂分享给大家,一起学习进步。



我们先说说BandGap(带隙电压)是啥。百度给出的解释是:

看上去比较复杂,我画了张简单的图表示,不是很准确,理解就好


如图,基准有两个材料串联而成,分别为温度正材料(温度升高阻值变大)和温度负材料(温度升高阻值变小)串联而成,这样,两个材料互相抵消,基准值就不会随温度发生变化。这样做的原因是在半导体制造中,几乎找不到不随温度变化的材料,所以选用了这种折中方案。

所以,和数据手册说的是一样的,基准不随芯片工作电压改变而变化。


所以,内部基准读取后需要进行数学转换,就能成我们想用的值。

但是,官方给的例程貌似是有点问题的,串口出来的,数值不对,呵呵

而且,由于每片芯片的制造差异性,每个基准的比例不是相同的,每片芯片有特异性。
我的几片同款芯片的这个测量值都是有差异的,相差也不小。

stc给出的方案是这样的,在5v标准电源下测量BandGap的adc读数,然后记录在eeprom内,以后的程序不就可以读取这个值并进行比例换算了吗?
但是,大家有没有觉得这样会异常的麻烦,5v基准供电电压不好找,如果大量生产的话,每片都要读取校准会费时费力。
所以,stc还是蛮善良的,其实他们早就给我们标定好了这个值,我们只需要想点小办法吧它读出来就好。
数据手手册里面是这样的



这里要吐个槽,stc的数据手册编写者你真蛋疼,居然把两个内容分开讲,讲adc的第九通道,在数据手册第10.8节,第906页;讲怎么读取得标定值,在数据手册第1.18节,第284页,这是个大坑啊,跨度一个世纪的内容,呵呵了。
扯远了,这个标定值会储存在两个地方,一个是RAM(内存)末尾,一个是ROM(程序区)末尾。但是官方比较推荐的读取地点好像是使用程序储存器末尾,好像是因为ram的数据容易被覆盖。
不过用rom区的话,要注意以下三个问题:
程序储存区末尾会被占用那么十几二十个字节,不过一般小程序也不影响啥,写满程序区的就要注意下了。
同时,在使用rom区数据时,在下载时要勾选选项“在ID号前添加重要测试参数”(在下载选项末尾的一个选项,默认是不选的,要记得勾上)
第三,不同储存空间的单片机在程序中要定义不同的地址,我的是stc15w404as,选的是内部储存为4k(#define ID_ADDR_ROM 0x0ff7      //4K程序空间的MCU),这个的话应该大家读懂吧。



另外提一句,使用基准,不管内部外部,都能计算出供电电压,如果电压下降啥的,能在程序里做出反应,比如说记录数据如eeprom什么的,实现掉电保护,这个大家脑洞了

提醒大家的事,使用外部晶振的时候,读不到bandgap的adc值,这个非常重要,望周知

感谢@mosliu 朋友的测试和补充,详情看这贴:STC15系列 读取BandGap的一点小小补充 另外吐槽下STC的客服|http://bbs.mydigit.cn/read.php?tid=1653284


好的,讲了这么多理论的废话,还不如直接上代码实践
顺便说下,使用了部分stc的例程,按人家要求说明 : /* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序   */
以下就是我们今天的核心代码,基本每行都有注释,大家先看,不懂的问,我给解释,文末也会给出完整代码给大家下载
  1. void ShowResult(uchar ch)
  2. {
  3.     uint adc_res10,//测量设定通道adc值
  4.     bandgap,       //bandgap预储存校准值,单位毫伏
  5.     adc_9gallery_res; //测量第九通道(bandgap)值
  6.     float power_voltage,        //系统供电电压,单位毫伏
  7.     ADC_voltage;     //设定通道电压值,单位毫伏
  8.     
  9.     uchar  code *cptr; //定义ROM(代码)区指针
  10.     //uchar  idata *iptr;//定义RAM(内存)区指针
  11.     
  12.     cptr = ID_ADDR_ROM;         //从程序区读取BandGap电压值(单位:毫伏mV)
  13.     bandgap=*cptr++;
  14.     bandgap<<=8;
  15.     bandgap+=*cptr;
  16.     /*iptr = ID_ADDR_RAM;         //从内存区读取BandGap电压值(单位:毫伏mV),貌似不推荐
  17.     bandgap=*iptr++;              //两种方法结果一样,
  18.                         //上面的方法需要在下载式勾选"在ID号前添加重要测试参数"选项,才可在程序中获取此参数
  19.     bandgap<<=8;                  //下面的这种方法不需要
  20.     bandgap+=*iptr;    */
  21.     //测量设定通道adc值
  22.     ADC_RES = 0;                    //清除结果寄存器
  23.     P1ASF = 0xff;                   //设置P1口为AD口
  24.     GetADCResult(ch);                //GetADCResult(ch)函数是从adc处读结果,输入时通道号,P1.0口就是0通道,以此类推
  25.     GetADCResult(ch);                 //读三次获得稳定
  26.     adc_res10= GetADCResult(ch);
  27.     //测量第九通道(bandgap)值
  28.     ADC_RES = 0;                    //清除结果寄存器
  29.     P1ASF = 0x00;                   //设置读第九通道
  30.     GetADCResult(0);                 //测bandgap时,调用此函数时通道数只能填0
  31.     GetADCResult(0);                 //读三次获得稳定
  32.     adc_9gallery_res=GetADCResult(0);
  33.     //计算系统供电电压
  34.     power_voltage=(float)bandgap*1024/adc_9gallery_res;
  35.     //计算ADC通道测得电压值
  36.     ADC_voltage=(float)bandgap*adc_res10/adc_9gallery_res;
  37.     printf("P1.%d ADC result:%d\n",(uint)ch,adc_res10);
  38.     printf("BandGap standard:%d mV\n",bandgap);
  39.     printf("BandGap value:%d \n",adc_9gallery_res);
  40.     printf("system power voltage:%.0f mV\n",power_voltage);
  41.     printf("ADC voltage:%.0f mV\n",ADC_voltage);
  42. }

代码完了以后,来试试实际效果
测量1.2v基准时,万用表值


单片机在5v供电下测量值

在3.3v供电下测量值

差距不算太大,能接受


图放不下了,楼下继续,大家有m币使劲砸吧

完整程序

已经在下面的二楼复制粘贴了,不要m币

[ 此帖被2545889167在2016-05-11 16:40重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共42条打赏 ,M币+200 ,专家+1
离线2545889167

发帖
13268
M币
20754
专家
302
粉丝
4860
只看该作者 1楼 发表于: 2016-04-27
请登录后查看
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共14条打赏 ,M币+54
12
离线2545889167

发帖
13268
M币
20754
专家
302
粉丝
4860
只看该作者 2楼 发表于: 2016-04-27
请登录后查看
本帖最近打赏记录:共16条打赏 ,M币+59
12
离线luannan

发帖
79
M币
64
专家
1
粉丝
6
只看该作者 3楼 发表于: 2016-04-27
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+3
离线milaoda

发帖
2263
M币
2679
专家
11
粉丝
83
只看该作者 4楼 发表于: 2016-04-27
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+3
离线rzlx

发帖
208
M币
241
专家
1
粉丝
14
只看该作者 5楼 发表于: 2016-04-27
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+3
离线wang_00008

发帖
636
M币
575
专家
3
粉丝
53
只看该作者 6楼 发表于: 2016-04-27
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+3
离线桃源客

发帖
3451
M币
762
专家
18
粉丝
245
只看该作者 7楼 发表于: 2016-04-28
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+3

发帖
661
M币
7254
专家
5
粉丝
36
只看该作者 8楼 发表于: 2016-04-28
Re:【教程向】谈谈stc15系列单片机adc第九通道BandGap(内部带隙电压基准)使用问题
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+3
离线xielc

发帖
2005
M币
1388
专家
1
粉丝
63
只看该作者 9楼 发表于: 2016-04-28
请登录后查看
本帖最近打赏记录:共1条打赏 ,M币+3
快速回复
限80 字节
“新手上路”发帖需审核后才能显示(请认真发帖),达到数码9级后取消此限制
 
上一个 下一个