bandgap的理解(内部带隙电压基准)
转载地址:http://bbs.mydigit.cn/read.php?tid=1635508
写的非常好,想把每句话都记住。
首先了解两个英文缩写。
Abbreviations缩略语 |
Full spelling 英文全名 |
Chinese explanation 中文解释 |
POR |
Power on reset |
上电复位 |
Vreg |
Reference Voltage |
基准电压/参考电压 |
一、研究背景
大家都知道,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的例程,按人家要求说明 : /* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序 */
#include <STC15F2K60S2.H> //MCU:stc15w404as
#include<stdio.h>
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define FOSC 11059200L
#define BAUD 9600
//工作频率11.0592MHz 串口波特率9600
//-----------------------------------------
//ADC相关设定参数
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
#define ADC_SPEEDL 0x20 //360个时钟
#define ADC_SPEEDH 0x40 //180个时钟
#define ADC_SPEEDHH 0x60 //90个时钟
//-----------------------------------------
//BandGap相关参数
#define ID_ADDR_RAM 0xef //对于只有256字节RAM的MCU(大部分系列)存放地址为0EFH
//#define ID_ADDR_RAM 0x6f //对于只有128字节RAM的MCU(stc15f/w100系列)存放地址为06fH
//注意:需要在下载代码时选择"在ID号前添加重要测试参数"选项,才可在程序中获取此参数
//容量不同的单片机请更改不同数值
//#define ID_ADDR_ROM 0x03f7 //1K程序空间的MCU
//#define ID_ADDR_ROM 0x07f7 //2K程序空间的MCU
//#define ID_ADDR_ROM 0x0bf7 //3K程序空间的MCU
#define ID_ADDR_ROM 0x0ff7 //4K程序空间的MCU
//#define ID_ADDR_ROM 0x13f7 //5K程序空间的MCU
//#define ID_ADDR_ROM 0x1ff7 //8K程序空间的MCU
//#define ID_ADDR_ROM 0x27f7 //10K程序空间的MCU
//#define ID_ADDR_ROM 0x2ff7 //12K程序空间的MCU
//#define ID_ADDR_ROM 0x3ff7 //16K程序空间的MCU
//#define ID_ADDR_ROM 0x4ff7 //20K程序空间的MCU
//#define ID_ADDR_ROM 0x5ff7 //24K程序空间的MCU
//#define ID_ADDR_ROM 0x6ff7 //28K程序空间的MCU
//#define ID_ADDR_ROM 0x7ff7 //32K程序空间的MCU
//#define ID_ADDR_ROM 0x9ff7 //40K程序空间的MCU
//#define ID_ADDR_ROM 0xbff7 //48K程序空间的MCU
//#define ID_ADDR_ROM 0xcff7 //52K程序空间的MCU
//#define ID_ADDR_ROM 0xdff7 //56K程序空间的MCU
//#define ID_ADDR_ROM 0xeff7 //60K程序空间的MCU
//-----------------------------------------
//声明
void InitUart();
void InitADC();
void SendData(uchar dat);
uint GetADCResult(uchar ch);
void Delay(uint n);
void ShowResult(uchar ch);
void main()
{InitUart(); //初始化串口InitADC(); //初始化ADCP1M1=0X01; //高阻输入while (1){//ShowResult(0); //显示通道0//ShowResult(1); //显示通道1ShowResult(2); //显示通道2//ShowResult(3); //显示通道3//ShowResult(4); //显示通道4//ShowResult(5); //显示通道5//ShowResult(6); //显示通道6//ShowResult(7); //显示通道7Delay(100);}
}
/*----------------------------
发送ADC结果
----------------------------*/
void ShowResult(uchar ch)
{uint adc_res10,//测量设定通道adc值bandgap, //bandgap预储存校准值,单位毫伏adc_9gallery_res; //测量第九通道(bandgap)值float power_voltage, //系统供电电压,单位毫伏ADC_voltage; //设定通道电压值,单位毫伏uchar code *cptr; //定义ROM(代码)区指针//uchar idata *iptr;//定义RAM(内存)区指针cptr = ID_ADDR_ROM; //从程序区读取BandGap电压值(单位:毫伏mV)bandgap=*cptr++;bandgap<<=8;bandgap+=*cptr;/*iptr = ID_ADDR_RAM; //从内存区读取BandGap电压值(单位:毫伏mV)bandgap=*iptr++; //两种方法结果一样,上面的方法需要在下载式勾选"在ID号前添加重要测试参数"选项,才可在程序中获取此参数bandgap<<=8; //下面的方法不需要bandgap+=*iptr; *///测量设定通道adc值ADC_RES = 0; //清除结果寄存器P1ASF = 0xff; //设置P1口为AD口GetADCResult(ch);GetADCResult(ch); //读三次获得稳定adc_res10= GetADCResult(ch);//测量第九通道(bandgap)值ADC_RES = 0; //清除结果寄存器P1ASF = 0x00; //设置读第九通道GetADCResult(0); //测bandgap时,调用此函数时通道数只能填0GetADCResult(0); //读三次获得稳定adc_9gallery_res=GetADCResult(0);//计算系统供电电压power_voltage=(float)bandgap*1024/adc_9gallery_res;//计算ADC通道测得电压值ADC_voltage=(float)bandgap*adc_res10/adc_9gallery_res;printf("P1.%d ADC result:%d\n",(uint)ch,adc_res10);printf("BandGap standard:%d mV\n",bandgap);printf("BandGap value:%d \n",adc_9gallery_res);printf("system power voltage:%.0f mV\n",power_voltage);printf("ADC voltage:%.0f mV\n",ADC_voltage);
}
/*----------------------------
读取ADC结果
----------------------------*/
uint GetADCResult(uchar ch)
{uint ADC_10BIT_RES;ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;_nop_(); //等待4个NOP_nop_();_nop_();_nop_();while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成ADC_CONTR &= ~ADC_FLAG; //关闭 ADCADC_10BIT_RES=ADC_RES; //得到高8位ADC_10BIT_RES<<=2;ADC_10BIT_RES+=ADC_RESL; //得到低2位return ADC_10BIT_RES; //返回ADC结果}
/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{SCON = 0x5a; //设置串口为8位可变波特率T2L = 0xE0; //设定定时初值T2H = 0xFE; //设定定时初值AUXR = 0x14; //T2为1T模式, 并启动定时器2AUXR |= 0x01; //选择定时器2为串口1的波特率发生器
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{P1ASF = 0xff; //设置P1口为AD口ADC_RES = 0; //清除结果寄存器ADC_CONTR = ADC_POWER | ADC_SPEEDLL;Delay(2); //ADC上电并延时
}
/*----------------------------
软件延时
----------------------------*/
void Delay(uint n)
{uint x;while (n--){x = 5000;while (x--);}
}
bandgap的理解(内部带隙电压基准)相关推荐
- BANDGAP VOLTAGE REFERENCE 带隙电压基准的问题
电压带隙基准设计,采用此种结构 ,其中运放用五管OTA级联共源级的方法设计 直流交流仿真如图.但是由于运放输出端要接bandgap电路的两个mos管栅端,而这两个mos管的栅端又与运放中两个pmos管 ...
- ADR01BRZ 精密电压基准IC 应用及介绍
ADR01.ADR02.ADR03 和 ADR06 是精密 10.0 V.5.0 V.2.5 V 和 3.0 V 带隙电压基准,具有高精度.高稳定性和低功耗. 这些部件采用微型 5 引脚 SC70 和 ...
- 串联型或并联型电压基准的选择
本文介绍了不同类型电压基准芯片的选择,提供了选择串联型和并联型电压基准时需要考虑的几项指标. 串联型电压基准 串联型电压基准具有三个端子:VIN.VOUT和GND,类似于线性稳压器,但其输出电流较低. ...
- STM32 之十 供电系统及内部参照电压(VREFINT)使用及改善ADC参考电压
问题 今天在使用 STM32F407 的 ADC 时遇到一个问题:ADC 的参考电压都是通过 Vref+ 引脚提供的并作为ADC转换器的基准电压(部分 MCU 没有 Vref+ 引脚).当我们使用 ...
- STM32 之十 供电系统及内部参照电压(VREFINT)使用及改善ADC参考电压,内部参照电压的具体方法,只有在STM32F0x芯片的参考手册中才能找到,其他MCU的参考手册都是很简单的说明
STM32 之十 供电系统及内部参照电压(VREFINT)使用及改善ADC参考电压 ZCShouEXP 2018-12-21 10:50:33 16404 收藏 32 展开 问题 今天在使用 ...
- STM32 之 供电系统及内部参照电压(VREFINT)使用及改善ADC参考电压和ADC校准
STM32 之 供电系统及内部参照电压(VREFINT)使用及改善ADC参考电压 发布时间:2018-12-21 10:50, 浏览次数:1553 , 标签: STM VREFINT ADC < ...
- 【硬件学习笔记003】玩转电压基准芯片:TL431及其他常用电压基准芯片
TL431 是三端可调节并联稳压器.可以通过两个外部电阻器将输出电压设置为介于 Vref(约为 2.5V)和36V之间的任意值.其输出阻抗典型值均为 0.2Ω.此类器件的有源输出电路具有非常明显的导通 ...
- DC-DC电压基准芯片和REF芯片
DC-DC电压基准芯片和REF芯片 (2013-03-19 10:29:54) 转载▼ 标签: 精密 基准电压 ref it 分类: 电子 电压基准芯片 新发现LM4140系列高精度基准电压源 LM2 ...
- STM32的内部参照电压VREFINT(1.2V)和ADC参考电压Vref+如何区分呢
一.STM32的内部参照电压VREFINT和ADCx_IN17相连接,它的作用是相当于一个标准电压测量点(和MSP430不一样..),内部参照电压VREFINT只能出现在主ADC1中使用. 内部参照电 ...
最新文章
- python使用matplotlib可视化线图(line plot)、将可视化图像的图例(legend)放置在图像外部、右侧区域
- 最小生成树模板总结--PrimKruskal
- mycheckpoint
- cmd中加载java源文件_如何在cmd中编译和运行java源文件
- mysql2008无法登陆_SQL2008不能登录实例
- indesign教程,如何使用共享交互式文档?
- android音频格式,适用于iOS和Android的音频格式
- 一个月的时间让你的词汇量翻一翻
- 针式打印机打印显示传真服务器,针式打印机三联纸怎么设置 点击上面的工具栏上的打印服务...
- 腾讯云服务器放音乐,使用腾讯云函数实现网易云音乐自动打卡签到
- centos下安装firefox
- QML 全屏 输入法无法显示
- [记录][问题]Win32调用C++/WinRT DLL
- 应届生想做产品经理该怎么走?
- 复旦大学的计算机专业分数线,2018复旦大学分数线 各专业分数线是多少
- Cognitive Complexity of methods should not be too high Refactor this method to reduce its Cognitive
- excel 将图片的链接URL 显示为图片 转
- 微前端:使用qiankun框架从 0-1 搭建vue构成微前端项目
- 图论宽度优先搜索---八数码
- 会计计算机敲打大赛,2017上半年会计实操技能竞赛“荣耀对决”总决赛!