个人成就
- 发布了43篇内容
- 获得了2次赞同
- 获得了5次收藏
个人简介
擅长领域
暂时没有设置哦~
-
RISC-V鸿蒙开发板单片机简介2(项目连载9)
这篇文章我们来简要的介绍一下Pygmy-E单片机使用的I2C通信接口,主要内容是通信协议的描述,框图的讲解,以及相关寄存器的介绍等等。本文介绍的时候,尽量把它和主流的STM32单片机对比,这样大家可以对两个I2C的外设都有更清晰的认识。其中红色框框选出来的关键字属于Pygmy-E单片机支持的I2C,绿色框框选出来的属于STM32F030C8T6这款单片机。
1. 传输速度
和主流的STM32单片机一样,Pygmy-E系列的单片机的I2C接口,一样支持不同的传输速度,从而适配不同的外设和场景诉求。
2. 组成框图
从框图上来看,两种类型的I2C接口组成单元是类似的。要实现I2C协议相关的信息收发功能,首先必须要有这些相应的功能;再一个,按照这样的模块进行对整个功能模块进行切分,可能在电路设计上相对最为简单。但是整体上,还是STM32这款单片机对I2C各个组成模块及其相互之间的关系描述得更加清晰。
3. 开始信号和信号传输信号
I2C通信协议,开始信号和结束信号,是在SCLK为低的时候,通过SDA这个引脚的变化来产生的。 SDA由高到低的时候,是start信号;SDA由低到高的时候,是STOP信号。那么既然这两个信号是开始和终止信号,那么在信号传输的过程中一定要避免这样的信号出现。那么从协议上看,在数据传输的过充中,数据信号的采样(保持不变)只能是在SCL为高电平的时候,数据信号的改变只能是在SCL电平为低的时候。另外为了避免,在SCL为高的时候,万一SDA的信号发生了变化,可以适当配置SDA和相对于SCLK信号的先发和延后时间。这个误识别的诱发因素会很多,比如布线的时候,如果不是等长线,就有可能导致默认配置的先发和延后时间失去作用。Pygmy-E单片机和STM32单片机都提供了相应的寄存器来配置这个时间。
从这个方面上来看,两款I2C电路基本是一致的,只是配置延时时间的寄存器可能是不一样的。
4. 寄存器
下面是配置两款I2C接口时所使用的寄存器,大家从图上可以看出,Pygmy-E系列的单片机I2C接口所需要配置的寄存器非常复杂,总计有68个寄存器需要配置。相比之下,STM32单片机所需要配置的寄存器就要少很多,明显感觉易用性更好。Pygmy-E单片机的I2C接口使用这么多的寄存器好处也当然是有的,它可以帮助我们对I2C接口模块有相对更为深入的理解。但是需要我们对I2C通信协议以及相关的应用非常熟悉才行,否则这么多的寄存器相当容易把开发者搞晕。
5. 从地址
两个I2C接口模块,都支持7位和10位地址协议。接口的通用性上都差不多。具体的通信内容的格式,这里就不在进行比较了。
对上述几个关键的方面进行比较后,我们基本上可以感觉到,相比STM32f030C8T6这款单片机,Pygmy-E单片机的I2C接口使用起来难度相对较高。但是它数量庞大的寄存器,同时增强了使用它时的灵活度。两款接口应该是各有所长,但是从通用性上而言,STM32的I2C接口可能会更加友好。
-
if和for等基本语句结构
大家好,我是张飞实战电子张角老师!
同学们好,我们从今天开始探讨单片机C语言,我们首先从if和for等基本语句结构开始。
if和for,这两个从本质上来说,是不是C语言的两个关键字呀。那么我们为什么又把它称之为C语言的基本结构的一部分呢。要回答这个问题,我们是不是首先要搞清楚C语言的基本结构是什么?
实际上,任何结构化编程语言的基本结构都是相同的,也就是三种基本的程序结构:顺序,分支和循环。由这三者最基本的结构,可以搭建出任何我们想实现的程序结构。在狄杰斯特拉(Edsger W. Dijkstra)反复研究面条式代码(spaghetti code),并在1968年给某位编辑写了一篇著名的简信,题为《Go to语句是有害的》之后,计算机科学家Corrado Bohm和Giuseppe Jacopini证明,使用顺序(sequencing),分支/选择(alternation)和循环(iteration)这三种流程结构就足以表达所有程序的本质。C语言作为结构化编程语言的一种,其程序结构,自然也是由这三种最基本的程序结构组成。
顺序执行程序,这个很好理解,一条语句接着一条语句执行就可以了。那么C语言的分支和循环是如何实现的呢?
对于分支,我们常见的关键词是不是有if/else和switch/case两种组合呀。if/else翻译过来,是不是就是“如果…,否则…”,是一个条件判断。如果用伪代码的方式来进行表达的话,一般有这两种形式。
第一种形式如下:
if(条件为真)
{
代码段1;
}
else
{
代码段2;
}
这里else的含义其实就是条件不为真,那么也就是条件为假。
第二种形式是这样的,
if(条件1为真)
{
代码段1;
}
else if(条件2为真)
{
代码段2;
}
else
{
代码段3;
}
第一种形式和第二种形式本质上的区别,其实就是第一个是双分支,第二个是多分支。两种不同的分支,我们要根据具体情况去使用。某种意义上多分支模式可以由双分支演变而来,比如我们可以在双分支模式里面的else里嵌套一个双分支结构就可以了。
if(条件1为真)
{
代码段1;
}
else
{
if(条件2为真)
{
代码段2;
}
else
{
代码段3;
}
}
从这个意义上看,双分支和多分支其实是一回事情,本质上都是分支。分支这个概念,大家应该都是相对容易接受的,任何一件事情总有它的对立面,高对低,胖对瘦,大对小,物质对暗物质等等。分支这个概念应该是反映了事物的一种本源的状态,是描述程序是不可再进行切分的维度,也就是说分支成为了任何程序的三种基本结构之一。
其实对于多分支的情况,C语言有另外一套关键字组合switch/case,写成伪代码的形式,大概是这样的。
switch(变量){
case 常数1:
代码段1;
break;
case 常数2:
代码段2;
break;
case 常数3:
代码段3;
break;
。。。
default:
代码段n;
break;
}
大家注意没,对于switch/case组合来说,它的条件一定要是常量,而且要是整数。这个是不是对判断的条件作出了限制呀。这里的default关键字,是和if/else里面的else对应的,表示意外情况。从表面看,switch/case适用于逻辑条件简单,但是分类较多的情况;if/else适用于判断条件复杂,但是分支较少的情况。但是从另外一个层面看来,switch/case所具备的功能,if/else完成起来,完全没有问题呀。那为什么还要搞出来这一个关键字组合呢?
我个人的理解是switch/case关键字的执行效率,在某些情况下,要比if/else要高。
int a = 0;
switch(a)
{
case -1:
break;
case -2:
break;
case -3:
break;
case -4:
break;
case 0:
printf("I am in switch case!n");
break;
default:
break;
}printf("I am between the switch case and if/else if/else!n");
if (-1 == a)
{
}
else if (-2 == a)
{
}
else if (-3 == a)
{
}
else if (-4 == a)
{
}
else if (-5 == a)
{
}
else
{
printf("I am in if/else if/else!n");
}比如对于上面的代码段,对于switch/case关键词对来说,程序是直接跳到case为0的情况下的;但是对于if/else而言,程序则是一句一句比较之后才达到了“else”这一句,程序执行效率的高低是显而易见的。
但是我们说,switch/case的程序执行效率可以比较高,并不是没有条件的。从汇编语言的层面来看,switch/case是建立了一张跳转表,因此需要一定的空间才行。这里某种程度上有以空间换时间的意思。
因此,如果程序可以使用switch/case尽量使用这个,以便提高它的执行效率。其实,我们这样比对一番之后,自己也就轻而易举地牢牢记住了它们,这个可能也就是知其然知其所以然的效果,符合人的记忆规律。
讲完了分支,我们来看一下循环。循环这个基本结构,在C语言里面,一共有两种实现方式,for循环和while循环,其中while循环还可以分为两种,一种是while循环,一种是do/while循环。我们下面分别看一下,这三种结构的程序表达大概是什么模样。
for(循环控制变量初始化;循环终止条件;循环控制变量增量){
循环体;
}
for循环的执行步骤是:首先执行循环变量的初始化,然后执行循环终止条件;如果判断条件为假(不符合终止条件),那么就开始执行循环体;然后执行循环控制变量的增量程序,执行完以后,再去判断是不是符合循环终止条件;如何符合条件,那么就退出循环;如果不符合条件,那么就继续执行循环体,并重复执行上述步骤。
感觉用第二种方式来描述这个循环体的执行过程,更为清晰。第一,先进行循环控制变量初始化;第二,执行循环终止条件,如果判断结果为假,则进入第三步;如果为假则循环终止并退出;第三,执行循环体;第四,执行循环控制变量增量,转入第二步;
注意,其实for循环括号中的三部分其实都可以省略,如果全部省略了,就变成了一个无限循环的死循环,跳不出来了。无限循环在操作系统中使用的是非常多的,每一个任务都是一个无限循环体,包括main函数也是一个无限循环体。
下面,我们来看一下while循环的代码格式。
循环控制变量初始化;
while(循环终止条件){
循环体;
循环控制变量增量;
}
while循环的执行步骤可以描述为如下的样子。
第一在while之前,先执行循环控制变量的初始化;第二,判断循环终止条件是否成立,如果成立那么就跳出循环,如果不成立就进入第三步;第三步,执行循环体;第四步,执行循环控制变量增量,然后进入第二步。
do/while的代码格式是什么样子呢?
循环控制变量初始化;
do{
循环体;
循环控制变量增量;
}while(循环终止条件)
while循环的执行步骤可以描述为如下的样子。第一,在do(也就是执行)之前,先执行循环控制变量的初始化;第二,先执行一次循环体和循环控制变量的增量;第三步,判断循环终止条件是否成立,如果成立那么就跳出循环,如果不成立就进入第二步;
我们来看一下呀,while和do/while主要的区别,一个是先判断再执行,一个是先执行再判断,那么也就是说do/while这个关键字组合中,函数体至少执行一次。但是这并不影响while和do/while之间的转化呀,同样的功能绝大多数情况下,可以用while也可以使用do/while来实现。那么有没有必须要用do/while的时候呢?答案是有的,在linux编程中,do/while常用的一个方式是do while(0)。
比如,我需要定义一个宏:
#define SAFE_FREE(p) do{free(p); p=NULL} while(0)
假设这里去掉do{....} while(0),及定义为:
#define SAFE_FREE(p) free(p); p=NULL;
那么以下代码:
If(NULL!=p)
SAFE_FREE(p)
else
.......
会被展开成如下的有仇
If(NULL!=p)
free(p); p=NULL;
else
.......
展开之后,存在两个问题。因为if分支后面有两个语句,会导致else分支没有对应的if,编译失败。即使假设没有else分支,SAFE_FREE中的第二句,无论if测试是否通过,这个都会被执行。那么如何解决上述问题呢?有人说给SAFE_FREE的定义加上{}就可以了,比如如下的样子:
#define SAFE_FREE(p) { free(p); p=NULL; }
代码展开如下:
If(NULL!=p)
{ free(p); p=NULL; };
else
.......
这样问题又来了,else 没有对应的if了,编译还是会失败。但是使用了do while(0)则可以完美解决上述问题。代码展开如下,
If(NULL!=p)
do { free(p); p=NULL; } while(0);
else
.......
所以,do while(0)的使用是为了保证宏定义的使用者能无编译错误的使用宏。
下面我们讨论一下,为什么C语言有了for,还需要while呢?除了上面的do while(0)的必要性之外,好像还真得没有确切的其他原因。比如在golang编译其中,就只有for,没有while了;再比如,java的源代码里面,就是有一堆的for(;;),据说可以提高性能。所以更大程度上讲,C语言只是为了,兼容程序员的编码习惯,保留了while这个关键字而已。
一些更现代的语言还加入了foreach、for in这种专门遍历集合的语法糖,也有python、ruby这种直接抛弃了C语言三段式for,只保留了for in,而把非遍历型的循环统统放到while循环里面的做法。
我们这次关于程序基本结构的探讨就先到这里。
参考资料:
① 基础学习C语言第四章:三种基本结构 https://zhuanlan.zhihu.com/p/97629275
② Linux - switch/case与if/else if/else的效率比较
http://blog.sina.com.cn/s/blog_5acb430f0100ael9.html
https://www.cnblogs.com/anlia/p/11685639.html
④ 深度理解do{} while(0)
https://blog.csdn.net/weibo1230123/article/details/81904498
-
ESP8266物联网开发板设计2
大家好,我们今天继续物联网开发板的原理图设计部分的探讨。
上篇文章,我们着重探讨了电源部分的工作过程,整体上确定了“反激”+ Buck + LDO三种电源配合的方式。反激部分,其实就是我们买的适配器,这部分我们已经确定通过外购的方式进行。LDO这个地方,使用的是AMS1117的方案,它主要的任务是实现5V到3.3V的降压。Buck则是实现电压从12V降低到5V的任务。
大家可能在其他地方也见到过,使用LDO的方案,把电压从12V降低到5V或者3.3V。使用这种方案有一个前提条件,那就是负载不能太重,也就是负载电流不能太大。如果负载电流太大,LDO DCDC的芯片就会发热比较严重。因为LDO这个模块的工作原理,它还是利用半导体器件(比如下图中的T4)的非线性阻抗(Rce))来降压的。压差越大,电流越大,那么LDO上面所消耗的功率也就越高。所以对大电流、高压差的情况,LDO就不太适合了。
那么我们必须采用一种内阻更低的能量传递方式,大家比较熟悉的就是开关电源了。降压开关电源比较常用的拓扑结构就是buck。它的原理,是使用储能器件(电容、电感)代替了耗能器件(电阻)进行能量传递,所以它的能效比非常高。另外,使用开关的开通和管断来调节能量传递的过程,实现了负载动态调节和宽电压输入,比如如果负载比较重,那么开关开通的时间就长一些,关闭的时间就短一些;如果负载毕竟轻,开关开通的时间就短一些,关闭的时间就长一些。
我们这个开发板的buck电路是使用DCDC的芯片来做的,这样可以做到板子的体积比较小,更加实用化。如果大家想彻底搞明白buck电路的工作原理,还是得想办法自己去搭建分立器件的电源转换电路,这样才能理解得更加深刻一些。如下图所示,我们这个buck电路使用的芯片是SY8120,开关控制的思路都被封装在器件内部了。
如果大家一下子搞不明白这个芯片的工作原理,可以后面找时间慢慢学习。我这里需要强调的是,对于开关电源来说,开发板布局非常重要的。因为开关信号是一个阶跃信号,它可以通过展开成一系列高频的傅里叶级数叠加,也就是展开成各个频率的信号。但是呢,我们需要的其实就是基波信号,其他高频的东西对于我们来说都是干扰。那么我们在布局的时候,就要尽可能减少这些高频信号的对外部的影响,尤其是Id部分,所以Id回路要尽可能的小,一个是减少环形天线对外辐射的影响,一个减小环路上走线寄生电感带来的影响。再一个,Buck电源输出的+5V的地,一定要单点接地,因为这个地相对来说比较脏,我们要通过单点接地的方式来降低它对其他器件的影响。另外在布局的时候,我们尽可能让ESP-12F的天线部分远离buck电路,进一步降buck Id主回路的影响,下图是SY8120 datasheet中给出来的布局参考,大家可以观察一下,IN ---> LX --->L ---> Cout ---> GND 这条线,其实回路已经尽可能的短了。虽然FB引脚也是一个高频回路,但是它的电流不大,相对来说没有那么重要,所以把它放在了相对次要的位置。大家注意呀,这里只是相对而言的。
最小系统中的复位电路,我们前面也提到了。那么我们使用的ESP8266这款单片机的复位过程具体是怎样的呢?我们来看一下datasheet相关的说明:
这里只是说外面加一个RC电路就好了,同时对走线提出了一定的要求,并没有讲清楚单片机是如何实现复位的。其实我们只要按照要求做,就可以了。但是我们还是要想办法尽可能对复位电路加深一些理解。我们可以参考STM32F030系列单片机的复位电路进行对比理解。
大家看一下下面两幅图,这两幅图说明是单片机上电时的复位过程。
大家看一下,Reset信号的波形,上电的时候,Reset保持为低时间可以分为两段。第一段时间,是VCC电位上电到POR电位的时间,第二段时间是Reset temporization的时间。第一段时间相对好理解,只有电压稳定了,单片机才能工作么。第二段时间Reset temporization这段时间大部分的时间应该是晶振起振的时间,还有其他器件reset复位的时间。我们做过一个Reset的测试,从上电开始到一个管脚输出高电平(程序第一行就是这个)的时间,在STM32 F030中,这个时间是2ms左右。具体ESP8266这个片子的上电复位是不是这么一个过程,我想大概是吧。目前还没有找到更多的材料支撑。
我们下面看一下STM32F030单片机的按键复位的说明。
大家可以看一下,产品文档这里并没有对按键复位的时间进行说明,只是说电压要下降到一定的程度才行,比如电压要降低到0.8V。那么这种情况下,我们电路设计的那个RC,其实只是起到了一个滤波作用,对不对,防止外界的干扰导致单片机复位。大家看看,这个作用和ESP8266对外界阻容电路的描述是不是一样的。所以我推测ESP8266的复位过程和STM32F030差不多(这里不打包票),大家如果能有更详细的资料,可以再深入研究下。
具体到外界阻容电路中R和C的取值,我们一般是取值R=10K,C=104。从上面的分析了来看,这里去其他值应该也没有什么问题,大家可以根据自己的实际情况(比如BOM表器件种类不要太多)进行选取。
下面我们来看一下晶振是如何起振的。因为模组已经把晶振封装到内部去了,我们不用去操心晶振部分电路的设计。但是其实晶振电路的设计非常关键,晶振毕竟是单片机的心跳呀。没有心跳信号,单片机如何工作。另外一个,我们的USB转串口电路中也用到了晶振电路部分的设计,所以这里我还是打算花一些时间把晶振的工作原理和一些设计的要点给大家讲清楚。
如上图所示,这个铁盖子下面其实是集成了不少东西的,其中就包括了一个26Mhz的晶振。只不过因为已经封装过了,我们看不到而已,就像我们前面提到的一样,看不到不代表不存在,是吧,呵呵。受限于篇幅的原因,这篇文章就先到这里。下篇文章,我们重点分析晶振的起振过程还有继电器、温度传感器等外设电路的设计。
①无源晶振起振条件及其工作原理 http://m.elecfans.com/article/582154.html
②51单片机晶振电路原理是什么
https://www.zhihu.com/question/30930577/answer/55822425
③ 三点式LC正弦波震荡电路详解
https://blog.csdn.net/weixin_42415539/article/details/88540709
④电容三点式震荡电路波形问题
http://bbs.eeworld.com.cn/thread-1090538-1-1.html#pid2904297
⑤三点式电容震荡电路的工作原理 https://zhuanlan.zhihu.com/p/354627295
⑥单片机上电复位时间 https://blog.csdn.net/zyboy2000/article/details/4673955
⑦ESP8266文档中心 https://docs.ai-thinker.com/esp8266/docs
-
斜坡补偿的由来
大家好,我是张飞实战电子张角老师!
在开关电源中,有一个相对不容易解释清楚,但是对整个系统的稳定性又起到重要作用的知识点-斜坡补偿。我们打算后面用一系列文章来深入探讨一下这方面的知识,争取让大家能够对这块内容有相对深入的理解。
我们首先需要回答的问题,就是开关电源系统为什么需要斜坡补偿,或者说斜坡补偿解决了哪方面的问题?从宏观上看,开关电源的调节系统可以分为两部分,一个是内环电流环,一个是外环电压环。之所以把电流环称之为内环,主要是因为它的调节速度更快,属于单周期调节。电压环,调节速度相对电流环肯定是更慢的,对于输出滤波电容来说,电压是电流的积分。电流环调节的结果要经过数十个周期之后,才能在电压信号上做出反应。
当系统的输出电流或者说电感电流,因为负载变化或者输入电压变化产生扰动的时候,在电压环起到调节作用之前,有可能发生电感电流的次谐波震荡,或者说是电感电流的振铃现象。
这里之所以说是有可能,主要是因为这个现象发生在CCM模式下,而且占空比大于50%的时候。当占空比小于50%的时候,扰动电流的震荡会自动趋于收敛。我们下面用图形化的方式给大家演示一下。
上图是占空比小于50%的时候,负载变化引起的电流扰动。大家可以看一下,这个扰动在几个周期后,会自动收敛。具体为什么会收敛呢?我们可以推算一下电流扰动量的变化公式。
大家可以看一下,当占空比小于50%的时候,Ton的时间内电流上升的斜率大于Toff时间内电流下降的斜率。那么这个电流抖动量的变化趋势和这两个斜率的比值很有关系。
具体的推导公式,如上图所示。我们这里是分两个三角形来进行计算的。在θ0的三角形内,根据正切关系可以得到δIo和It(两个三角形的公共部分)比例关系式①。实际上这个正切关系本质上是不是就是斜率呀。同样的,在θ1这个三角形内,我们也可以得到式子②。这两个式子化简以后,就会得到关系式③。大家可以看一下,δI1是不是要比δIo要小呀,因为m2小于m1,对吧。当占空比小于50%的时候,是不是m2一定小于m1呀。那么经过几个周期的迭代,是不是扰动量慢慢变小后,系统也就收敛了。
但是当占空比大于50%的时候,也就是m2大于m1的时候,这个扰动量是不是也来越大,结果也就会出现电感电流的震荡,如下图所示。
对于控制系统的开关芯片而言,Ton的时间也就会出现波动,也就是会出现所谓的大小波交替现象的发生。这个波动的电流对系统的稳定性是无益的,需要想办法解决掉。那么该怎么解决呢?这个也就是斜坡补偿的由来:既然这种情况下m2大于m1,我们能不能通过斜坡补偿的方式使得整体的斜率大小关系发生改变呢?
下篇文章,将会对这个问题进行更深入的分析。
-
讲透有史以来广受欢迎的运算放大器μA741(5)---增强镜像电流源
大家好,我是张飞实战电子张角老师!
这篇文章,我们从T7这个管子说起。T7这个管子的存在主要是增加对称性,减小运算放大器本身不对称带来的误差。这句话怎么说呢?如果没有T7这个管子,那么T5、T6这两个管子的基极偏置电流,是不是都来自于Q3的Ic。还是沿着上篇文章的例子来分析,如果IN-电压不断抬升,IN-和IN+之间的压差不断增大。那么流过T5的Ie不断增加,那么T5 E极的电压不断抬升;相对应的,流过T6的Ic不断减少,T6 E极的电压不断降低。那么流向T6的Ib电流在不断加大,流向T5的Ib电流在不断减小。因为T7这个管子的存在,T5、T6这两个管子的Ib电流主要来自电源,而对T6的Ic造成的影响是最小的,这个时候T6这个管子Ic和Ib之间的关系才逐渐往饱和方向移动。如果没有这个T7呢,那么T5、T6的Ib电流是不是全部来自Q3的Ic了呀。对于T6这个管子而言,它是不是处于临界放大状态。临界放大状态也是放大状态。那么T6 Rce的阻抗也就降低不到更低的水平,那么反过来说,T5、T6的B极电压也就无法降低到更低的水平,这样会使得T5的Ib减少不到更低的水平,那么对于T5的Ib和Ic而言,放大程度就不会更深。而我们希望的是不是让T5处于深度放大状态,这样才能尽可能提高F点的输出电压。那么很显然把T7去掉的做法,对这种工作状态是不利的。
我们再看另外一个状态,如果IN+大于IN-,那么是不是T6的Ic大于T5的Ic,那么这个时候T5是往饱和状态移动,而T6是往放大状态移动,对吧。我们要想T5的输入增益更大,也就是说T5这个管子C极电压的变化范围更宽,是不是T5的饱和深度越深越好呀。T5要想饱和深度更深,是不是只能T5的基极电压相对来说可以更高一些,或者说在T6的C极电压上升的过程中,T5的基极依然可以获得更多的电流。那么如果没有T7这个管子,T5、T6的基极电流则主要靠Q3的Ie电流分得,如果T5所需的基极电流越大,那么也就会对T6这个管子本身的工作状态造成一定的影响。大家看一下T6这个时候本身就是临界放大状态的接法,二极管当成三极管来使用,那么T6这个管子的Vbe之间的压差也就被锁定了,是零。那么随着T6的Ic电流加大,T6这个管子C极的电压也相对难上去,因为B极和C极电压被T5这个管子B极到地的电压钳位住了。如果通过T7这个管子把T5、T6的基极和T6的C极隔离开,那么T6的C极电压也就会高一些。
那么由于T7的存在,T5和T6的C极电压变化就会更对称一些,比如当IN+电压大于IN-的时候,T6的C极电压可以升高得更高对应着T5的C极电压可以降得更低;当IN-大于IN+的时候,T5的C极电压会升得更高,对应着T6的C极电压可以降得更低。如果没有T7,就没有这样的对称性,如上面两种情况分析,这个时候T6工作在临界饱和状态。但是T7这个器件是不是一定是必须的呢?实际上较新的运算放大器,比如LM324,T7都是不存在的。那么也就是说,其实这样严格的对称性,从实践上来说,应该是不是必须的。
我们下面看一下T5、T6这两个三极管的射极电阻。那么第一个问题就是,为什么这里需要下面需要加两个电阻呢?我们说当IN+=IN-的时候,T5这个管子的C极输出应该是刚刚好使得输出为零。T5的C极输出信号是驱动后级的达林顿管的,也就是中间的放大级。那么我们可以调整这两个电阻使得输出值达到要求,这里本质上也就是实现阻抗匹配,R4+T5的Rce与T2、Q4的Rce之和进行合适的分压,R3+T6的Rce与T1、Q3的Rce之和进行合适的分压。我们今天的分享就先到这里。
