发帖数

43

原创数

43

关注者

17

阅读数

10116

点赞数

2

张角

  • STM32 C语言“函数”深入剖析

    大家好,我是张飞实战电子张角老师!我们今天对C语言函数的概念进行相关的探讨。探讨的思路还是基本按照前面几篇文章的思路来进行,也就是说需要依次回答:是什么,为什么和怎么用的问题。具体到单片机C语言的函数,我们首先要明确函数是一个什么东东?C语言为什么要使用函数?这个问题主要是相对于汇编语言来说的,大家知道汇编语言就没有函数。函数是如何定义和声明的?后面的,就是函数在实际使用过程中相关的问题,比如函数和变量的定义以及声明有什么不同?函数与函数之间如何进行交互,比如参数传递以及函数如何返回计算结果?最后一部分,函数设计可能是C语言程序设计中的关键一环,我这里会总结一些函数设计相关的一些技巧,分享给大家,进一步减少程序设计过程中出错的可能性,提高编程的效率。

    我们首先来看,函数是什么呢?首先,函数有一个名字,这个名字大多数情况下,描述了它的基本功能。然后有的函数有参数,有的函数没有参数;有的函数有返回值,有的函数没有返回值。函数的参数,可以理解为函数进行运算时的加工原料;函数的返回值可以理解为函数计算结果。括号中的东西(函数体),可以理解为函数对数据的加工过程,或者理解为计算过程。

    image.png

       从上面的描述来看,函数应该是一个功能的封装。一般我们的C语言程序,是由许许多多封装起来的函数组成的。但是大家如果写过汇编语言的程序,可能就会有感觉,其实汇编语言并没有函数的概念,汇编语言程序就是一系列指令的罗列。那我们不禁要问,为什么C语言要引入函数的概念呢?函数概念的引入是需要解决什么问题?

    image.png

       大家看一下,函数的引入是不是相当于把一个复杂程序的功能实现了拆解呀,具体拆解的颗粒度因人而异,因程序而已。这个拆解的思路,是不是完美体现了分而治之的策略。在编写程序的过程中,有些常用的功能很有可能屡次被调用,我们把这些常用的功能封装成一个一个函数。程序写到这里的时候,只需要调用这个函数就可以了,不用再重新把代码写一遍,这样是不是就可以较大程度的较少代码量呀。

    实际上,我们调用的各种库函数,可以说是在编程中一些最常用的功能的集合。这些写好的、已经经过验证的、较为基本的函数模块,可以极大提升程序的开发效率。这个就相当于,建房子时,有好多基本的结构可以拿来直接使用,比如直接拿来一个柱子、一间房子、一个卫生间等等,不需要自己再使用最基本的砖块从头开始搭建。这样建房子(编程序)的效率是不是会猛增呀。

    再一个,没有这个函数的封装,如果程序较大、功能较复杂,我们面对的是不是一个超长的代码呀,那读起来是不是就比较费劲。这个就有点类似古代的文言文不分段落、没有标点符号一样,读起来是不是就比较吃力。那么可以说函数这个概念的引入,可以把一些较长的程序切分成了很多个小模块,那是不是极大地增强了程序的可读性。程序的可读性强,那是不是就从侧面降低了程序的开发和维护成本呀,不用消耗那么多的智力资源就能完成任务。

    前面,我们从函数功能的重用度或者说代码量的大小,以及函数对程序的可读性增强两个方面阐述了函数存在的必要性。那么C语言毕竟是人类发明的,肯定要从方便人去进行程序开发的角度来进行语言架构的设计,那么自然C语言就会引入函数的概念。从本质上讲,函数的引入就是为了降低程序开发的难度(这个是相对汇编语言而言的),提升程序开发的效率,方便人用更少的时间去做更多的事情。

    再一个,我们看一下,函数与函数之间的组装配合,实现了复杂的程序功能,这个过程是不是像极了人类社会中各个组织之间的相互配合。那么我们在进行程序开发的时候,函数的功能拆分怎么样才是相对比较合理呢?我觉得有两个指标,一个是函数之间调用的深度不要太深,太深的调用会影响程序的可读性。对于一个程序来说,不要分太多层,最好尽可能扁平化;第二个,函数与函数之间,功能一定要独立起来或者说功能解耦一定要尽可能彻底,同一层的函数与函数之间的功能没有相互依赖的关系。从图形上来说,这个可能就是一个树形的结构,第一个数不要太高,太高了人爬上去比较困难;第二个分支与分支之间不能相互影响,必须是各自隔离开,这样维护起来才更方便。从这个角度上,看对一个复杂的程序功能进行有效的拆解的过程,有点像行军打仗时,对军队的管理:不同的部分有不同的功能,各个部分之间有联系但不能是依赖(要能够独立行动),每个部分不能太大否则不好管理(尾大不掉),层级不要太多否则容易政令不通。

    讲完了函数是什么,以及C语言为什么要使用函数,那么就到了下面一个部分,如何声明及定义函数。函数的定义和声明,有点像全局变量,或者说函数都有全局属性,它的作用域是全局的。既然是全局的,那肯定要有声明和定义,一般情况下声明是放在xx.h”头文件里面,定义则是放在“xx.c”文件里面。当然,如何一个函数只是在局部使用,并不对外提供服务,那么可以在这个函数名字面前加上关键字“static”。另外,在这个局部特定的文件里面,这个static函数放在了调用它的函数前面,那么这个函数同样也不需要在进行声明了。编译器会自动找到这个函数,并在链接的时候,自动链接。

    既然默认的情况下,函数和全局变量都有全局属性,那么它们在声明和定义上有什么区别呢?主要的区别就在这个关键字extern”上,全局变量声明的时候,一定要加上extern关键字;但是函数声明的时候,则不需要extern关键字(或者说这个可以省略)。至于为什么有这样的区别,可能就是因为函数这种“数据类型”过于复杂,它的定义和声明之间差别极大,定义有函数体存在,对吧,声明却没有。但是对于变量来说,声明和定义是不是没有什么区别呀,比如定义“int a”,声明也用“int a”,两个是不是重复的呀,所以对于变量来说,声明的时候一定要加上“extern”。这样,其实我们对extern这个关键字,也做了一定的总结。

    函数的名字,本身就是一个地址,但从这一点上来看,它有点像数组,和结构体等什么的不太一样。那为什么会这样呢?函数的名字为什么要是一个地址呢?这个可能就和单片机执行程序的思路一样,从某一个地址开始开始执行,那么自然函数的名字就是一个地址更加有利于编译系统对程序进行编译。那么既然函数的名字是一个地址,我们的变量类型里面又有一个指针类型变量,那么他们两个肯定会发生关联,那也就是说一个指针变量里面存储了函数的地址值。这个指针,我们称之为函数指针,全称应该是函数类型的指针,用以区别于整数类型的指针、浮点数类型的指针等等。函数类型的指针,它的声明自然是与众不同的,声明的时候就得按照函数的形式来搞,这个是遵循int* p之类的关于指针声明的法则的。与之相关的一个,比较容易引起混淆的概念,是指针函数。其实如果想区分开来,也是蛮简单的,就是一个返回指针数据类型的函数。这里只是函数指针和指针函数放在一起容易混淆而已。

    讲完了函数的声明和定义,我们来看一下第三个问题,函数与函数之间怎么怎么进行交互的。这个交互包括两部分,一个调用方给被调用方数据传递,另一个是被调用方返回值给调用方。调用方给被调用方传递数据,其实大家理解起来也比较简单,就是通过函数的参数进行的。函数的参数需要什么类型的数据,调用方要按照约定传过去。被调用方给调用方传递数据,方式就多了。第一种方式,可以通过返回值的方式,把计算结果返回给调用方;第二种方式,则比较隐晦,不是通过计算结果来实现计算结果返回。具体实现的方式,调用方给被调用方传递参数的时候,传递的是地址;被调用方,通过修改这个地址指向的值来进行计算结果的返回。这个地方其实就是值传递和地址传递的区别,值传递的时候,没有办法实现计算结果这样返回。

    最后这一部分,我们来讲一讲函数设计的一般技巧,这样可以让我们在程序设计的时候,更少犯错,进一步提高程序编写的效率。

    第一个,原则上尽量少使用全局变量。每个源文件负责本身文件的全局变量,同时提供一组对外函数,方便其他函数使用该对函数来访问这个变量,比如SetValue”、“GetValue”等等,不要直接读写全局变量。尤其是在多线程编程的时候,必须要使用这种方式,并且要对读/写操作加锁。

    第二,和这个类似,函数也尽量少使用static类型的变量,这种变量有记忆功能。有记忆功能的函数,其行为可能是不可预测的,因为它的行为可能取决于某种“记忆状态”,这种函数既不利于理解也不利于维护。

    第三,我们要避免函数有太多参数,尽量把函数参数控制在4个或者4个以内。过多的函数参数,可能会导致函数的使用成本太高,比如容易把参数的顺序搞错。

    第四,函数体的规模尽可能小,比如控制在80行以内或者说一页屏幕要能够看完。这个规则也可以说我们进行功能拆解的时候,要遵守的。当然,特殊的函数除外呀。

    第五,我们要在函数体的入口如,对参数的有效性进行检查,尤其是指针参数。

    第六,函数的返回值,一定不能是临时变量的地址。这个地址是在栈空间里面的,函数执行结束后,这个地址就是无效的了。那么自然这个地址,不能用作函数的返回值。

    第七,如果是地址传递,则尽量在指针前面使用const”关键词修饰,防止指针被函数内存的计算误修改。当然特殊需求除外。

    关于C语言函数相关的知识,我就和大家先探讨到这里。


    参考资料:

    C语言中为什么要引入函数的概念http://blog.sina.com.cn/s/blog_6fd2803b0100y9fl.html

    C语言函数 https://www.cnblogs.com/wucongzhou/p/12498949.html

    函数指针与指针函数 https://www.cnblogs.com/nevel/p/6370264.html

    定义与声明、头文件和extern总结 https://www.cnblogs.com/liushui-sky/p/7693537.html

    C语言深度解剖,陈正冲,北京航空航天大学出版社


    收藏 1 回复 0 浏览 246
  • 讲透有史以来广受欢迎的运算放大器μA741(7)---放大级、输出级及米勒电容

    大家好,我是张飞实战电子张角老师!

    image.png

    我们接着上面文章,继续分析运放的输出级。受限于运放封装的体积,运算放大器的推电流和拉电流都不会太大。那么为了限制电流超过一定的值,uA741内部还专门设计了限流电路,包括推电流限制电路和拉电流限制电路。

    我们先来看推电流限制电路这个功能的实现主要是靠T13这个管子。从电源流经T12R9,然后再到负载(Vo)的电流达到一定程度的时候,R9两端的电压就会达到0.7V。我们来计算一下这个电流值。I = 0.7V/R9 = 0.7V/27R = 25mA。那么也就是说,当流过R9的电流值达到25mA左右的时候,R9两端的电压会达到0.7V。大家看一下,R9这个电阻两端的电压是不是恰好就是T13的基极和射极的端电压,那么也就是说此时T13饱和导通了。T13饱和导通以后,T12Vbe是不是就小于0.7V了,那么T12是不是就关闭了。那么自然流过R9的电流就变小了。R9T13这两个器件在这里扮演的,是不是就是一个负反馈的角色,本质上利用的是N管基极电位和集电极电位相位相反的特性来实现的。

    image.png

    下面我们来看一下,拉电流是如何限流的,这个功能主要是由Q8T15T14这三个器件来实现的。

    当运放输出为低的时候,比如Q6射极电压低于输出电压Vo,那么对于运放来说,电流的流向是从负载流向Q7的。当流经R10的电流达到一定程度的时候,Q8这个管子就会开通了。Q8这个管子开通了之后,T15这个管子就会流过电流了。T14这个管子是镜像T15的,这里是一个镜像电流源,也就是说T15T14的集电极电位是相同的。随着流过T15的电流越来越大,那么T15集电极上的电压也就越来越低。同理,T14集电极上的电压也就越来越低,当T14集电极上的电压降低到一定程度之后,那么T8T9这两个管子就会趋向于关闭状态。这个时候,T9集电极上的电压就会升高了,那么Q6射极上的电压也就提高了,那么流过Q7IbIc都会变小了。这样也就起到了拉电流的保护作用。

    另外,在741内部,当时的研发人员还搞了一个比较牛逼的发明,就是在放大级和输出级之间加上了一个电容,这个电容也称作米勒电容。

    image.png

    因为T8T9组成达林顿管形式,放大倍数会很大。如果每个管子的放大倍数是100倍,那么两个管子联合起来就是10000倍。那么也就是说F点电压微小的变化,都会在T9的集电极产生非常剧烈的电压变化。这个剧烈的dv/dt,其实对运放的稳定性是不利的。为了解决这个稳定性的问题,科学家们尝试了很多办法,最终在uA741这个运放内部形成了一个较为完美的方案,就是加上一个小电容。在这之前,运放内部都是没有电容的。我们下面来看一下,这个电容可以起到什么样的效果。我们假定F点电压是向下降低的,那么T9 C端的电压是不是急剧上升呀;这个急剧上升的电压,会通过弥勒电容给F点充电,对吧。那么F点的电位是不是就不会下降得那么快了。那这样,T9 C点的电压也就不会上升得那么快了,也就是这个地方的dv/dt也就没有那么剧烈了,进而整个运放系统的稳定性也就得到了改善。但是这个改善,肯定是有成本的。对于放大交流信号,大家很容易看出来,运放整体的增益是下降的;信号的频率越高,运放整体的增益也就越低。某种意义上讲,这个电容在这里起到的是一个低通滤波的作用。


    收藏 0 回复 0 浏览 241
  • STM32 UART通信深入探讨

           大家好,我是张飞实战电子张角老师!

    在单片机开发过程中,我们常用的通信协议主要有UARTSPII2C这几种,是吧。这三种通信协议,本质上都是串口通信,也就是说在一个时钟周期中,只发送一个数据位。顾名思义,如果在一个时钟周期里面发送多个数据,是不是就是并行通信了,并行通信,自然需要更多的数据线,进而会占据更多的资源。不过并行通信的好处也是显而易见的,也就是说单位时间内(或者说一个时钟周期内)可以传递更多的数据,比如在大屏显示这种通信类型的时候,一般就需要使用并行传输协议。没办法呀,数据量太大,不得不如此。但是在相对低速的通信场景中,串口通信能够满足绝大多数的需求,所以在单片机的外设资源中,串口通信占据了不少份额。

    image.png

         我们首先来分析一下串口通信的原理。串口通信的接收过程,大概就是上图中描述的样子。这个图中我们只是使用三个数据来示意表达。DSR发送过来的“010”这三个数被移位寄存器移位以后,通过“D1D2D3”并行输出。实际上一般这里是8D触发器,实现8个串行数据的并出效果,单片机的最小存储单元一般是8bits么。发送端实现的一般是“并入串出”,只是方向反过来了,原理和上面的一样的。上图中N管和P管组成的电路是为了上电的时候,对D触发器的数据进行复位,这个地方大家不必太在意。

    UARTSPII2C这三种最为常用的串口通信中,以UART的实现最为简单,通信的双方不需要严格的时钟配合,只需要设定好波特率就可以了。所谓不需要严格的时钟同步,也就是说通信的双方可以使用各自的时钟,通信双方的时钟频率不一定相等,我们在使用UART进行数据通信的时候,每次发送的数据最长是8bits,可以比这个短,但是不能再比这个长了。如下图所示,数据位可以是8/7/6三类。那究竟是为什么呢?一次发送多个数据不行么?

    image.png

    异步通信可以允许通信的双方具有一定的时钟误差,时钟误差越大,每次能够发送的数据位数就越短;时钟误差越小,每次能够发送的数据长度也就越长。为什么是这样呢?假定对于主机,一个bit对应的脉冲数正好是10个,对于从机一个bit对应的脉冲数是10.2个。那么随着bit数的增多,比如达到5bit的时候,从机就会出现有51个脉冲数,那多出来的一个脉冲数该怎么对应呢?电路设计上该怎么设计呢?换句话说,就会出现数据错位。从这个例子来看,只要从机和主机时间频率上有误差,随着单次数据传递量的增长,那么一定会有数据错位出现。这个也就是UART进行数据传输的时候,一次只传输一个byte,主要的目的就是为了防止出现数据错乱的情况发生。

    我们下面用图形化的方式来说明一下这个问题。

    image.png

        如上图所示,PWM1PWM2是两个不同的时钟信号,大家可以看一下这两个时钟的周期明显是不一样的。我们让这两个时钟都同时从A时刻起步,大家可以看一下,到达B时刻的时候PWM1PWM2已经反相了,到达C时刻的时候PWM1PWM2又变成同相了。大家可以看一下,到达C时刻的时候,PWM2的周期数已经比PWM1多了一个了,那么多出来的这个时钟周期就会出现无法和数据位匹配的情况。反过来对于数据来说,也就是会出现数据错乱的现象。

    但是SPIUART通信的双方有一条时钟线相连,通过这条时钟线他们实现了严格的时序匹配。因为双方时序完全一致,那么在数据采样、移位以及存储的时候,就不可能出现数据错乱的情况。某种意义上时钟有多快,数据传输的速度就会有多快。当然实际应用中,SPII2C数据传输的速度,还受到通信接口本身器件特性(结电容)、CPU处理数据的速度、存储器存储数据的速度以及布线等因素的影响,具体的数据传输速度是考虑了诸多因素之后确定的一个值,我们需要具体应用具体分析。

    对于Uart来说,为什么通信双方的波特率需要设置的是一样的呢?波特率是不是就是数字信号采样的速率,如果通信双方采样的速率不一样,很显然会导致错误的结果。我们假定UART发送方的波特率是9600,接收方的波特率是19200。发送方发送的数据是“0101 0001”,那接收方会接收到什么数据呢?我们这里接收方数据采样的速率是不是发送方的两倍呀,大家可以看下面的图。

    image.png

        接收方数据采样出来的数据是不是0011 0011”呀,是不是发送方的每个数据才接收方采样了两次呀,而且停止位是不是还出现了错误。这个例子从侧面说明了,发送方和接收方波特率必须一致的原因。

    异步通信,相比同步通信,还有一个缺点,那就是说信号传递的速度相对较慢。在UART协议中,每个字符都需要起始位和停止位作为字符和开始和结束的标志,另外还有一个校验位,这些辅助设施大约增加了20%的信息位,以至占用了信号传输的时间,所以通信的速度就上不去。

    UART通信过程的探讨,我们先到这里。


    收藏 0 回复 0 浏览 232
  • 讲透有史以来广受欢迎的运算放大器μA741(3)---电流源

    大家好,我是张飞实战电子张角老师!

    这篇文章,我们来分析一下电源及输入级几个管子的工作状态。

    我们下面来看一下,N管和P管的放大接法(恒流源接法)。大家可以看一下,如果负载阻值不超过一定的值,那么Q2T2就一定是处于放大状态的,这个时候满足Ic = β*Ib这个关系。当负载阻值RL比较大的时候,Vcc/(Rf+RL)能够提供的电流值小于了恒流值,这个时候三极管就会处于饱和状态。那么uA741这个管子里面,从接法上看,T1T2 Q3Q4这四个管子都是放大状态接法,它们具体是工作在什么状态呢?

    image.png

    前面的分析中,我们把IN+IN-都接到了地上,我们假定此时运放输出的电压为零。下面我们来看一下,如果把IN+IN-这两个管脚都接到+5V上,这个时候运放的输出会有什么变化?T1T2这两个管子的工作状态会有什么变化?

    从前面的分析可以看出,Q3Q4这两个管子存在的意义就是引出Ib反馈电流。如果两个输入端的电压都调整成+5V,对于T1T2这两个管子的IcIb之间的比例关系会发生变化么?这个分析就取决于D点电位在这种状态下是如何变化的。这个时候,运放分析起来就相对比较复杂。我们这里采用极限分析法,可以假定一种极端的情况,如果给IN+IN-这两个端口都加上电源电压VCC,这个时候T1T2Ib电流肯定是加大的,因为T1T2IbIc之和是一个定值,所以流经T1T2这两个管子的Ic之和肯定减小。那么T1T2这两个管子肯定往饱和方向移动。那么同样的,Q3Q4也会往饱和方向移动,T1T2VceQ3Q4Vce都在变小,那么这个时候F点的电压也就会上升,这种因为输入电压变化导致的输出电压的变化,我们称之为失调电压。因为T1T2IcIb200倍的放大关系,所以我们认为即使有影响,这个影响也是很小的。那么也就是说T1T2Ic电流之和变化很小,也就是T1T2这两个N管的负载基本不变,那么也就是说T1T2这两个管子一直工作在放大状态。

    实际的工作状态应该是这样的,当T1T2Ib增大的时候,意味着VbdVcd的压差在增大,那么这个时候,T1T2Ic也要增大。问题是我们前面提到过,这两个电流之和是一个定值,等于T3Ic

    所以这里只能Vd的电位增加,那么自然VbdVcd之间的压差变小了。那么也就是说Vd这里是一个浮动的电压,在不同的输入电压下呈现不同的值。

    image.png

    Q3Q4这两个P管,因为它们的放大倍数没有T1T2大(我们假定N管放大倍数是200倍,P管放大倍数是50倍),但是它们Ic电流也是相等的。所以Q3Q4这两个管子这两个管子的Ib电流要大一些,这里主要是增强反馈回路的作用。。

    下面我们来看一下运算uA741这个运算的放大过程。我们说Q3Q4的基极电位是相同的。当Vin+大于Vin-的时候,那么流过T1Q3Ic电流是要大于T2Q4Ic电流的。这个也很好理解,因为Vab大于Vac,而AB回路和AC回路上的是两个相同的PN节。相同的PN节,加上不同的开启电压,那么自然Ib电流是不同的。Ib电流不同,那么自然Ic电流也是不同的。如果Vab大于Vac,那么流过T1Q3IcI1)是要大于流过T2Q4IcI2)的,这两个电流值发生变化,就会导致T5C极电压发生变化,T5C极电压也就能反映IN+IN-之间的压差。那么这样也就可以给中间级(增益级)提供放大信号输出。 

    image.png

    收藏 0 回复 0 浏览 227
  • 对RC电路的直观理解

    大家好!我是张飞实战电子张角老师!今天给大家分享对RC电路的直观理解。

    RC电路是较为常见的一种组合电路,在电路设计的过程中,经常用到。目前网上有各种各样RC的资料,但是给RC添加正弦激励实测的波形,其实很难找;能够同时把电容和电阻上的电压放在一起的波形就更少。没有这些波形,其实我们对RC电路就缺少直观的认识。

    本文将站在实测波形的基础上,给大家分析RC电路的正弦波响应,争取给大家带来直觉和感官上的理解。关于RC电路频率响应推导的文章,大家自行百度就好了。

    首先给出,我们实测电路的原理图。大家也看到了这个原理图,其实没有什么稀奇。


    图片4.jpg

    下图蓝色的部分,是我们输入的正弦信号,也就是Ui;黄色部分,是电容上的电源,也就是原理图中的Uo

    图片5.jpg

    从这个波形图中,我们首先可以看出电容电压的相位肯定是滞后于信号源的:①在一个周期内,输入信号Ui领先输出信号Uo达到峰值;②从波形图来看,即使是在启动的第一个周期中,两个信号的相位差和稳态的时候也是一致的。另外,大家可以看到明显的幅值衰减,这个其实就是滤波的效果。随着正弦波信号频率不断增加,当Uo的峰值达到Ui峰值的0.707倍的时候,正弦波的频率就是截止频率。

    图片6.jpg

    我们下面来看第二幅图,图中紫色部分的波形是输入电压波形和输出电压波形相减的结果,实际上这个电压波形是不是就是电阻上的电压呀(一般的示波器里面都有不同通道信号幅值相减的功能)。那么从图上,我们是不是直觉上得出来如下的结论:①电阻上的电压相位是领先于信号电压相位的;②电阻上电压的相位是领先于电容上电压相位的。其实第二个很容易理解,对于电容来说,i=c*du/dt,也就是说电容的电流是电压的微分。微分就意味着相位超前。如果我们把这个超前相位角具体化的话,那就是90度。因为本文不涉及公式推导,其实这就是一个复数旋转的计算,但是大家可以从图形上是不是很直观的看出来紫色和黄色的波形,相位角相差就是90°。

    那么如果我们给RC电路加上一个方波信号呢?下图中的方波信号,是一个高频的方波,

    图片7.jpg

    占空比是50%。大家可以看一下,因为方波的周期太短了,如果大家熟悉电容充放电公式的话,电容的电压一定会充到一个相对高的值以后,再一个周期内充电升高的电压才会等于放电放掉的电压。因为在电容电压比较低的时候,电容充电的速度是比较快的;而放电速度则相对较慢。随着电容电压的提高,充电速度则不断降低,但是放电的速度则不断加快,那么当电容达到某一个电压幅值的时候,充电和放电的时间正好相等。

    从上面这个图可以看出来,高频的交流信号肯定是被滤波了。大家还可以实测下,频率越高,输出的三角波峰峰值之间相差也就越小。

    这个过程还有一个额外的收获,那就是电容的直流电压分量。这个直流电压分量理想情况下,只和方波的占空比有关系。不知道大家有没有联想到buck电路的占空比,其实这里思路是一样的:buck电路输出的直流电压和占空比有关系,交流成分被LC滤波器给滤掉了。LC滤波器,一方面滤波能力比较强,再一个能量损失也小,所以buck电路不使用RC滤波器,而是使用LC滤波器。


    收藏 0 回复 0 浏览 221
×
张角