• 小船说翻就翻:硬件工程师VS软件工程师

    关于软件工程师和硬件工程师总有太多的话题。 常态往往是这样滴: 板子出问题了,硬件工程师:肯定是软件的原因!软件工程师:绝对是硬件的问题! 以下内容摘自知乎匿名用户一位美国在校学生所写,虽然或有失偏颇,但还是很能说明问题的: 1. 我个人理解的就业与行业前景 因为我个人对美国这方面了解更多,就先从美国说一说。我相信硬件工程师和软件工程师的就业前景应该是提这个问题的人最想知道的方面。 就我所了解的,在现在以及可预见的未来,这个行业对软件工程师的需求绝对是碾压硬件工程师的。也就是说,招软件工程师的职位比硬件工程师的职位要多的多,而且软件工程师找工作上来说会比硬件工程师更容易 先从企业的角度来讲讲。我个人认为造成这个差异的原因,第一个是基本上所有的公司,从初创公司到全球百强,都有对软件工程师的需求。现在哪个公司不需要几个码农来开发app,或者做个web。但是做硬件这种工作并不是所有公司会去做的。举个简单的例子,摩根大通银行在我们学校的招聘会上有明确招软件工程师,expedia在我们学校招聘会上也明确招聘软件工程师,如果这个两个公司突然说要招电子工程师,这不是逗我吗。。而且哪怕是硬件公司,也需要大量的软件工程师来支持硬件前端工作。 第二点我觉得要归功于现在的创业潮。不管在美国在中国互联网创业都是趋势,但是可以说绝大部分的初创互联网公司做的都是软件方向。有个点子,有点技术,找几个合伙人抱着电脑就能开干了。但是初创公司要专注做硬件开发就比较难了,因为成立设计硬件公司的门槛和起步开销比较大。所以这也导致大部分初创公司以互联网为主,能做的了硬件设计的公司基本上都是处于垄断地位的大企业。 第三个很重要的原因就是硬件设计在现在来看已经是相对成熟的技术,我甚至有ee的同学跟我说大部分硬件的东西已经步入夕阳产业的范畴,因为很多东西已经成了规范,也因为很多东西被自动化所取代。前一阵子全球大牌的硬件公司才裁了不少人,intel更是裁掉了接近20%的硬件工程师。但是互联网热从90年代开始到现在热头还没过,而且未来诸多产业如人工智能,机器学习,图像识别,大数据都才刚起步,所以还有一定的上升空间。 还记得当初我们学校的初创公司招聘会上几十家公司只有一家招硬件工程师,而且还是偏软件的硬件工程师,剩下的公司里98%都在找会码代码的人;大企业的招聘会上才能见到nvidia, arm, intel, TI 的身影,但是哪怕是这样基本上所有的公司招牌上都会有大写加粗的招computer science的字样。。 再从个人的角度来讲。想成为一名软件工程师找到工作的门槛远比成为一名合格的硬件工程师低很多。要想以软件工程师的身份混到个饭碗,能学两门语言学好常用的数据结构刷点题就基本上能找到薪水小几千的岗位。我甚至知道国内有专门的软件工程师培训机构,那种专门教java和算法,两个月速成班,而且所声称的学生就业率还挺高的。但是要想成为一名合格的硬件工程师,不是科班出身的不好好学几门模电数电信号逻辑设计的课,没有在学校实验室里自己焊点电路做实践,连简历都发不出去。而且现在要想学个什么语言框架,网上搜一搜“”xxx语言入门教程“”就有非常丰富的资源,但是要是在网上搜“如何学好超大规模集成电路设计”,要想找到可以受用的资源几乎是不可能的。而且就我所参加的招聘会来说,如果有招硬件工程师基本都要求有研究生的学位,但是对软件工程师的要求基本上就是熟悉算法数据结构,会web编程有相关经历就够了。软件工程师很多时候吃的是体力,硬件工程师大部分时候是吃经验,所以硬件工程师一般得有一定的经历积淀才能脱颖而出。尤其像模电这种上手程度很高的方向,没个十年八年的相关经验根本不算学成出师。所以说本身对从业者的资质要求更高,也是硬件工程师不好找工作的原因之一。 上面是我所认为的短时间内软件工程师就找工作方面来说会比硬件工程师更容易的原因。但是这并不意味着会编程就肯定找得到工作,也不意味着硬件产业就会低迷下去。软件工程师的职位多,但是每年从事这个职业的人也更多,虽然我认为现在软件工程师短期内还没有出现饱和的趋势(毕竟那么高的工资还摆在那),但是总有一天这个行业也会像金融产业一样降温(人才供过于求)。硬件产业虽然大部分已经有步入夕阳产业的趋势,但是曾经一度被宣称没啥好搞的供电网络最近也被smart grid搞得神乎其神,美国top5的高校都还设立了相关实验室。此外,现在物联网,车联网,智能家居的概念被炒得火热,我相信等相关成熟的支持技术(能量采集,低功耗通信)以及统一的开发平台一旦出现,硬件工程师的需求只会更多,虽然这些产品依旧只有那些有背景的大公司才做得动(不过因为欧美国家电子产业上的封锁,国家也在硬件设计上砸了很多银子,初创企业也会慢慢增加,相信国内的相关机遇也会更多)。而且毕竟软件产业毕竟还是依靠硬件,如何设计低功耗,高稳定性,能够承载大吞吐量计算量的硬件也是这个产业的挑战,毕竟人工智能,机器学习,视觉处理等领域是很吃硬件计算量的。没有强大的硬件支持,阿狗要想打败李世乭还是痴心妄想吧。 2. 工作常态  现在在一家设计为设计硬件的公司所设计软件的百强软件公司实习,做的工作大部分还是偏软件,所以本身对工作常态也并没有非常深入的自己的感受。但是就我观察身边的同事以及跟别人的交流来看,不管是做软件硬件,都是要:对。着。电。脑。。。 软件工程师平时就是上班啊调试程序,比较低级的码农只能给高级软件工程师大大下手,帮他们做测试,实现他们设计好的东西。当然了做到高级工程师了才有能力开发设计自己公司的产品。如果在初创公司工作节奏更紧张,如果赶上产品要上线可能需要加班调试。遇到程序爆炸了可能还需要on call(就是你负责的东西突然出问题了,你的manager直接打个电话给你你得马上去公司修bug),至少我知道amazon是有这个机制。 我现在还没有在纯做硬件的公司实习过,但是从我知道的事实来看,硬件工程师不会比软件工程师轻松。硬件工程师也需要调试电路啊调试脚本啊反正也有跟软件工程师交叉的工作。工作环境的话取决于细分的工作类别。开发fpga的估计跟码农一样坐办公室,搞mems的嵌入式的就长期入驻实验室了。因为大部分硬件公司都是相对成熟的大企业,所以工作节奏普遍不会像在初创公司那么紧张,不过像在华为这样的企业就另说了。。。 当然了不管是在软件工程师还是硬件工程师,工作强度应该都是高于其他industry的职业的。毕竟这个行业竞争会越来越激烈,这也是聪明人聚集的地方。 至于工资的话,就平均来讲,美国这里的软件工程师年薪会略高于硬件工程师(从glassdoor以及其他门户的数据来看),但是软件工程师一样也有收入低的,硬件工程师的收入也有碾压软件工程师的。只要你技术过硬,薪水都不是事儿。 3. 个人感受  我个人的感觉是不管怎样,这两个行业在未来都会有非常非常多的机遇与挑战(详细原因见第一点)。不管是软件设计还是硬件设计底下都有更多细小的分支(比如说你硬件设计是想做vlsi,dsp,处理器设计,通信,fpga开发还是嵌入式,软件设计你想做web开发,app开发,软件开发,嵌入式软件工程师,操作系统还是distributed system)。 我个人是对两个大方向都很有兴趣,但是我决定自己最终的方向还是嵌入式设计和处理器设计,这两个行业都应该算是夹在了纯硬件设计和纯软件设计的中间。尤其是产业对嵌入式工程师的要求更高,能够自己设计mixed signal pcb,自己调试应用代码写kernel code,能调试无线通信,基本意味着一个合格的嵌入式工程师要对硬件和软件相关方面有足够的知识。我自己是比较讨厌做web开发app纯开发软件的工作,因为这些工作的门槛太低,不是科班出身的人可能都能混的比你好得多,体现不出来自己的价值。而且我比较喜欢把电路板和各种元件握在手里的感觉,而且我发现自己能够设计一个可以用的硬件的时候那种成就感会高于debug之后的成就感。当你发现自己在经受了大学的磨练真正拥有了学习知识的能力以后,丰富的网上资源以及自身的积累都会让你学习这些网页app知识非常轻松,所以我个人更喜欢硬件底层,以及和硬件底层打交道的软件领域。软件硬件的课程都不会简单,而且两个学科的工作量不是其他学科能比的(学工科的天天做project呆lab,学统计的上完课就回家看电影。。)所以要想学好,还是需要花一定精力,尤其美国的大学工科院系workload相对国内高校来说有增无减。确定这是你想要的,再给予考虑。以上内容是不是说出了做软件与做硬件的不同体会?不过,据说,老工程师对此的回答是:工作久了就会发现其实需求才是根本,软件硬件只是实现需求的途径..... 【1】八个经验搞定开关电源PCBLayout 【2】程序员又翻车了!脑袋短路时他们是怎么想的? 【3】电源防反接电路的几种实现方案 【4】知道了电容的这些作用,就可以玩转电容 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-25 关键词: 嵌入式 程序员

  • 8个经验搞定开关电源PCBLayout

    素材来源:八号线攻城狮 其实对于一个开关电源工程师而言 PCB的绘制其实是对一款产品的影响至关重要的部分,如果你不能很好的Layout的话,整个电源很有可能不能正常工作,最小问题也是稳波或者EMC过不去。 这是别人家的成品开关电源,模组,今天以这个电源模组的设计重点跟大家聊聊。 1 经验一:安规走线间距 这个是写在协议里面的,如果你不按照这个做,耐压测试一定是过不了的,因为高电压,会直接空气击穿。注意保险丝之前的距离是比较远的,要求3mm以上,这就是为啥保险丝都会放在电路最前端的原因。 第二个要注意的是就算安规没有写,如果两根走线太近,正常工作也依然会击穿的,两根1mm间距的PCB外层耐压是200V,所以一般220v交流或者310V直流的走线距离至少2mm以上,一般都是在2.5mm以上的。 这些器件都是有安规要求的,说白了,就是两个器件有最小尺寸需求的,太小的器件其实是不可能过安规的,这就是所谓的开关电源PCB工程师实质上是带着镣铐在跳舞的原因。 开关电源变压器的骨架,同样是为了符合安规所以要有严格的把关。尤其是初级,到次级的距离,小功率变压器是必须飞线的。 飞线的长度也要被管控,如果飞线太短,耐压可能会受到影响,而如果飞线太长,会有可能对外辐射电磁信号,EMC过不了,所以需要在规格书里面详细写清楚,PCB绘制的时候,飞线的焊盘一定要注意,不能太妖孽。  2 经验二:电流走向 这个其实很少有真的被提及,其实原因也很简单。很多人不注意啊。 注意这里保险丝之后,接压敏电阻VR1再接x2电容的走线,完全是绕了一个弯这是为什么? 理由很简单,不让电流在PCB上面有回头路可以走。电流只走阻抗最小的部分,如果直接覆铜,必经的元器件就有可能会被跳过,所以这样做不可以。 同样的,这里的电解电容,一样是为了避免电流绕过必经的电容,直接流到负载上。 虽然画法不同,但是实际起到的作用是一样的。 这就是一个错误的案例,红色L火线先接了共模电感,再接的x2电容,共模电感到x2电容的这段线就会产生一个奇妙的现象,电流来回走,变成了一根天线,x2电流充电的时候,导线内部电流是正向,电容放电的时候,导线内部的电流是反向的,这不是天线是什么? 3 经验三:最小高压主电流回路 这就是实际布线时候的布局,大家可以参考一下,JT1是飞线,直接把310V正电压引入了变压器。 4 经验四:独立电压采样走线 开关电源的采样电压一定要和开关电源的大电流走线分开。要从开关电源输出电源的最末端去独立拉线采样,这样可以避免负载电流对采样线上形成的干扰。 采样电路在最末端。直接从负载输出端取电压,采样走线上不走大电流,避免了各种采样误差。 5 经验五:PCB载流能力 众所周知PCB的过电流能力是有限的,但是PCB上的电流究竟能过多少呢? 上面这个表格可以给你一个详细的参考。看过表格,你应该知道了对于小功率开关电源而言,高压侧的走线完全没有必要搞的很粗,除非是为了为器件提供散热,否则1mm一般是足够的,最多2mm多数情况都能够胜任了。 但是对于低压侧,大电流怎么办? 一方面是增加线宽,一方面是通过去掉部分阻焊层,并在钢网层制造窗口,让导线上锡水。导线的载流能力就会得到相应的增加。(注意一定要在Paste钢网层开孔,否则不会真的上焊锡的,切记切记) 6 经验六:PCB过孔散热的技巧 许多时候我们需要通过PCB线路板来散热,这个时候我们会打一些过孔,然后把热量传递到PCB的反面去。 这时候有一个小技巧,那就是孔塞可以增加热传导的效率,但是孔塞有一个常见最大孔塞直径,一般是过孔直径不大于0.45mm、我保险一点一般都是取0.4mm直径 7 经验七:放电管的绘制 一般在开关电源的高压侧与低压侧之间会有一个放电管,用来释放静电。 许多工程师都会最后在PCB Layout的时候手工绘制。 而我的建议是直接做成一个封装,然后和PCB关联调用,这样不会破坏PCB的联动性。 只是说你需要绘制两个异形封装罢了。还算比较容易。 注意这里只需要去掉阻焊层,千万不要在中间绘制钢网层,因为这里是不需要上锡的,只有焊盘需要上锡 8 经验八:元器件封装 一般而言,元器件一律按照IPC-SM-782A封装标准制作,对于个别需要承受高压的采样电阻单独对待,因为电阻焊盘之间的间距和耐压有关,所以焊盘需要适当拉开一些,但是同时又不能拉的太开,避免不必要的焊接不良率。 这是控制器用来直接连接高压的采样分压电阻,如果间距不符合要求,很有可能就会耐压不够击穿。贴片电阻器也是有耐压的,不过耐压不够就要加大封装。 这些差不多就是在开关电源设计时候的,全部PCB绘制经验了。 说实话,开关电源的绘制一路被人忽悠过来,这里面半桶水的人太多了,很多都是玄学,而这些都是相对来说算是靠谱一些的,试验后验证过的经验,这也是那些开关电源制作大牛们的血泪教训,很多时候他们当然不希望别人知道,这也没有办法,今天分享出来就是希望能有更少的人去走这些弯路,能给大家一些帮助。 【1】 电源防反接电路的几种实现方案 【2】 知道了电容的这些作用,就可以玩转电容 【3】 为什么Y电容容量基本都不大于0.1uF? 【4】 华为内部资料:电容的介绍和深入认识 【5】 封装图鉴:掌握这17种元器件PCB封装,设计板子就容易多了! 【6】 八层板PCB设计,电脑主板设计分析 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: PCB 开关电源

  • 知道了电容的这些作用,就可以玩转电容

    电容是电路设计中最为普通的常用器件,属于无源元件,常常在高速电路中扮演重要角色。它的作用和用途多种多样,如:在旁路、去藕、滤波、储能方面的作用;在完成振荡、同步以及时间常数的作用等。 01 隔直流 电容的作用之一,阻止直流通过而让交流通过。   02 旁路(去耦) 电容的另一个作用,为交流电路中某些并联的元件提供低阻抗通路。       ▶旁路电容 旁路电容,又称为退耦电容,是为某个器件提供能量的储能器件。它利用了电容的频率阻抗特性(理想电容的频率特性随频率的升高,阻抗降低),就像一个水塘,它能使输出电压输出均匀,降低负载电压波动。旁路电容要尽量靠近负载器件的供电电源管脚和地管脚,这是阻抗要求。   在画PCB时候特别要注意,只有靠近某个元器件时候才能抑制,电压或其他输信号因过大而导致的地电位抬高和噪声。即把直流电源中的交流分量,通过电容耦合到电源地中,起到了净化直流电源的作用。如下图为旁路电容,画图时候要尽量靠近IC1.   ▶去藕电容 去耦电容是把输出信号的干扰作为滤除对象。去耦电容相当于电池,利用其充放电,使得放大后的信号不会因电流的突变而受干扰。它的容量根据信号的频率、抑制波纹程度而定,去藕电容就是起到一个“电池”的作用,满足驱动电路电流的变化,避免相互间的耦合干扰。下图为去耦电容。     ▶两者区别 旁路电容实际也是去藕合的,只是旁路电容一般是指高频旁路,也就是给高频的开关噪声提高一条低阻抗泄防途径。高频旁路电容一般比较小,根据谐振频率一般取 0.1F、0.01F等;而去耦合电容的容量一般较大,可能是10F或者更大,依据电路中分布参数、以及驱动电流的变化大小来确定。   旁路是把输入信号中的干扰作为滤除对象,而去耦是把输出信号的干扰作为滤除对象,防止干扰信号返回电源。 03 耦合 电容的还有耦合作用,即作为两个电路之间的连接,允许交流信号通过并传输到下一级电路 。   用电容做耦合的元件,是为了将前级信号传递到后一级,并且隔断前一级的直流对后一级的影响,使电路调试简单,性能稳定。   如果不加电容交流信号放大不会改变,只是各级工作点需重新设计,由于前后级影响,调试工作点非常困难,在多级时几乎无法实现。   04 滤波  这个对电路而言很重要,CPU背后的电容基本都是这个作用。   即频率f越大,电容的阻抗Z越小。当低频时,电容C由于阻抗Z比较大,有用信号可以顺利通过;当高频时,电容C由于阻抗Z已经很小了,相当于把高频噪声短路到GND上去了。     滤波作用:理想电容,电容越大,阻抗越小,通过的频率也越高。电解电容一般都是超过1uF,其中的电感成份很大,因此频率高后反而阻抗会大。   我们经常看见,有时会看到有一个电容量较大的电解电容并联了一个小电容,其实大的电容通低频,小电容通高频,这样才能充分滤除高低频。电容频率越高则衰减越大,电容像一个水塘,几滴水不足以引起它的很大变化,也就是说电压波动不是很大的时候,电压可以缓冲,如下图。   05 温度补偿 针对其它元件对温度的适应性不够带来的影响,而进行补偿,改善电路的稳定性。     由于定时电容的容量决定了行振荡器的振荡频率,所以要求定时电容的容量非常稳定,不随环境湿度变化而变化,这样才能使行振荡器的振荡频率稳定。因此采用正、负温度系数的电容释联,进行温度互补。   当工作温度升高时,C1的容量在增大,而C2的容量在减小,两只电容并联后的总容量为两只电容容量之和,由于一个容量在增大而另一个在减小,所以总容量基本不变。   同理,在温度降低时,一个电容的容量在减小而另一个在增大,总的容量基本不变,稳定了振荡频率,实现温度补偿目的。 06 计时 电容器与电阻器配合使用,确定电路的时间常数。     输入信号由低向高跳变时,经过缓冲1后输入RC电路。电容充电的特性使B点的信号并不会跟随输入信号立即跳变,而是有一个逐渐变大的过程。当变大到一定程度时,缓冲2翻转,在输出端得到了一个延迟的由低向高的跳变。   时间常数:以常见的RC串联构成积分电路为例,当输入信号电压加在输入端时,电容上的电压逐渐上升。而其充电电流则随着电压的上升而减小,电阻R和电容C串联接入输入信号VI,由电容C输出信号V0,当RC (τ)数值与输入方波宽度tW之间满足:τ>>tW,这种电路称为积分电路。   07 调谐 对与频率相关的电路进行系统调谐,比如手机、收音机、电视机。   变容二极管的调谐电路   因为lc调谐的振荡电路的谐振频率是lc的函数,我们发现振荡电路的最大与最小谐振频率之比随着电容比的平方根变化。此处电容比是指反偏电压最小时的电容与反偏电压最大时的电容之比。因而,电路的调谐特征曲线(偏压一谐振频率)基本上是一条抛物线。 08 整流 在预定的时间开或者关半闭导体开关元件。     09 储能 储存电能,用于必须要的时候释放。例如相机闪光灯,加热设备等。如今某些电容的储能水平己经接近锂电池的水准,一个电容储存的电能可以供一个手机使用一天。     一般地,电解电容都会有储能的作用。对于专门的储能作用的电容,电容储能的机理为双电层电容以及法拉第电容,其主要形式为超级电容储能。   其中超级电容器是利用双电层原理的电容器,当外加电压加到超级电容器的两个极板上时,与普通电容器一样,极板的正电极存储正电荷,负极板存储负电荷;在超级电容器的两极板上电荷产生的电场作用下,在电解液与电极间的界面上形成相反的电荷,以平衡电解液的内电场。这种正电荷与负电荷在两个不同相之间的接触面上,以正负电荷之间极短间隙排列在相反的位置上,这个电荷分布层叫做双电层,因此电容量非常大。 精彩文章推荐: 运算放大器和比较器有什么区别? 为什么Y电容容量基本都不大于0.1uF? RS485接口EMC电路设计方案 技术贴:STM32串口通信波特率如何计算 高速PCB设计EMI的九大规则,工程师必看 八层板PCB设计,电脑主板设计分析 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 元器件 电容

  • 解了这14道C语言谜题后,所有人却都笑了!

    素材来源:电子世家- 巧学模电数电单片机 本文展示了14个C语言的迷题以及答案,代码应该是足够清楚的,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。 如果你不看答案,不知道是否有把握回答各个谜题?让我们来试试。 1 下面的程序并不见得会输出"hello-std-out",你知道为什么吗? #include #include int main() { while(1) { fprintf(stdout,"hello-std-out"); fprintf(stderr,"hello-std-err"); sleep(1); } return 0; } 参考答案 stdout和stderr是不同设备描述符。stdout是块设备,stderr则不是。对于块设备,只有当下面几种情况下才会被输入:遇到回车;缓冲区满;flush被调用。而stderr则不会。 2 下面的程序看起来是正常的,使用了一个逗号表达式来做初始化。可惜这段程序是有问题的。你知道为什么吗? #include int main() { int a = 1,2; printf("a : %d\n",a); return 0; } 参考答案 这个程序会得到编译出错(语法出错)。逗号表达式是没错,可是在初始化和变量声明时,逗号并不是逗号表达式的意义。这点要区分,要修改上面这个程序,你需要加上括号:"int a = (1,2);"。 3 下面的程序会有什么样的输出呢? #include int main() { int i=43; printf("%d\n",printf("%d",printf("%d",i))); return 0; } 参考答案 程序会输出4321,你知道为什么吗?要知道为什么,你需要知道printf的返回值是什么。printf返回值是输出的字符个数。 4 下面的程序会输出什么? #include int main() { float a = 12.5; printf("%d\n", a); printf("%d\n", (int)a); printf("%d\n", *(int *)&a); return 0; } 参考答案 该项程序输出:"0 12 1095237632"。 原因是:浮点数是4个字节,12.5f转成二进制是:01000001010010000000000000000000,十六进制是:0x41480000,十进制是:1095237632。所以,第二和第三个输出相信大家也知道是为什么了。 而对于第一个,为什么会输出0,我们需要了解一下float和double的内存布局,如下: • float: 1位符号位(s)、8位指数(e),23位尾数(m,共32位)。 • double: 1位符号位(s)、11位指数(e),52位尾数(m,共64位)。 然后,我们还需要了解一下printf由于类型不匹配,所以,会把float直接转成double,注意,12.5的float和double的内存二进制完全不一样。别忘了在x86芯片下使用是的反字节序,高位字节和低位字位要反过来。所以: • float版:0x41480000 (在内存中是:00 00 48 41)。 • double版:0x4029000000000000 (在内存中是:00 00 00 00 00 00 29 40)。 而我们的%d要求是一个4字节的int,对于double的内存布局,我们可以看到前四个字节是00,所以输出自然是0了。这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。 5 下面,我们再来看一个交叉编译的事情,下面的两个文件可以编译通过吗?如果可以通过,结果是什么? //file1.cint arr[80]; //file2.cextern int *arr; int main() { arr[1] = 100; printf("%d\n", arr[1]); return 0; } 参考答案 该程序可以编译通过,但运行时会出错。为什么呢?原因是,在另一个文件中用 extern int *arr来外部声明一个数组并不能得到实际的期望值,因为他们的类型并不匹配。所以导致指针实际并没有指向那个数组。 注意:一个指向数组的指针,并不等于一个数组。 修改:"extern int arr[]"。 6 请说出下面的程序输出是多少?并解释为什么?(注意,该程序并不会输出"b is 20") #include int main() { int a=1; switch(a) { int b=20; case 1: printf("b is %d\n",b); break; default: printf("b is %d\n",b); break; } return 0; } 参考答案 该程序在编译时,可能会出现一条warning: unreachable code at beginning of switch statement。我们以为进入switch后,变量b会被初始化,其实并不然,因为switch-case语句会把变量b的初始化直接就跳过了。所以,程序会输出一个随机的内存值。 7 请问下面的程序会有什么潜在的危险? #include int main() { char str[80]; printf("Enter the string:"); scanf("%s",str); printf("You entered:%s\n",str); return 0; } 参考答案 本题很简单了。这个程序的潜在问题是,如果用户输入了超过80个长度的字符,那么就会有数组越界的问题了,你的程序很有可能会crash了。 8 请问下面的程序输出什么? #include int main() { int i; i = 10; printf("i : %d\n",i); printf("sizeof(i++) is: %d\n",sizeof(i++)); printf("i : %d\n",i); return 0; } 参考答案 如果你觉得输出分别是:10,4,11。那么你就错了。 错在了第三个,第一个是10没有什么问题,第二个是4,也没有什么问题,因为是32位机上一个int有4个字节。但是第三个为什么输出的不是11呢?居然还是10?原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式。 9 请问下面的程序的输出值是什么? #include #include #define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0])) #define PrintInt(expr) printf("%s:%d\n",#expr,(expr)) int main() { /* The powers of 10 */ int pot[] = { 0001, 0010, 0100, 1000       }; int i; for(i=0;i

    时间:2020-11-24 关键词: C语言 嵌入式

  • RS485接口EMC电路设计方案

    一、原理图 1.  RS485接口6KV防雷电路设计方案 图1  RS485接口防雷电路 接口电路设计概述: RS485用于设备与计算机或其它设备之间通讯,在产品应用中其走线多与电源、功率信号等混合在一起,存在EMC隐患。 本方案从EMC原理上,进行了相关的抑制干扰和抗敏感度的设计,从设计层次解决EMC问题。 2.电路EMC设计说明: (1) 电路滤波设计要点: L1为共模电感,共模电感能够对衰减共模干扰,对单板内部的干扰以及外部的干扰都能抑制,能提高产品的抗干扰能力,同时也能减小通过429信号线对外的辐射,共模电感阻抗选择范围为120Ω/100MHz ~2200Ω/100MHz,典型值选取1000Ω/100MHz; C1、C2为滤波电容,给干扰提供低阻抗的回流路径,能有效减小对外的共模电流以同时对外界干扰能够滤波;电容容值选取范围为22PF~1000pF,典型值选取100pF;若信号线对金属外壳有绝缘耐压要求,那么差分线对地的两个滤波电容需要考虑耐压; 当电路上有多个节点时要考虑降低或去掉滤波电容的值。C3为接口地和数字地之间的跨接电容,典型取值为1000pF, C3容值可根据测试情况进行调整; (2) 电路防雷设计要点: 为了达到IEC61000-4-5或GB17626.5标准,共模6KV,差模2KV的防雷测试要求,D4为三端气体放电管组成第一级防护电路,用于抑制线路上的共模以及差模浪涌干扰,防止干扰通过信号线影响下一级电路; 气体放电管标称电压VBRW要求大于13V,峰值电流IPP要求大于等于143A; 峰值功率WPP要求大于等于1859W; PTC1、PTC2为热敏电阻组成第二级防护电路,典型取值为10Ω/2W; 为保证气体放电管能顺利的导通,泄放大能量必须增加此电阻进行分压,确保大部分能量通过气体放电管走掉;  D1~D3为TSS管(半导体放电管)组成第三级防护电路,TSS管标称电压VBRW要求大于8V,峰值电流IPP要求大于等于143A;峰值功率WPP要求大于等于1144W; 3.接口电路设计备注: 如果设备为金属外壳,同时单板可以独立的划分出接口地,那么金属外壳与接口地直接电气连接,且单板地与接口地通过1000pF电容相连; 如果设备为非金属外壳,那么接口地PGND与单板数字地GND直接电气连接。 二. PCB设计 1.  RS485接口电路布局 图1  RS485接口滤波及防护电路布局 方案特点: (1)防护器件及滤波器件要靠近接口位置处摆放且要求摆放紧凑整齐,按照先防护后滤波的规则,走线时要尽量避免走线曲折的情况; (2) 共模电感与跨接电容要置于隔离带中。 方案分析: (1)接口及接口滤波防护电路周边不能走线且不能放置高速或敏感的器件; (2) 隔离带下面投影层要做掏空处理,禁止走线。 2.  RS485接口电路分地设计 方案特点: (1)为了抑制内部单板噪声通过RS485接口向外传导辐射,也为了增强单板对外部干扰的抗扰能力,在RS485接口处增加滤波器件进行抑制,以滤波器件位置大小为界,划分出接口地; (2)隔离带中可以选择性的增加电容作为两者地之间的连接,电容C4、C5取值建议为1000pF,信号线上串联共模电感CM与电容滤波,并与接口地并联GDT和TVS管进行防护;且所有防护器件都靠近接口放置,共模电感CM置于隔离带内,具体布局如图示。 方案分析: (1)当接口与单板存在相容性较差或不相容的电路时,需要在接口与单板之间进行“分地”处理,即根据不同的端口电压、电平信号和传输速率来分别设置地线。“分地”,可以防止不相容电路的回流信号的叠加,防止公共地线阻抗耦合; (2)“分地”现象会导致回流信号跨越隔离带时阻抗变大,从而引起极大的EMC风险,因此在隔离带间通过电容来给信号提供回流路径。 相关文章推荐: RS485的上下拉电阻如何选择? RS485方向切换如何设计电路?介绍5种方案及优劣势分析 RS485是硬件接口,那么他是怎么实现数据通讯的呢?Modbus-RTU协议解析 一个小电路引起的疑惑:RS485电路 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: PCB 电子电路

  • 运算放大器和比较器有什么区别?

    运算放大器和电压比较器在原理符号上确实是一样的,都有5个引脚,其中两个引脚为电源+和电源-,还有两个引脚为同相输入端(+)和反向输入端(-),最后一个引脚是输出端。 但是它们的功能是不一样的,运放的功能及用途更复杂,而比较器就相对简单得多。 电压比较器 下面简单讲解一下比较器的基本原理,比较器的原理挺简单,目的是比较两个输入端的电压大小,若正输入端的电压为a,负输入端的电压为b,则当a>b时,输出为高电平(逻辑1);当a<b时,输出为低电平(逻辑0)。 下面结合原理图进行说明,如下图原理图,比较器输入端的电压为IN1、IN2,供电为VCC/GND,上拉电阻1K,上拉电压为VCC。 当输入电压IN1>IN2时,即正输入端的电压较高,输出高电平(VCC); 当输入电压IN2>IN1时,即负输入端的电压较高,输出低电平(0V)。 比较器的用途很广,可用于比较热敏电阻、光敏传感器等电压信号,用于离散量控制,比如通过比较器采集光敏电阻的电压判断白天还是夜晚等,比较器还可以用于模拟量负反馈电路当中,比如电压调节等。 运算放大器 运放的用途很多,基本的运放电路有同相比例放大电路、反相比例放大电路、加法器、减法器、差分比例运算电路、微分电路、积分电路等,掌握这些基本的集成运放电路原理,基本上可以区分电路图中符号一样的电路符号属于比较器还是运放。 一般情况下,运放都会在输出端与输入端之间串联一个电阻用于反馈,而一般情况下电压比较器输出端与输入端之间是没有电阻的,绝大部分电路都可以通过此区别来区分,但是也有特殊情况,这要根据具体原理具体分析了。 比如 运放也可以当比较器使用 ,其输出端与输入端之间开环(不接反馈电阻),使用运放当比较器其别在于不用上拉电阻,当IN1>IN2时,输出电压为VCC(运放电源电压),当IN1<IN2时,输出电压为0。 总结 专业基础扎实,掌握电压比较器和运放的基本电路之后,基本上直接就能够判别原理属于运放还是比较器,只有少量的特殊情况需要具体分析,通过专业知识分析其原理很快就能够判别其属于运放还是比较器。 相关文章推荐: 模拟电路的精髓:运放,该如何选型? 学会虚断和虚短,运放电路就不难! 差分运放,PT100采集处理电路设计 模电老司机这样说:学会“虚短”和“虚断”,运放电路分析不求人 单比较器设计的滞回电路如何改变滞回回差? 合理使用运算放大器,方便你我他! 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 运算放大器 比较器

  • 技术贴:STM32串口通信波特率如何计算?

    波特率的计算 STM32下的波特率和串口外设时钟息息相关,USART 1的时钟来源于APB2,USART 2-5的时钟来源于APB1。在STM32中,有个波特率寄存器USART_BRR,如下: STM32串口波特率通过USART_BRR进行设置,STM32的波特率寄存器支持分数设置,以提高精确度。USART_BRR的前4位用于表示小数,后12位用于表示整数。但是它还不是我们想要设置的波特率,想要设置我们串口的波特率大小还需要进行计算。其实有关波特率的计算是下面这一条表达式: 从上面的表达式,我们引入了一个新量USARTDIV,它表示对串口的时钟源fck进行分频。假设我们已知道了波特率和fck时钟频率的大小,那么通过上式便可以计算出USARTDIV的具体大小,然后再通过USART的值大小对波特率寄存器进行设置。 USARTDIV通过上面的表达式得出,是一个带有小数的浮点数(如27.75)。将小数部分和整数部分分开,分别得到一个整数值n(如27)和一个小数值m(如0.75)。有了这两个值我们便可以填写USART_BRR寄存器进而设置我们串口波特率大小了。 将整数部分m(27 = 0x1B)直接写入USART_BRR的后12位部分;将小数部分n乘以16后得到的整数值(如0.75 x 16 = 12 = 0xC)写入USART_BRR前4位部分,最后USART_BRR的值为0x1BC。 注意:如果小数部分乘以16之后仍带有小数,则要四舍五入去除小数部分得到一个新的整数,再将其写入USART_BRR的前四位。 为什么在计算波特率的公式中要乘以16 我们知道串口通信是通过TXD和RXD这两条线进行通信的,当接收器的RXD连接着发送器的TXD,接收器的TXD连接着发送器的RXD,接收器和发送器可以通过RXD和TXD互传数据。当接收器检测到RXD这条线的电平被拉为低电平,立即开始接收发送器发送过来的数据,刚刚那个低电平只是一个告知接收器可以接收数据的起始位而已。 在数据的传输中,信号可能受到一些干扰而产生一些抖动,如下图。如果接收端只对这些信号数据采样一次,那么它有可能采样到的是抖动的不准的数据,进而使数据传输不准确,所以接收端在采样数据线上的数据,通常都要采样多次,然后通过比较获得准确的数据。 前面已经说过,USARTDIV,它表示对串口的时钟源fck进行分频,而这16表示的正是1bit数据的采样次数。为什么呢? 将这个表达式的分子分母倒过来,可以得到下面这条表达式 每一位的传输时间只有1/TX_baud,这个总时间除以16,所以每采样一次的时间正好是T1,即新分频后的周期。而初始的串口时钟信号来自于APBx,APBx时钟信号需要经过分频才会等于T1,所以才需要分频USARTDIV。 精彩文章推荐: STM32基础分析——PWM配置 STM32单片机:独立看门狗、窗口看门狗的配置 STM32如何配置外部中断? stm32-hal库开发简介 STM32定时器如何配置? 如何高效阅读《STM32参考手册》?大神来教你! STM32只会用库函数,不会用寄存器,能写好程序吗? 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 单片机 数字信号

  • 华为内部资料:电容的介绍和深入认识

    无源滤波元器件中,电容是一个很重要的基本元器件,但应用中由于对电容的认识不深,存在一些不正确的使用而造成问题。本文主要针对常用的三类电容(铝电容、钽电容和陶瓷电容),从电容结构、制造工艺入手,结合滤波模型关注的参数性能进行深入的剖析,最后引出如何正确可靠应用电容。结构上采取每类电容一大章,每一章三小节分析:第一小节简单介绍电容的结构和生产加工工艺流程;第二小节为电容主要性能参数的变化特点,涉及到如何应用等方面;第三小节介绍电容使用中的物理可靠性问题需要关注的地方。同时附录还对三类电容在参数、特性及应用上做了深入的比较。 精彩文章推荐: 初学不识“电容”意,再看已是电老炮 设计电路如何确定使用多大的电容?记住四种情况就够了 电阻和电容并联的几个作用 为什么要进行电容补偿?如何补偿? 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 元器件 电容

  • 高速PCB设计EMI的九大规则,工程师必看!

    随着信号上升沿时间的减小及信号频率的提高,电子产品的EMI问题越来越受到电子工程师的关注,几乎60%的EMI问题都可以通过高速PCB来解决。 以下 是九大规则: 01 规则一:高速信号走线屏蔽规则 在高速的PCB设计中,时钟等关键的高速信号线,走线需要进行屏蔽处理,如果没有屏蔽或只屏蔽了部分,都会造成EMI的泄漏。建议屏蔽线,每1000mil,打孔接地。 02 规则二:高速信号的走线闭环规则 由于PCB板的密度越来越高,很多PCB LAYOUT工程师在走线的过程中,很容易出现一种失误,即时钟信号等高速信号网络,在多层的PCB走线的时候产生了闭环的结果,这样的闭环结果将产生环形天线,增加EMI的辐射强度。 03 规则三:高速信号的走线开环规则 规则二提到高速信号的闭环会造成EMI辐射,然而开环同样会造成EMI辐射。 时钟信号等高速信号网络,在多层的PCB走线的时候一旦产生了开环的结果,将产生线形天线,增加EMI的辐射强度。 04 规则四:高速信号的特性阻抗连续规则 高速信号,在层与层之间切换的时候必须保证特性阻抗的连续,否则会增加EMI的辐射。也就是说,同层的布线的宽度必须连续,不同层的走线阻抗必须连续。 05 规则五:高速PCB设计的布线方向规则 相邻两层间的走线必须遵循垂直走线的原则,否则会造成线间的串扰,增加EMI辐射。 简而言之,相邻的布线层遵循横平竖垂的布线方向,垂直的布线可以抑制线间的串扰。 06 规则六: 高速PCB设计中的拓扑结构规则 在高速PCB设计中,线路板特性阻抗的控制和多负载情况下的拓扑结构的设计,直接决定着产品的成功还是失败。 图示为菊花链式拓扑结构,一般用于几Mhz的情况下为益。高速PCB设计中建议使用后端的星形对称结构。 07 规则七:走线长度的谐振规则 检查信号线的长度和信号的频率是否构成谐振,即当布线长度为信号波长1/4的时候的整数倍时,此布线将产生谐振,而谐振就会辐射电磁波,产生干扰。 08 规则八:回流路径规则 所有的高速信号必须有良好的回流路径。尽可能地保证时钟等高速信号的回流路径最小。否则会极大的增加辐射,并且辐射的大小和信号路径和回流路径所包围的面积成正比。 09 规则九:器件的退耦电容摆放规则 退耦电容的摆放的位置非常的重要。摆放不合理根本起不到退耦的效果。其原则是:靠近电源的管脚,并且电容的电源走线和地线所包围的面积最小。 相关文章推荐: EMC相关:有效降低传导辐射干扰的技巧 EMC抗干扰设计——RS485 接口的电磁兼容设计 什么是电气间隙,什么是爬电距离,PCB为什么要开槽? 电磁继电器的几个参数,了解完就会用继电器 模拟量传感器如何抗干扰,有哪些措施? PCB板边缘的敏感线为何容易ESD干扰 如何选用电源滤波器,电源滤波器有哪些重要参数? 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 电磁 PCB

  • 封装图鉴:掌握这17种元器件PCB封装,设计板子就容易多了!

    素材来源:张飞实战电子 元器件封装的构建是PCB设计中的一个重要环节,小小的一个错误很可能导致整个板子都不能工作以及工期的严重延误。常规器件的封装库一般CAD工具都有自带,也可以从器件原厂的设计文档、参考设计源图中获取。 封装名称与图形如下: 01 晶体管 02 晶振 03 电感 04 接插件 05 Discrete Components 06 电容 07 可变电容 08 数码管 09 可调电阻 010 电阻 011 排阻 012 继电器 013 拨码开关 014 跳线 015 集成电路 016 1.5mmBGA 017 1mmBGA 018 1.27mm BGA 良好合格的一个器件封装,应该需要满足以下几个条件: 1、设计的焊盘,应能满足目标器件脚位的长、宽和间距的尺寸要求。特别是要注意:器件引脚本身产生的尺寸误差,在设计时要考虑进去--- 特别是精密、细节的器件和接插件。不然,有可能会导致不同批次来料的同型号器件,虽然焊接加工良率高,但却发生大的生产品质问题!因此,焊盘的兼容性设计(合适、通用于多数大厂家的器件焊盘尺寸设计),是很重要的! 关于这一点,最简单的要求和检验方法就是:把实物的目标器件放到PCB板的焊盘上进行观察,如果器件的每个引脚都处在相应的焊盘区域里。那这个焊盘的封装设计,基本上是没有多大问题。反之,如果部分引脚不在焊盘里,那就不太好。 2、设计的焊盘,应该有明显的方向标识,最好是通用、易辨别的方向极性标识。不然,在没有合格的PCBA实物样品做参考的时候,第三方(SMT工厂或私人外包)来做焊接加工,就容易发生极性焊反,焊错的问题! 3、设计的焊盘,应该能符合具体那个PCB线路厂本身的加工参数、要求和工艺。比如,能设计的焊盘线大小、线间距、字符长宽是多少等等。如果PCB尺寸较大,建议大家按市面流行、通用的PCB工厂的工艺进行设计,以因品质或商业合作问题而发生更换PCB供应商的时候,可选择的PCB厂家太少而耽搁了生产进度。 精彩文章推荐: 电容实物、封装,区分正负极的方法 电子入门基础知识之:封装 八层板PCB设计,电脑主板设计分析 太美了!PCB布线怎么可以这么美? PCB回流是什么?如何解决? PCB大神的那些专属技巧和风骚走位 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 电路板 PCB

  • C语言中的三目运算符是啥?有何用处?

    一般来说,C语言中的三目运算符为 a?b:c 即有三个参与运算的量。 由条件运算符组成条件表达式的一般形式为: 表达式1? 表达式2:表达式3 求值规则为:如果表达式1的值为真,则以表达式2 的值作为条件表达式的值,否则以表达式2的值作为整个条件表达式的值。条件表达式通常用于赋值语句之中。 例如条件语句: if(a>b) max=a;else max=b; 可用条件表达式写为 max=(a>b)?a:b; 执行该语句的语义是: 如a>b为真,则把a赋予max,否则把b 赋予max。 在我们使用条件表达式时,还应注意以下几点: (1)条件运算符的运算优先级低于关系运算符和算术运算符,但高于赋值符。因此 max=(a>b)?a:b可以去掉括号而写为 max=a>b?a:b (2)条件运算符?和:是一对运算符,不能分开单独使用。 (3)条件运算符的结合方向是自右至左。 例如: a>b?a:c>d?c:d应理解为a>b?a:(c>d?c:d) 这也就是条件表达式嵌套的情形,即其中的表达式3又是一个条件表达式。 void main(){int a,b,max;printf("\n input two numbers: ");scanf("%d%d",&a,&b);printf("max=%d",a>b?a:b);//对于“三目运算符是什么”,可以理解为if() 语句一;else 语句二;a? b : c} 三目运算符简单好用。 相关文章推荐: 都说C语言的精髓是指针,但是指针太难懂了,怎么办? 求求你,别再写这么多if...else...了 根据时序编程,单片机驱动74HC595实现数码管显示 大佬故事:初中开始学编程,大学毕业后直接进微软... 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: C语言 嵌入式

  • 八层板PCB设计,电脑主板设计分析

    来源于网络的前辈PCB作品 学好PCB设计的方法之一就是通过前辈的作品学习前辈的设计方法和技巧。 我们能在前辈的作品中学到元件布局、板层设置、线路布线 板层设置 1. 信号层(TOP) 第一层信号层,又叫顶层,实物打板回来是能够看得见的一层,可以摆放电子元件的一层。由上图可见这层布线比较多。原因之一就是电子元件的摆放在同一层,走线的过程中不需要设置过孔转换层。这样可以避免过孔阻碍其他层的走线。在多层板布线反而要注意过孔的设置。 2. 电源层(VCC) 在这层没有看到走线。是因为这一层都是电源网络。在设计时使用特定的线进行电源分割,前提需要在电子元件布局的时候把同一电压的电子元件摆放在一个区域内,通过过孔连接到这一层的相同区域,所以不需要走线。 3. 信号层(Inner Layer3) 这层主要走信号线,其次还有一些电源走线。下图图中比较大一点的走线就是电源线,小的为信号线。 4. 信号层(Inner Layer4) 这层与上一层走线布置基本上一样。走线为信号线和电源线。 5. GND层 这层为GND网络层,通过过孔连接。 6. 信号层(Inner Layer5) 7. GND层 图片略。 这层与第5层一样。 8. Bottom层 这层跟顶层一样。很多的小芯片走线基本上都在顶层或者这一层。 走线或者布线 1. 蛇形走线 这种走线看起来感觉挺漂亮的。这样走线的目的是为了延长走线的总长度。应用在并行数据线中,使同一组并行数据线的走线长度一致,这样在高速传输数据的时候数据到达的时间保持一致。 蛇形走线的布线步骤是先使用普通的走线布线完同一组并行数据线。然后找出这一组数据线长度最长的线,再以这跟最长的线的长度为参考把比这个参考值小的线通过蛇形走线延长到与参考值相等或者到达这个参考值的一定范围之内。相关走线布线功能一般的电路板设计软件都有只需要设置相关参数就可以。 2. 差分线 差分线其实跟上面的蛇形非常相似,上面的蛇形走线是一组数据线。而差分线只有两根线。但是比蛇形走线的要求更高,更严格。不但要线的长度一致,还需要线与线的距离保持一定的距离。还好相关的软件都有这种走线的功能,也只需要设置相关的参数即可。 3. 大走线或者宽走线 在布线中比较大的线一般为电源走线,这跟元件负载有关,相关理论就不在这细说了。 元件布局 以上就是前辈作品中的元件布局,是不是很好看。元件布局基本上都是按照模块化的设计方式进行布局,这样布局的好处就是把实现同一功能的相关电子元件布局在一起使得小模块内的走线长度可以更短,小模块放置在大模块的时候方便框选完整的模块。在布线的时候不要走太多的弯路。 同类文章推荐: 太美了!PCB布线怎么可以这么美? 你常用哪种软件画原理图和PCB PCB大神的那些专属技巧和风骚走位 PCB的诞生,奠定了电子行业发展的基础 为什么电路板有绿色、黑色等?有什么区别吗? 芯片要焊接在电路板上吗?SMT流程怎样? 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 电路板 PCB

  • 女工程师的自嘲:聪明的女生,长大后都变成了男人

    我,理工科,研究生,女的。 从今天早上起,我就一直被一个问题纠结到现在。我九点起来,十点出门,刷牙洗脸穿衣服不超过十分钟,也就是说,我花了五十分钟,还是没能成功的刷上一层正常的睫毛膏。我可以花两分钟焊接一个176脚的 DSP芯片,每一个脚的宽度都不会超过我的睫毛,两分钟我可以均匀的刷176个脚的焊锡,但我花20分钟都没办法刷匀我绝对不超过176根的眼睫毛!虽然 一直被玩笑,但我今天真的觉得,我可能真不是个女的。 前天晚上走在回宿舍路上,和师妹对话:我:晚上回去把打毛球的充一下电,我用下。师妹:好,可是那个电池现在不太好,充一晚上也只能用个半小时。我:哦,是5V供电的么?是的话我们可以带个开关电源回去,直接连着用。师妹:…… 好吧,我觉得我可能真的不是一个女的。回想起情人节晚上,吃饭时见了男朋友兄弟的老婆,目测不超过95斤,外套没注意,脱了外套穿黑色花边衬衫,头发挽起来,精致妆容,笑容甜美,喝卡布奇诺。我费心的买了一件终于不是黑色的大衣,结果还不堪的起了一身毛球,因为怕冷,大衣里面的毛衣里面还有一件棉衣,披头散发,头发下面因为烫卷又用了洗发皂的 缘故,已经好久没有梳开了,妆容就更别提了,纯裸妆,真心纯裸妆。装逼的点了个卡布奇诺,喝了一口,果断换了加冰可乐。问他们晚上去看什么电影,小女子悠悠告诉我们说去看LOVE。被问到下午我俩去看了什么电影,男朋友无奈的:地心历险记2,是她要看的。亲爱的,我真心是给你丢人了……好吧,我觉得我确实可能不是女的。我到底是从什么时候开始不是女的了呢?小学的时候还是臭美的,穿裙子,这时候估计还是女的。初中了,细细瘦瘦的,应该也还是女的。高中,好像就没再穿过裙子了,然后,被作为学习好的,聪明的一类,选择了理工科。后来,可能就是我悲剧的开始。妈妈会对姐姐说:穿好衣服出去买点菜。穿好衣服出去买个馍。穿好衣服出去买……妈妈会对我说:穿个旧衣服去地下室帮你爸抬个啥。家里啥啥坏了,你看看怎么回事……上大学以后,在大街上能让我驻足回头的,不是黑丝美女就是光腿美女。悲催的想起一个周末,我和室友在楼下洗自行车(借的,被我俩骑到泥巴里,不洗干净不好意思还),看着文科的美女们,一个个花枝招展的打着小阳伞出去约会了……好吧,我应该真不是个女的。大四毕业,最多的行李就是被子,无数的被子,原谅我来自寒冷的北方,却受不了南方的冷。真正女生的行李,牛逼的我见过光鞋盒就不下40个的,我他妈鞋可能就只有四双!还大都是运动鞋!就一双女人一点的单鞋,还被我穿去爬了一趟紫金山,毁了…… 好吧,我开始接受自己不是个女的了。今年寒假回学校,路上听MP3,发现带的大耳机夹耳朵,带了的小耳机又是电话上的耳机,插着试了试发现接口倒是一样,就是只能听见伴奏,要按下通话键才听 得到歌声,可是又不能一直按着。果断拆开,看到通话键是个小触点开关,撕了一点纸,叠好,按在开关上,再把壳子装好,开关果断压住,搞定!躺在铺上听着歌,一股悲凉油然而生啊……好吧,我真心不是个女的!现在看来,也许在男生眼中,女生 有才就是缺德。我拆装手机、笔记本、耳机,修理电器,都不如能判断一件大衣是不是起毛球来的有魅力。我依旧还是不会化妆,依旧还是喜欢看美女,依旧还是喜 欢捣鼓电路,依旧还是喜欢喝可乐,最喜欢吃的是洋快餐,看不懂新潮的装扮,冬天穿衣服只希望不会冻着,夏天下定决心改头换面而买的衣服都没穿出过门,两条 长裙只能拿来当睡衣……好吧,我是爷们,纯的。我可以自己修电脑,自己装软件,自己下电影。我可以一个人吃饭,可以几个月不逛街,可以买到的衣服功能仅限于遮羞和御寒。我可以自己提大包小包大行李,逛 超市买两箱牛奶也绝对搬得回来。我可以一个人在异乡平安顺利的度过七个年头,我强大到足够照顾自己,也许还能顺带照顾别人。想你或者想家的时候我也会哭会 难受,听到有人向你示好我可以装的很大度,我可以不吃醋,假装不在乎,但真心话我就不告诉你,觉得失了大气。好吧,我是个有些懒,有点胖,不打扮,不好看,感情小迟钝,工作精明,生活独立,内心软弱的理工科研究生,性别不详。是不是聪明一点的理工科女生,都变成了男人…… 有趣文章推荐: 尼玛,Github上最邪恶的开源项目了!女孩子勿进哦~ 牛人自述,我是华为编译器的优化师 中国“最牛”程序员,一人之力单挑微软 什么程序员也有自己的节日?1024,1GB 如何找一份不加班的工作 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 电路板 PCB 焊接

  • 一文了解PID算法

    PID的数学模型 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在很多控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的。PID算法的一般形式: PID算法通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻): 1.输入量为 2.输出量为 3.偏差量为  PID算法的数字离散化 假设采样间隔为T,则在第K个T时刻: 偏差=  积分环节用加和的形式表示,即  微分环节用斜率的形式表示,即 PID算法离散化后的式子:  则可表示成为:   其中式中: 比例参数 :控制器的输出与输入偏差值成比例关系。系统一旦出现偏差,比例调节立即产生调节作用以减少偏差。特点:过程简单快速、比例作用大,可以加快调节,减小误差;但是使系统稳定性下降,造成不稳定,有余差。 积分参数 :积分环节主要是用来消除静差,所谓静差,就是系统稳定后输出值和设定值之间的差值,积分环节实际上就是偏差累计的过程,把累计的误差加到原有系统上以抵消系统造成的静差。 微分参数 :微分信号则反应了偏差信号的变化规律,或者说是变化趋势,根据偏差信号的变化趋势来进行超前调节,从而增加了系统的快速性。 PID的基本离散表示形式如上。目前的这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由上述表达式可以轻易得到: 那么: 上式就是离散化PID的增量式表示方式,由公式可以看出,增量式的表达结果和最近三次的偏差有关,这样就大大提高了系统的稳定性。需要注意的是最终的输出结果应该为: 输出量 =  + 增量调节值 目的 PID 的重要性应该无需多说了,这个控制领域的应用最广泛的算法了. 本篇文章的目的是希望通过一个例子展示算法过程,并解释以下概念: (1)简单描述何为PID, 为何需要PID,PID 能达到什么作用。 (2)理解P(比例环节)作用:基础比例环节。 缺点: 产生稳态误差. 疑问: 何为稳态误差 为什么会产生稳态误差. (3)理解I(积分环节)作用:消除稳态误差. 缺点: 增加超调 疑问: 积分为何能消除稳态误差? (4) 理解D(微分环节)作用:加大惯性响应速度,减弱超调趋势 疑问: 为何能减弱超调 (5)理解各个比例系数的作用 何为PID以及为何需要PID? 以下即PID 控制的整体框图,过程描述为:  设定一个输出目标,反馈系统传回输出值,如与目标不一致,则存在一个误差,PID 根据此误差调整输入值,直至输出达到设定值. 疑问: 那么我们为什么需要PID 呢,比如我控制温度,我不能监控温度值,温度值一到就停止吗? 这里必须要先说下我们的目标,因为我们所有的控制无非就是想输出能够达到我们的设定,即如果我们设定了一个目标温度值,那么我们想要一个什么样的温度变化呢. 比如设定目标温度为30度, 目标无非是希望达到图1 希望其能够快速而且没有抖动的达到30度. 那这样大家应该就明白,如果使用温度一到就停止的办法,当然如果要求不高可能也行,当肯定达不到图1 这样的要求,因为温度到了后余温也会让温度继续升高.而且温度自身也会通过空气散热的. 图  系统输出的响应目标 综上所述,我们需要PID的原因无非就是普通控制手段没有办法使输出快速稳定的到达设定值。 控制器的P,I,D项选择 下面将常用的各种控制规律的控制特点简单归纳一下:(1)、比例控制规律P:采用P控制规律能较快地克服扰动的影响,它的作用于输出值较快,但不能很好稳定在一个理想的数值,不良的结果是虽较能有效的克服扰动的影响,但有余差出现。它适用于控制通道滞后较小、负荷变化不大、控制要求不高、被控参数允许在一定范围内有余差的场合。如:金彪公用工程部下设的水泵房冷、热水池水位控制;油泵房中间油罐油位控制等。(2)、比例积分控制规律(PI):在工程中比例积分控制规律是应用最广泛的一种控制规律。积分能在比例的基础上消除余差,它适用于控制通道滞后较小、负荷变化不大、被控参数不允许有余差的场合。如:在主线窑头重油换向室中F1401到F1419号枪的重油流量控制系统;油泵房供油管流量控制系统;退火窑各区温度调节系统等。(3)、比例微分控制规律(PD):微分具有超前作用,对于具有容量滞后的控制通道,引入微分参与控制,在微分项设置得当的情况下,对于提高系统的动态性能指标,有着显著效果。因此,对于控制通道的时间常数或容量滞后较大的场合,为了提高系统的稳定性,减小动态偏差等可选用比例微分控制规律。如:加热型温度控制、成分控制。需要说明一点,对于那些纯滞后较大的区域里,微分项是无能为力,而在测量信号有噪声或周期性振动的系统,则也不宜采用微分控制。如:大窑玻璃液位的控制。(4)、例积分微分控制规律(PID):PID控制规律是一种较理想的控制规律,它在比例的基础上引入积分,可以消除余差,再加入微分作用,又能提高系统的稳定性。它适用于控制通道时间常数或容量滞后较大、控制要求较高的场合。如温度控制、成分控制等。鉴于D规律的作用,我们还必须了解时间滞后的概念,时间滞后包括容量滞后与纯滞后。其中容量滞后通常又包括:测量滞后和传送滞后。测量滞后是检测元件在检测时需要建立一种平衡,如热电偶、热电阻、压力等响应较慢产生的一种滞后。而传送滞后则是在传感器、变送器、执行机构等设备产生的一种控制滞后。纯滞后是相对与测量滞后的,在工业上,大多的纯滞后是由于物料传输所致,如:大窑玻璃液位,在投料机动作到核子液位仪检测需要很长的一段时间。总之,控制规律的选用要根据过程特性和工艺要求来选取,决不是说PID控制规律在任何情况下都具有较好的控制性能,不分场合都采用是不明智的。如果这样做,只会给其它工作增加复杂性,并给参数整定带来困难。当采用PID控制器还达不到工艺要求,则需要考虑其它的控制方案。如串级控制、前馈控制、大滞后控制等。Kp,Ti,Td三个参数的设定是PID控制算法的关键问题。一般说来编程时只能设定他们的大概数值,并在系统运行时通过反复调试来确定最佳值。因此调试阶段程序须得能随时修改和记忆这三个参数。数字PID控制器(1)模拟PID控制规律的离散化   (2)数字PID控制器的差分方程 参数的自整定在某些应用场合,比如通用仪表行业,系统的工作对象是不确定的,不同的对象就得采用不同的参数值,没法为用户设定参数,就引入参数自整定的概念。实质就是在首次使用时,通过N次测量为新的工作对象寻找一套参数,并记忆下来作为以后工作的依据。具体的整定方法有三种:临界比例度法、衰减曲线法、经验法。1、临界比例度法(Ziegler-Nichols)1.1  在纯比例作用下,逐渐增加增益至产生等副震荡,根据临界增益和临界周期参数得出PID控制器参数,步骤如下:(1)将纯比例控制器接入到闭环控制系统中(设置控制器参数积分时间常数Ti =∞,实际微分时间常数Td =0)。(2)控制器比例增益K设置为最小,加入阶跃扰动(一般是改变控制器的给定值),观察被调量的阶跃响应曲线。(3)由小到大改变比例增益K,直到闭环系统出现振荡。(4)系统出现持续等幅振荡时,此时的增益为临界增益(Ku),振荡周期(波峰间的时间)为临界周期(Tu)。(5) 由表1得出PID控制器参数。 表1 1.2  采用临界比例度法整定时应注意以下几点:(1)在采用这种方法获取等幅振荡曲线时,应使控制系统工作在线性区,不要使控制阀出现开、关的极端状态,否则得到的持续振荡曲线可能是“极限循环”,从线性系统概念上说系统早已处于发散振荡了。(2)由于被控对象特性的不同,按上表求得的控制器参数不一定都能获得满意的结果。对于无自平衡特性的对象,用临界比例度法求得的控制器参数往住使系统响应的衰减率偏大(ψ>0.75 )。而对于有自平衡特性的高阶等容对象,用此法整定控制器参数时系统响应衰减率大多偏小(ψ<0.75 )。为此,上述求得的控制器参数,应针对具体系统在实际运行过程中进行在线校正。(3) 临界比例度法适用于临界振幅不大、振荡周期较长的过程控制系统,但有些系统从安全性考虑不允许进行稳定边界试验,如锅炉汽包水位控制系统。还有某些时间常数较大的单容对象,用纯比例控制时系统始终是稳定的,对于这些系统也是无法用临界比例度法来进行参数整定的。(4)只适用于二阶以上的高阶对象,或一阶加纯滞后的对象,否则,在纯比例控制情况下,系统不会出现等幅振荡。1.3  若求出被控对象的静态放大倍数KP=△y/△u ,则增益乘积KpKu可视为系统的最大开环增益。通常认为Ziegler-Nichols闭环试验整定法的适用范围为: (1) 当KpKu > 20时,应采用更为复杂的控制算法,以求较好的调节效果。(2)当KpKu < 2时,应使用一些能补偿传输迟延的控制策略。(3)当1.5 (4)当KpKu< 1.5时,在对控制精度要求不高的场合仍可使用PI控制器,在这种情况下,微分作用已意义不大。2、衰减曲线法 衰减曲线法与临界比例度法不同的是,闭环设定值扰动试验采用衰减振荡(通常为4:1或10:l),然后利用衰减振荡的试验数据,根据经验公式求取控制器的整定参数。整定步骤如下:(1)在纯比例控制器下,置比例增益K为较小值,并将系统投入运行。(2)系统稳定后,作设定值阶跃扰动,观察系统的响应,若系统响应衰减太快,则减小比例增益K;反之,应增大比例增益K。直到系统出现如下图(a)所示的4:1衰减振荡过程,记下此时的比例增益Ks及和振荡周期Ts数值。 (3)利用Ks和Ts值,按下表给出的经验公式,计算出控制器的参数整定值。      (4)10:1衰减曲线法类似,只是用Tr带入计算。 采用衰减曲线法必须注意几点:(1)加给定干扰不能太大,要根据生产操作要求来定,一般在5%左右,也有例外的情况。(2)必须在工艺参数稳定的情况下才能加给定干扰,否则得不到正确得 整定参数。(3)对于反应快的系统,如流量、管道压力和小容量的液位调节等,要得到严格的4:1衰减曲线较困难,一般以被调参数来回波动两次达到稳定,就近似地认为达到4:1衰减过程了。(4)投运时,先将K放在较小的数值,把Ti减少到整定值,把Td逐步放大到整定值,然后把K拉到整定值(如果在K=整定值的条件下很快地把Td放到整定值,控制器的输出会剧烈变化)。3、经验整定法3.1方法一A:(1)确定比例增益使PID为纯比例调节,输入设定为系统允许最大值的60%~70%,由0逐渐加大比例增益至系统出现振荡;再反过来,从此时的比例增益逐渐减小至系统振荡消失,记录此时的比例增益,设定PID的比例增益P为当前值的60%~70%。(2)确定积分时间常数比例增益P确定后,设定一个较大的积分时间常数Ti的初值,然后逐渐减小Ti至系统出现振荡,之后在反过来,逐渐加大Ti至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%~180%。(3)确定积分时间常数Td积分时间常数Td一般不用设定,为0即可。若要设定,与确定 P和Ti的方法相同,取不振荡时的30%。(4)系统带载联调,再对PID参数进行微调,直至满足要求。 3.2 方法一B:(1)PI调节(a)纯比例作用下,把比例度从较大数值逐渐往下降,至开始产生周期振荡(测量值以给定值为中心作有规则得振荡),在产生周期性振荡得情况下,把此比例度逐渐加宽直至系统充分稳定。(b)接下来把积分时间逐渐缩短至产生振荡,此时表示积分时间过短,应把积分时间稍加延长,直至振荡停止。(2)PID调节(a)纯比例作用下寻求起振点。(b)加大微分时间使振荡停止,接着把比例度调得稍小一些,使振荡又产生,加大微分时间,使振荡再停止,来回这样操作,直至虽加大微分时间,但不能使振荡停止,求得微分时间的最佳值,此时把比例度调得稍大一些直至振荡停止。(c)把积分时间调成和微分时间相同的数值,如果又产生振荡则加大积分时间直至振荡停止。3.3 方法二:另一种方法是先从表列范围内取Ti的某个数值,如果需要微分,则取Td=(1/3~1/4)Ti,然后对δ进行试凑,也能较快地达到要求。实践证明,在一定范围内适当地组合δ和Ti的数值,可以得到同样衰减比的曲线,就是说,δ的减少,可以用增加Ti的办法来补偿,而基本上不影响调节过程的质量。所以,这种情况,先确定Ti、Td再确定δ的顺序也是可以的。而且可能更快些。如果曲线仍然不理想,可用Ti、Td再加以适当调整。3.4 方法三:(1)在实际调试中,也可以先大致设定一个经验值,然后根据调节效果修改。  流量系统:P(%)40--100,I(分)0.1--1  压力系统:P(%)30--70,   I(分)0.4--3       液位系统:P(%)20--80,   I(分)1—5  温度系统:P(%)20--60,   I(分)3--10,D(分)0.5--3(2)以下整定的口诀:阶跃扰动投闭环,参数整定看曲线;先投比例后积分,最后再把微分加;理想曲线两个波,振幅衰减4比1;比例太强要振荡,积分太强过程长;动差太大加微分,频率太快微分降;偏离定值回复慢,积分作用再加强。4、复杂调节系统的参数整定以串级调节系统为例来说明复杂调节系统的参数整定方法。由于串级调节系统中,有主、副两组参数,各通道及回路间存在着相互联系和影响。改变主、副回路的任一参数,对整个系统都有影响。特别是主、副对象时间常数相差不大时,动态联系密切,整定参数的工作尤其困难。在整定参数前,先要明确串级调节系统的设计目的。如果主要是保证主参数的调节质量,对副参数要求不高,则整定工作就比较容易;如果主、副参数都要求高,整定工作就比较复杂。下面介绍“先副后主”两步参数整定法。第一步:在工况稳定情况下,将主回路闭合,把主控制器比例度放在100%,积分时间放在最大,微分时间放在零。用4:1衰减曲线整定副回路,求出副回路得比例增益K2s和振荡周期T2s。第二步:把副回路看成是主回路的一个环节,使用4:1衰减曲线法整定主回路,求得主控制器K1s和T1s。根据K1s、K2s、T1s、T2s按表2经验公式算出串级调节系统主、副回路参数。先放上副回路参数,再放上主回路参数,如果得到满意的过渡过程,则整定工作完毕。否则可进行适当调整。如果主、副对象时间常数相差不大,按4:1衰减曲线法整定,可能出现“共振”危险,这时,可适当减小副回路比例度或积分时间,以达到减少副回路振荡周期的目的。同理,加大主回路比例度或积分时间,以期增大主回路振荡周期,使主、副回路振荡周期之比加大,避免“共振”。这样做的结果会降低调节质量。如果主、副对象特性太相近,则说明确定的方案欠妥当,就不能完全依靠参数整定来提高调节质量了。实际应用体会:一是利用数字PID控制算法调节直流电机的速度,方案是采用光电开关来获得电机的转动产生的脉冲信号,单片机(MSP430G2553)通过测量脉冲信号的频率来计算电机的转速(具体测量频率的算法是采用直接测量法,定时1s测量脉冲有多少个,本身的测量误差可以有0.5转加减),测量的转速同给定的转速进行比较产生误差信号,来产生控制信号,控制信号是通过PWM调整占空比也就是调整输出模拟电压来控制的(相当于1位的DA,如果用10位的DA来进行模拟调整呢?效果会不会好很多?),这个实验控制能力有一定的范围,只能在30转/秒和150转/秒之间进行控制,当给定值(程序中给定的速度)高于150时,实际速度只能保持在150转,这也就是此系统的最大控制能力,当给定值低于30转时,直流电机转轴实际是不转动的,但由于误差值过大,转速会迅速变高,然后又会停止转动,就这样循环往复,不能达到控制效果。根据实测,转速稳态精度在正负3转以内,控制时间为4到5秒。实验只进行到这种程度,思考和分析也只停留在这种深度。二是利用数字PID控制算法调节直流减速电机的位置,方案是采用与电机同轴转动的精密电位器来测量电机转动的位置和角度,通过测量得到的角度和位置与给定的位置进行比较产生误差信号,然后位置误差信号通过一定关系(此关系纯属根据想象和实验现象来拟定和改善的)转换成PWM信号,作为控制信号的PWM信号是先产生对直流减速电机的模拟电压U,U来控制直流减速电机的力矩(不太清楚),力矩产生加速度,加速度产生速度,速度改变位置,输出量是位置信号,所以之间应该对直流减速电机进行系统建模分析,仿真出直流减速电机的近似系统传递函数,然后根据此函数便可以对PID的参数进行整定了。两次体会都不是特别清楚PID参数是如何整定的,没有特别清晰的理论指导和实验步骤,对结果的整理和分析也不够及时,导致实验深度和程度都不能达到理想效果。 怎样形象理解PID算法 小明接到这样一个任务: 有一个水缸点漏水(而且漏水的速度还不一定固定不变) 要求水面高度维持在某个位置 一旦发现水面高度低于要求位置,就要往水缸里加水。  小明接到任务后就一直守在水缸旁边,时间长就觉得无聊,就跑到房里看小说了,每30分钟来检查一次水面高度。水漏得太快,每次小明来检查时,水都快漏完了,离要求的高度相差很远,小明改为每3分钟来检查一次,结果每次来水都没怎么漏,不需要加水,来得太频繁做的是无用功。 几次试验后,确定每10分钟来检查一次。这个检查时间就称为采样周期。 开始小明用瓢加水,水龙头离水缸有十几米的距离,经常要跑好几趟才加够水,于是小明又改为用桶加,一加就是一桶,跑的次数少了,加水的速度也快了, 但好几次将缸给加溢出了,不小心弄湿了几次鞋,小明又动脑筋,我不用瓢也不用桶,老子用盆,几次下来, 发现刚刚好,不用跑太多次,也不会让水溢出。这个加水工具的大小就称为比例系数。 小明又发现水虽然不会加过量溢出了,有时会高过要求位置比较多,还是有打湿鞋的危险。他又想了个办法,在水缸上装一个漏斗, 每次加水不直接倒进水缸,而是倒进漏斗让它慢慢加。这样溢出的问题解决了,但加水的速度又慢了,有时还赶不上漏水的速度。 于是他试着变换不同大小口径的漏斗来控制加水的速度,最后终于找到了满意的漏斗。漏斗的时间就称为积分时间 。 小明终于喘了一口,但任务的要求突然严了,水位控制的及时性要求大大提高,一旦水位过低,必须立即将水加到要求位置,而且不能高出太多,否则不给工钱。 小明又为难了!于是他又开努脑筋,终于让它想到一个办法,常放一盆备用水在旁边,一发现水位低了,不经过漏斗就是一盆水下去,这样及时性是保证了,但水位有时会高多了。 他又在要求水面位置上面一点将水凿一孔,再接一根管子到下面的备用桶里这样多出的水会从上面的孔里漏出来。这个水漏出的快慢就称为微分时间。 拿一个水池水位来说,我们 可以制定一个规则, 把水位分为超高、高、较高、中、较低、低、超低几个区段; 再把水位波动的趋势分为甚快、快、较快、慢、停几个区段,并区分趋势的正负; 把输出分为超大幅 度、大幅度、较大幅度、微小几个区段。 当水位处于中值、趋势处于停顿的时候,不调节; 当水位处于中值、趋势缓慢变化的时候,也可以暂不调节; 当水位处于较高、趋势缓慢变化 的时候,输出一个微小调节两就够了; 当水位处于中值、趋势较快变化的时候,输出进行叫 大幅度调节……。 如上所述,我们需要制定一个控制规则表,然后制定参数判断水位区段的界值、波动趋 势的界值、输出幅度的界值。 比例控制(P)是一种最简单的控制方式。其控制器的输出与输入误差信号成比例关系。 根据设备有所不同,比例带一般为2~10%(温度控制)。 但是,仅仅是P控制的话,会产生下面将提到的offset (稳态误差),所以一般加上积分控制(I),以消除稳态误差。 比例带与比例控制(P)输出的关系如图所示。用MVp运算式的设定举例: 稳态误差(Off set) 比例控制中,经过一定时间后误差稳定在一定值时,此时的误差叫做稳态误差(off set)。 仅用比例控制的时候,根据负载的变动及设备的固有特性不同,会出现不同的稳态误差。 负载特性与控制特性曲线的交点和设定值不一致是产生稳态误差的原因。 比例带小时不会产生。为消除稳态误差,我们设定手动复位值--manual reset值(MR),以消除控制误差。 手动复位(Manual reset) 如前所述,仅用比例控制不能消除稳态误差。 为此,将MR(manual reset值)设为可变,则可自由整定(即调整)调节器的输出。 只要手动操作输出相当于offset的量,就能与目标值一致。 这就叫做手动复位(manual reset),通常比例调节器上配有此功能。 在实际的自动控制中,每次发生off set时以手动进行reset的话,这样并不实用。 在后面将叙述的积分控制功能,能自动消除稳态误差。 所谓积分控制(I),就是在出现稳态误差时自动的改变输出量,使其与手动复位动作的输出量相同,达到消除稳态误差的目的。 当系统存在误差时,进行积分控制,根据积分时间的大小调节器的输出会以一定的速度变化,只要误差还存在,就会不断的进行输出。 积分时间的定义:  当积分项和比例项对于控制器的输出的贡献相同,即积分作用重复了一次比例作用时所花费的时间,就是积分时间。 微分控制(D)的功能是通过误差的变化率预报误差信号的未来变化趋势。通过提供超前控制作用,微分控制能使被控过程趋于稳定。 因此,它经常用来抵消积分控制产生的不稳定趋势。 微分时间的定义:  当输入量持续的以一定速率变化时,微分项和比例项对于控制器的输出的贡献相同,即微分作用重复了一次比例作用时所花费的时间,就是微分时间。 实际中如何使用 我们看一个生活例子,冬天洗热水澡,需要先放掉一段时间的冷水,因为水管里有一段冷水,热水器也需要一个加热过程,等过了这段时间之后水温有些接近目标值后,开始调节水龙头来调节冷、热水之间的比例及出水量,之后再慢慢的微调,在洗浴过程中感觉温度不合适,再一点点的调节。这个过程,其实就是PID算法过程。我们之所以微调,是因为水温的变化速度与我调节的速度不相匹配,存在一个滞后效应,我们需要调节一点点,等一下再感觉一下温度,不够再调节一点点,再感觉,这个过程就叫PID算法,也可以说,滞后效应是引入PID的原因。 失去的能否找回来?能、只是我找回了纽扣,却发现衣服已经不再了。这个就是滞后效应。 负反馈系统,都有滞后效应,但为什么运放、电源这类的却从来不提PID算法呢?这是因为这类系统的滞后延时时间非常短,若考虑这个延时,负反馈引入180度相位,延时恰好引入180度相位,则完全可能引起振荡。问题在于这个延时时间足够短,它的谐振频率点比较高,以运放为例,加入延时加上负反馈引起的谐振点为10MHz,但这片运放的频率响应是1MHz,则在10MHz下完全不可能导致振荡,因为这个芯片的频响特性只有1MHz。我们常用的线性电源IC,比如SOT23封装的LDO,假如输出不加电容,就会输出一个振荡的波形,相对来说电源IC的滞后效应比运放要大,但是,因为电源一般后面都要接大电容的,它的频响特性很低,接近直流0Hz,所以当有电容时候,就无法振荡了。 而工业控制领域,比如温度等,都是滞后效应很严重的,往往都是mS,甚至是10mS级别的,若直接用负反馈,因为激励与反馈的不同步,必然导致强烈的振荡,所以为了解决这个问题,我们需要引入PID算法,来实现这类滞后效应严重系统的负反馈控制,我们以高频感应加热设备加热工件,从常温25度加热到700度为例做说明: 1、25~600度,100%的全功率加热工件,这是因为温差太大,前期要全功率,先加热到靠近目标温度。之所以考虑在600度,是因为滞后效应,若设定太高,当发现接近700度再停下来,但实际上,温度会冲过700度。当然,600度是一个经验值,以下几个温度点都是经验值,根据实际情况而来。 2、600以上,开启P算法,P就是根据测量值与目标值的误差来决定负反馈的大小。P算法公式:反馈=P*(当前温度-目标温度)。但因为负反馈是基于存在误差为前提的,所以P算法导致一个问题,永远到不了想要的值:700度。因为到了700度,反馈值就没有了。P算法的开启,进一步逼近了目标温度,假设稳态下可以达到650度,这样就算因为滞后效应导致的延时,也不会超过700度太多。 3、当达到P算法的稳态极限650度附近的时候,比如640度,就应该开启另外一个算法解决P算法引起的极限误差,那就是I算法。I算法就是为了消除这个P算法导致的误差值,毕竟我们想要的是700度,而不是650度。I算法,本质上讲就是获取一个700度下对应的一个驱动值,之后用这个驱动值来取代P算法,那么我们怎么得到这个驱动值呢,唯一的手段就是把之前的误差都累加起来,最后得到一个期望值,这个期望值就是我们想要的驱动值。因为只要与目标值存在误差,那么把这些误差值积累起来再去反馈控制,就能一步步的逼近目标值,这如同水温不够高,再加一点点热水,不够高再加,这样总能达到想要的水温。值得注意的是,I算法不能接入太高,必须要在P算法的后期介入,不然很容易积累过大。这个时候可以引入一个误差门限,比如误差为60,当作6来处理,误差为50,当作5来处理,消除大的误差值,具体根据项目情况决定。 4、当I算法把工件温度加热到很接近目标温度后,那么可以调节的范围就很小了,最后一点点的微动,让调节的每一次的变化,不要太大,这就是D算法。D算法本质上讲就是反对剧烈的变化,所以适用于达到目标温度的时候。 PID算法其实不复杂,但从目前看,很多人都是因为对这三者的使用条件不了解导致的问题,都是从加热一开始,三个要素都上,结果可想而知。P算法是温度接近目标值的时候用,I算法是在P算法到稳态极限的时候用,D算法是达到目标值附近的时候用。实际项目中,D算法一般不用,效果不大。假如非要找一个现实中对应的实物,那么以开关电源为例,TL431基准电源比较器可以认为是P,输出滤波电容C是I,输出滤波电感是D,两者完全等价。它们各自的应用工作点可以认为:假设目标温度700度,600~800度:P算法;640~760度:I算法;690~710度:D算法。具体值,以实验为准,数据仅供参考。 最后给出一个PID最通俗的解读:我们设计一样东西,一般都是先打个样,这个样跟我们想要的接近,但细节没到位,这就是P,样有差异,所以就要修改,拟合逼近,这就是I,到了定稿,就不允许随便修改了,就算要修改,也是有限制的修改,这就是D。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    时间:2020-11-24 关键词: 算法 PID

  • 都说C语言的精髓是指针,但是指针太难懂了,怎么办?

    素材直接来源:大鱼机器人 说到指针,估计还是有很多小伙伴都还是云里雾里的,有点“知其然,而不知其所以然”。但是,不得不说,学了指针,C语言才能算是入门了。指针是C语言的「精华」,可以说,对对指针的掌握程度,「直接决定」了你C语言的编程能力。 在讲指针之前,我们先来了解下变量在「内存」中是如何存放的。 在程序中定义一个变量,那么在程序编译的过程中,系统会根据你定义变量的类型来分配「相应尺寸」的内存空间。那么如果要使用这个变量,只需要用变量名去访问即可。 通过变量名来访问变量,是一种「相对安全」的方式。因为只有你定义了它,你才能够访问相应的变量。这就是对内存的基本认知。但是,如果光知道这一点的话,其实你还是不知道内存是如何存放变量的,因为底层是如何工作的,你依旧不清楚。 那么如果要继续深究的话,你就需要把变量在内存中真正的样子是什么搞清楚。内存的最小索引单元是1字节,那么你其实可以把内存比作一个超级大的「字符型数组」。在上一节我们讲过,数组是有下标的,我们是通过数组名和下标来访问数组中的元素。那么内存也是一样,只不过我们给它起了个新名字:地址。每个地址可以存放「1字节」的数据,所以如果我们需要定义一个整型变量,就需要占据4个内存单元。 那么,看到这里你可能就明白了:其实在程序运行的过程中,完全不需要变量名的参与。变量名只是方便我们进行代码的编写和阅读,只有程序员和编译器知道这个东西的存在。而编译器还知道具体的变量名对应的「内存地址」,这个是我们不知道的,因此编译器就像一个桥梁。当读取某一个变量的时候,编译器就会找到变量名所对应的地址,读取对应的值。 初识指针和指针变量 那么我们现在就来切入正题,指针是个什么东西呢? 所谓指针,就是内存地址(下文简称地址)。C语言中设立了专门的「指针变量」来存储指针,和「普通变量」不一样的是,指针变量存储的是「地址」。 定义指针 指针变量也有类型,实际上取决于地址指向的值的类型。那么如何定义指针变量呢: 很简单:类型名* 指针变量名 char* pa;//定义一个字符变量的指针,名称为paint* pb;//定义一个整型变量的指针,名称为pbfloat* pc;//定义一个浮点型变量的指针,名称为pc 注意,指针变量一定要和指向的变量的类型一样,不然类型不同可能在内存中所占的位置不同,如果定义错了就可能导致出错。 取地址运算符和取值运算符 获取某个变量的地址,使用取地址运算符&,如: char* pa = &a;int* pb = &f; 如果反过来,你要访问指针变量指向的数据,那么你就要使用取值运算符*,如: printf("%c, %d\n", *pa, *pb); 这里你可能发现,定义指针的时候也使用了*,这里属于符号的「重用」,也就是说这种符号在不同的地方就有不同的用意:在定义的时候表示「定义一个指针变量」,在其他的时候则用来「获取指针变量指向的变量的值」。 直接通过变量名来访问变量的值称之为直接访问,通过指针这样的形式访问称之为间接访问,因此取值运算符有时候也成为「间接运算符」。 比如: //Example 01//代码来源于网络,非个人原创#include int main(void){    char a = 'f';    int f = 123;    char* pa = &a;    int* pf = &f;        printf("a = %c\n", *pa);    printf("f = %d\n", *pf);        *pa = 'c';    *pf += 1;        printf("now, a = %c\n", *pa);    printf("now, f = %d\n", *pf);        printf("sizeof pa = %d\n", sizeof(pa));    printf("sizeof pf = %d\n", sizeof(pf));        printf("the addr of a is: %p\n", pa);    printf("the addr of f is: %p\n", pf);        return 0;} 程序实现如下: //Consequence 01a = ff = 123now, a = cnow, f = 124sizeof pa = 4sizeof pf = 4the addr of a is: 00EFF97Fthe addr of f is: 00EFF970 避免访问未初始化的指针 void f(){    int* a;    *a = 10;} 像这样的代码是十分危险的。因为指针a到底指向哪里,我们不知道。就和访问未初始化的普通变量一样,会返回一个「随机值」。但是如果是在指针里面,那么就有可能覆盖到「其他的内存区域」,甚至可能是系统正在使用的「关键区域」,十分危险。不过这种情况,系统一般会驳回程序的运行,此时程序会被「中止」并「报错」。要是万一中奖的话,覆盖到一个合法的地址,那么接下来的赋值就会导致一些有用的数据被「莫名其妙地修改」,这样的bug是十分不好排查的,因此使用指针的时候一定要注意初始化。 指针和数组 有些读者可能会有些奇怪,指针和数组又有什么关系?这俩货明明八竿子打不着井水不犯河水。别着急,接着往下看,你的观点有可能会改变。 数组的地址 我们刚刚说了,指针实际上就是变量在「内存中的地址」,那么如果有细心的小伙伴就可能会想到,像数组这样的一大摞变量的集合,它的地址是啥呢? 我们知道,从标准输入流中读取一个值到变量中,用的是scanf函数,一般貌似在后面都要加上&,这个其实就是我们刚刚说的「取地址运算符」。如果你存储的位置是指针变量的话,那就不需要。 //Example 02int main(void){    int a;    int* p = &a;        printf("请输入一个整数:");    scanf("%d", &a);//此处需要&    printf("a = %d\n", a);        printf("请再输入一个整数:");    scanf("%d", p);//此处不需要&    printf("a = %d\n", a);        return 0;} 程序运行如下: //Consequence 02请输入一个整数:1a = 1请再输入一个整数:2a = 2 在普通变量读取的时候,程序需要知道这个变量在内存中的地址,因此需要&来取地址完成这个任务。而对于指针变量来说,本身就是「另外一个」普通变量的「地址信息」,因此直接给出指针的值就可以了。 试想一下,我们在使用scanf函数的时候,是不是也有不需要使用&的时候?就是在读取「字符串」的时候: //Example 03#include int main(void){    char url[100];    url[99] = '\0';    printf("请输入TechZone的域名:");    scanf("%s", url);//此处也不用&    printf("你输入的域名是:%s\n", url);    return 0;} 程序执行如下: //Consequence 03请输入TechZone的域名:www.techzone.ltd你输入的域名是:www.techzone.ltd 因此很好推理:数组名其实就是一个「地址信息」,实际上就是数组「第一个元素的地址」。咱们试试把第一个元素的地址和数组的地址做个对比就知道了: //Example 03 V2#include int main(void){    char url[100];    printf("请输入TechZone的域名:");    url[99] = '\0';    scanf("%s", url);    printf("你输入的域名是:%s\n", url);    printf("url的地址为:%p\n", url);    printf("url[0]的地址为:%p\n", &url[0]);    if (url == &url[0])    {        printf("两者一致!");    }    else    {        printf("两者不一致!");    }    return 0;} 程序运行结果为: //Comsequense 03 V2请输入TechZone的域名:www.techzone.ltd你输入的域名是:www.techzone.ltdurl的地址为:0063F804url[0]的地址为:0063F804两者一致! 这么看,应该是实锤了。那么数组后面的元素也就是依次往后放置,有兴趣的也可以自己写代码尝试把它们输出看看。 指向数组的指针 刚刚我们验证了数组的地址就是数组第一个元素的地址。那么指向数组的指针自然也就有两种定义的方法: ...char* p;//方法1p = a;//方法2p = &a[0]; 指针的运算 当指针指向数组元素的时候,可以对指针变量进行「加减」运算,+n表示指向p指针所指向的元素的「下n个元素」,-n表示指向p指针所指向的元素的「上n个元素」。并不是将地址加1。 如: //Example 04#include int main(void){    int a[] = { 1,2,3,4,5 };    int* p = a;    printf("*p = %d, *(p+1) = %d, *(p+2) = %d\n", *p, *(p + 1), *(p + 2));    printf("*p -> %p, *(p+1) -> %p, *(p+2) -> %p\n", p, p + 1, p + 2);    return 0;} 执行结果如下: //Consequence 04*p = 1, *(p+1) = 2, *(p+2) = 3*p -> 00AFF838, *(p+1) -> 00AFF83C, *(p+2) -> 00AFF840 有的小伙伴可能会想,编译器是怎么知道访问下一个元素而不是地址直接加1呢? 其实就在我们定义指针变量的时候,就已经告诉编译器了。如果我们定义的是整型数组的指针,那么指针加1,实际上就是加上一个sizeof(int)的距离。相对于标准的下标访问,使用指针来间接访问数组元素的方法叫做指针法。 其实使用指针法来访问数组的元素,不一定需要定义一个指向数组的单独的指针变量,因为数组名自身就是指向数组「第一个元素」的指针,因此指针法可以直接作用于数组名: ...printf("p -> %p, p+1 -> %p, p+2 -> %p\n", a, a+1, a+2);printf("a = %d, a+1 = %d, a+2 = %d", *a, *(a+1), *(a+2));... 执行结果如下: p -> 00AFF838, p+1 -> 00AFF83C, p+2 -> 00AFF840b = 1, b+1 = 2, b+2 = 3 现在你是不是感觉,数组和指针有点像了呢?不过笔者先提醒,数组和指针虽然非常像,但是绝对「不是」一种东西。 甚至你还可以直接用指针来定义字符串,然后用下标法来读取每一个元素: //Example 05//代码来源于网络#include #include int main(void){    char* str = "I love TechZone!";    int i, length;        length = strlen(str);        for (i = 0; i 

    时间:2020-11-24 关键词: C语言 嵌入式

首页  上一页  1 2 3 4 5 6 7 8 9 10 下一页 尾页
发布文章