• 嵌入式开发中需要用到设计模式吗?

    嵌入式开发中需要用到设计模式吗?

    工作有些年了,每每看到一些朋友会问,设计模式需要学吗?好像做嵌入式的从没遇到过需要用设计模式的,所以一直没系统学习,但是我也知道这个很重要,久而久之,到头来还是没学。 这里我说一下自己的看法和思考,来看看一些问题。 什么是设计模式? 设计模式是代表了开发人员不断积累的最佳的实践,是软件开发人员在软件开发过程中面临的一般问题的最优解决方案。 也就是说,经过了不断的发展,不同的问题或者方案有对应的一套法子,而这个法子被总结成了这么几十种通用模式,我们如果遇到了就对应着去套用就可以了。 当然那几大开发原则和二十几种设计模式大家还是随便去找都可以找到说明的,笔者就不多说了(我也只用到了其中几种),大家自行学习为好。 开发中为什么很少用设计模式? 在平时项目开发中,我们很少使用设计模式,我感觉这个现象还是很正常的,不是说工作中没用到设计模式,而是大多数情况下我们项目中没想那么多,更多的是做一些需求更改,而忽略本质。 设计模式的目的是提供可拓展性和可维护性,但是我们开发的项目本身,大部分都是固定写死的,逻辑单一,我们开发的模块也并不在其他的位置或项目中复用,目的很明确就是做当前的业务。 平时开发中用到设计模式的地方很少,但是框架就不同的了,框架必须适应不同的项目,具备高弹性和拓展性。他们要能适应各种不同的环境,所以,设计模式在框架设计中处处可见。 假如一开始在大公司或者接手一个接近成熟的项目时,那大概率会负责一些小模块或者细分领域的开发;而在小公司或者是几乎从零开始做项目的时候,可能我们本身还不够去设计一个符合项目长期规划的架构,最终导致写的代码比较乱,维护性差。 所以在嵌入式开发中,当我们有了一定的基础和项目经验的时候,我们就会想着,嗯,一个好的架构多么重要啊,或者我需要去好好学一下设计模式了。 嵌入式开发一定要学设计模式吗 ? 可以这么说,设计模式为拓展而生。 平时项目中的业务逻辑代码,大部分功能是死的,是专为这个场景而生的,不会在另外的场景中出现,这种业务的开发,是不需要设计模式的。 但是如果需求有变化,我们一般可能就直接修改源代码了,这样实际上带来了一定的修改成本,而为了一个项目中可能不明确的未来变化,而精心设计扩展性很高的架构,成本也是显而易见的,所以,这是一个取舍。 当然,从长期来看,一个好的设计是值得的,毕竟与其不断的修改新的需求,还不如一劳永逸,这样开发人员才能从各个方面高效去开发了。 在嵌入式软件开发中,当软件系统到达一定的复杂程度时,设计模式就显得尤为重要。虽然搞嵌入式的常常是基于一些16位/32位/64位单片机开发,而且这些可能受一些硬件方面的限制,但是单片机软件也是可以遵循软件工程的基本原则来进行架构的。 从代码组织的角度比如组件化、分层、去耦等等,或者从设计角度比如基于消息队列、事件驱动等等,都是有因可循的。 所以对于这个问题,嵌入式开发最好是要学设计模式,这里鼓励大家多看看重构、设计模式、面向对象的C等方面的书籍。 设计模式该怎么学? 前面说了那么多,设计模式是什么,嵌入式中哪里用到了设计模式,设计模式到底需不需要学等等,好,那你告诉我到底怎么学! 这里我想分一些情况来说,关于这个问题,设计模式怎么学习,得看你的程度、你主要解决什么问题、你负责的部分而定。 若你的编程水平或者学习的程度还没到那(还在学习怎么编程阶段),看了自然是懵逼的,这个时候还是好好补补基础知识,这些还用不到。 若在项目当中,你解决的大部分是一些业务逻辑,这种情况能用的设计模式不多,因为需要的是业务模式,也就是参考设计模式原理,自己设计业务模式改改需求啥的,就没必要了。 若你负责或参与应用框架或与其相关,那帮助就大了,这个时候用什么设计模式,怎么去设计就要考验功底了。 当然,不管怎么说,只要有时间即使是你目前程度还不到,你也可以学习设计模式使自己提升程度,但得一步一步来,稳中进步。 这个学习也不是一次性把所有的都学习了,这样其实也很难掌握,可能只是知其表而已,一般先从某个与你要处理的问题相关或者常会遇到的模式开始学起,一次学一个,学的深一些。 大部分人最常提的是单例、工厂、策略这几个,比如一个功能,要求既要支持串口通信,又要支持TCP通信,而对调用方来说最好不要知道它们的区别,这就是典型的策略模式场景。 这种比较常见的情况,很多项目中都可能遇到,因此不可能不学,网上也有很多经验分享,还有很多教程例子,这个时候也不可能学不会。 总结 到此,你觉得设计模式有没有用? 每个人的情况不同,学习过程不一定是这样,做的工作内容肯定也不一样,关键点是只要你在这行,在写代码,那么一般一定用得到其中几个模式,等你学会几个,并且常用,时间久了自然就明白了。

    嵌入式ARM 嵌入式 设计模式

  • 有一个傻X导师是种怎样的体验?

    有一个傻X的导师是种怎样的体验?1100+224万网友评论 作者:匿名用户 我多少也是保研的,选导师怎么就瞎了眼选了这个狗屁傻逼。 昨天仔细读了一下学院的毕业要求,发现ei会议检索也可以毕业,我就自己写了一篇打算投出去。这个逼就开始diss我,说我净投这些没用的。放屁!什么叫没用?我可以用来毕业怎么就没用了? 对你可能是没用的,因为这些不算你晋升的条件。你都快五十岁的人了,还是副教授,你想晋升你就自己写论文啊!还能指望学生带你发SCI啊?研一的时候我确实想发SCI,可是经过两年的痛苦,现在只想顺利毕业。我自己写的论文自己找的期刊投出去,到你这就没用了。真鸡儿好笑。感想你,成功的浇灭了我科研的热情,让我明白了别人都靠不上,只能靠自己。 他自己的博士是在职读的,成果都是别人带的,自己连SCI都没写过,成天就让我发SCI。我写完了给他看,他一眼都不看就让我投,还不说投哪个期刊,全程都是我上网看期刊评价改格式,投两个都被拒了,他看审稿意见让我改,也不说怎么改,因为他也不知道应该怎么改。 整天催我发论文,可是你踏马告诉我论文怎么写?没有项目没有经费,实验做不了,实验室没有帮手,我就靠一个旧的笔记本就能发出来SCI?跑个仿真程序电脑都要卡死了。 这三年没有给过我一分钱补助,我没有跟着他出过一次差,只有第一年因为保研得了奖学金。平时给你不少好吃的,你给我们什么了?除了冷嘲热讽阴阳怪气,无穷无尽的压力。找工作的时候参加面试,你竟然放屁:成天参加没用的,最后一个公司都不去。那我就要问你了,你告诉我怎么样在不投简历不面试的情况下选一个最好的工作? 最近跟他透露了几次要毕不了业了要延期了,希望他给我点建议,这个逼可到好,他说延毕就延毕呗,多大点事啊? 放你妈了个屁,我延毕对你有好处?每年你的学生都要靠运气才能保证不延毕,每年都差点毕不了业,你没想想你的原因吗?你到现在也没有告诉我怎么毕业,似乎你一点都不关心我。 还说就应该逼我们,逼我们三天也能写出论文了。qnmlgb,你以为杂志社是我家开的吗?我投论文第二天就有结果?哪个期刊不得两三个月才出结果?这期间除了等待也没别的办法。 人家导师打个招呼论文就中了,你呢? 你能干什么?除了每天瞎bb不会别的。也没见你自己写过什么论文。哦对了,去年学院考核你任务量没达标被院长骂了,不知道你害不害臊。整天摸鱼,不求上进,还总是push我,你做到表率了吗? 现在我每天吃不下饭睡不着觉,头发一把一把掉,马上就要抑郁了 ,你每天嘻嘻哈哈跟别人聊天,一点都不着急呢。 有此回答为证,我要是延毕了,一定剁了你个狗日的。sct,呸! 作者:匿名用户 如果某天我得绝症了,我会向大家征集傻逼导师的信息,我带他们一起上路。 作者:晴空烈酒 帮一个孩子贴回答 有个傻逼导师的情况是这样的,论文批改结果永远只有“改,重写,不对”这样的字眼,怎么改,为什么不对,该怎么写只有鬼知道 就是没实习的时候催着你实习,工作以后催着你回学校 就是说好周末见面,请好假调好工了,又告诉你没空,不见了 就是大大晚上打电话突突突机关枪一样说你态度有问题,不积极,全盘否定你曾经做过的努力 就是让你在上班的时候请假回学校交报告,然后他自己不在学校,在家里 这已经不是傻逼的问题了 这是缺德 作者:匿名用户 不到四十正教授,进组之前各种好说话,超级温柔,让我感觉我遇到了世界上最好的导师。进组之后发现这简直是我这辈子最大的错觉。讲讲三个最受不了的点: 1. 什么都不会还爱bb,从来没有学术上的指导,全是大话空话。张口不离态度努力。 2. 不在意学生是否进步了学到了东西,只要能给他做出项目就行。 还没正式入学,就被拉进组做横向。(好吧,就当提前适应研究生生活了也没什么)我进组第一周自己看看论文,自己学学Python被说是浪费时间(一个dl的项目,我不学Python怎么做)。我啥都不会又没人教还不让我自己学了?你是就想要那种刚进组就啥都会,能直接给你两周做完一个项目的学生?那你还是去招博士后吧别招硕士了。 3. 经常拿之前退学的学生来恐吓 「之前的那几个退学的学生都是和你一样噢,我替你感到不安啊!」 自己的学生退学了你还挺自豪? 只能怪自己进组之前了解的太少。多向前辈问问也许就不会掉进坑了。 作者:匿名用户 导师傻逼不是你说傻逼就傻逼的,所有人都认为他傻逼那才是真的傻逼,很幸运我的导师就是这样的一个人~ 当年钦佩他的才华,听过他的讲座,且是我们学校引进的教授~我特么好不容易获得一个保研资格便义无反顾的选了他~ 首先,傻逼体现在他感人的情商,他一来便与系主任有矛盾,这也罢,最主要的是他还要在上课的时候、与别的老师谈话的时候说系主任坏话,生怕别人不知道他与系主任有矛盾~只一段时间,当别的老师提到他无一不皱眉、撇嘴、翻白眼~p.s之所以离开之前那个学科排名全国第一的学校就是因为把人得罪完了,混不下去才来的我们城市~ 其二,他的生活乱七八糟~离过三四次婚,他自己一人来我们的城市,从不按时吃饭睡觉,也不管别人,因为性骚扰之前的助手而闹翻,所有事情都让我干~没有时间观念,没有礼貌~想什么时候打电话就什么时候打 其三,超级吝啬,从不给我们发钱,每次我们和他吃饭都是我们掏钱,经常让我们给他买饭买水果、、寄快递,买书啥的都不给钱,我给他报账还猜忌我们渗钱 其四,脾气火爆,干什么都急的要死,一件没给他干好就把你之前的努力否定~神经质~莫名其妙的就炸了~ 其五,自以为是,想要的多实干的少,到处挣钱无心学术,申个国基金,基本都是我写的~要写一本书,写了三万字没写完,其中我写了两万多字~ 。。。。。 所以说,选导师这种事情一定要跟别的老师同学商量一下~大家都说了不咋地的导师一定不咋地~我现在只求快点上完硕士~结束了我惨痛的研究生生涯~ 作者:匿名用户 我硕士3年和博士4年都跟的是一个导师,最后在他的单位工作了一年不到,辞职走了,每每看到这样的话题都忍不住想出来说两句,但是又觉得可能涉及到一些黑幕,说出来怕被和谐,但是如果不说的话,我觉得还会不停的有人上当受骗,所以还是的说一说。 我是一名普通的医学生 读书比其他行业的大学生要略多几年 现在在一家地区三甲医院工作 随着工作时间的增加 却越来越觉得身心俱疲 甚至开始觉得抑郁  开始服用抗抑郁药物 身边的亲人 朋友 都觉得不可思议  也不外乎这样的劝解:“学历这么高,工作也挺好,有什么原因让你这么压抑呢?” 确实,在普通人看来,医生这个职业,确实是体制内较为稳定的工作之一,有知识,有地位,收入也不算太低,但什么原因让我如此压抑呢?我不禁一次次问自己,突然一天清晨惊醒后,我突然意识到原来过去的7—8年时光,在我生命里留下了不可磨灭的痕迹, 写下这篇文章,可能会有很多不为人知的潜规则暴露在公众面前,但正如手术一样,没有创伤,也无法治愈疾病,希望随着时间的推移,无数的潜规则能够暴露在阳光下,让医疗这个行业,也让现行的硕博士培养制度,在改革的浪潮中,变得更为公正、阳光、民主,让弱者的声音,不再软弱无力。 (文中涉及的真实人名和地名等,均以化名代替) 现行的导师制度——权力下的半剥削制度 我本科就读于沿海城市T市的一所二流医院院,毕业后因为各种原因,决定回到家乡所在的N省继续深造,作为一名什么刚刚背完很多医学书的小白,对于研究生生涯是非常憧憬的,想象中的研究生生活,有和蔼的导师,友善的师兄,融洽的同门,大家一起为患者谋福利,为医学发展而奋斗,每每想到这样的场景,总是会信心满满,在考研之前,对于如何选择一所不是本校的导师,着实需要做很多功课,也需要一定的运气,官网也好,能获取到的资料也好,都只是一小部分,更多的需要的是打听,但就算如此,也无法完全了解一个导师是否适合自己,也无法知道自己是否适合导师,就像古时娶亲,不到掀开盖头那一刻,永远不知道对方的模样。 在回到C市之前,做了很多准备,也被官网上导师的资料所吸引,著名专家、博导、院长等等一大堆头衔,对于一个对于医学有无限憧憬的小白来说,这无疑是十分令人向往的,到了面试的那天,一起参加面试的几个学生先是一起被安排到了行政楼7楼的一间会议室,开始复试,复试的体量非常大,英语部分直接就是一篇外文全文的文献,两个小时的时间对于参加硕士面试的小白是不可能完成的,正在困惑时,监考的人(后来才知道是博士的一个师兄)说:不要急,写不写得完和录取不录取你们没有任何关系…… 到面试的环节,院长秘书上到楼上来按顺序把考生一个个叫到楼下的院长办公室,由于我是笔试第一,第一个喊得就是我,于是我跟着秘书来到了办公室门口的一个凳子上坐下,让我等着,一会儿便出来了一个叼着烟的女人(后来知道是副院长),叼着烟的一个戴眼镜的男人(看样子才知道是导师本人),几个人边抽烟,边骂骂咧咧的说着某个人的事,很随意的开始提问:老家哪里的,父母干嘛的,喜欢什么运动……最后问了一个唯一与学术相关的问题:英语过了几级,然后便安排我回到了楼上继续考试。我靠,难道面试不用自我介绍?不用英文?不问专业相关问题?考完试之后问了问一起考试的几个人,都是这种情况,瞬间对这个导师以及这家医院的印象大打折扣,但也决定先去读了再说。 2008年,医学类硕士大部分都是科学学位,专业学位刚刚开始试点,但医学类的研究生大部分时间都会在医院跟着导师从事临床工作,积累临床经验,所以一开学就被叫到了科室跟着值班,导师大部分时间都是搞行政的,只有大手术才会亲自上一下,但后来发生的一些事,逐渐的颠覆了我对整个医院的理解。这里先简单列举一下一些奇葩事,如果大家有兴趣再详细讲述。 1、去到医院不久,因为要找导师签字,刚想给他打电话,便被身边的博士师兄呵止,说不能直接给导师打电话,要先给他的秘书打电话,然后预约,才能去找他。 2、刚进科室第二天,看到科室里一个师兄在背英语单词,便问他研究生生涯应该注意些什么,结果他的回答是:不要对这个地方抱有任何幻想,这些狗日的太坏了。 3、后来听说各种奇闻异事,大概是说导师原本是另一家省级医院的副院长,因为好色,和科室的一个护士发生了不正当关系,被原配师娘(也是同一个单位的某科室护士长)到科室打了护士一顿,闹得沸沸扬扬,不得已才调到了同城的另一家市级三甲医院。 4、在中央反"四风“之前,每次开学术会,凡是有省外的专家过来参会,必定是安排研究生全程陪同,有一次导师请专家吃饭,席间酒不够,于是便打电话给秘书,秘书安排我和另一个同学坐着医院的救护车,去给他们送酒,酒放下,导师大手一挥,你们走吧。我靠,寒冬腊月,8点多,他们吃的正欢,我们还饿着肚子。 5、手术台上脾气极差,涵养极差,某次手术过程中,负责准备的师兄没有理解他的意图,在准备时少做了某个步骤,在手术间破口大骂:我X你妈……然后各种包含人体器官的词汇喷涌而出,我们在手术间外面吓得不敢进去。 6、自己从来没有写过一篇文章,没有申请过一个课题,全都是拉关系、送礼拿到的科研基金,下面的学生有些也喜闻乐见,做课题时玩命的报假账,据说有个师兄做完课题买了辆车。 7、某次参加评选某个城市的人才奖,由于要网上投票,便告诉我们这些学生不用去上班了,在家给他投票,连上一次网,一个IP投10票。 8、作风及其败坏,来到市级医院没多久便看上了ICU的一个美小护,就找借口把她调到了身边当某个系统的管理员,当时美小护已经结了婚,老公也是医院行政的一个职工,结果没多久就离婚了,导师也和原配师娘离了婚,然后和美小护结了婚,于是我们得喊一个中专毕业、比导师小20岁,仅仅比我们大一两岁(有的师兄甚至比她年长)的人:师娘。然后师娘的原配被从党政办公室,调到了保卫科——看大门…… 9、临近研究生毕业,想考到北上广读个博士,也趁机摆脱这个环境,没想到二导专门把我叫到办公室,讲了个故事:某个师兄,人勤奋,学习也棒,业务也精,在硕士毕业的时候没有知会导师,便直接报考了上海一所一流大学的博士,由于博士都需要推荐信,如果硕士老板原因联系相熟的导师,几率会更大,于是师兄便去找了导师,结果导师沉默不语,也不写推荐信,结果师兄因为推荐信的关系,笔试第一的成绩最后也没有被录取,由于当时各个学校的博士招生有时间差,师兄便回到了本校继续报考导师的博士,顺利进到了面试,结果……被撸了,而且一撸,就是三年,三年连续报考,都被自己的导师给否了,直到第四年,只有他一个人进面试,才被录取。后来才知道,报考除他以外的博士,就是看不起他,原话是:不忠诚的人,不要。考博士和忠不忠诚,有多大关系,难道是洪兴?进了可以,想出来只有死了才可以?于是,为了不被整死,又不想耽误自己的时间,我也只能报考他的博士,后来发生的事更加印证了我知道的,由于延期毕业的学生太多,被学校停止招生,期间毕业的师弟,凡是去找他说想考博士的,得到的都是沉默甚至是当面谩骂。 10、作为导师,很重要的一项工作就是指导研究生的研究工作和论文撰写,我在那里8年,两次毕业,两本毕业论文,导师一个字都没有看过,更甚至由于硕士论文被抽到了外送盲审,需要他审阅后签字才可以邮寄,送个他说明情况后,一个周后去找他,他告诉我:论文我找不到了,你重新给我送一本来,于是我默默的自己签了字邮寄出去了。 11、每次答辩,导师都要请很多省外的专家来,头些年这部分来回机票和食宿费用都由医院买单,后来纪委说这样操作违规,于是便由答辩秘书找参加答辩的学生收费用,我博士毕业后的第一年,充当答辩秘书,导师交待我,博士收一万,硕士收5000,等答辩结束后由我拿信封装好答辩费用和来回机票的费用给专家,等我拿到机票一看,基本都是头等舱,而且某个专家期间还改签了四五次,住宿都是在五星级酒店,房费大概1400多一晚,期间导师还和这些专家在酒店吃了个自助餐,人均599,这些费用最后都有参加答辩的学生支付,虽然对于已经工作的人也不是一大笔钱,但是有的师弟家是农村的,这样的费用,且不论数额大学,我真的觉得很过分。 12、教师节,没到教师节,便会有已经在导师单位工作的师兄组织,大家凑份子给导师送礼,一般博士1000,硕士500,一开始还会去买一些礼品,有一年组织的师兄去买了菲拉格慕的皮鞋和领带,据说他扔在办公室从来没看过,于是后来便直接送钱了,2万多的信封,夹在贺卡里,直接递过去,导师打开摸了摸厚度,没有任何推测或者觉得不妥,就直接交给秘书了。 13、腐败问题,据我所知,每个月都要从师兄当主任的科室,拿走一部分经济收入,作为给他的“孝敬费”,而在那家医院,光师兄当主任的科室,就有至少两个。还有一些他的表弟、亲戚,都在医院的车队或者后勤工作,和小师娘关系好的护士,都变成了护士长。背后有什么交易,不得而知。医院进门就有一排院领导专用车位,其中有两辆路虎是他的专车,据说都是别人借他使用的。抽的烟全都是1000块以上一条的,喝的茶都是一千多一包的竹叶青,小师娘还开了个福特野马,招摇进出医院,听说他和原配师娘的女儿在美国读书,至于这些钱从哪里来,不得而知。 14、媚上嘴脸极为恶心,每当有卫生系统或者其他官员来检查,必定要求所有的学生和医护两边分站,列队欢迎,曾有有一位级别很高的领导来医院做手术,直接要求学生和职工24小时不间断守着这位领导(后来出并发症死了),这也罢了,毕竟是70岁的老人。后来另一位领导的女婿(他本人是另一家医院的医生,30多岁)来我们医院手术,居然又让我和另一个师兄24小时不间断守着他,还排了护士做特护。 15、学术造假,因为是被从省级医院扫地出门的,于是便想尽各种办法出名,做各种不符合指征、但可以造成轰动效应的手术,一次一个工程师要做手术,本来一种简单的术式可以完成,但为了完成他的大计,便让我和博士师兄篡改病历,使病历上看符合复杂手术指征,可惜最后手术失败,患者死了,患者妻子没多久服毒自杀了。每次有上级来检查,我们做的事就是疯狂的改数据、改病历。 16、喜欢各种浮夸大场面,之前监管不严的时候,组织全院外科系统吃年饭,美其名曰团拜会,其实都是各个科室自己出钱去包席,上千人一起吃饭,然后他便可以站在台上享受君临天下的假象。学生去敬酒,挂在嘴边的一句话就是:谁喝得多就重点培养谁。对于我这种不会喝酒的,自然也就不去凑热闹了。 写到这里,我觉得还有很多没有说完,但有些涉及到行业内幕,有些涉及到具体人名,不便再说出来,但是我离开那里4年,不断地听说有人离开,甚至有的师兄主任辞职去出家,有的副院长辞职走人,我想,一家单位的繁荣,离不开能人,更离不开良好的氛围,一个离开的人比进去的人多的单位,量你再通过各种国内国际认证,终究是粉饰太平,骗人骗己罢了。

    嵌入式ARM 硕士 导师 SCI

  • 三极管的工作原理书上都讲不清楚,为什么能被制造出来?

    我还是那个观点,一定要站在发明者的角度来看问题,只有这样,一切问题才都能迎刃而解。因为模电的内容就是发明---使用---发现问题---改进---再发明—再使用的过程,是我们学习前人发明和使用的东西。 我们就以二极管和三极管为例,二极管是控制导线中电子的流动方向,而三极管是控制导线中流动电子的多少。这也是“电子技术”的根本。理论搞明白了实验就简单了。 下面主要是以三极管为例来说明导线中电流的控制。 我们都非常熟悉家用手电筒电路,手电筒电路中有“三要素”,即电源VCC、灯泡L(或者说负载Rc)、 开关K,如下图所示。 现在,我们不想用手动方式去实现开关K的合上以及断开,我们想用一个信号去控制一个器件来实现电路的“通和断”。 要想控制一根导线中的电流,首先要把这根导线断开,断开的两端我们分别叫做C端和E端(C和E实际上是输出回路的两端)。 如果我们在C和E之间加个器件,这个器件如果能使电流从C端流进并能从E端流出来(因为C和E本来就是我断开的一个回路的两端),同时这个电流又能被我们加的信号所控制住,那么这个器件就成功了。(一定要注意,我们要实现什么目标,我们要控制一个电回路的通和断) 为了实现上述要求,接下来我们就在C-E之间放一个NPN(或PNP)结构的半导体,可是,现在的问题是,在这种情况下无论怎样在C和E之间加电源 (不击穿情况下)  ,C-E这根导线始终都不会有电流(其实这种情况下,C-E之间是有穿透电流的(它是由少子引起的),因其非常小,这里忽略不计,这也是半导体材料存在的缺点。实际上,我们不希望它存在)。 我们又知道,电子流动的方向与人们定义电流的方向相反(这是因为当时人们以为电线里流过的是电流),所以,我们将中间半导体引出一个电极(B极)。 在B-E之间(实际上是加在发射结上,见PN结特性)加一个正向电压,这时发射区就会向基区发射电子从而形成E极流出的电流Ie,但是,要想实现这个电流是从C端入、从E端出,则必须要把发射区发射的这些电子都收集到C极去,这样我们需要在C和E之间加正向电压,使集电结处于反向击穿状态,使电子能顺利收集到C极,这个收集电子的能力要比发射电子的能力强,它就像一个大口袋,你发射区发射多少我就收多少(这样就能理解三极管输出特性曲线了,当B极电流一定时,随着CE电压的增加,C极电流就不再增加了,因为B极电流一定时,发射区发射的电子数量就一定了,你收集的能力再强也要不到多余的电子了),这样,这个器件就成了,可以实现电流从C端到E端(因为当初我假设它们之间是被我断开的导线两端),最理想的是流进C端的电流就等于E端流出的电流,同时这个电流又被一个BE电压(或信号)控制,但是,三极管不是一个理想的器件,因为C端电流不等于E端电流,有一部分电流流过B极,我们尽量使C端电流等于E端电流,所以,这就是为什么在工艺上要使基区浓度要低而且还要薄,同时集电结的面积还要大的根本原因。 谈一谈Ic受Ib控制的问题: 通过前面的叙述,我们已经知道发射极电流Ie受发射结电压控制,由于我们采取了工艺上的措施,使得集电极电流Ic近似等于发射极电流Ie,这样就可以说集电极电流Ic受发射结电压控制。我们又从三极管输入特性曲线可知,当Vbe和Ib的关系处于特性曲线的近似直线的位置时,基极电流Ib与发射结电压就成线性关系,这样,可以说集电极电流Ic与基极电流Ib就成比例关系。往往我们会站在不同角度来看问题,我们从电流放大的角度来看时,刚才说过集电极电流Ic比基极电流Ib大很多,同时它们又成比例关系,因此,在进行计算的时候就说成是集电极电流Ic受基极电流Ib控制。这其实是人们站的角度不同而已(从电流放大的角度来看的),其实,集电极电流Ic还是由发射结电压控制的,等到了高频小信号模型的时候,就会说集电极电流受发射结电压控制了。 Uce电压的作用是收集电子的,它的大小不能决定Ic的大小,从三极管输出特性曲线可以看到,当Ib一定时(也就是Ube一定时),即使Uce增加,Ic就不变了,但是,由于半导体中有少子存在,使得输出特性曲线随着Uce增加而有些上翘,其实这是半导体材料存在的问题。实际上,Ie是受从输入端看进去的发射结电压控制的(可以参见三极管高频小信号模型),加Uce电压的时候发射结已经处于导通了,它的影响不在发射结而在集电结,加Uce电压是为了让Ic基本等于Ie,所以说Ic受发射结电压控制,人们为了计算方便把这种控制折算成受Ib控制,就是因为说成这样,使得人们不太容易理解三极管工作的原理。从输出回路受输入回路信号控制的角度来看,Ic不是由Ie控制的,但是,Ic其实是由Ie带来的,所以,也可以说Ic受Ie影响的,这也得受三极管制造工艺影响,如果拿两个背靠背二极管的话,怎么也不行。 尽管三极管不是一个理想器件,但是,它的发明已经是具有划时代意义了。由于它的B极还有少量电流,因为这个电流的存在意味着输入回路有耗能,如果我不耗能就能控制住你输出回路的电流,那这个便宜就大了,所以,后来人们发明了场效应管。其实,发明场效应管的思想也是与三极管一样的,就是为了用一个电压来控制导线中的电流,只是这回输入回路几乎不耗能了,同时,器件两端的电流相等了。 从使用者的角度(非设计者)来看看三极管的应用: 三极管的两个基本应用分别是“可控开关”和“信号的线性放大”。 可控开关:C和E之间相当于一个可控开关(当然。这个开关有一定的参数要求),当B-E之间没有加电压时,C-E之间截止(C-E之间断开);而当B-E之间电压加的很大,发射区发射的电子数量就多,C极和E极的电流就很大,如果输出回路中有负载时(注意,输出回路没有负载CE之间就不会饱和),由于输出回路的电源电压绝大部分都加到负载上了,CE之间的电压就会很小,CE之间就处于饱和状态,CE之间相当于短路。在饱和情况下,尽管C极电流比基极电流大,但是,C极电流与输入回路的电流(基极电流)不成β的比例关系。 以最简单的电路为例,我们家里都有手电筒,手电筒有三个要素(具有普遍意义):电源、灯泡(负载)和开关,这里的开关需要直接手动进行合上与断开,用三极管代替这个开关我们就能实现用信号来控制,计算机在远端就能控制这个回路。控制高压、大电流的还请大家看看IGBT等功率芯片及模块,那是真震撼。 从另一方面看饱和:从输出特性曲线可以看到,IB一定时VCE电压不用很大,那个输出特性曲线就弯曲变平了,这说明收集电子的电压VCE不用很大就行,其实不到1V就行,但是,实际上我们在输出回路都是加一个电压很大的电源,你再加大VCE也没有用,我们看到,IB一定时VCE增加后对IC的大小没有影响(理想情况),所以要想把发射的电子收集过去,VCE根本不用很大电压。 但是,通常情况下,我们会在输出回路加入一个负载,当负载两端电压小于电源电压时,电源电压的其它部分就加在CE两端,此时三极管处于线性放大状态。但是,负载两端电压的理论值大于电源电压时,则三极管就处于饱和状态,这种情况IC不用很大也行。 所以不要以为VCE一定很大三极管集电极才能收集到电子,可以看到收集电子的电压很小就行。从电压角度来看,集电极电流不一定很大,在选择合适负载电阻的情况下,三极管也可以处于饱和状态,所以,饱和与负载有关,如果电源电压很大,那饱和时VCE就这么一点点电压而言那当然是微不足道的,所以,很多地方就将它约等于零了,但是并不能说它没有电子收集能力。 信号的线性放大:这种情况下,C极电流与B极电流成线性比例关系IC=βIB(BE之间电压要大于死区电压,同时,VCE不趋于零),而且,C极电流比B极电流大很多,前面已经知道,C极电流的大小受BE电压控制(人们为了分析问题方便,将这种控制关系说成是C极电流受B极电流控制)。实际上,马路上到处跑的汽车就是一个放大器,它是把驾驶员操作信号给放大了,它也是线性放大,是能量的放大,而多余的能量来自于燃烧的汽油。 模电这门课从三极管小信号模型开始的绝大多数内容都是讲小信号放大问题,共射极、共集电极、共基极的4个电路是基本,其它的是由他们组合而成的,它们的电路组成、电路交直流分析、电路性能分析是关键。 其它的就是功率放大的问题、模拟集成运算放大器内部结构设计问题、运放的应用、如何减少非线性失真和放大稳定问题(负反馈)、正弦波产生(正反馈)等等。 模电从细节和总体上把握。 模电的学习: 从使用者的角度来看,其实,模电这门课并不难,学生往往被书中提到的所谓少子、多子、飘移、扩散等次要问题所迷惑,没有抓住主要问题,有些问题是半导体材料本身存在缺陷导致的,人们为了克服这些缺陷而想出了各种解决办法,所以,模电中有许多是人们想出的技巧和主意。从三极管三个电极连接的都是金属的角度来看,金属中只有自由电子的定向流动才有电流,金属中哪有什么空穴之类的东西,如果把人们的视线停留在三极管的内部,那一定使人们不容易理解,如果你跳出来看问题,你就会理解科学家当时为什么要发明它,也会使你豁然开朗。但是,从设计者角度来看,需要考虑的问题就很多了,否则,你设计出来的器件性能就没有人家设计的好,当然也就没有市场了。如果谁能找到一种材料,而这种材料的性能比半导体特性还好,那么他一定会被全世界所敬仰。所以,学习模电的时候,一定要用工程思维来考虑问题,比如,为什么要发明它?它有什么用途?它可以解决什么问题?它有哪些不足?人们是如何改进的?等等。 再谈可控开关: 三极管要工作在饱和或截止状态,此时C和E之间相当于可控开关,B极加输入信号,为了防止三极管损坏,B极要接限流电阻,余下的问题就是,所控制的负载应接在C极还是E极?它的功率有多大?驱动电压多大?电流多大?你选的三极管能否胜任?不胜任怎么办?改用什么器件?低压和高压如何隔离?等等。 再谈信号的线性放大: 这种情况下,C极电流是B极电流的β倍,以三极管放大电路为例: (1)直流工作点问题,为什么要有直流工作点?什么原因引起工作点不稳定?采取什么措施稳定直流工作点? 为什么要有直流工作点?是因为PN结只有外加0.5V以上电压时才有电流通过(硅材料),而我们要放大的微弱的交变信号幅度很小,将这个微弱的变化信号直接加到三极管的基极和射极之间,基极是没有电流的,当然,集电极也不可能有电流。所以,我们在基极首先要加上直流工作电流后,三极管三个电极就都有直流电流了, 以NPN管子为例,共射、共基、共集电极三个电路的直流都是一个方向,无论三极管电路的哪种接法,它们的直流电流方向都是一样的,在这基础上,再在输入端(发射结)加入微弱交流小信号后,这个微弱信号就会使基极电流产生扰动,由于集电极电流与基极电流成比例关系,则集电极电流(输出回路电流)也会发生扰动,这样,这个输出回路电流中就有被输入交流信号影响的扰动信号,我们要的就是输出回路这个被基极扰动电流控制的集电极扰动的信号(输出交流信号),这个输出回路(集电极-发射极)扰动的信号比输入(基极)扰动信号大,这就是放大,也可以说,放大其实是输出回路电流受输入信号的控制。但是,不管怎样扰动,总体上是不能改变三个电极电流的方向的。 如果直流工作点设置合理时,那个扰动信号就与输入交流小信号成比例关系,而且又比输入信号大,我们要的就是这个效果。 (2)交流信号放大问题,共射极、共集电极、共基极电路的作用、优点和缺点是什么?如何克服电路的非线性?为什么共射--共基电路能扩展频带?为什么共集电极放大电路要放在多级放大电路的最后一级?多级放大电路的输入级有什么要求?人们在集成电路中设计电流源的目的是什么?它的作用是什么?如何克服直接耦合带来的零点漂移?为什么要设计成深负反馈?其优点和问题是什么?深负反馈自激的原因是什么?什么是电路的结构性相移?什么是电路的附加相移?什么情况下电路输出信号与输入信号之间出现附加相移?等等。 (3)集成运算放大器,为了克服半导体器件的非线性问题(不同幅度信号的放大倍数不一样),人们有意制成了高增益的集成运算放大器,外接两个电阻就构成了同相或反向比例放大电路,这时整个电路的电压放大倍数就近似与半导体特性无关了(深负反馈条件下),放大倍数只与外接的两个电阻有关,而电阻材料的温度特性比半导体材料好,同时线性特性也改善了。在计算的时候注意运用“虚短”和“虚断”就行了,模电学到这里那就太简单了,所以,如果不考虑成本时谁还会用三极管分立元件组成的放大电路,还得调直流工作点。集成运算放大器的其它应用还很多,如有源滤波器、信号产生电路等。 负反馈自激振荡与正弦波产生电路的区别 负反馈自激振荡是由于某个未知频率信号在反馈环路中产生了额外的180度的附加相移,负反馈电路对这个频率信号来讲就变成了正反馈,同时,对这个频率信号的环路增益又大于1,这种情况下,负反馈电路就自激了(对其它频率信号,此电路还是负反馈)。而正弦波振荡电路是人们有意引入的正反馈,可以说对无数个频率信号都是正反馈,既然这样,环路中就不用有附加相移了,但是,这样的信号太多了,所以,人们需要在反馈环路中设计一个选频电路来选择某一个频率信号,当然,对被选取的信号来讲,这个选频电路就不需要有额外相移了。 以上大致总结了一些问题,仅供参考。 为了从全局了解这门课,以及更容易学好这门课,建议参见我主页上我写的文章“模拟电子技术基础课程新的目录”,希望对大家有帮助。 来源|作者:知乎|李泽光 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    玩转嵌入式 工作原理 三极管

  • 如何获取整数的各个字节

    题目:获取0x12345678各个字节。 方法一:结构&联合 #include typedef unsigned int uint32_t; typedef unsigned char uint8_t; union bit32_data { uint32_t data; struct { uint8_t byte0; uint8_t byte1; uint8_t byte2; uint8_t byte3;     }byte; }; int main(void) { union bit32_data num;          num.data = 0x12345678; printf("byte0 = 0x%x\n", num.byte.byte0); printf("byte1 = 0x%x\n", num.byte.byte1); printf("byte2 = 0x%x\n", num.byte.byte2); printf("byte3 = 0x%x\n", num.byte.byte3); return 0; } 运行结果: 这种方法的缺点是:会受到大小端的影响。只有在明确大小端的情况下可稍微用一用。以上是小端模式下的运行结果。 结构&联合法不仅仅是在获取数据各个字节有用,在数据协议、数据位拆分等方面很实用,之后再做更详细的分享。 方法二:移位操作 #include #define GET_LOW_BYTE0(x) ((x >>  0) & 0x000000ff) /* 获取第0个字节 */ #define GET_LOW_BYTE1(x) ((x >>  8) & 0x000000ff) /* 获取第1个字节 */ #define GET_LOW_BYTE2(x) ((x >> 16) & 0x000000ff) /* 获取第2个字节 */ #define GET_LOW_BYTE3(x) ((x >> 24) & 0x000000ff) /* 获取第3个字节 */ int main(void) { unsigned int a = 0x12345678; printf("byte0 = 0x%x\n", GET_LOW_BYTE0(a)); printf("byte1 = 0x%x\n", GET_LOW_BYTE1(a)); printf("byte2 = 0x%x\n", GET_LOW_BYTE2(a)); printf("byte3 = 0x%x\n", GET_LOW_BYTE3(a)); return 0; } 运行结果: 这也是获取数据各个字节的最常用也最有效的方法。这种类似的位操作在嵌入式方面应用得很多,比如在LCD操作中表示像素颜色值、FLASH的操作等方面都有用到。位操作推荐文章: 《C语言位域(位段)详解》 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    玩转嵌入式 字节 整数 移位操作

  • 使用VSCode编译Keil工程

    VSCode全称Visual Studio Code,是微软推出的一款轻量级的代码编辑器,免费且功能强大。支持各种插件,支持几乎所有的主流程序语言的语法高亮、代码自动补全、括号匹配等。 Keil是一款优秀的编辑和编译一体的嵌入式开发软件,但其编辑器的功能一直比较弱,被众多用户所诟病。本篇文章将介绍使用VSCode来代替Keil实现单片机程序的编辑和编译。 首先要安装Keil和VSCode软件。安装过程不详细介绍。 安装完成后打开VSCode,安装两个插件,首先安装C/C++插件。然后安装Keil Assistant,该助手会在Keil的工程目录新建一个.vscode的文件夹,并添加相关文件,使工程能被VSCode软件所识别。 安装完成后点击设置,在Extension Settings菜单下,设置Keil安装路径。 (这里是设置Keil MDK,如果是Keil C51,设置在上面)。 设置完成后直接打开Keil的工程文件即可。 打开后就可以体验VSCode强大的编辑器功能了,比Keil本身的要好用多了。 将鼠标放在工程目录上,可以看到编译、下载的图标: 编译、下载与Keil中的一样,因为它就是调用的Keil的编译器和下载驱动。 不足的地方就是该插件只支持编译和下载,不支持在线调试,不太完善。 还有另外一种方式可以完全摆脱Keil,使用VSCode编写单片机程序。 需要安装gcc、OpenOCD等多个插件,配置也比较复杂,感兴趣的朋友可以自己探索一下。

    玩转嵌入式 Keil VSCode

  • PCB板上可以走100A的电流吗?大电流路径设置技巧

    通常的PCB设计电流都不会超过10 A,甚至5 A。尤其是在家用、消费级电子中,通常PCB上持续的工作电流不会超过2 A。但是最近要给公司的产品设计动力走线,持续电流能达到80 A左右,考虑瞬时电流以及为整个系统留下余量,动力走线的持续电流应该能够承受100 A以上。 那么问题就来了,怎么样的PCB才能承受住100 A的电流? 方法1:PCB上走线 要弄清楚PCB的过流能力,我们首先从PCB结构下手。以双层PCB为例,这种电路板通常是三层式结构:铜皮、板材、铜皮。铜皮也就是PCB中电流、信号要通过的路径。根据中学物理知识可以知道一个物体的电阻与材料、横截面积、长度有关。由于我们的电流是在铜皮上走,所以电阻率是固定的。横截面积可以看作铜皮的厚度,也就是PCB加工选项中的铜厚。通常铜厚以OZ来表示,1 OZ的铜厚换算过来就是35 um,2 OZ是70 um,依此类推。那么可以很轻易地得出结论:在PCB上要通过大电流时,布线就要又短又粗,同时PCB的铜厚越厚越好。 实际在工程上,对于布线的长度没有一个严格的标准。工程上通常会用:铜厚/温升/线径,这三个指标来衡量PCB板的载流能力。 以下两个表可以参考: 从表中可以大约知道1 OZ铜厚的电路板,在10°温升时,100 mil (2.5 mm) 宽度的导线能够通过4.5 A的电流。并且随着宽度的增加,PCB载流能力并不是严格按照线性增加,而是增加幅度慢慢减小,这也是和实际工程里的情况一致。如果提高温升,导线的载流能力也能够得到提高。 通过这两个表,能得到的PCB布线经验是:增加铜厚、加宽线径、提高PCB散热能够增强PCB的载流能力。 那么如果我要走100 A的电流,我可以选择4 OZ的铜厚,走线宽度设置为15 mm,双面走线,并且增加散热装置,降低PCB的温升,提高稳定性。 方法2:接线柱 除了在PCB上走线之外,还可以采用接线柱的方式走线。 在PCB上或产品外壳上固定几个能够耐受100 A的接线柱如:表贴螺母、PCB接线端子、铜柱等。然后采用铜鼻子等接线端子将能承受100 A的导线接到接线柱上。这样大电流就可以通过导线来走。 方法3:定做铜排 甚至,还可以定做铜排。使用铜排来走大电流是工业上常见的做法,例如变压器,服务器机柜等应用都是用铜排来走大电流。 附铜排载流能力表: 方法4:特殊工艺 另外还有一些比较特殊的PCB工艺,国内不一定能找得到加工的厂家。英飞凌就有一种PCB,采用3 层铜层设计,顶层和底层是信号布线层,中间层是厚度为1.5 mm的铜层,专门用于布置电源,这种PCB可以轻易做到小体积过流100 A以上。 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    玩转嵌入式 PCB 大电流

  • 设计模式_工厂方法模式_C语言实现

    简介 我们接简单工厂方法模式_C语言实现中生产电脑的模拟场景来看。 在简单工厂方法中,不同供应商的硬盘都由HardDiskFactory创建出来。这种做法存在几个问题: 1、当供应商很多时,HardDiskFactory就会成为一个“过大类” 2、假设现在要新引入一家硬盘供应商,那就需要在HardDiskFactory的Create方法中增加一个case分支。在Create方法中增加case分支的做法违反了“开闭原则”。 我们现在要讲的“工厂方法”可以解决上述问题: 工厂方法针对每一个供应商的硬盘提供一个工厂。通过不同工厂对象来创建不同的产品对象。也就是说,工厂方法不直接定义用于创建对象的类,而是定义一个创建硬盘对象的接口,让子类决定实例化哪一个供应商的硬盘。 当新增一个硬盘供应商时,只需要新增一个工厂对象。不需要在原有工厂中增加代码,所以不违反“开闭原则”,也不会因为不断增加供应商而产生“过大类”。 硬盘对象创建 参与者 1、Product: HardDisk 定义硬盘对象的接口(与简单工厂方法相同) 2、Concrete Product: SeagateHardDisk, ToshibaHardDisk 实现不同供应商的硬盘(与简单工厂方法相同) 3、Factory: HardDiskFactory 声明硬盘工厂方法,具体硬盘对象的创建交给其子类 ConcreteFactory 4、ConcreteFactory: SeagateHardDiskFactory, ToshibaHardDiskFactory 创建具体硬盘对象 UML HardDisk、SeagateHardDisk、ToshibaHardDisk示例代码与简单工厂方法完全一致,此处不再重复 HardDiskFactory代码示例: hard_disk_factory.h: #include "seagate_hard_disk_factory.h" #include "seagate_hard_disk.h" #include "stdio.h" #include "stdlib.h" struct HardDisk* SeagateCreate(struct HardDiskFactory *this) { struct SeagateHardDisk *seagateHardDisk = NULL; if ((seagateHardDisk = malloc(sizeof(struct SeagateHardDisk))) == NULL) { printf("fail in malloc\n"); return NULL;     }     SeagateHardDisk(seagateHardDisk); return (struct HardDisk*)seagateHardDisk; } void SeagateDestroy(struct HardDiskFactory *this, struct HardDisk *hardDisk) { if (hardDisk != NULL) { free(hardDisk);         hardDisk = NULL;     }     } // 构造函数 void SeagateHardDiskFactory(struct SeagateHardDiskFactory *this) { this->hardDiskFactory.Create = SeagateCreate; this->hardDiskFactory.Destroy = SeagateDestroy; } // 析构函数 void _SeagateHardDiskFactory(struct SeagateHardDiskFactory *this) { this->hardDiskFactory.Create = NULL; this->hardDiskFactory.Destroy = NULL; } ToshibaHardDiskFactory代码示例: toshiba_hard_disk_factory.h: #include "hard_disk.h" #include "hard_disk_factory.h" #include "seagate_hard_disk_factory.h" #include "toshiba_hard_disk_factory.h" #include "stddef.h" void main() { struct HardDisk *hardDisk = NULL; struct HardDiskFactory *hardDiskFactory; struct SeagateHardDiskFactory seagateHardDiskFactory; SeagateHardDiskFactory(&seagateHardDiskFactory);     hardDiskFactory = (struct HardDiskFactory *)&seagateHardDiskFactory; // 创建 seagate 硬盘对象 hardDisk = hardDiskFactory->Create(hardDiskFactory); // 使用 seagate 硬盘对象 hardDisk->Operation(hardDisk); // 销毁 seagate 硬盘对象 hardDiskFactory->Destroy(hardDiskFactory, hardDisk);     _SeagateHardDiskFactory(&seagateHardDiskFactory); struct ToshibaHardDiskFactory toshibaHardDiskFactory; ToshibaHardDiskFactory(&toshibaHardDiskFactory);     hardDiskFactory = (struct HardDiskFactory *)&toshibaHardDiskFactory; // 创建 toshiba 硬盘对象 hardDisk = hardDiskFactory->Create(hardDiskFactory); // 使用 seagate 硬盘对象 hardDisk->Operation(hardDisk); // 销毁 toshiba 硬盘对象 hardDiskFactory->Destroy(hardDiskFactory, hardDisk);     _ToshibaHardDiskFactory(&toshibaHardDiskFactory); } 客户端显示示例:

    嵌入式大杂烩 C语言 工厂方法 设计模式

  • 学习单片机必须要知道的字节小知识

    很二很二的单片机  单片机比较二,啥都不认识,只认识0和1,即所谓的“二进制”,由于把0和1认到了极致,所以单片机能用0和1干许多事情。人在看二进制数据时,比较麻烦。比如二进制110 0100,不能一眼看出是十进制100,这无疑降低了效率。为了提高效率,人类发明了很多单位,比如bit、Byte、KB、MB等。 今天的文章很简单,但是很重要。但是把简单的事情做到极致,人人都可以是单片机。 什么是bit位 二进制只有0和1两个状态,非此即彼,其中的任意一个状态就是一个bit位。bit位是数据存储的最小单位。一个bit有0和1两种状态;两个bit就有00、01、10和11四个状态;以此类推,三个bit就有000-111等八个状态,这个规律符合2^n。所以计算机能表示很多种状态。 单片机都有位数之分,比如STM8S为8位单片机,表示一次最多能处理8位数据;STM32F103为32位单片机,一次最多可以处理32位数据。 什么是字节Byte 数据比较多时,二进制看起来比较麻烦。八个bit位的数据构成一个字节Byte,所以一个字节有8位,即

    玩转嵌入式 单片机

  • STM32 RTC及定时闹钟功能实现

    对于学习过51单片机的同学来说,一般使用RTC功能,一般都会使用51单片机+DS1302的方案,在STM32单片机中,因为STM32单片机自带RTC模块,所以我们只需要使用一个STM32即可,不需要外挂实时时钟芯片了。 RTC实时时钟简介 "RTC"是Real Time Clock 的简称,意为实时时钟。 STM32提供了一个秒中断源和一个闹钟中断源,修改计数器的值可以重新设置系统当前的时间和日期。 STM32的RTC外设,实质是一个掉电后还能继续运行的定时器,通过配置,可以让它准确地每秒钟中断一次。 所谓掉电,是指电源VDD断开的情况下,为了RTC外设掉电可以继续运行,必须给STM32芯片通过VBAT引脚接上外部3.3V供电。 当主电源VDD有效时,由VDD给RTC外设供电。 当VDD掉电后,由VBAT给RTC外设供电。 无论由什么电源供电,RTC中的数据始终都保存在属于RTC的备份域中,如果主电源和VBAT都掉电,那么备份域中保存的所有数据都将丢失。(备份域除了RTC模块的寄存器,还有42个16位的寄存器可以在VDD掉电的情况下保存用户程序的数据,系统复位或电源复位时,这些数据也不会被复位)。 上图来自于《STM32中文参考手册》 备份寄存器是42个16位的寄存器,可用来存储84个字节的用户应用程序数据。他们处在备份域里,当VDD电源被切断,他们仍然由VBAT维持供电,数据不会丢失,所以我们可以使用这些寄存器预存一些运行状态信息。 比如我们可以在RTC初始化之后,对BKP_DR1寄存器写入一个值,比如0x5050,然后在 RTC_Init(void)函数开始处,先读取并判断BKP_DR1寄存器的值是否为0x5050,进而可以知道系统的RTC是否有VBAT外部电源维持供电。 STM32时钟系统 参考《STM32中文参考手册》中对STM32的时钟系统的详细说明。 RTC的时钟源可以来源于3个渠道: 来自于低速外部时钟LSE,也就是外部的晶振,一般选用32.768KHz 来自于高速外部时钟HSE的128分频,即HSE/128 来自于低速内部时钟LSI 使用HSE分频时钟或者LSI的时候,在主电源VDD掉电的情况下,这两个时钟来源都会受到影响,因此没法保证RTC正常工作(在有自动校准功能并对时钟的精度要求不是很高的情况下,还是可以使用HSE分频时钟作为RTC时钟的),所以RTC一般都选用低速外部时钟LSE,晶振的频率为实时时钟模块中常用的32.768KHz,因为32768 = 2^15,分频容易实现1秒的时钟频率,所以被广泛应用到RTC模块。 在配置RTC模块的时钟时,把输入的32768Hz的RTCCLK进行32768分频得到实际驱动计数器的时钟TR_CLK = RTCCLK/37768 = 1Hz,计时周期为1秒,计时器在TR_CLK的驱动下计数,即每秒计数器RTC_CNT的值加1。 RTC时间设置 RTC时间设置就是对RTC计数器寄存器RTC_CNT进行设置。 该寄存器由两个16位的寄存器RTC_CNTH和RTC_CNTL组成,总共32位,用来记录秒钟值。 理论上可以计算2^32 = 4,294,967,296‬ s,大约136年。 所以设置RTC时间或者获取RTC时间,就是设置RTC_CNT寄存器或者获取RTC_CNT寄存器的值。 所以封装的设置时钟的函数RTC_Set(),就是求得设定的时间与1970年1月1日 00:00:00之间的秒数,然后通过RTC_SetCounter()函数,写入RTC_CNT寄存器即可。 注意: 每次操作RTC_CNT时应该要使能PWR 和 BKP 时钟,允许访问BKP域,否则会操作失败。 /* Enable PWR and BKP clocks*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* Allow access to BKP Domain */PWR_BackupAccessCmd(ENABLE); /* Wait until last write operation on RTC registers has finished*/RTC_WaitForLastTask();/* 修改当前RTC计数寄存器内容 */RTC_SetCounter(Cnt);/* Wait until last write operation on RTC registers has finished*/RTC_WaitForLastTask(); RTC闹钟 在实际应用中,我们有时会用到定时闹钟功能,我们简单的可以在main函数的while循环中,通过比对当前时间和设定时间值是否相等进行判断是否定时时间到,比如: //主循环 while(1) { times++; if(t!=calendar.sec) { t=calendar.sec; NowHour = calendar.hour; NowMinute = calendar.min; NowSecond = calendar.sec; if(NowHour==AlarmHour&&NowMinute==AlarmMinute&&NowSecond==AlarmSecond) { //执行预定动作 } } } 除了上面的方法外,我们还可以使用RTC的闹钟中断来实现。 使能RTC_IT_ALR中断,并设置闹钟时间: 闹钟中断响应 在主电源VDD有效的情况下(待机),RTC还可以配置闹钟事件使STM32退出待机模式。 结果展示 RTC_Init(void)函数中,设置初始化时间如下: 程序会在串口助手中,每秒钟输出一条时间信息,40S后执行一次闹钟中断。 STM32串口发送数据和接收数据方式总结! STM32配置SPI通讯功能 还在敲代码? 来看看如何自动生成"状态机"代码 SPI怎么玩?搞懂时序,运用自如 什么是DMA? STM32如何配置DMA? STM32基础分析——PWM配置 STM32单片机:独立看门狗、窗口看门狗的配置 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    玩转嵌入式 STM32 51单片机

  • 标准化模块接口--统一消息

    点击上方「嵌入式大杂烩」,选择「置顶公众号」第一时间查看嵌入式笔记! 链接:https://www.cnblogs.com/hhao020/p/5018951.html 本来今晚想写如何搞动态加载和动态补丁的,但很不幸,翻遍了硬盘,也没找到以前的代码,连网盘里都没备份。这时候,才焕然大悟--半年前我换上现在的笔记本,淘汰了那台老掉牙的台式机。 所幸硬盘没丢,不过一时时也没法读里面的数据了。等过些日子,读出里面的数据再谈动态加载和动态补丁技术。今天说些简单的,能在软件设计中立即用得上的,模块间通信技术--统一消息。 统一消息模型,最早的启发是UT的Wacos SSI。那是一个很不错的通信模型,允许模块间的通信统一成队列通信;而在物理上,模块可能位于各种网络中的不同的实体,又或者是不同的进程,线程。 记得那会调试核心网的程序,在板卡上是没有什么调试环境的,除了WindShell(同CSHELL)外,就没什么支撑了。 于是我们就把软件用GDB加载到目标机(无盘工作站),然后开始测试。有人不理解了,这没啥啊!现实是这价值很大,大型系统的嵌入式开发,能争取到的机房空间、设备和板卡总是奇缺,就当时的情况来说,我们三四个人才能分到一套设备。 Wacos_SSI的队列通信技术,让我们可以把目标机做成功能板块,且只需要极少量的修改,就能和实际系统的主控板进行通讯联测,工作效率的提升自不待言。 再后来,哥在Nortel的时候知道了TIPC协议,好象是E///和IBM捣腾出来的东西。思路上,和Wacos SSI很接近。所不同的是,Wacos SSI在消息头里使用了IP地址,而TIPC则是自定义的节点地址,也因此包含了一个额外的节点地址和特定网络间的地址翻译过程。 另外一个区别是,Wacos SSI考虑了远程节点间通信和本地通信的差别,只有远程通信时才传递消息实体,而本地则是传递标识(Handle)来快速完成。TIPC则没讲述这个层次的程序设计问题,也因此在工程实践中应用寥寥。 现如今,UT没了,Nortel也没了。特别是UT,十多年过去了,哥特别怀念那段日子,和我的那个团队。无奈,哥就是灾星,跟喜欢的公司相克。很多局外人都说UT不咋的,就一个做小灵通的;可哥的眼里,那的许多软件开发团队,战斗力一点不比Huawei差。 就说哥做的网关城域交换机,才十来个人,而huawei是几十人,好几倍啊,最后市场表现还是平分秋色。当然,我还是蛮佩服huawei的,他们的东西真心做的漂亮,维护界面人性化,不像我们的,很多事情要命令行来实现。不过我们也有特点,就是架构做的非常好,以至于客户的需求,总是能很快实现,而且基本上对现有功能是0风险。呵呵,据说气死不少人! 这当中,有三大功臣: Wacos SSI; 状态机; 数据驱动模型。 状态机的代码,已经在昨晚的内存泄漏里的链接里提供了,有兴趣可以下载或是用在喜欢的地方,哥只希望它有更多机会发挥价值。 嗯,Wacos SSI排在第一!是的,Wacos SSI的消息通信让我们的系统变得非常柔性,模块与模块间几乎没有什么复杂的耦合。想想现在那些公司招聘需求里,要求什么多任务多线程编程能力,精通什么信号量和同步技术,哥就想哭,这就是我们的软件水平,时刻准备着处在玩死自己。 哥做程序,只考虑CPU有几个线程核,至于系统有几个进程线程,都是这个决定的,而且合并拆解任务,都是分分钟能改代码实现的事。 跟哥一起做软件,就只要记住几点:无论你和谁通信,你只要知道他的地址,然后发消息给他就好了;而你也只要看着自己的队列,有消息就干活,没消息就歇着。 至于发消息,就一个标准的函数,而消息封装格式,也是统一的。至于系统函数库里提供的什么信号量,管道啥的,千万别尝试在应用里面使用,否则,编译器会用编译错误来告诉你行不通。 有点扯远了,回到正题。 统一消息的定义,包含两个部分,消息标签和消息头,具体如下: typedef struct _MSG_TAG_TYPE_{zAddr_t srcAddr;zAddr_t dstAddr;zHandle_t msgHandle;} PACKED zMsg_t;typedef struct _MSG_HEAD_TYPE_{byte_t sysrsvd[8]; //reserved for adding src & dst addresses on network. word_t msgLen;word_t msgId; dword_t srcInst;dword_t dstInst;} PACKED zMsgHdr_t;typedef struct _MSG_HEAD_EX_TYPE_{zAddr_t srcAddr;zAddr_t dstAddr; word_t msgLen;word_t msgId; dword_t srcInst;dword_t dstInst;byte_t msgBuf[1];} PACKED zMsgHdrEx_t; zMsg_t结构是消息标签,应用程序收、发消息时,都是收发的这个数据结构,如下: int zMsgSend(zMsg_t *msg); 通常来说,我们应该把这个消息标签做的比较小,因为做的太大,来回复制它的内容是需要耗费CPU时间的。比如,你可以将zAddr_t定义成word,zHandle_t定义成dword,这样只需要8字节就够了。不过记得字节对齐,一般来说,要保证长度是4的倍数。 消息头就是消息内容的头部格式段,除了这个头部,剩下的就是应用自定义的payload部分。zMsgHdr_t和zMsgHdrEx_t实质上是一样的。这里面的地址部分,不是必须的,只有当消息透过网络或是总线传递时,才是必须的,否则没法由边界模块还原。而对于应用,如无特别约定,那几个字节是无意义且内容不确定的。 消息标签和消息间是通过msgHandle关联。这样,当消息在本地传递时,msgHandle指向的是一块普通内存;而当消息在本地进程间通信时,则指向共享内存;至于网络或是某个总线传递,边界模块负责本地内存数据和网络数据间的转换。如此一来,最大程度的减少实际消息体的拷贝开销,让消息传递变得高效,且细节处理对应用透明。 Wacos SSI的地址部分,填的是IP地址;当然,它还定义了一个模块号来配合这个地址使用。整个通信过程很简单,应用只需要申请一个队列,并告知SSI,这个队列和哪个目的模块号使用。 正常情况下,这个做法都能满足需求,但碰上程序模块重新规划或是特俗测试目的,就有点力不从心了。因此,哥在zMsg_t标签里彻底放弃了IP+module的地址组成,改为TIPC的地址方式。不过这也就让系统必须维护一个路由表,用来完成特定目的地址到队列的映射。 统一消息路由表定义如下: typedef struct Z_UDP_ADDR_TYPE{dword_t ip;word_t port;} zUDPAddr_t;typedef struct Z_MSGQ_ADDR_TYPE{void *qid;} zQueAddr_t;typedef struct Z_MSGQ_OUT_TYPE{zAddr_t addr; zUDPAddr_t udpAddr;zQueAddr_t queAddr; } zMsgRoute_t; 路由表项里首先是地址,对应的是消息的目的地址。接下来是网络地址和队列地址,可以有一个或是都有。 仅队列地址:说明是本地(或者是需要经隐形边界代理转发)的消息,目的地址为队列所有者; 仅网络地址:说明是远程消息,且应该直接网络发送,无需经过边界代理,目的地址为远端模块地址; 含两类地址:远程消息,应用发送时通过队列地址送入边界模块,再通过网络地址发送,,目的地址为远端模块地址。 总上面的关系可以看出,队列和地址间的关系是一对多的关系,即多个地址的消息可能被投送到同一个队列。 这就让模块合并变得异常容易,当然,不安规则出牌的模块什么时候什么方法都白搭。通常来说,如果有IP网络的通信要求,系统就需要创建一个基础的网络边界模块。 这个模块本身可能并不需要地址,而只需要提供一个消息聚合的队列。当然,在一个开放的网络环境下,这个边界模块可能还需要做些安全性的工作,比如过滤非法消息等,这可以通过在模块内额外配置源IP地址,端口或是源目的地址等实现。 如果远端并不支持zMsg_t工作,则这时候的边界模块就需要做好消息的翻译过程,为远端模块分配映射模块地址。当然,这些都是本地的,不属于路由表内容。 从地址映射到真实的目的队列或是网络地址,是个频繁的操作,设计上必须要非常高效。对于地址非常少的系统,比如总共才七八个模块,可以用一个紧凑的数据来做,简单且不妨碍效率。但对于有数十或是上百个地址的系统来说,遍历方法就不可取了。这时应该用二分搜索,或是平衡二叉树。 比如城域交换机,有十来块子功能卡,每张卡上有十来个模块,整个系统的地址空间有一百多,采用二分搜索,最多8次就够了!相比消息处理函数的指令数,这部分开销完全可以接受。而从另一个角度来说,统一消息让程序变得简单可控,系统内减少了消息的拷贝操作,所带来的系统效率和性能提升,远远大于查询路由表的开销。 当嵌入式世界有了统一消息后,哪些多线程的开发技巧还有很大价值么?一般应用开发者真的需要理解这些知识么? 温馨提示 由于微信公众号近期改变了推送规则,如果您想经常看到我们的文章,可以在每次阅读后,在页面下方点一个「赞」或「在看」,这样每次推送的文章才会第一时间出现在您的订阅列表里。 版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。 猜你喜欢: 实践 | AP3216三合一整合型光感测器实验分享 实用 | 一个高性能通信库的简单使用分享 不按套路出牌,这么来写IIC驱动? 干货 | C语言实现面向对象编程(附代码) 2020年精选原创笔记汇总 在公众号聊天界面回复1024,可获取嵌入式资源;回复 m ,可查看文章汇总。 文章都看完了不点个吗 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    嵌入式大杂烩 通信技术 软件设计 嵌入式

  • 你会接受师兄的追求吗?

    今天小编在逛知乎看到一个很有趣的话题“作为一个研究生,你会接受同实验室的博士师兄追求吗?”,关注该话题同学有1200+人,被浏览超过237万次! 作者:淡腾铲屎官二号 链接: https://www.zhihu.com/question/403553392/answer/1318357466 恋天恋地恋师妹 防火防盗防师兄 当然以上是玩笑。 能不能接受不是看他是不是你师兄,而是这个人靠不靠谱。靠谱的话,不要太爽。因为以后带你发文章,找工作不要太舒服。如果不靠谱,你也会很惨,毕竟抬头不见,低头见。要是他心胸狭隘,没谈成,还给你穿小鞋挖坑给你跳,你更是难以躲避。 所以,擦亮双眼!先看看靠不靠谱!而且我个人建议,就算要谈,不要待在一个实验室。可以是一个大课题组,但是平时的实验室休息间要分开,保持适当的距离。这对两个人都好。 至少我见过的,我一个很敬重的师兄最后娶了我一个师姐。现在天天老婆孩子热炕头,然后基金写双份,方案设计也双份。我一个师弟,娶了带他的师姐,同样走上了方案设计双份,基金写双份的“幸福生活”!( ⸍ꔷ͈ᗄꔷ͈⸌)o彡 ps 我当年读书的时候,课题组男女比1:10,男生就个位数。单身就我一个。然后我师母在我参加的第一次组会上就说“谈恋爱这个啊,我们不支持也不反对,但是不能在一个实验室!” 然后呢,我就把这个话听进去了。单身了五年。以至于我约个妹纸晒太阳逛超市被发现,都能成为整个课题组的头条新闻! 然后呢,在毕业之前,我师母和我聊天的时候就问我:怎么咱们组里这么多漂亮妹纸,你咋就一个看不上呢? 我:不是您老说最好不要找组里的吗?! 师母:孩儿啊!你怎么这么傻啊!(声音高了八度) 我就你一个男学生(声音在提高了八度), 你找个组里,我又能把你怎么样(声音提高了多少度我已经记不清了)! 唉! 我当时表情很精彩,内心感动的稀里哗啦的!肠子的颜色都是青色的! 2020.07.06更新 没想到上热榜了,谢谢大家的点赞! 然后我说明一下,很多人羡慕男女比,但是怎么说呢,emmmm 我貌似从来没在女生少的环境里待过。 小学四年级到毕业,不知道是不是班主任故意,我座位周围环绕了8个女同学!那时候我还是个鼻涕虫!擤个鼻涕都能被几个女生轮流掐后背那种!别说,这八个女生我还有几个有联系方式,还都挺漂亮。只能说女神们掐人也挺疼的! 初中也是三年女同桌呢! 高中三年理科班,妹纸少了点,但是也是男生三十多点,女生接近20人。 到了本科,大专业90人,女生接近60人。 硕博正文说过了。 工作了,现在课题组学生应该是三四十人。男学嘛,还挺多的!足足有五六人之多!入职的时候,领导耳提面命“和女学生谈恋爱这个事,我们不反对,但是你最好不要和女学生有什么关系!不然出了事,我们可管不了你,前途都没了!就算要找女学生,只准女学生甩你,不准你甩女学生!最好不找女学生!” 我当然是绝对听领导话的老实人啦! 所以呢,我就开始了工作日老实上班,休息日和基友还有猫儿子一起玩耍的幸福生活! 作者:猫奴有喜 链接: https://www.zhihu.com/question/403553392/answer/13144970 我就比较厉害了,我追的我师弟~( ̄▽ ̄~)~,现在是老公o(≧v≦)o。 同实验室,隔桌,天坑有机合成,我给他供了几十克的中间体,换他给我压硅胶柱子ԅ(¯ㅂ¯ԅ),连个论文致谢都不给我,我都论文里谢他给我压柱子啊,结果搞得答辩老师都以为我的实验是他做的,我亏大了(눈_눈)。我博士毕业时,他硕士毕业,就这个节奏吧。 我自认颜值还不错,性格开朗,当之无愧的聪明,思维天马行空,桃花也不错,我爸的评价是情圣ԅ(¯ㅂ¯ԅ),一个手数不过来那种节奏吧。这货也就是在某个下午,我百无聊赖的压柱子,他从实验室门口探头询问怎么找老师联系读研,我就惦记上了,这小哥哥帅,我那时还不是空窗期。。。然后过了一阵我俩都恢复单身狗状态时,就经常一起打游戏,吃食堂,然后在拒绝了我无数次各种抵死不从后,勉强答应了。 然后毕业了,他去国外读博四年,我在不止五百强菊花厂厮杀,然后他回国博后两年,我换了个厂厮杀。一直异地,假期相聚。 现在他混高校,我继续在企业厮杀。我俩节奏跟正常男女可能不一样吧。 我俩能结婚,原因也挺荒唐的。工作两年,有个保险公司致电忽悠我买保险,说配偶也能享受啥福利,我TM没配偶啊,然后跟人家说你等我一下,我结个婚去。放下电话就给他发语音,我这准备买个保险,配偶也能享受福利,咱结个婚呗赶紧把户口本寄过来吧~(「・ω・)「嘿。对面一脸懵逼,也不知道说点啥,就说好。过了没一周,我就没有买保险的热情了,就让他不用寄了(๑òᆺó๑)。 但没多久,他就回国跟我求了个婚,我看在戒指的份上勉强答应一下,一切流程就走完了,反正一直异地,我也没啥结婚的感觉,毕竟那时在菊花厂,我想修电脑,汉子们能从厂门口排到坂田路口,有了那张纸,我就时常感叹耽误了我的十里桃花啊。领证时,我从外面出差抽空回来,他回国,一起过了一个端午节,节后第一天上午去领证,中午吃个饭,然后下午我俩奔赴机场,他出国继续读书,我继续出差,没有神马甜蜜,只是走个流程。一直以来,风里是我,雨里是我,在厂里厮杀很不容易,我的其他帖子里吐槽过电视剧一样的斗争剧情。 我可能不太正常,太独立,就像现在我自己在外奋斗,问题都是自己解决,跟他讲,他没经历过,也没啥建议。想换工作,目标是800公里以外的一个公司,我想的就是怎么自己搬家,自己开车过去,我妈就跟我说,让他跟你做伴一起开车,你俩是夫妻,你不能这样子。。。我也想有个靠山呀,奈何我跑得太快。 所以,题主,能有个博士师兄追你,对你好,以后他进入社会早,经验多,真的是个可以依靠的人,你也没啥不喜欢,那你就从了吧。博士的发展都还是不错的,我这种土鳖虽然在菊花厂混的辛苦但是成果从来不少,出来后基本所向披靡,现任公司里的八国联军都不能奈我何,我在一个日韩引进技术风向的行业,把公司里的日韩美帝的专家都干服了我说的算,虽然辛苦,却不甘心在家生娃,才搞得如此独立。我冲的太快,也想有个能给我引导的人。 疫情期间,我老公高校放假到我这里来住了俩月,我正常上班,他给我做饭洗衣收拾家,幸福的生活啊,下班有饭吃,游戏有人陪,遛弯有人陪,猫屎有人铲,我吐槽有人倾听,我觉得就是前所未有的舒服,可惜好日子也就那几天哈。所以准备换个地方,离他近点,我这能力,去哪里应该都有人嗨皮收留,现在就想近点,哈哈。 也希望题主能幸福。 刚换工作不久,试用期没过一半,就怀了个崽,距离近了,就每周都能见到汉子,然后就酱紫了→_→,对不起我领导啊(›´ω`‹ )。 但是我有套路能解决公司的祖传产品问题,相信不会把我赶走的吧,希望能帮公司雄起,多发银子,多赚奶粉钱哈哈。现在开始混行业圈子了,得把自己推出去,以前干了好多活,但是懒得出门,都是让手下兄弟出去露脸,现在想想,只有合作的几个大厂和他们私下交流的人知道我的丰功伟绩,更多的人不知道呀。为了以后能找个地方养老,得出来给大家瞅瞅了。 然后就有厂想请我当顾问,赚外快那种,还没决定是不是答应嘎。离开上个东家,运气不错,新东家这里是我的福地,解决问题时百蒙百中,得到大佬认可并替我对外吹牛逼,等了几年的崽也来了,有人上赶着送奶粉钱,汉子也能经常见到,有点嗨皮。 博士毕业不会差到哪里去呀,看我这土鳖就混的挺不错的,所以大家遇到博士GG就果断求包养吧 (  ω  )  。 作者:毛毛链接: https://www.zhihu.com/question/403553392/answer/1306076902 谈恋爱,为什么总是想着各种外部的条件,而不是想着恋爱最根本的问题:到底喜不喜欢这个人。 所以呢?你不接受同实验室的师兄的原因是什么?不喜欢一个实验室抬头不见低头见?自己都念研究生了,可以找个更好的?他都博士了,科研能力看着一般,未来没啥发展? 而你接受同实验室师兄的原因又是什么呢?sci带你共同一?每个月的劳务能请你吃大餐给你买口红?能帮你完成实验? 难道最本质的问题,不应该是你喜不喜欢这个人吗? 作者:薰风初入弦 虽然我是个男生…… 只是想提醒一下,办公室恋情(研究生实际上就是一种学徒工。)的一大隐患是万一分手了,之后各种事情处理起来都很麻烦,毕竟每天低头不见抬头见的。 所以我不推荐任何人在本组(本公司)谈恋爱,虽然能走到一起当然是好事,但最后走不到一起才是常态 作者:西泠kylin 链接: https://www.zhihu.com/question/403553392/answer/1320253426 会 同一导师,我俩还做同一个课题,每天早八点到晚十一点,一周七天最少六天都待在一起,单论相处时间来说比同宿舍姐妹们都长。 然后,我猜最怕我俩吵架的,不是父母也不是共同好友,而是我们老师(ಡωಡ)…… 一吵架课题难免受影响,所以我俩那是连架都不敢吵,无比和谐……(˙︶˙)…… 现在已经领证啦~(请忽略美颜也磨不平的劳动人民跑Western的双手) 作者:Roswell 链接: https://www.zhihu.com/question/403553392/answer/15094188 不谢邀,没人邀。只是想单纯说几句。 研究生校园恋情什么是长期相处下去的内在原因?rich?帅?助我发文章的大腿?都是重要却非必要。 核心:两人在一起总有说不完的话,无论是生活琐事,娱乐八卦或是学术交流。也许,刚开始两人互相吸引是有外貌的因素,而真正决定两人能否继续的还是在是否能交流预约。 我是属于自己经历的也多,身边人故事也多。经历过与看过,男女刚开始因容颜、谈吐互相吸引,而长久相处下来发现每天除了互相嘘寒问暖,却无其他话题可聊。 我的实验生活你不懂,你的世界我也进不去,你们觉得这种关系能长久下去吗? 当然,你们要是老乡或什么小学、初中、高中、大学、幼儿园校友,有共同经历,那另当别论,因为你们的共同背景使得你们可以有机会相处下去。为什么如此看重长期交流愉悦与否,因为这背后会反应你们的所思所想是否一致,甚至可以说反映的是大家三观是否契合。 我 是一个穷小子,想的是柴米油盐,你是一个大小姐,想的是歌剧红酒各种show,你觉得这样的交流可以长期稳定吗? 我 是一个实验狂,想的是搞大文章,拿国奖未来割VC韭菜,而你是一个热爱生活,觉得生活永远比学术重要的人,那大家只怕最终也要分道扬镳。 哪怕是男女想的都是在实验间隙,一起作为减压释放的玩伴,只要两人都是这样,且不伤害其他人,好歹也是三观契合,估计也会稳定。 而不是,你一个她发消息,她就觉得烦。 我见过许多对实验室师兄师妹,刚开始因为学术交流相识,后来发现大家有其他话题可以很愉悦交流,最后水到渠成。当然,我也见过贸然出击,刚开始互相觉得还不错,但最后互相进不去对方世界,最终草草收场。 研究生了,大家做一个决定前都是会过脑子的,会评估对方与自己是否有共同规划,考虑过作为一段实验室恋情应如何平衡学业、生活的。所以要是有合适的,可以尝试。 要是站在老板角度,他们最看重的是你们的感情是否会影响你们俩与实验室的科研进度,只要不影响,其实老板是不太有所谓的。当然,个别老板可能担心这样形成小团体,影响实验室管理与发展。 啰嗦了那么多, 总结:先做好评估 (长期交流愉悦与否,是否有互相吸引之势,未来有无共同规划,是否会影响自身与实验的平衡),即使上述几点不能兼具,可以评估这种损害是否是在你俩可承受范围,要是可以,那就大胆去爱吧。 END 来源:大鱼机器人 版权归原作者所有,如有侵权,请联系删除。 ▍ 推荐阅读 你怎样选择开源免费RTOS? GD32也开始假货翻新泛滥了 工程师姓什么很重要!别再叫我“X工”!!! →点关注,不迷路← 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    嵌入式ARM 程序员

  • 如果诸葛亮用C++写出师表

    代码如下: 运行结果: END 来自:人人网 链接:http://blog.renren.com/share/308645063/17257436317 版权归原作者所有,如有侵权,请联系删除。 ▍ 推荐阅读 你怎样选择开源免费RTOS? GD32也开始假货翻新泛滥了 工程师姓什么很重要!别再叫我“X工”!!! →点关注,不迷路← 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    嵌入式ARM 编程 C

  • 入门PIC需要准备什么工具

    最近,一个帖子上了21ic论坛的热榜。名为panxiaoyi的网友在论坛咨询了关于入门PIC的技巧,背景是这样的: 1:8位的PIC,选什么型号来学比较好?要求这个芯片是近几年【新推出】的【大众化】的,有LQFP32以下封装甚至有PID封装的。 2:MPLAB IDE ,MPLAB X IDE ,MPLAB® XC8 ,它们之间是什么关系?需要注册或者购买版权的吗?我只会用C语言,我需要安装什么软件? 3:需要购买下载线吗?还是有USB转串口即可下载?仿真工具暂时就不考虑了(如果是一体化的便宜的也可以考虑)。 4:我之前就喜欢玩AVR的ATmega48-88-168,没有选择M128来玩是因为觉得它比较老款,而且它没有LQFP32以下的封装,再说我也不需要太大的资源 5:最重要的是我不懂得E文,之前的AVR有少量的中文,后来出的基本没有中文数据手册了,而我这几天发现原来PIC【官网】有大量的中文数据手册,而且 MPLAB X IDE 也是中文界面的,既然它对中文这么友好,所有我就想学一下它。这几天我还在【芯圣】单片机那里购买了3块HC89F0541的51系列1T的开发板,正准备来玩一下的,突然发现这个PIC有个中文社区,里面有大量的中文资料,所以,就不想了解HC89F0541了,估计PIC比较可靠是吗? 另外也想说一下这个HC89F0541芯圣单片机,看【芯圣】资料他家的所有单片机都有一个很好的特色,就是:外设功能引脚全映射模块。它允许大部分功能端口可任意映射到任意I/O 端口,比如说UASRT的TXD,RXD,它可以指定由任意的IO脚输出或者输入。 热心的网友是这样推荐的: 开发、学习PIC单片机要用到以下软硬件工具: 1. MPLAB IDE 老的集成开发环境软件,这个是所有PIC单片机的开发平台,2016年以后推出单片机基本上已经不支持了; 2. MPLAB X IDE 新的集成开发环境软件,支持全部的8位、16位和32位芯片(部分比较老的芯片不支持); 3. MPLAB® XC8是8位单片机C语言编译器,你用C语言编程必须要用此编译器,需要单独安装配合 MPLAB X IDE 使用; 4. 另外还要用到PIC单片机开发板、编写器(如KIT4或ICD3、ICD4); 5.建议买一个 MPLABPICKit4在线调试器。 以上是最基本的开发配置。 推荐MPLAB X IDE(集成开发环境) + XC8(编译器), 硬件可以直接选择一块curiosity nano开发板。PIC系列8位单片机为适应各种不同的用途,推荐PIC16F722/3/4/6/7。另外,PIC16F1946和PIC16F877A是8位单片机中性价比较高的一种。 最终,panxiaoyi在芯片方面选择了PIC18F27Q10和PIC18F47Q10系列。选择它们是因为它们有中文数据手册,资源丰富,某宝购买方便,也不贵,包邮10多元。下载线选择了pic kit3.5。 软件环境方面,现在已经安装了 MPLAB X IDE v4.20 没有安装5.x版本,因为4.x的中文界面更好,同时也安装了xc8。 点灯例程: #include #include #include #include "CONFIGURATION.h"int main(int argc, char** argv){ unsigned long i; for(i=1000000;i>0;i--) { TRISA=0; PORTA=0; } for(i=1000000;i>0;i--) { TRISA=0; PORTA=255; } return (EXIT_SUCCESS);} #ifndef XC_CONFIGURATION_H#define XC_CONFIGURATION_H#include // include processor files - each processor file is guarded. // PIC18F24Q10 Configuration Bit Settings// 'C' source line config statements// CONFIG1L#pragma config FEXTOSC = ECH // External Oscillator mode Selection bits (EC (external clock) above 8 MHz; PFM set to high power)#pragma config RSTOSC = HFINTOSC_64MHZ// Power-up default value for COSC bits (HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1)// CONFIG1H#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled)#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)// CONFIG2L#pragma config MCLRE = INTMCLR // Master Clear Enable bit (If LVP = 0, MCLR pin (RE3) is an input; If LVP =1, MCLR pin (RE3) is MCLR)#pragma config PWRTE = OFF // Power-up Timer Enable bit (Power up timer disabled)#pragma config LPBOREN = OFF // Low-power BOR enable bit (Low power BOR is disabled)#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled , SBOREN bit is ignored)// CONFIG2H#pragma config BORV = VBOR_190 // Brown Out Reset Voltage selection bits (Brown-out Reset Voltage (VBOR) set to 1.90V)#pragma config ZCD = OFF // ZCD Disable bit (ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON)#pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle)#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)//#pragma config DEBUG = OFF // Debugger Enable bit (Background debugger disabled)#pragma config XINST = OFF // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed Addressing Mode disabled)// CONFIG3L#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)#pragma config WDTE = OFF // WDT operating mode (WDT Disabled)// CONFIG3H#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)#pragma config WDTCCS = SC // WDT input clock selector (Software Control)// CONFIG4L#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)// CONFIG4H#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-30000Bh) not write-protected)#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)#pragma config SCANE = ON // Scanner Enable bit (Scanner module is available for use, SCANMD bit can control the module)#pragma config LVP = ON // Low Voltage Programming Enable bit (Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored)// CONFIG5L#pragma config CP = OFF // UserNVM Program Memory Code Protection bit (UserNVM code protection disabled)#pragma config CPD = OFF // DataNVM Memory Code Protection bit (DataNVM code protection disabled)// CONFIG5H// CONFIG6L#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)// CONFIG6H#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#endif /* XC_HEADER_TEMPLATE_H */ 其他PIC网友优质开箱测评帖: 1、[PIC®/AVR® MCU] 【CuriosityNano测评报告】初识PIC16F15244 用户:21ic蓝V作者jinglixixi 最近,如愿地收到了PIC16F15244Curiosity Nano评估工具包。其实说是工具包会有些误解,它其实是由一块PIC16F15244开发板和2排插针构成。 除去包装后,将开发板与排针连接后,则如图1所示。 图1  PIC16F15244开发板 由于工具包并没有配置相应的USB线,所以在找到一条USB线后便迫不及待连上电脑相看一下上电后的效果,其状态如图2所示。也就是说除了电源指示灯被点亮外,并无太大的变化。 图2  上电效果 但与此同时,在电脑上还有着一定变化的,明显的效果就是在安装驱动后,桌面上出现了一个虚拟的U盘,见图3所示。 图3 虚拟U盘 在打开U盘后,可见到里面存有3个文件,见图4所示。 图4 U盘内容 此时若打开资源管理器,则可看到不仅有虚拟的U盘,还有虚拟的串口,见图5所示。 图5 虚拟串口 观察到这里,似乎能做的也就这些了,那我们就为后续的工作先做些准备把。 1.找到那张器件联络图(原理图),下载为: ww1.microchip.com/downloads/en/DeviceDoc/PIC16F15244_Curiosity_Nano_Schematics.pdf,该原理图给我们的关键内容如图6所示。 由此可知,板载的2个器件与MCU的连接关系为: LED(黄色)  --- RA2(低电平点亮) SW(用户键)--- RC2(按下为低电平) 此外,串口的占用引脚为: TX(发送)  --- RC1 RX(接收)  --- RC0 2. 找到硬件的用户使用指南,其下载网站为: ww1.microchip.com/downloads/en/DeviceDoc/PIC16F15244-Curiosity-Nano-Hardware-User-Guide-DS50003045A.pdf 图6 关键内容 3. 了解PIC16F15244为我们具有哪些特色,其主要内容为: 4. 开发工具的配备,其主要内容为: 随后的工作就是下载软件来构建开发环境了,由于手头的开发环境是基于MPLAB® XIDE 5.30,所以需要重新下载安装MPLAB® X IDE 5.40,因为在MPLAB® XIDE 5.30下是找不到PIC16F15244,这一点似乎不如KEIL,如果能下载个升级包把问题解决了多好! 2、[PIC®/AVR® MCU] 【CuriosityNano测评报告】+初次上手PIC单片机之PWM呼吸灯 用户:南来之风 非常感谢论坛提供了一次难得的初次体验PIC单片机的机会。官网的资料是非常详细的,对于这款Curiosity Nano,建议从Github上开始学起来。 github.com/microchip-pic-avr-examples/pic16f15244-pwm-led-blink 首先是环境的搭建: 正确安装好驱动后,在端口中应该可以看到“Curiosity Virtual COM Port” 开发环境安装好后,首先打开MPLAB XIDE5.40,软件是自动识别我们这款板子,而且硬件资料,软件demo一应俱全,非常的便利! 转到Git上,试着运行一个pwm-led-blink-master的项目,下载后先build一个工程。 成功后,把程序下载到板子上。 与此同时,把GND和RA2引脚引出,连接到一个简易示波器的输入端,可以看到PWM的方波驱动LED闪烁,在简易示波器上显示出响应的波形。 在例程的基础上,增加了几个不同占空比的值,目前占空比可以选择0,12,25,37,50,62,75,88,100。代码比较糙,但还是贴出来了: uint16_t Array_dutyCycle[] ={0x0000,0x007F,0x00FA,0x177,0x01F4, 0x0271,0x02EE,0x036A,0x03E7};uint16_t i;uint8_t index = 0;int8_t direction = 1;void main(void){ SYSTEM_Initialize(); // Initialize the device INTERRUPT_GlobalInterruptEnable(); // Enable the Global Interrupts INTERRUPT_PeripheralInterruptEnable(); // Enable the Peripheral Interrupts while(1){ if(direction == 1){ if(index != 8) PWM3_LoadDutyValue(Array_dutyCycle[++index]); else{ direction = -1; PWM3_LoadDutyValue(Array_dutyCycle[--index]); } } else{ if(index != 0) PWM3_LoadDutyValue(Array_dutyCycle[--index]); else{ direction = 1; PWM3_LoadDutyValue(Array_dutyCycle[++index]); } } for(i = 5120; i!=0;i--); }} 可以看出PWM的波形占空比变化时候LED0的亮度也随之变化。 3、[PIC®/AVR® MCU] 【CuriosityNano测评报告】+开箱、建立开发平台及LED闪烁 用户:hu9jj 周末收到本次评测的主角PIC18F57Q43核心板,鲜红的外包装依旧那么惹人喜爱: 两个防静电包装袋中分别是排针和PIC18F57Q43核心板: 核心板上的焊盘依旧的交叉错位,稍加用力将排针插入核心板,就可以直接使用,省略焊接步骤。我之前曾打样了几块扩展板,本次依然派上用场: 上电之后,打开MPLAB X IDE,系统自动识别核心板,通过链接就可以下载PIC18F57Q43的相关资料: 电路图、硬件用户手册及数据表下载完之后,照例先升级PACK包: 我懒得选择,依次升级了全部PACK,因此花了一个多小时才完成: 准备工作基本完成之后,开始新建项目: 我安装的是中文版IDE,但不知怎么回事,有时菜单不出现中文,不过这无伤大雅,选择“New Project”就是:   照旧选择标准项目(参见上图),然后进入第二步,选择芯片类别:类别选择正确之后,在设备栏中输入“PIC18F57",然后从下拉列表框中选择对应的核心板型号,当然,您愿意录入完整的核心板型号也行,然后在工具栏中选择您的核心板编号,这样项目便会与核心板挂钩: 下一步便是选择编译器: 新建项目的最后一步是输入项目名称、选择项目文件存放的位置等: 至此,项目新建完毕,下一步就是通过MCC来配置代码,完善必要的代码文件: 可以从Window下拉菜单中点击进入(或退出)代码配置器MCC,也可以直接点击工具栏上的图标进入或退出MCC:点击之后,首先需要确定MCC配置文件存放的位置,我通常按默认的位置,直接点击“保存”按钮: 通过下载的电路图,我们知道LED是接在RF3引脚、KEY是接在RB4引脚,因此在引脚图表中将RF3设置成output,将RB4设置成input,为了容易理解,点击右上部分的Pin Module选项,然后在对应引脚的名称设置成KEY和LED: 配置完成后,不要忘记点击右上部的"Generate"选项来生成代码:退出MCC之后,打开main.c文件,添加一个计时用的全局变量ms,并在主循环中写入下列代码,用于计时和控制LED引脚电平翻转: 编译并下载程序到核心板上: 稍等片刻,程序烧录完毕,黄色LED灯便闪烁起来了,开发平台也顺利建立了。这是测试的动画: END 资源:21ic论坛,整理:付斌 版权归原作者所有,如有侵权,请联系删除。 ▍ 推荐阅读 你怎样选择开源免费RTOS? GD32也开始假货翻新泛滥了 工程师姓什么很重要!别再叫我“X工”!!! →点关注,不迷路← 免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

    嵌入式ARM 单片机 PIC

  • 硬件工程师画电路板常见犯错的地方

    编排 | strongerHuang 我之前公司有一个硬件工程师,不管什么类型的PCB,没有哪次是一次性OK的,即使那种很简单,几个元器件/芯片的电路板,也会给你搞错。 下面分享一下工程师常见犯错的地方。 1、有极性的电容,原理图和PCB把管脚搞反了? 2、电源和地忘记接了。。。。还有接反的。。。 3、连接器的线序搞反了 4、RX、TX接反了。。。 5、想当然的写一个封装,结果没有这个规格的器件,百度文库下载datasheet,结果根本买不到这个器件。 6、直接抄电路,结果器件根本买不着。 曾经一个做智能锁的团队,电路直接抄三星的智能锁,结果里面一个电容式触摸按键的控制器,是韩国产的很难买到,而且没有什么代理和支持。纯靠自己试验和摸索。 7、选择电容的时候,只考虑容量,没有考虑耐压,结果这么大的封装放不下满足规格电容。 8、选择电阻的时候,只看阻值,不看功耗。 9、画完PCB,不看DRC报告,靠眼睛看飞线,回板后就真的飞线了。 10、封装做反了。。。 11、散热焊盘的阻焊层没有处理 免责声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。 ------------ END ------------

    strongerHuang 电路板 硬件 PCB

  • 图观目前各类芯片的交货周期

    来源 | ittbank 芯片小幅度涨价我忍了,但交货周期也这么长,怎么能忍? 下面给大家总结了目前各类芯片的交货周期,看看有没有你的供货商。 各类芯片交期表 注:如上表有遗漏或错误之处欢迎指正。 免责声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。 ------------ END ------------

    strongerHuang 芯片 IC

发布文章