Chinese Blog

    Publish
     
      • 温湿度传感器在空气净化器中的应用

        Siliconlabs | 09/267/2015 | 07:26 AM

        1.png

        随着消费者对大气污染关注度的不断提高,空气净化产品逐渐成为市场上的焦点,很多人家里都安装了空气净化器。而各种传感技术的发展和应用,使空气净化器的性能和功能全面提高,进一步实现了舒适、安全、节能。当前市面上的空气净化器一般都装有三种传感器——温湿度传感器、粉尘传感器和异味传感器。

         

        温湿度传感器是几十年来的传统元器件,目前产品越来越小型化,并通过精确的计算,被赋予了新的应用生命力。对于空气净化器而言,温湿度传感器是必须的,其作用是检测室内湿度(干燥状态),净化器根据该数据控制加湿量,即可保证室内环境在一定的湿度范围内,以保持最舒适的湿度。

         

        空气净化器设计方案

        本设计采用Silicon Labs的EFM32TG840作为主控MCU,结合数字温湿度一体传感器芯片Si7020,以及CO2传感器、空气质量传感器等数据采集进行空气质量分析,并控制加湿装置、空气净化装置来进行空气净化。该空气净化器方案能够对室内空气质量状况进行实时监测、反应灵敏并且具有相应的处理措施;能够感应人体活动并做出判断,给出相应处理措施——能够吸附各种有害物质还具有杀菌功能;具有友好的人机交互界面;具有自动开关机、定时操作、多种工作模式选择和多种操作方式。

         

        系统框图如下:

        3.png

        主控MCU

        EFM32是由Silicon Labs公司采用ARM Cortex-M0+\M3\M4内核设计的高性能、低功耗32位微控制器。本设计采用M3内核的EFM32TG840F32单片机,其封装为QFP64,Flash和RAM资源为32KB和4KB。

         

        温湿度传感器

        数字温湿度一体传感器芯片Si7020:采用低K电介质聚合物检测温湿度的专利设计,具有低漂移和低迟滞及卓越的长期稳定性,标准I2C数字输出,宽的工作电压范围,同时具有很高的温度精度(+/-0.3℃)和湿度精度(+/-2%RH),专为极低功耗、小体积(3mm×3mm×1mm)应用设计,具有良好的品质、响应速度快、抗干扰能力强、性价比高等优点。

         

        空气质量\CO2传感器

        空气质量传感器是用测量颗粒物的传感器,本设计选择灰尘传感器,可以灵敏感知到烟草产生的香烟气和花粉、房屋粉尘颗粒等;CO2传感器用于检测空气环境的二氧化碳浓度,二氧化碳浓度过高,人体会感觉胸闷缺氧呼吸困难,甚至窒息死亡,目前市场上常用的都是红外原理的二氧化碳传感器。

         

        电源模块

        空气净化器为市电供电,带电压转换电路,EFM32的工作电压为1.8~3.8V,Si7020工作电压为1.9~3.6V,根据MCU、传感器、EEPROM等来选择转换电压。

         

        空气净化装置

        采用双波长光氢等离子空气净化器,能够吸附并电解空气中的细小颗粒,对空气中的细菌、病毒及有机污染物进行杀灭、降解,使得室内的空气得以净化,从而提高室内空气品质。

         

        加湿装置

        采用超声波加湿装置,超声波加湿器已被广泛应用在各种领域。超声波加湿器采用每秒200万次的超声波高频震荡,将水雾化为1微米到5微米的超微粒子和负氧离子,达到均匀加湿,能清新空气和增进健康的目的,一改冬季暖气的燥热,从而营造舒适的生活环境。

         

        显示模块

        采用段式LCD进行显示,显示数据包括当前净化器状态、空气温湿度、控制质量、灰尘颗粒浓度及CO2浓度等,由于主控MCU EFM32TG840F32集成了LCD驱动,外部可以省去一个LCD驱动芯片。

         

        按键控制

        按键主要为人工设置、信息查看等提供人机交互接口,本设计采用普通机械按键。

         

        EEPROM

        用于存储相关参数,数据量并不大,采用8KB或者16KB即可。

         

        红外遥控

        红外遥控采用一体化红外遥控接收头,它将红外接收管(光电二极管)、放大器、滤波器及解调器集成在一个硅片上,不仅尺寸小、无需外部元件,并且具有抗光电干扰性能好(无需外加磁屏蔽及滤光片)、接收角度宽等特点。

         

        温湿度传感器Si7020的优势

        选用高精度、高可靠性、高稳定性的温湿度传感器Si7020、空气质量传感器及CO2传感器,提供实时高质量的空气质量监控;采用了多款低功耗器件,并由MCU自主对环境进行检测和判断,适时启用空气净化装置和超声波加湿器,达到省电节能的目的;采用LCD显示和红外遥控显示,丰富、直观、控制方便,具有良好的人机接口;内置EEPROM,能够记忆用户设置,根据用户喜好智能化设置工作模式、空气质量参数等。

         

        温湿度传感器Si7020具有优异的可靠性、稳定性及高精度特性,非常适合于对温湿度检测指标有一定要求的空气净化器的应用,该温湿度传感器经过出厂校准,并将校准数据保存在片上的非易失性存储器内,并有可选的保护膜,保证了芯片的一致性及长期稳定性。因此,Si7020非常适合于空气净化器。

         

        原内容地址:

        http://www.sekorm.com/Ecnew/934

      • 无线可穿戴产品致胜设计六大策略

        Siliconlabs | 09/267/2015 | 07:11 AM

        1.png

         

        无线可穿戴产品致胜设计六大策略

        作者:Mendy OuzillouSilicon Labs物联网MCU和无线产品市场总监

         

        当美国漫画家Chester Gould在Dick Tracy的手腕上画出手表图案时,他一点也没有意识到,科幻小说能在70年后变为现实。作为一名连环画画家,Gould想象出未来设备,却没有考虑太多细节。如今,这些非常真实的腕上设备和其他无线可穿戴设备(WWD)为工程师带来一系列他们必须克服的设计细节挑战。工程师必须在经济实惠、引人注目、超紧凑的设计中无缝集成复杂的传感、处理、显示和无线技术,且可在单一、小巧和具有成本效益的电池供电下工作数个月,甚至数年。下面让我们一起来讨论对于可穿戴设备、技术和组件选择的具体需求,以及如何在超小的外形尺寸中实现复杂功能、长电池使用寿命和无缝无线连接。

         

        在可穿戴产品设计中,工程师必须考虑三个关键因素:各种操作模式下的功耗(节能)、从匹配电路到天线之间的适当RF设计,以及设计中器件的集成度。我们将更详细地讨论集成所面临的挑战,因为很难在不考虑功耗和RF设计的情况下独立讨论这个因素。

         

        大多数无线可穿戴设备涵盖共同的组件,包括电池、天线、微控制器(MCU)、无线电和传感器。从这个名单上看,显而易见,电池将在很大程度上影响可能实现的功能和WWD的工作寿命。考虑到电池电量将会快速耗尽,大多数WWD并非一直保持连续的数据传输,因此通常我们假设通信是突发的和偶发的。此外,集成了无线电的MCU,通常被称为无线MCU(WMCU),它使用方便、节省电路板面积并且降低了功耗,因此我们也假设在可穿戴设计中采用WMCU。

         

        为应用选择合适的WMCU是一项复杂的决策过程,因为对于功能丰富的设备的高功能性将受到电池操作寿命的限制。如果我们仅仅关注WMCU的峰值功耗,那么从电池寿命这一单一因素来看,评估结果是相当令人失望的。然而,WWD通常工作在多种不同的能耗模式(EM),并且仅在极少情况下进入高功耗状态。因此,通过考虑在各种能耗模式中所花费的时间,我们可以评估电池的实际使用寿命。

         

        Silicon Labs为其基于ARM架构的EFM32 MCU定义了5种能耗模式:EM0(活动/运行)、EM1(休眠)、EM2(深度休眠)、EM3(停止)和EM4(关闭)。这5种模式使得设计人员能够灵活地决策和优化系统的整体功耗。然而,能够识别这些模式以及数据手册中的规格数据并不能确保“在各种模式下都获得低功耗”,或者简单地说,不能确保“节能”。确保节能并发展良好的终端客户体验是构建WMCU可运行于这些不同模式的方法。事实上,依赖于突发传输之间的时间间隔,活动模式EM0可能仅占整体功耗中极小比例。而深度休眠模式EM2所占用的时间可以代表电池使用寿命的最大比例。

         

        当为应用选择最佳WMCU时,工程师应当关注以下特性,包括可提供高集成度、具有良好架构的低功耗WMCU。超低功耗WMCU的一些特性无需多说,但也应被完整地列出:

        • 最低运行功耗(EM0)
        • 最低待机电流(EM1和EM2)
        • 微处理器内核的选择,包括8位和32位ARM Cortex(从M0+到M4)
        • 无线电配置选择,包括单收、单发、收发一体和性能等级

        其他MCU特性,包括相关架构和集成度,同样重要而且需要进一步说明:

        • 极短的唤醒时间
        • 自主的外设操作
        • 自主的外设间操作(外设反射系统)
        • 低能耗传感器接口(LESENSE)
        • 丰富的高能效外设和接口
        • RF集成

        最低待机电流和极短唤醒时间

        当打算设计一个尽可能节能的无线可穿戴设备时,人们必须要想到所有可能的功耗优化办法。当设备唤醒时,它必须要尽可能快,如:尽可能快地收集和处理数据,然后尽可能快地返回到休眠模式。确保在休眠模式和活动模式之间快速转换是一项必须要考虑到的关键要素。一个处理器在活动模式所花费的时间即使仅比另一个处理器多出10%,那么对电池寿命的影响也是巨大的。例如,假设处理器1花费99.9%的时间在休眠模式(1µA),0.1%的时间在活动模式(10mA),同时处理器2花费99.89%的时间在休眠模式,0.11%的时间在活动模式,那么第二个处理器的整体电流消耗将增加9.1%。有趣的是,如果处理器1和2在每6小时中分别处于活动模式100ms和110ms,那么其结果就会突显出极低的深度休眠电流的重要性。在这种情况下,第二个处理器只比第一个多消耗0.44%的电量。然而,如果处于活动模式的时间相同,并且把深度休眠电流从1 µA增加到1.1 µA,那么电流消耗将上升9.6%!

         

        自主的外设操作

        取决于可穿戴设备的功能特性,可能需要对片上外设进行频繁、甚至持续的交互或监视。在这种情况下,CPU在这些时间内要保持活动的需求将导致电池电量的消耗非常明显。确保片上拥有无需CPU参与的自主操作能够使系统运行在低能耗模式的同时,仍然能够执行非常高级的任务。这些外设可包括串行接口(例如,低能耗UART、免晶体USB)、I/O端口(例如,外部中断、GPIO)、定时器和触发器(例如,低能耗定时器、低能耗传感器接口)、模拟模块(例如,ADC、LCD控制器)和安全(例如AES加速器)。

         

        自主外设之间的操作(外设反射系统)

        也有一些情况,外设之间可能需要进行通信。在这些情况下,一个外设需要能够产生一个或者多个能够立刻被另一个片上外设所感应到的事件。例如,一个定时器能够被设定创建一个事件,然后触发一个ADC开始采样。在外设之间使能自主的操作,无需唤醒CPU,能够确保获得最低的系统功耗。这种能力是Silicon Labs EFM32 MCU架构的一个关键特性,被称为外设反射系统(Peripheral Reflex System)。

         

        低能耗传感器接口(LESENSE

        最终当CPU需要被唤醒以执行特定任务时,大多数MCU被设置为在一系列特定时刻上唤醒,并监视它的接口,如果没有动作需要,它将返回到休眠模式。这些定期唤醒循环产生了不必要的电池能量消耗。EFM32 MCU采用的LESENSE架构允许对模拟传感器(电阻式、电容式和电感式)进行自主监测,仅仅在相关事件或者条件满足时才唤醒CPU,就跟其他事件处理一样。例如,LESENSE能够被设置去自主地监测一个温度传感器,仅仅超过可编程的99华氏度门限时才通过外设反射系统唤醒CPU采取动作。因此,使用LESENSE能够最小化CPU使能的时间,当不得不消耗最大功耗时,尽可能地缩短最大功耗时的运行时间。

         

        丰富的高能效外设

        开发一个在各种操作模式下都尽可能减少能耗的可穿戴设备需要仔细审查MCU的各个运行方面。虽然我们已经讨论了外设的自主操作,但我们还需要进一步讨论外设本身的低功耗需求。如果外设本身功耗极大或者如果时钟在非必要情况下使能,那么自主操作起到的作用也会非常小。

         

        就外设本身而言,时钟管理单元对于MCU或者WMCU整体功耗起着重要作用。时钟管理单元可以对多种时钟和振荡器进行单独控制,并且基于操作所采用的功耗模式和使能的外设进行最优化时钟选择。使用低能耗振荡器结合灵活的时钟控制方案,能够尽可能地最小化应用中的功耗。高能效的时钟管理单元包括低电流振荡器、低启动时间、动态系统时钟分频、时钟门控,以及用于32kHz外设模块和时钟预分频器。

         

        低能耗自治UART的有效性对于获得超低系统功耗也是同等重要的,尤其是在深度睡眠(EM2)模式,这时大多数其他外设与CPU都处于关闭状态。UART应该包括必要的硬件支持来最小化异步串行通信中的软件干预。通过使用32.768 kHz时钟源,低能耗的UART可支持高达9600 baud/s,并且当完成UART帧接收后,可以快速唤醒CPU。

         

        当设备的大部分部件处于断电状态时,低能耗定时器能够被用于定时和输出,因此允许在执行简单任务的同时保持系统功耗绝对最小值。如果适当配置,这种定时器能够提供高达16kHz频率(32kHz振荡器频率的一半)的无差错波形。

         

        对于MCU或者WMCU中的模拟资源,例如ADC、DAC、LCD控制器、模拟比较器和其他外设,应当仔细分析它们的功耗和灵活性。例如,12位1Msps ADC在全速时可消耗350 µA,但是并非所有应用都需要运行在这种速率下。在仅需要6位、1ksps的应用中,这时ADC仅消耗0.5µA,功耗显著减少了。LCD控制器应当能够在没有任何CPU干预下运行定制动画,并且仅仅是更新数据时才唤醒CPU。

         

        加密占用非常大的片上资源,且显著消耗电池电量。最低成本的8位MCU通常需要把安全逻辑作为运行时代码来执行,而32位MCU最可能包括一个AES加速器。当硬件AES加速器可用时,它应当有能力在无需CPU参与下自主运行,并且应当包括支持自治密码模式的DMA以最小化电池消耗。

         

        RF集成

        以上的讨论内容主要集中在MCU架构之内。然而,其他与无线收发器相关的特性也应当关注。基于应用需求,无线可穿戴设备可能从不需要接收信息,但是多数设备需要在一些时候发射数据。电池供电设备的低功效放大器会显著增加系统功耗,并且使应用增加电池尺寸和成本以满足系统运行寿命的需要。例如,长距离通信设备可能需要RF有+13dBm、16dBm或甚至+20dBm等级别输出功率。虽然在WMCU中集成+10dBm RF功率放大器(PA)是普遍存在的,但是如果应用需要更大输出功率,那么就需要片外的三极管或者放大器。问题是对于创建低成本且切实可行的解决方案来说,这些片外助推器是无益的,因为解决方案既要满足高效又要低成本。因此,在要求长距离和/或者频繁通信的应用中,效率和电池寿命通常与获得具有竞争力的成本目标是矛盾的。克服这个问题的一种方法是确保WMCU中集成适当大小的PA,甚至最大可达+20dBm。通过在WMCU设备中集成PA,PA的电流消耗能够被最小化。归功于PA输出和助推放大器之间的适当匹配,以及发射链的安全设计对温度和电压变动的补偿,因此没有损耗。一个完全集成的PA使得PA操作得以完全控制,确保获得最低功耗。

         

        许多应用运行于2.4GHz频段,这种情况下,IC供应商有机会可以通过集成匹配电路和提供单端RF输入输出来简化系统设计。Sub-GHz应用倾向于覆盖非常宽的频率范围,从数百MHz到1GHz。在这些情况下,集成匹配组件是不现实的。然而,在WMCU中集成通常片外使用的被动器件,并且由于对于分离实现方案有成本优势,因此在大多数流行的频段应用中是可行的。

         

        最后,我们在无线可穿戴设备中还没有讨论的是天线发射和接收特性。由于尺寸和成本限制,大多数无线可穿戴设备的天线发射特性一般都较差,因为它们通常简单地把天线打印在PCB板面材料上(像FR4)。为了补偿天线损耗或低增益,最简单方法是增加RF输出功率来获得期望的输出功率。不幸的是,如前面所讨论的,这个发射器将比那些天线已经被优化过的发射器消耗更大的能量。更好的设计和更低的匹配电路损耗将是最优化操作的保证,但是天线设计具有极大的设计难度,特别是当考虑到可穿戴设备所处不断变化的RF环境时。由靠近终端用户身体(例如手覆盖到设备上时)而产生的不匹配波动能够引起许多问题。一些WMCU设备,例如Silicon Labs的Si4010“片上遥控器”发射器,有集成的天线调谐电路,能够在这些时候动态地补偿天线。这种电路起着非常重要的作用,不仅控制功耗,而且也确保无线电辐射保持在法规限定范围之内。

         

        一种补偿较差天线接收性能的方法是把系统设计成天线分集接收,即采用多天线。虽然许多应用将从实施天线分集中获益,但也有一些因素需要考虑。首先,天线分集倾向于帮助那些在发射端和接收端之间的距离上有如此情况的:接收到的信号水平接近背景噪声水平(即接近链路覆盖范围的边沿),或者由多径传输或物体遮挡而产生的衰落传输环境。

         

        为了降低功耗和芯片成本,WMCU IC通常仅集成一条接收路径,因此天线分集必须通过一个片外天线开关进行切换,以便在两个天线之间交替选择。然而,由两个天线共享一条接收路径的方案可能比人们预期消耗更多的功耗。因为在这种情况下,发射的前导符长度必须被扩展,以便为两个天线按顺序进行评估提供足够的时间。为分析和选择最佳天线,也增加了计算成本和电流消耗。

         

        最后,还有一个间距问题。在无线通信系统中天线之间的距离被推荐为波长( l)的整数倍或分数倍,最小间距是¼ l。在2.4GHz,波长为125mm,依据最小间距l/4或31.25mm的分离天线设计在一些无线可穿戴设备内是可行的。然而,对于工作在Sub-GHz频段的WWD来说,克服这种挑战将变得极其困难。在868MHz频段,天线应当被保持最小86mm的间距,这导致在许多WWD应用中无法使用天线分集。

         

        因此,工程师必须在改善传输距离和接收性能与增加复杂性和尺寸、计算成本和电流消耗之间进行权衡。假设天线分集不是问题,增加的计算成本和相应的功耗能被克服。那么,在变化的和非同步的环境中,定期地在天线间进行切换也是需要的,因为无线电在信息包到达前不知道哪个天线能够实现更好的接收效果。Silicon Labs的EZRadioPRO收发器拥有集成的前导符质量检测器以基于RSSI值来决定信号质量,并确认有效信息包到达两个天线。集成检测器的好处是它能够选择最佳的天线,卸载MCU负担,从而也在选择过程中减少整体功耗。

         

        总结

        如果今天Chester Gould依旧健在,那么他肯定印象深刻,他的想象力已被大大超越。众多公司已经推出了远远超过Dick Tracy具有无线电话功能的腕表设备,并且正在开发各类更先进的可穿戴设备。然而,当设计人员试图集成更多特性和功能到无线可穿戴设备时,底层的关注点几乎总是相同的——如何获得更低的功耗、如何在设计中适应小的外形尺寸、如何确保设备具有可靠的无线通信。而且最终的关切点将是如何以尽可能低的价格获得这些产品设计目标,但是那是我们的另一个话题…“Six-two and even, over and out”。

         

        原文刊载于电子工程专辑网站,链接为:

        http://www.eet-china.com/ART_8800715709_865371_TA_caf104a2.HTM

      • 嵌入式开发入门系列博客之五:时钟(第 1 部分:MCU 时钟和中断介绍)

        Siliconlabs | 09/266/2015 | 11:22 AM

        makersguide_ch5_1.jpg

        前言:在完成此章节任务过程中,您将详细了解 MCU 时钟脉冲源和扩展、中断及其处理器,以及如何从系统层次管理所有这些功能。

         

        此章乍一看可能无关紧要,但实际上很难制作出一个或一组 LED 灯光变暗、时暗时亮和动画效果。我将描述必要的各层定时,而您将生成一个类似于 80 年代热门电视剧“霹雳游侠”中 Michael Knight 火鸟跑车引擎盖上红色扫描栏的扫描动画效果。在完成此任务的过程中,您将详细了解 MCU 时钟脉冲源和扩展、中断及其处理器,以及如何从系统层次管理所有这些功能。您需要熟练掌握这些基础知识,以便未来学习更为复杂的课程。

         

        本课程所需材料

        • 无焊料面包板和布线用电线
        • 3 个通孔 LED
        • 3 个通孔 2k-ohm 电阻

        MCU 时钟

        内核 MCU 中以及外围设备使用的大多数时钟并不用于计时。计算机硬件中的时钟用于为电子电路提供活动信号,以确保步调一致。时钟用于调整部件的运行速度。具有较慢时钟的外围设备的耗电量也较低。时钟速度越快,功耗越高。

         

        在您试图使您的装置运作时,您最不要考虑的就是如何配置时钟。但是如果您配置错误,将付出巨大代价,系统可能会顽固地拒绝运行。因此,为防止出现这样的情况,请阅读这篇简短的概述。我尽力列出了您目前应了解的最重要事项。下图从另一个角度展示了时钟体系结构中一些组件的相关性。

        5.1_overview.png

        时钟体系结构的一般拓扑

         

        EFM32 MCU 中的所有时钟均采用由时钟管理单元 (CMU) 控制的数字波形,而且通常来自模拟振荡器。EFM32 系列振荡器都是石英晶体或电阻-电容 (RC) 网络。石英晶体振荡器必须与两个电容一起安装在印刷电路板中,并在一对引脚处插入 MCU。晶体振荡器的谐振频率固定,且必须在装配电路板时选择。RC 时钟脉冲源位于 MCU 内,而谐振频率可通过配置寄存器控制。晶体振荡器的精度高于 RC 振荡器,后者的调谐机制由 MCU 驱动,以用于持续补偿不准确之处。

         

        时钟脉冲源具有两种可能的频带。低频带脉冲源为 32.768 kHz,高频带脉冲源的可调范围为 1 到 32 MHz(对于 Zero Gecko,上限为 24MHz)。振荡器脉冲源可分为低频晶体振荡器 (LFXO) 脉冲源和高频晶体 振荡器 (HFXO) 脉冲源,以及低频 RC 振荡器 (LFRCO) 脉冲源和高频 RC 振荡器 (HFRCO) 脉冲源。时钟脉冲源基于应用需求而选择。对于准确度与额外板载组件、快速执行与低功耗,可折衷选择解决方案。时钟脉冲源可在 MCU 运行时更改,以调整当前任务的功耗。HFRCO 具有很短的唤醒时间,因此是通过复位启动 MCU 的默认脉冲源。

         

        还有两个特殊的时钟脉冲源,分别是:AUXCLK,闪存编程和 SWO 输出频率为 14 MHz,和超低频 RC 振荡器 (ULFRCO),运行频率为 1 kHz,用于在深度睡眠状态运行 Watchdog 定时器外围设备。

         

        选择时钟脉冲源后,从这些脉冲源生成的数字时钟具有可调运行频率,并通过时钟倍频器路由。这些时钟可通过 MCU 中的配置寄存器进行控制。当时钟路由至外围设备后,仅可通过预分频器时钟分频器降低时钟速度(即,无法倍增时钟脉冲源来使时钟快于其脉冲源)。预分频器设置是可能的最高频率。时钟分频上限(生成潜在最慢运行时钟)可参见您 MCU 的参考手册。数字时钟本身可设计为其他外围设备的时钟输入脉冲源。

        5.1_clocking_overview.png

        通过 EFM32 MCU 的可配置时钟路径

         

        时钟的相关知识非常广泛,我将在讨论各个外围设备时详加描述。如有兴趣,您可以在您 MCU 的参考手册以及在 Simplicity Studio 中使用此窗格找到的应用说明中详细了解。使用 em_cmu.h 中提供的时钟管理单元 (CMU) 软件工具来控制您的时钟脉冲源。

         

        为什么所有这些计时知识很重要?因为要记录编程时间,必须了解每秒可执行的操作数量,而且我们还需要确保每秒的操作数量保持一致。否则,生成的解决方案将变化不定,造成糟糕的用户体验。

         

        连续编程和基于中断的编程

        到目前为止,我们编写的代码具有严格连续性。在程序顶端开始执行,单步调试代码,而且各行逻辑直接控制设备的输入和输出,并确定接下来将执行哪几行代码。连续代码易于理解,因为您可以轻松地通过程序逐行回顾和追踪,打印输出并预测接下来会发生什么。无需担心您小型程序外的任何状况。缺点是一次只能执行一项操作。如果您想要一次执行多项操作,必须生成快速运行的 while 循环,并逐一开始不同事件。我们在上节课中完成过此任务,我们搜寻了按钮按下状态,然后在每次通过 while 循环时一次闪烁一个 LED。

         

        为运行操作系统 (OS) 的系统编程时,我们的程序作为线程或进程运行。每个线程或进程都可通过完全连续方式编写,然后 OS 将在 CPU 上为每个线程或进程提供完成工作的时间,从而产生同时进行多项操作的错觉(即使是在单个 CPU 内核上)。可以在采用 EFM32 系列的嵌入式系统中运行 OS,但运行 OS 本身就需要大量资源,这并不总是最具成本效益的方法。而且因为资源具有限制性且不标准,嵌入式 OS 具有固有问题。

         

        为在没有 OS 的情况下同时处理多项任务,固件设计者转为使用用于触发中断处理程序(也称为中断服务程序ISR)的中断源(也称为中断请求IRQ),来仅在特定事件发生时突然执行操作。事实上,OS 基于中断建立,并从程序员处提取中断。EFM32 系列具有许多可用的中断源,可供您配置并编写中断处理程序,以在中断事件发生当时执行操作。我们可以用基于定时器的中断重写上节课的示例,这将简化此示例中的逻辑。不妨回顾下,我们使用了输入按钮来选择是否使 LED 闪烁。按一下将使其闪烁,再按一下可将其关闭。我们还增加了在 LED 关闭时进入深度睡眠模式 EM4 的功能。利用中断执行相同操作的程序如下所示。

         

        configure GPIOs
        wait for input button to be unpressed
        configure EM4 wake up mechanism
        configure button press interrupt
        configure LED timer interrupt
         
        LED_state = false
         
        define button pressed interrupt handler function:
        turn off LED
        wait for button to be unpressed
        enter EM4 sleep state
         
        define LED blink timer interrupt handler function:
              if LED_state == false
                    turn on the LED
                    LED_state = true
              else
                    turn off the LED
                    LED_state = false
         
        while (true)
        enter EM3 sleep state

         

        顺便说下,我将偶尔使用该伪代码来传达代码含义,而不是使用复杂的 C 程序语言句法。

         

        该伪代码假设我们为定时器配置适当的中断期,以用于切换开关 LED,并按照正确的引脚和极性配置按钮中断。此程序易于理解,而且因为无需一直运行 while 循环,所以可节省功耗。MCU 将在绝大多数时间保持低功耗状态,只在有人按下按钮或定时器到期时唤醒,在后一种情况下,MCU 需要将单个 GPIO 转换至不同状态,然后便会回到睡眠状态。

         

        不一定必须使用中断来完成简单闪烁 LED 任务。我们已通过连续编程轻松完成此任务。但如果要使多个 LED 产生变暗、时暗时亮和“追逐舰”效果,以及处理任何需要解决的逻辑问题,就可能难以通过单个 while 循环完成。中断和硬件定时器通常是合适的选择,并可延长使用电池运行解决方案的时间。

         

        我们将在下节课中继续讨论 SysTick 中断。

         

        前一章节 | 下一章节

      • 嵌入式开发入门系列博客之四: 控制板外组件(第4部分: 按钮输入和深度睡眠状态)

        Siliconlabs | 09/266/2015 | 11:21 AM

        makersguide_ch4_4.png

        利用按钮输入控制 LED 灯带


        现在,我们的简易小型嵌入程序已通过硬编码完全配置为不断重复执行同一操作。不妨改变下做法,通过按钮开关来启动或停止闪烁。入门套件中有两个按钮,而且与板载 LED 一样,按钮电路详情可参见入门套件原理图:

        4.4_user_pushbuttons.png

        两个按钮都已上拉至 VMCU(MCU 的电源电压),具有 1M-ohm 电阻。此类电阻视为弱上拉电阻,但已足以拉高开关 MCU 侧的 VMCU,直到用户按下按钮。此时,将电路连接至地面的 100-ohm 电阻设置了比 VMCU 距地面近 100,000 倍的电阻分压器,且按钮电路已拉低。通常高压的电路会立即拉低,我们便可在固件中检测此变化。

         

        您可能认为 UIF_PB0 和 UIF_PB1 会映射回端口 B、引脚 0 和 1。但实际上会映射到端口 B、引脚 9 和 10。PB0 代表按钮 0,PB1 代表按钮 1。在嵌入式系统开发中不应作任何假设,这是您应该记住的第一课!当您读取错误引脚时,通常不会获得反馈,也没有实际方法来查找故障原因,只能重复检查所有连接。

         

        将某个引脚用作输入,然后在回路中读取其中的值。利用该输入,我们可以使 LED 灯带仅在按钮按下时闪烁。

         

        首先,生成函数以启动单个 LED 闪烁开/关周期:

        void blink_one_cycle(void)
        {
              // Turn on the LED
              GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 1);
         
              // Add some delay
              for(volatile long i=0; i<100000; i++)
                ;
         
              // Turn off the LED
              GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0);
         
              // Add some more delay
              for(volatile long i=0; i<100000; i++);
                ;
        }
        Then, create #defines for PB9 as an input button and call that function from within the new code:
        #define BUTTON_PORT     gpioPortB
        #define BUTTON_PIN      9
         
        int main(void)
        {
          /* Chip errata */
          CHIP_Init();
         
          CMU_ClockEnable(cmuClock_GPIO, true);
         
          GPIO_PinModeSet(BUTTON_PORT, BUTTON_PIN, gpioModeInput, 0);
         
          while (1)
          {
                // Grab the state of the button, 1 for high voltage, 0 for low
                bool live_button_state = GPIO_PinInGet(BUTTON_PORT, BUTTON_PIN);
         
                // If the button is currently pushed, blink a single cycle
                if (live_button_state == 0)
                {
                      blink_one_cycle();
                }
          }
        }

        如果一切连接妥当,按下该按钮将使 LED 灯带闪烁,而松开该按钮则会使其停止闪烁。

         

        接下来制作 LED 灯带开关,其中按一次可开启 LED,再按一次可将其关闭。为此,我们需要记录按钮状态,如下所示:

        int main(void)
        {
          /* Chip errata */
          CHIP_Init();
         
          CMU_ClockEnable(cmuClock_GPIO, true);
         
          GPIO_PinModeSet(BUTTON_PORT, BUTTON_PIN, gpioModeInput, 0);
         
          // The initial state of the button is high when not pushed
          bool past_button_state = 1;
          // Start out not blinking
          bool blinking = false;
         
          while (1)
          {
                // Grab the state of the button, 1 for high voltage, 0 for low
                bool live_button_state = GPIO_PinInGet(BUTTON_PORT, BUTTON_PIN);
         
                // Invert the blinking mode every time a button is pressed
                // which generates a low voltage on a pin
                if (past_button_state == 1 && live_button_state == 0)
                {
                      past_button_state = 0;
         
                      // Invert the blinking mode, so that it is buffered and will
                      // keep blinking/not blinking when the button is released
                      blinking = !blinking;
                }
         
         
                // Reset the past state when the button is released
                if (live_button_state == 1)
                {
                      past_button_state = 1;
                }
         
                // Finally decide if there is going to be a blink cycle or not
                if (blinking)
                {
                      blink_one_cycle();
          }
            }
        }

         

        现在就大功告成了,您已可通过具有用户界面的输入引脚控制该 MCU。但该 MCU 会无限循环,直到按钮按下。这样非常耗电,而且由于我们可能需要将该 MCU 嵌入电池运行的设备,因此可以将其设置为在等待时睡眠。

         

        设置 MCU 在等待时睡眠

        将 MCU 设置为潜在最低能耗状态 EM4,可以达到近于关闭 MCU 的效果。退出此状态后的效果也与按下复位按钮非常类似,因此不能指望在进入和退出 EM4 状态后,任何变量会得到保留。这对本示例没有影响。但 EM4 可视为“软关机”状态。

         

        不过,入门套件中用于按钮的引脚无法将该部件从 EM4 状态唤醒,因此如果我们将其设置为 EM4 状态,就只能通过断电或按复位按钮来将其唤醒。这不是我们想要的。幸运的是,我们可以使用跳线来将按钮电路连接到能够从 EM4 状态中唤醒系统的输入引脚。

         

        参考手册中的 GPIO 到寄存器章节部分提供了最全面的相关详情,介绍了一些作为 EMU 外围设备控制 EM4 唤醒的配置寄存器。

         

        配置寄存器用于控制 MCU 外围设备的运行方式,请不要与 ARM 内核寄存器混淆。内核中的寄存器用于执行汇编码。配置寄存器嵌入在硬件中,由内存控制器映射到简单内存地址空间,因此可通过固件程序轻松访问。MCU 库的标头文件为所有外围设备配置寄存器生成 #define,我将在下列代码中使用这些定义。如有任何疑问,您可以随时通过将鼠标光标悬停在寄存器名称上,来查看 IDE 显示的实际内存位置。

         

        在 GPIO 配置寄存器空间中,启用名为 GPIO_EM4WUEN 的寄存器,该寄存器还用于选择用来唤醒系统的一个或多个(如果需要)引脚。GPIO_EM4WUPOL 寄存器持有唤醒引脚的极性,因此我们可以将其配置为高压或低压唤醒。请注意,我们还需要手动关闭几乎所有使用中的 GPIO,因为我们将需要保持 GPIO 模块通电,以在 GPIO 上寻找唤醒信号。如果我们在输出模式中保持 GPIO 引脚,则将继续驱动这些引脚,持续耗电。如果您需要在深度睡眠模式中继续驱动 GPIO,这可能有利于您的设计,但也可能只会耗电而已。

         

        我将选择引脚 PC9 作为 EM4 唤醒引脚,因为这是入门套件中唯一合适的引脚,而且位于 J100 跳线上。我将对开关输入引脚 PB9 和 PC9 进行物理连接,然后在 GPIO_EM4WUEN 寄存器中启用 PC9。这样,该按钮在 PB9 和 PC9 都适用于该 MCU。如果我们需要或使用这两者,只需将所有代码转接到 PC9。这些是电气性连接的副本。

        4.4_input_jumper.jpg

        由于该系统在退出 EM4 状态时基本以复位状态唤醒,我们需要为其设置初始状态,以使用户察觉不出中断,仍然认为是连续操作。用户应察觉不到该系统曾睡眠并进入过 EM4 状态。

         

        您需要将 em_emu.c 文件从 em_src 目录添加到您的 emlib 目录,就像我们在上节课中对 em_gpio.c and和 em_cmu.c 所做的一样。然后,将标头文件添加到源代码顶部,即 #include "em_emu.h"。

         

        接下来,生成名为 enter_em4() 的新函数,并从用于停止闪烁的代码中调用该函数。为设置妥善以确保 em4 实现闪烁效果,我将闪烁变量设置为 1。这样,LED 将持续闪烁,直到按钮再次按下。

         

        #define EM4_PORT              gpioPortC
        #define EM4_PIN               9
        #define EM4_WAKEUP_ENABLE     0x04  // Must change when changing w/u pin
        void enter_em4(void)
        {
              // Set PC9 as an input, used to wake the system
              GPIO_PinModeSet(EM4_PORT, EM4_PIN, gpioModeInputPull, 1);
         
              EMU_EM4Init_TypeDef em4_init = EMU_EM4INIT_DEFAULT;
              EMU_EM4Init(&em4_init);
         
              // Retain GPIO modes while in EM4, to wake it up with button press
              GPIO->CTRL = 1;
              GPIO->EM4WUEN = EM4_WAKEUP_ENABLE;
              GPIO->EM4WUPOL = 0;     // Low signal is button pushed state
         
              // Wait for the button to be released before we go to sleep
              // or else we will immediately wake back up again
              while (!GPIO_PinInGet(EM4_PORT, EM4_PIN))
                    ;
         
              // Add some delay to let the switch settle
              for(volatile long i=0; i<100000; i++);
         
              GPIO->CMD = 1;          // EM4WUCLR = 1, to clear all previous events
         
            EMU_EnterEM4();
        }

         

        进入 enter_em4() 函数后,我们设置该芯片,以在低极性唤醒 PC9 GPIO 引脚。我增加了 while 循环,以等待按钮松开,否则 MCU 将立即睡眠、查找 PC9 GPIO 低压,并退出 EM4 状态。

        最后,在主代码中,我转变了闪烁变量的初始状态,并增加了另一项条件:

        int main(void)
        {
          /* Chip errata */
          CHIP_Init();
         
          CMU_ClockEnable(cmuClock_GPIO, true);
         
          GPIO_PinModeSet(BUTTON_PORT, BUTTON_PIN, gpioModeInputPull, 1);
         
          // Wait for the button to be released before we start blinking
          // or else we will immediately go back to sleep
          while (!GPIO_PinInGet(BUTTON_PORT, BUTTON_PIN))
                    ;
         
          // Add some delay to let the switch settle
          for(volatile long i=0; i<100000; i++);
         
          // The initial state of the button is high when not pushed
          bool past_button_state = 1;
          // Start out blinking at first
          bool blinking = true;
         
          while (1)
          {
                // Grab the state of the button, 1 for high voltage, 0 for low
                bool live_button_state = GPIO_PinInGet(BUTTON_PORT, BUTTON_PIN);
         
                // Invert the blinking mode every time a button is pressed
                // which generates a low voltage on a pin
                if (past_button_state == 1 && live_button_state == 0)
                {
                      past_button_state = 0;
         
                      // Invert the blinking mode, so that it is buffered and will
                      // keep blinking/not blinking when the button is released
                      blinking = !blinking;
                }
         
                // Reset the past state when the button is released
                if (live_button_state == 1)
                {
                      past_button_state = 1;
                }
         
                // Finally decide if there is going to be a blink cycle or not
                if (blinking)
                {
                      blink_one_cycle();
                }
                else
                {
                      enter_em4();
                }
          }
        }

         

        运行此代码后,您将发现 LED 灯带在初次启动后不停闪烁。按下按钮后,IDE 将指示失去与入门套件的连接,而且 LED 将停止闪烁。这是因为系统进入深度睡眠状态,并关闭了调试端口。再次按下按钮后,LED 灯带立即开始闪烁,但不会自动连接调试器。

         

        提示:如果您想要查看运行系统的状态,可以在 IDE 菜单中依次选择“运行 -> 连接至”。此操作将连接到运行的系统,而不加载闪存,也不会指定 MCU 复位。只有在系统通电、闪烁且不处于 EM4 状态的情况下,此操作才有效。

         

        现在,当 LED 灯带关闭时,您的 MCU 仅消耗几微瓦特的电力。这仅是开端一步,我们的目标是通过纽扣电池、太阳能电力或能量收集解决方案来运行项目。

         

        如果您在疑虑 MCU 能否在 LED 亮起的同时进入深度睡眠状态,在闪烁模式下应关闭 LED 灯带时通过定时器唤醒,那么您已经超前开始思考了下一章的内容。在开始接触其他外围设备前,我会在下节课中先讨论一个更为基本的主题,包括可随时使用的时钟、定时器和中断。

         

        前一章节 | 下一章节

      • 嵌入式开发入门系列博客之四: 控制板外组件(第3部分: 控制板外LEDs)

        Siliconlabs | 09/266/2015 | 11:20 AM

        makersguide_ch4_3.png

        编写软件以闪烁板外 LED,包括采用单独 12V 电源的 LED 光带。

         

        控制板外 LED

        启动 Simplicity Studio 并重新加载上节课使用的闪烁程序。确保一切正常,且板载 LED 再次闪烁。然后,将用于控制该 LED 的端口和引脚从 PE2 更改为 PD14。要执行此操作,我使用 #define 编译器指令,以通过几行代码更改所有引脚位置实例。如果我已在上节课中执行了此操作的话,我们现在就只需通过代码更改一处的端口和引脚分布。

         

        #include "em_device.h"
        #include "em_chip.h"
        #include "em_cmu.h"
        #include "em_gpio.h"
         
        #define LED_PORT  gpioPortD
        #define LED_PIN   14
         
         
        /**************************************************************************//**
         * @brief  Main function
         *****************************************************************************/
        int main(void)
        {
          /* Chip errata */
          CHIP_Init();
         
          CMU_ClockEnable(cmuClock_GPIO, true);
         
          while (1)
          {
                // Turn on the LED
                GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 1);
         
                // Add some delay
                for(volatile long i=0; i<100000; i++)
                      ;
         
                // Turn off the LED
                GPIO_PinModeSet(LED_PORT, LED_PIN, gpioModePushPull, 0);
         
                // Add some more delay
                for(volatile long i=0; i<100000; i++);
                      ;
          }

        完成这些更改后,按下 IDE 中的调试按钮,然后您应看到该板载 LED 不再闪烁,且面包板上的板外 LED 开始闪烁。板外 LED 的灯光可能比该板载 LED 更暗或更亮,具体取决于大小和亮度等级的区别。

         

        GPIO 模式和驱动能力

        如果我们希望该 LED 变得更亮,可以降低限流电阻的电阻值,但需确保流通的电流不超出最大正偏压电流等级。但对于来自 MCU 中单个 GPIO 引脚的驱动电力,存在限制。默认情况下,GPIO 的电流上限为 6mA。

         

        该 GPIO 引脚可配置为输入或输出。但也有许多其他参数可用于将引脚配置为特定类型的输入或输出。参考手册中提供了全面的相关描述,下表仅概述了各模式的能力:

        SimplicityIDE.png

        备用驱动力可在 GPIO 寄存器,以及具有“DRIVEMODE”设置(可将限值设为 0.1mA、1mA、6mA, 和 20mA)的 API 中控制。MCU 中各端口可设置不同的备用驱动力,而且各 GPIO 可设置为应用“DRIVEMODE”设置,或者保持默认的 6mA 设置。必要时,您可以选择 20mA 设置,但通过外部控制设备驱动高电流更有效果,您将在本课程的稍后部分了解相关详情。将 MCU 的功耗和电流量保持在最低值。

         

        制作 12V LED 光带

        松散型 LED 非常适用于面包板,但不便于处理大量 LED。您可以购买用于更高电压的 LED 灯带盘,此类灯带盘具有嵌入式限流电阻和应用广泛的背部黏胶。这些灯带盘价格低廉,而且与其他类型的白炽灯照明相比,可保持低温,但我们需要找到控制它们的方法。我们可在具有松散型 LED 和电阻的面包板上生成 12V 灯带,来证明该想法能否成立。


        如果您准备为 MCU 提供 12V 电源以驱动某条 LED 灯带,请打消这一念头,因为这将会

        4_3_equivalent.png

        因为这将会把您的 MCU 烧坏。我们不能使用 MCU 来直接为 LED 提供 12V 电源。我们需要在 MCU 和 12V 电源之间添加一个开关,然后改为控制该开关。将要用于执行此任务的设备名为晶体管,这一基本电路元件具有所有必要能力,可帮助我们完成很多有趣的操作。该元件不仅可用作开关和放大器,还可用于控制电流。在此情况下,我们会将 NPN 晶体管接入面包板,以打造开关。

         

        用于控制 12V LED 灯带的等效晶体管电路

        Sparkfun 中的这一系列产品是不错的入门级晶体管。您还可以访问此链接下载晶体管电路的详细说明,或者点击此处获取简明有用的相关信息。此处列出了一些微控制器接口电路范例。我发现我经常会有很多问题以及“如果...,会怎么样”的疑问,而这些无法通过一个晶体管介绍就得到满意的答案。由于设备用途广泛,电路也变化无穷。


        可视化晶体管电路中的电压和电流曾经对我来说也是一个难题,直到我发现了一个极为方便的应用,名为 EveryCircuit。该应用支持 iOS 和 Android 设备,也可在计算机上通过 Chrome 浏览器访问。这款小型工具只需每年 $10 ,可用于虚拟连接电路元件、编辑元件的属性,进而在运行模拟时可视化流通的电压和电流。在模拟所有实际效果方面,该应用并非技术上最完美的,但应该足够帮助您完成任务。

        4_3_every_circuit.png

        显示电流和电压的 EveryCircuit 模拟

        借助此工具,您可以轻松处理电源电压值、更改限流电阻值、更改 LED 数量等,并可查看任一操作对电路的影响。在 NPN 晶体管电阻为 3k-ohm 的情况下,我将该晶体管用作开关。但如果您将放大电阻值调高,则可改变流通 LED 的电流。因此,您可实际使用此 NPN 晶体管进行电流控制。

         

        并没有特殊的 12V LED。12V 灯带使用我们一直使用至今的相同 LED,因为 LED 的物理结构基本上是固定的。模拟中串联了多个 LED,然后通过尺寸适当的串联电阻限制电流,支持的电源电压范围为 9V 到 13V。

         

        这意味着,无需为晶体管的 12V 一侧添加任何限流电阻,这些电阻已包含在灯带设计中了。我们只需将 MCU 连接到数字开关,并向 LED 灯带附加 12V 电源。无需对固件进行任何更改。这完全属于硬件变更,而且您已从驱动松散型 LED 变为驱动整个灯带。是不是很酷?

         

        所以快像这张 EveryCircuit 图一样在您的面包板上布线吧。首先,装配 12V 电池组,并测量该电池组的电压,以确保所有 AA 电池的两极安装正确。然后,连接面包板电路,如下所示。

        4_3_bread_conn.png

        警告:入门套件和面包板之间仅可连接两条电线。一条接地,另一条将 PD14 连接到面包板中部的电阻。绝不能将 12V 电路连接到入门套件,否则将损坏套件。其他电压电源和入门套件之间应始终连有电阻或其他组件。

         

        建议在连接入门套件前组合电路并仔细检查。连接的最后一条电线是 PD14 控制信号线。加载程序以闪烁 PD14 时,晶体管应在控制从 12V 电源到 LED 灯带的电压。如果您的电路无法亮起,使用多路复用器在应有电压的位置检查是否存在电压。您可以将检查结果与 EveryCircuit 模拟关联考虑,尝试找出故障原因。请确保 LED 的长脚按照电池电压方向安装。这一步骤经常出错,而且一旦出错,往往需要重新开始。

         

        看看现在能不能使这些 LED 闪烁吧!

        4_3_final.png

         

         

        前一章节 | 下一章节

      • 嵌入式开发入门系列博客之四: 控制板外组件(第2部分: LED电路)

        Siliconlabs | 09/266/2015 | 11:19 AM

        makersguide_ch4.2.jpg

        在第四章的第一部分,您配置了入门套件来控制外部设备,现在该学习如何在面包板上制作 LED 电路了。

         

        LED 理论

        在第一课中,您编写使 LED 闪烁的代码时,实际上是在编写软件。您不是在独立制作 LED 电路。不过,我们确实从该课程中学到了知识,因为我们在本课中将要制作的电路已尽在掌握!我们拥有原理图!利用 Simplicity Studio,您可在欢迎屏幕上点击名为“套件文档”的窗格。打开该窗格后,您将看到适用于该板的“Wonder Gecko 入门套件”和“原理图”的访问渠道。在第 2 页用户界面部分,您可以看到您在第一课中控制的 LED 的 LED 电路。

        4_2_led_shematic.png

        Wonder Gecko 入门套件中的 LED 电路

        称为 UIF_LED[1..0] 的左侧总线可追溯至 MCU 中的端口 E、引脚 PE2 和 PE3。(如有疑问,可以在原理图的第 3 页查看该图。)

         

        在此电路中,入门套件设计者将各用户 LED 与限流电阻串联。与 LED 串联的此电阻限制了可流过整个电路的电流量。如果没有这些电阻,可能会流通过大电流,从而导致 LED 烧坏。

         

        如果您回顾下上节课,会发现我们将用户 LED 的 GPIO 设为了高水平,来向 LED 提供电力。该 MCU 并不生成电压,只是作为通过软件控制的开关。该开关一侧为 LED 电路,另一侧为 MCU 的源电压 (3.3V)。

        4_2_mcu_switch.png


        MCU 作为开关的等效电路

        可流通此电路的最大电流量可使用欧姆定律计算得出:

        V = IR

        其中 V = 电压,I = 电流,且 R = 电阻。

         

        由于该入门套件中的 MCU 源电压为 3.3V,而且可以在此处看出电阻为 3k-ohm,因此通过重排(还记得代数吗?) 我们可以算出可流通整个电路的最大电流为:

        I = V / R = 3.3 / 3000 = 0.0011A or 1.1mA

        算出的最大电流量为 1.1mA,但前提是该 LED 像布线用电线一样电阻为零,但事实上并非如此。该 LED 具有内部电阻,因此可流通电路的实际电流量更小。对于相互串联的电阻,会产生更大的电源-地面总体电阻。该电阻仅作为保护设备,来确保该 LED 不会获取超过指示灯所需的电力。

         

        该 LED 的极性如下图所示。为确保导电和发光,该 LED 必须按照正确的方向安装。如果您装反了,虽然不会造成糟糕后果,但会导致无法点亮。因此,为确保该 LED 能够工作,阳极处的电压应高于阴极。适用电压为多少?具体的正向电压参数可在各 LED 的规格说明中查看,但一般而言,LED 的电压范围为 2V 到 3.3V。实际电压可以略低于此范围下限,但您不应通过降低电压的方法来减弱 LED 灯光。下节课将介绍减弱 LED 灯光的适当方法。您也可输入更高的电压,但为免损坏 LED,需要使用限流电阻。

        4_2_led_mark.png

        LED 原理图符号和常见的物理设备极性标记

        因此,为使用您的 LED 和电阻在面包板上重现第一节课的内容,将引脚 PD14 从入门套件中新焊接的排针连接到面包板的第一列。这将作为 MCU 中用于控制外部 LED 的 GPIO。将位于面包板第 1 行的 3k-ohm 电阻与 MCU 控制线放在一起,并将其另一侧放到第 4 列。将单通孔 LED 安装到面包板的第 4 和第 5 列,将该 LED 的阳极放到第 4 列。LED 的阳极具有较长导线,与具有较短导线的阴极相比,应距输入高电压更近。将 LED 的阴极第 5 列与入门套件中标为 GND 的引脚连接。

        4_2_stk_conn.png

        LED 方向和面包板连接

        面包板中的各列孔与该列中的所有引脚相连接。分线板中引脚位于底部的组件通常跨于中心分离器,然后在分离器一侧将多条电线连接到面包板中的各列孔,实现设备间的连接。

        4_2_bread_conn.png

        面包板连接图

        现在,您的电路已完成,而且我们已制作出入门套件原理图中显示的电路,但我们需要将该软件更改为控制不同的 GPIO,而不是已连接板载 LED 的 GPIO。下节课将介绍相关详情。

         

        前一章节 | 下一章节

      • 嵌入式开发入门系列博客之四: 控制板外组件(第1部分: 面包板)

        Siliconlabs | 09/266/2015 | 11:19 AM

        makersguide_ch4.1.png

        在上一节课中,您学习了如何通过闪烁 Wonder Gecko 入门套件中的板载 LED 在 MCU 中发现生命的火花。我可以花更多时间来探讨所有板载电路,并且在接下来的课程中我将谈论更多相关内容,但真正有意思的是您能够用自己制作的电路来控制板外组件。这正是动手制作的意义所在,对吧?在本节课中,您将在无焊料面包板中制作自己的 LED 电路,并利用此入门套件中的按钮控制这些 LED。

         

        在最初的几节课中,我将刻意安排些较简单的项目,使您能够逐渐熟悉嵌入式系统。这样,我们可以先学习一些基本知识,在之后的课程中再逐渐增加复杂度。

         

        本课程所需材料

        • 无焊料面包板和布线用电线
        • 通孔 LED
        • 其他通孔电阻
        • 12V 电池组,或 12V 电源
        • PN2222A NPN 晶体管,1 Amp 等级
        • 焊铁和焊料
        • 54mm 排针
        • 多路复用器,也称为伏特奥姆计 (VOM)

        使用无焊料面包板

        创建硬件项目的最棘手问题之一是首先必须确定组件,并了解组件应发挥的功能以及如何连接所有这些组件。此问题非常重要,而且往往没有绝对的正确或错误答案。软件项目和硬件项目之间的区别就像是多选题测试和“自由发挥”测试之间的差异一样。由您来决定如何连接这些组件并确保其不熔化。

        假设上来说,您可以了解已选组件的要求、绘制示意图并设计印刷电路板 (PCB) 以放置组件,然后等待数周来印刷电路板、装配组件并获得交付。通常接下来您会发现自己无意间逆向连接了最重要的部件,因此必须再多等数周才能试用该电路。虽然有时超高速电路要求如此繁杂的过程,但一般情况下,大多数基于 MCU 的项目都无此必要。


        更好的办法是:您可以用无焊料面包板来连接这些组件。这样做不仅可以获取设计效果的

        4.1_kit.png

         

        近即时反馈,还可边进行 PCB 制造边开始固件工作。

         

        无焊料面包板和多种布线用电线

        利用面包板实施设计的缺点是最后会产生一堆交错的电线,因此不妨利用不同颜色、标签来处理电线或者将其捆扎起来,以免过于杂乱。请记住,面包板并不像正确制作的 PCB 那么可靠,PCB 具有较短的组件间电路。此阶段的目标是确保您将组件恰当连接起来,而不要求设计稳健。

         

        分线板

        自问世以来,半导体的尺寸一直在不断缩小。以前您可以订购“适用于面包板”版本的芯片,以用于大引脚设计,但现在已不是如此了。为利用最新、最先进的半导体技术制作面包板,您需要使用分线板,这种板将表面安装技术 (SMT) 组件中的极小引脚(或在某些情况下为小球)按可用引脚中心距(引脚间的距离,通常为 2.54mm,即 0.1 英寸)进行分离,以便将其连接到无焊料面包板。

        4.1_accelerometer_breakout.png

        2.54mm 中心距通孔的加速计分线板

        您的入门套件就是一个不完全的分线板。该板将 MCU 上的大部分引脚分离至 2.54mm 通孔,可用于放置发挥部件功用和通过 USB 连接计算机所需的其他电路。

         

        您可以访问 Sparkfun 和 Adafruit 等网站,以及 Mouser、Ebay 和 Amazon 来获取分线板或评估套件。但并不总是能在市面上买到,而且套件的成本往往高于裸片。

        4.1_breakout.png


        Schmartboards 0.5mm SMT 2.54mm 通孔分线板

        如果您勇于学习和尝试新事物,可以自己制作分线板。您可以利用分线板裸片进行制作,Schmartboards 提供多种组件包类型的裸片。制作时,您需要具有细尖头的焊铁和较好的放大镜或显微镜。焊料已位于板上,而且 SMT 设备与凹槽对应,便于排列对齐,因此您只需加热引脚和电路。这样,如果您一不小心损坏了组件,可以直接进行更换,而无需使用全新的分线板。

         

        制作外部 LED 电路

        要使用带面包板的入门套件,您需要沿着入门套件的边缘,将 2.54mm 通孔排针焊接到通孔测试点。您将发现焊接是或早或晚必须学习的技能,至少应学会焊接 2.54mm 中心距连接器,这属于入门级技能。订购分线板,开始实践操作。将 2.54mm 通孔孔头连接到分线板上的孔中。然后对入门套件执行相同操作。我喜欢焊接 2.54mm 通孔孔头,这样塑料条和长导线将位于入门套件的顶部(如下图所示)。对于小型分线板,我会将排针焊接到分线板的底部,并直接将其插入无焊料面包板。

         

        4.1_headers.png

        请务必使用左侧显示的排针,并沿着入门套件的顶部将短导线安装到板中的孔内,然后翻转板面,在背面进行所有焊接操作。

        SimplicityIDE.png

        焊接引脚时,尝试将焊料置于引脚一侧,将焊铁头置于另一侧,以便焊料在两者之间“流动”。您需要加热这两块金属,这样焊料可以同时将其接合,确保实现最佳连接。参见下图。如果圆铜焊垫加热不足,焊料将在引脚上变为球形,且不会流入接头。这称为冷焊点

        4.1_soldering.png

        将排针焊接到入门套件

         

        针对通孔的底部行和标为 J100 的跳线位置重复此流程。这是入门套件右侧、按钮旁边的位置。板上垂直排列着五个孔。

        4.1_j100_header.png

        现在,入门套件上的所有测试点位置均应与接头引脚相配了。

        在下节课中,您将了解连接外部 LED 所需的 LED 理论知识。

         

        前一章节 | 下一章节

      • 嵌入式开发入门系列博客之三: Hello World

        Siliconlabs | 09/266/2015 | 11:18 AM

        makers-iot_ch3_1_header.png

        在本课中,您将了解如何编写您的首个嵌入式程序。当软件程序员学会一种新语言时,通常使用该语言编写的首个程序仅是在显示屏上输出文字“Hello World”。由于嵌入式系统并不总是具有显示屏,我们一般会做的是使 LED 闪烁。此外,您将全面了解如何创建嵌入式可执行程序,以及如何将该程序转至 Wonder Gecko 入门套件。

         

        首先,通过 USB 线插入入门套件,并确保系统检测到该套件。由于您已在第一节课中安装了 Simplicity Studio,驱动程序应可识别并连接到该套件。接下来,打开 Simplicity Studio,并在“文件”菜单创建“新 Silicon Labs MCU 项目”。将该项目命名为“3_Hello_World”,然后 Simplicity 会为您打开 emptyProject.c 文件。

         

        入门套件中的 Wonder Gecko MCU 可通过 USB 线或置于左下角的小型纽扣电池通电。您现在无需使用纽扣电池,因此请确保小型开关滑向右侧。如果此开关设置错误,入门套件可由计算机通过 USB 检测到,但您将无法通过 Simplicity Studio 对该 MCU 进行编程。

         

        ch3.2_wondergecko.png

         

        C 代码文件结构

        如果您曾使用过类似 C 语言编写代码,则可跳过此节。在本节课中,我假设大部分读者可能接触过高级计算机语言,但不一定是 C 语言。因此,我将在此节中提供详细全面的介绍,以便您了解 C 语言程序的相关术语。

         

        emptyProject.c 文件由 Simplicity Studio 自动创建,并用计算机 C 语言编写。此文件包含 C 语言源代码,该代码将通过计算机程序编译器解析,并通过链接器与其他支持源代码链接,然后转译为可执行程序。接着,该可执行程序会转至您的 MCU 以执行。计算机程序解析、编译、链接、转为可执行程序的过程称为生成过程。

         

        通过此过程为嵌入式项目制作的软件称为固件。称其为固件是因为传统意义上,嵌入式软件一次写入,无法再进行更新。如今,许多设备中都包含可升级的固件,因此软件和固件之间的区别愈发不明显了。

        3.1.2.png

        emptyProject.c 的内容

        emptlyProject.c 文件的第一部分是注释块标头。此注释块不是必填字段,仅用于供人们了解该文件的目的和版权声明,通常包含旨在保护公司的冗长许可条款。此注释部分一般用开始块注释标记 /* 和结束注释标记 */ 指明。这两个标记之间的所有信息都会被程序忽略,您可以随意修改这部分内容。这些内容可以显示在代码中的任何位置,甚至是包含在单行代码中。这就是 C 语言风格注释。您还可以使用 C++ 语言风格注释,此类注释用两道斜杠 // 在单行的其他位置加入任何内容。我比较喜欢使用这类注释,因为只需要两次击键,而无需使用换档键。

         

        您可能会在注释标头中看到一些略显奇怪的 @ 符号,其实这是 docstring 字符串。显示的 docstring 字符串使用 @file@brief 等特殊关键词,因为该字符串用于通过第三方工具 Doxygen(不属于 Simplicity Studio)基于源代码生成文档。如果没有这一文档编制机制,将会有大量源代码,而没有任何文档!

         

        一般,此注释块后的区域用于输入 #include 声明,这种编译器指令可以指明哪些文件应包含在编译程序中。# 符号表示编译器指令(也称为预处理器指令),而且 Simplicity Studio 可为此指令添加不同颜色以进行标识。#include 告知编译器在何处查找将用于代码的任何外部函数,并可放入常量和已为特定 MCU 模式设置的 #define#define 之后会用于其他预处理器指令 #if#ifdef#ifndef#endif。以 # 符号开始的任何声明都不会出现在可执行程序中。这些声明不会在 MCU 中执行,但可控制哪些代码块将加入可执行程序。Simplicity Studio 将基于 #if/#ifdef/#ifndef 声明,自动隐去不在您 MCU 中执行的代码块。

         

        emptyProject.c 文件包含两段 #include 声明。第一段为 #include “em_device.h”,用于将您的程序设置为可在 EFM32 MCU 上运行。该声明使您的代码能够读取 MCU 中的寄存器,并访问 Silicon Labs 团队已为您的程序设置访问权限的所有常量。如果没有该声明,每次需要使用 MCU 特有功能时,您都必须在参考手册中查找每个 MCU 设置的大量详情或者其他值。第二个声明为 #include “em_chip.h” ,引入程序稍后部分引用的函数 CHIP_Init()。


        使用 Simplicity Studio 的最佳好处之一是能够通过悬停鼠标光标在源代码中找到标识符的更多相关信息,更可通过选中和右键点击查看所有类型的可执行操作。例如,当我们将鼠标悬停在 include 声明上时,不会显示任何信息。但如果高亮文件名称并点击右键,就会看到很多选项。按照“Open Declaration”菜单选项操作,或者按 F3 按钮,Simplicity 将打开一个新标签,其中显示了所引用的文件。向下滚动还会看到 CHIP_Init() 函数的定义

        __STATIC_INLINE void CHIP_Init(void)
        {
        #if defined(_EFM32_GECKO_FAMILY)
          uint32_t                    rev;
          SYSTEM_ChipRevision_TypeDef chipRev;
          volatile uint32_t           *reg;
        ...

         

        现在无需为看不懂这些定义而担忧。先相信我,记住这是 CHIP_INIT() 函数的定义就好。

        导航回 Simplicity Studio 中的 emptyProject.c 选项卡。

         

        在编译器指令部分的后面,有一个描述主函数定义用途的 docstring。函数是程序的入口,因此具有特殊性。指定返回类型函数名称,后跟放在括号内的可选输入参数,即可创建函数定义。

         

        对于主函数来说,必须指定 int 作为返回类型并且无参数。注意:与桌面编程不同,由于没有命令行,因此无法将命令行参数传递至嵌入程序中。

         

        完成函数定义后,后面紧跟着是函数实现(括入波形括号 { } 中)。

         

        主函数的第一行是代码注释 /* Chip errata */,其目的在于说明下一行的函数调用实现的功能。能够在代码中看到注释是一件好事。但是借助 Simplicity Studio,您甚至可以了解到函数功能的更多信息。将鼠标悬停在 CHIP_Init() 函数调用上,即可在弹出窗口中看到将在浏览器中显示的信息:

        chp3_code_info.png

        如果您突出显示 CHIP_Init,然后右键单击并选择“Open Declaration”,则会打开参考文件 em_chip.h 并显示在函数声明的位置,同时在函数定义上方的 docstring 中显示函数的用途:

        /**************************************************************************//**
         * @brief
         *   Chip initialization routine for revision errata workarounds
         *
         * This init function will configure the EFM32 device to a state where it is
         * as similar as later revisions as possible, to improve software compatibility
         * with newer parts. See the device specific errata for details.
         *****************************************************************************/

        现在,您知道了 CHIP_Init() 函数的功能,我甚至都不需要告诉您!希望您在需要了解函数功能时对函数执行这种操作。

         

        最后,固件会进入 while 循环,这种循环可保持 MCU 永久运行,或直到您使用新的可执行文件加载时对其进行重置。

         

        找到板载 LED

        我们已在第一节课程中编译并构建了简单的 emptyProject.c 文件,因此可以跳过这一步骤。接下来,我们将修改这个文件,以启用连接入门套件上的板载 LED 的通用输入/输出 (GPIO) 引脚。下一步的目标是在连接到入门套件测试 LED 的 GPIO 引脚上输入电压。为此,我们需要了解测试 LED 连接到 Wonder EFM32 MCU 上的哪个 GPIO 引脚。我们可以直接在 Simplicity Studio 中完成这一操作。

         

        点击 IDE 右上角的“Simplicity 视角”图标,即可返回 Simplicity Studio 主屏幕。

        chp3_simplicity_perspective.png 

        然后,点击“套件文档”方块:

         

        chp3_kit_doc_tile.png

        系统则会显示适用于您套件的所有可用文档。

        chp3_kit_documentation.png

        打开该套件的用户手册后,您会发现第七页上写着:“LED 连接着高电平有效配置中的引脚 PE2 PE3它告诉我们打开 LED 所需了解的所有信息。

         

        启用 GPIO 时钟

        在尝试向任何引脚输入电压之前,我们首先必须打开 GPIO 时钟源。默认情况下,除 HFCLK 外的所有时钟均已禁用,HFCLK 是让程序在 MCU 上运行的唯一时钟,但不允许许多外围设备(如果有)运行。

         SimplicityIDE.png

        要启用 GPIO 时钟,我们需要在编译器指令部分添加语句 #include “em_cmu.h” 文件。该操作可引出简化工作必需的时钟管理单元 (CMU) EFM32 库。我们只需使用“em_system.h”中的定义来完成操作,但是需要完成一系列的事件。Silicon Labs 的库团队已算出这些支持库中的事件顺序,因此如果没有更好的方法,我通常会使用它们。

         

        请注意,无论何时在编译器中添加 .h 文件,我们都必须在构建环境中添加其他的库驱动程序。.h 文件属于标头文件,可输入函数声明和某些定义。但是,部分定义只能在 .c 文件(实现文件)中找到。将 emlib 驱动程序的 .c 文件输入 3_Hello_World 项目的方法有些复杂。我希望能有更简单的方法,但是事实就是如此……

         

        如果您使用的是 Windows 计算机,那么您需要的文件位于 C:\SiliconLabs\SimplicityStudio\v2\developer\sdks\efm32\v2\emlib\src。对于所有其他计算机,文件路径与 SiliconLabs 安装目录有关。只需将整个路径复制到您的浏览器或查找器窗口,并标记为书签即可。然后,无论何时您需要库文件,请打开此书签,在目录中找到文件并复制到 Simplicity Studio 的 emlib 目录中。在这种情况下,我们需要 em_gpio.c 文件和 em_cmu.c 文件。选择两者后,将其复制到 3_Hello_World 项目的 emlib 目录中。

         

        将这些文件复制到 emlib 时,Simplicity Studio 将询问您是否希望复制这些文件或链接这些文件。如果您复制这些文件,则会及时冻结文件,这些文件在您作出改变之前不会发生任何变化。如果您链接这些文件,那么您的库文件会在您更新 Simplicity Studio 软件时进行更新。我喜欢创建副本,然后控制何时获得现有项目的更新。

         

        我们需要将下面的 CMU 函数调用添加到代码中才可启动 GPIO 时钟。只需将其拖至无返回任务的 CHIP_Init() 函数调用的后面即可。

         

        CMU_ClockEnable(cmuClock_GPIO, true);

         

        我如何知道这一点的?这很简单,因为它会出现在所有示例中。但是如果我并不知情,那么我如何可以发现?再次说明,相关信息位于 Simplicity Studio 软件中。选择 IDE 右上角的“Simplicity 视角”按钮,返回 Simplicity Studio 主屏幕。然后,选择“软件文档”方块。您现在应该已熟悉了方块样式,因此我没有提供图片。在出现的窗口中,您应下拉至 Wonder Gecko 部分并点击链接“Wonder Gecko 产品系列的 emlib 外围设备 API”,系统随即会向您显示详细介绍所有可用 emlib 函数的互联网页面。

        ch3.2_api.png

        点击 CMU_ClockEnable 程序分支后,您会看到函数功能的所有详情:

        ch3.2_clockenable.png

        对于了解现有的库函数及其用途,这款工具很有用。但是现在看到参数列表时,您可能会想:CMU_Clock_Typedef 是什么?如何将其传到函数中?这很简单。只需点击链接到该类型枚举列表的 CMU_Clock_Typedef 即可。您会看到 cmuClock_GPIO 已位于该表中。您已在文件的顶部添加了 em_cmu.h,因此 Simplicity Studio 会检测出枚举,并会赋予其斜体蓝色样式,表示它是已知枚举。

         

        设置高状态 GPIO 引脚

        现在我们已启用时钟,可以准备开启 LED 了。您可以再次浏览 emlib API 指南,找到“em_gpio.h”库(记得在编译器指令部分的代码顶端加上 #include “em_gpio.h”)以及以下函数:

         

        GPIO_PinModeSet(gpioPortE, 2, gpioModePushPull, 1);

         

        重述一次,gpioPortE 和 gpioModePushPull 的枚举可在 em_gpio.h 库标头文件或 emlib API 指南中找到。无需为不了解 gpioModePushPull 的含义而担心。下节课将介绍相关详情。通过此声明可指示 GPIO 外围设备将引脚 E2 的输出模式设置为推拉驱动程序,并将该引脚设置为高状态。回顾下,您会发现其中一个测试 LED 位于引脚 E2 处,且属于“高电平有效”类型,这意味着我们必须将引脚 E2 驱动至高状态,才能开启 LED。这就是我们已完成的任务。

         

        一切顺利!我们现在可在入门套件中运行首个程序了。

         

        构建和运行可执行程序

        现在按下构建按钮,就是我们曾讨论过像个小锤子、位于屏幕顶部工具栏中的按钮。当您完成更改后,IDE 将自动保存并构建 emptyProject.c 文件。正常情况下,您会看到底部控制台“构建控制台”中的数据流动,直到其显示操作是否成功。请务必每次回头查看日志,查找是否出现警告和错误,因为警告往往和错误一样糟糕,都会造成失败结果。始终滚动至“构建控制台”中显示的首个警告或错误,然后逐个查看。阅读详情,并尝试解决该问题。然后重新构建,直到没有任何错误或警告。

         

        构建可执行程序后,您可以将其转至 Wonder Gecko 并在 MCU 中运行。要进行此操作,按下工具栏中的调试图标。该图标的外观类似于小故障图标。

        ch3.2_icon.png

         

        调试工具会先保存您的文件,然后(重新)构建可执行程序,并将该程序转至 Wonder Gecko,您的当前执行行图标会留在 main() 函数的首行中。

        SimplicityIDE.png

        将第 30 行设置为断点,该行包含 CMU_ClockEnable() 函数。为此,在第 30 行左侧空间点击右键,并选择“切换断点”。您的屏幕应显示如下:

        ch3.2_debugger.png

        顶部显示“运行”、“暂停”、“分离”、“复位”、“进入”和“越过”图标,Simplicity Studio 会自动切换至“调试视图”。您现在可使用这些图标。首先点击“运行”按钮。Simplicity Studio 将执行第 30 行前的所有行,将当前行图标置于第 30 行,并准备执行该行。在该处点击“越过”按钮,您将看到当前执行箭头移至第 31 行。按下“越过”按钮后,系统会执行第 30 行中的代码,而且仅执行该行。在 MCU 中,GPIO 时钟应处于活跃状态,已可执行第 31 行。再次按下“越过”按钮即可!LED0 应在入门套件中亮起!

        ch3.2_led.png

        LED0 提供 LED 照明

         

        使其闪烁

        先等等!我们可以将其开启,但“Hello World”程序要求我们使其闪烁。先完成这项任务吧。

         

        我们需要依次关闭和开启该 LED,但如果开关的速度过快,就看不清灯光闪烁了。要知道,MCU 的操作速度极快,高于肉眼的观察速度。这是以纳秒、微秒和毫秒为单位计算的。所以我们需要增加延时,然后关闭该 LED,再增加延时,之后将其重新开启,周而复始地重复这一过程。延时可通过多种方法增加,是后续课程的重要主题之一,我们现在先采用一种简单的执行延时方法。

         

        生成如下主函数:

        int main(void)
        {
          /* Chip errata */
          CHIP_Init();
         
          CMU_ClockEnable(cmuClock_GPIO, true);
         
          /* Infinite loop */
          while (1)
          {
                // Turn on the LED
                GPIO_PinModeSet(gpioPortE, 2, gpioModePushPull, 1);
                      
                // Add some delay
                for(volatile long i=0; i<100000; i++)
                    ;
               
                // Turn off the LED
                GPIO_PinModeSet(gpioPortE, 2, gpioModePushPull, 0);
               
                // Add some more delay
                for(volatile long i=0; i<100000; i++)
                    ;
          }
        }  

         

        执行上述代码后,您的 LED 应会有序闪烁。原理如下。我们利用 for 循环使 MCU 内核忙于做无用功,从而增加延时。这无疑是最糟糕的一种延时方法,因为无法保持一致的处理器速度,而且功耗较大。我在此示例中使用此方法,只是因为其较为快捷和便利。此方法非常适合用于原型设计阶段。关键词 volatile 向编译器指示变量 i 的变化可能会超出编译器的控制。例如,同一内存空间中可能运行其他 MCU,因此该变量随时可能发生变化。基于构建设置,编译器可能会“优化掉”重复(无用的)i 设置。整行指令可能都不会显示在可执行程序中。声明 volatile 可指示编译器谨慎处理,并要求机器执行该无用循环 100,000 次,从而增加充足延时以使 LED 固定状态,确保肉眼可见的短暂关闭效果。这有助于您了解 MCU 在短短一秒间可完成的操作。如果编译器会优化掉 i 设置,那么 for 循环不会出现在您的可执行程序中,也根本不会发生延时。LED 的闪烁速度将快到您根本观察不到。

         

        这样便完成了您的首个真正的嵌入式程序。恭喜!您已加入能够编写嵌入式程序的精英团队。现在不妨向团队成员展示您的闪灯创作。但请尝试使用“编译”和“易失性变量执行延时”等刚刚学会的术语,而不是仅将其描述为闪灯。

         

        如果您还想深入探索,不妨研究下如何加快或减慢闪烁速度。可以使其闪烁三次,然后停止一会儿吗?可以将闪烁速度加快到使 LED 看起来像是变暗了一样吗?可以使 LED 逐渐变亮,就像日出一样吗?您现在已掌握相关工具,可使用我们已讨论过的简单语句。在注释部分发表您的解决方案。

         

        在下节课中,我们将继续研究非常重要的 GPIO 和其他驱动方法,包括基础电子知识和面包板介绍。

         

        前一章节 | 下一章节

      • 嵌入式开发入门系列博客之二:入门

        Siliconlabs | 09/266/2015 | 11:17 AM

        Maker's Guide

        微控制器 (MCU) 与计算机的差异

        所有计算设备都有自己的心脏,即一个处理数据的小小“计算器”。这是其最基本的功能。俗称的处理器“内核”不过是一个输入数字(可理解为指令)并输出其他数字(也就是指令的结果)的机器。我们讨论的是全球最强大的服务器还是最小的产品,这一点并不重要。从这个层面来说,所有计算机都是一样的。

        最强大的计算机处理器和小型 MCU 的主要差异通常在于:

        • 支持的指令类型,
        • 处理指令的速度(即时钟频率),
        • 通常一次可处理的指令的位宽,
        • 捆绑处理器内核的数量(并行工作)以及

        内核周围加速指令处理速度的支持电路。

         

        MCU vs Computer

        计算机与微控制器

         

        因此,连接互联网的大型服务器的时钟频率最高可达数 GHz,有至少四个内核运算大量硬件加速 64 位宽指令,并且配有用于存放快速本地内存和其他硬件加速电路的大型缓存。这需要耗费很多能源,但是这些服务器使用电源线与交流插座相连,因此能够持续工作。另一方面,MCU 通常以电池供电,并且需要耗费尽可能少的能源,时钟频率尽可能低(节能考虑),只能处理低至单核 8 位宽的少量指令。嵌入式 MCU 的目的在于利用尽可能少的资源处理尽可能多的操作。这个特点使得 MCU 成本低廉,可以用于一次性产品中。

         

        但是,关键的一点在于 MCU 在最根本的层面上与标准桌面计算机或网络服务器并无差异,您在过去可能已接触过此类设备的编程。它们的核心均具备相似的数值运算器,只是外围设备不同罢了。因此,您已经掌握的在普通计算机上的编程技术可帮助您学习如何对嵌入式设备进行编程。有没有放松点?

         

        然而,尽管所有移动/台式/服务器计算机都有一套标准资源(比如硬盘、显示器和网络接入等)可供编程人员使用,但 MCU 却截然不同。大部分情况都有严重的资源限制,制造商和型号之间的专业化程度很高。您必须谨慎选择 MCU,以防在执行特定的嵌入式任务时浪费财力或精力。此外,您必须小心使用身边的可用资源。我会在这方面为你们提供帮助。

         

        此外,所有移动/台式/服务器计算机预安装的操作系统 (OS) 可帮助编程人员编写、存储和执行源代码以及优化机器的大量资源。如果出现错误,OS 可通知编程人员相关错误,从而扭转败局。OS 的作用十分强大,但是它的存在会消耗大量宝贵的资源,而这对于您的 MCU 解决方案来说功耗过高。尽管 MCU 所谓的“RTOS”具备专用的实时 OS 和完整的后续资源,但是很多嵌入式解决方案不需要花费此类开销或者没有充足的理由来承担此类资源的开支。

         

        关于 EFM32 系列 MCU

        本课程所选择的 EFM32 系列 MCU 为 32 位内核。通常来说,这表示可一次处理 32 位的信息。也有 8 或 16 位的 MCU,这些 MCU 一次可处理的数据更少。一次可处理的数据越多,程序的执行时间就越短。

         

        EFM32 系列处理内核的类型为 ARM Cortex M0+、M3 或 M4(具体取决于 EFM32 型号),均已从 ARM 公司获得授权。这些 ARM 内核在移动设备市场十分流行,并且获得了数千家公司的授权。ARM 内核支持 Thumb 格式的机器指令。但是从编程人员的角度来说,指令格式的类型通常不太重要,因为软件编程通常以较高级的语言编写,而编译器会负责将较高级的语言转译为机器指令。下节课会介绍这一过程。

         

        MCU Bare Minimum

        MCU 最低组件要求

         

        但是 MCU 远不止是一个 ARM 内核。为了在最低要求下使用内核,MCU 需要一些非易失性存储器(在没有电源的情况下继续编程的存储器,通常为闪存存储器)来存储软件指令、一些随机存取存储器 (RAM) 来存储这些指令的结果,以及一些输入/输出引脚来接受程序指令并将指令结果传送至外部。尽管 ARM 内核的授权来自于一家公司,但是 MCU 上的其余模块可从其他供应商采购,或者由生产 MCU 的半导体公司进行定制。

         

        拥有最低要求的 MCU 后,我们可以使用它来将程序嵌入到所有类型的电子产品中。编程人员需要在这种精简 MCU 的限制内完成工作,但可以完全运行某些应用程序。但是在 EFM32 系列 MCU 中,编程人员有很多选择。为制造更为强大且节能的 MCU,Silicon Labs 添加了很多板载硬件加速计模块(称为外围设备),这些设备可自动执行原本在软件中进行严格编程极为麻烦或耗时的很多任务。下图显示了这些板载外围设备。

         

        MCU Exter.png

        EFM32 系列的外围设备

         

        板载外围设备摘要

        要了解他们在这种小型嵌入式芯片内添加的所有设备,请仔细阅读本部分。如果您看不懂其中的很多内容,请不必担心,因为这只是简单的概述。这些术语看得越多,就越理能解它们的含义。本书大篇幅介绍了这些外围设备,我会在课程中尽可能多地介绍这些内容。

         

        此外,所有这些外围设备均在各型号的简明参考手册中有详细介绍,并附带 Simplicity Studio 的链接,而此刻 Simplicity Studio 正在下载到您计算机硬盘中。在完成设置并开始运行后,我还会在本部分的后面时间介绍如何在 Simplicity Studio 中找到这些参考手册。

         

        系统监控器 – 适用 EFM32 所有型号

        • RMU – 复位管理单元 – 控制 MCU 的复位信号:在上电时释放复位,或在掉电时执行复位。
        • CMU – 时钟管理单元 – 启用、禁用或控制 MCU 中的时钟速度。这可能并不是您所认为的计时时钟。实际上,MCU 中仅有一到两个时钟用于计时。时钟通常用于控制内核和外围设备的运行速度。没有时钟的模块会被禁用。默认情况下,除 MCU 内核时钟外的所有时钟均为禁用状态,即使是内核时钟也可在睡眠模式下禁用。我将在后续课程中详细介绍时钟源。
        • EMU – 能源管理单元 – 控制能源模式,自动化关闭外围设备时钟并再次启动的过程,进而实现节能。
        • WDOG – 看门狗定时器 – 让编程人员能够控制在复位前 MCU 的锁定时间或处于永久回路的时间。这一点对于恢复执行不良指令集的系统很重要。
        • DBG – 调试接口 – 实现 MCU 闪存、外围设备配置设置和 RAM 的编程和检查。这一点对于将程序转移至 MCU 并随之调试这些程序很有必要。

        通信外围设备

        • GPIO – 通用输入输出 – 这是最重要的外围设备之一,可让 MCU 在 MCU 引脚上接收数据或输出数据。但是请注意,如果在启动和激活外围设备后,已确定这些引脚更加具体的目的,那么 MCU 上的很多其他外围设备则会替代 GPIO 外围设备。
        • USART – 通用同步异步接收器/传输器 – 这是一种“瑞士军刀型”外围设备,可通过串行连接实现 MCU 和外部设备之间通信的自动化。串行连接的意思是每一位的数据按时间跟随下一位数据,就像是单文件行。可在 SPI、I2C、I2S 和 UART 等多种格式下运行。它可在异步模式(没有作为锁存信号的独立时钟行)或同步模式下运行(伴有锁存时钟行)。如果以上很多内容看不懂,请不必担心。我们会在后续课程中详细介绍该外围设备。
        • UART - 通用异步接收器/传输器 –这是 USART 的子集,仅可在异步模式下与外部设备进行通信。仅适用部分型号。
        • I2C – 内部集成电路 – 也叫做“I 平方 C”,是另一种以串行数据格式与外部设备通信的外围设备。
        • USB – 通用串行总线 – 另一种串行通信方式,可将外部 USB 设备作为主机或外围设备进行通信。这是现代消费类计算机进行通信的常见方法。仅适用部分型号。
        • EBI – 外部总线接口 – 可实现串行模式连接设备的通信。并行连接具有多个地址和/或数据引脚,以便从每个锁存时钟边缘传输多位数据。通常这可用于外部存储器,因为可提升 MCU 存储器空间。还可用于 LCD 屏幕等其他设备。仅适用部分型号。
        • TFT - 薄膜晶体管显示器驱动程序 – EBI 的子模块,此驱动程序负责与 TFT 显示屏幕帧缓冲器的连接。仅适用部分型号。
        • LCD – 液晶显示器驱动程序 – 可驱动分段式 LCD 显示器。仅适用部分型号。

        模拟外设

        • ADC – 模拟数字转换器 – 将内部信号或外部 MCU 引脚上的电压转换成以精确数字表示电压的数值代码。这些转换的速度最高可达每秒一百万次,ADC 通常可与频率组件用于快速变化的信号。这可用于实际模拟环境中的取样,例如用于音频记录/处理、创建示波器、无线电和各种科学仪器中。仅适用部分型号。
        • ACMP – 模拟比较器 – 将 MCU 引脚与其他 MCU 引脚或属于设备操作电压的内部参考进行对比。这一点与 ADC 相似,但是灵活性较低。输出并不是一串数字,而是单个内部信号或外部 MCU 引脚上的高低信号。ACMP 一般用于比较波动较少的电压,例如检测是否存在其他外部设备。如果配合相应的电阻网络使用,还可以用于对比电压以确定外部电压级别。当然,还有众多其他的用途,因为这种功能对于创意十足的设计者来说十分实用。
        • PCNT – 脉冲计数器 – 可对 MCU 输入引脚上的电子脉冲进行计数。一般用于计算轴旋转次数,在有关电机编码的课程中,我们还会介绍一些常见用途。
        • DAC – 数字模拟转换器 – 将程序中的数字值转换为模拟电压,进而输出到 MCU 引脚上。这与 ADC 正好相反,是 MCU 输出模拟值的唯一方式。多数 MCU 引脚只能输出二进制的数值,这些电压值等于电源电压或没有任何电压。DAC 一般用于将数字音乐文件转换为扬声器可播放的波形文件,同时也适用于很多需要快速波动的模拟电压的其他用途。仅适用部分型号。
        • OPAMP – 运算放大器 – 运算放大器是 DAC 的子模块,用于将电压从输入量级放大到输出量级。启动后,DAC 会持续使用运算放大器,但是如果未启用 DAC,则可将 OPAMP 用作您设计中的分立电路元件。仅适用部分型号。
        • IDAC – 电流数字模拟转换器 – 与 DAC 相似,但作用于电流。相关用途包括限制 LED 或任何其他需要控制电流量的设备所消耗的电流。仅适用部分型号。
        • VCMP – 电压比较器 – 与 ACMP 相似,但是唯一输入电压是 MCU 本身的源电压,因此可释放 ACMP 引脚用于其他电压源。VCMP 一般用于测量向 MCU 供电的电池电量。
        • LESENSE – 低能耗感应接口 – 在低能状态下连接多个外围设备的控制器,否则不可用。仅适用部分型号。

        定时器外围设备

        • 定时器 – 带有可编程触发器的快速运行时钟。定时器可正数也可倒数,并能够在计时器归零、过零或达到预定值时提示软件。定时器的时钟速率可以控制,而显示事件可输出到输出引脚。该定时器通常用于及时测量小事件,而不是用于计时,尽管可通过跟踪软件变量的过零来计算较长的间隔。该定时器还可用于脉冲宽度调制 (PWM),我们会在后续课程中详细介绍 PWM。
        • LETIMER – 低能耗定时器 – 定时器的子集,可在低能耗模式下运行,功能比定时器少。仅适用部分型号。
        • RTC – 实时时钟 – 用于精确计时,跟踪时间长度(从秒到年)长于定时器外围设备的一般时间长度,甚至能够在深层睡眠模式下运行。仅适用部分型号。
        • BURTC – 备份实时时钟 – 与 RTC 一样,此外围设备可实现长时间的精确计时,但是在最深层的睡眠模式下,系统会第二个将其断电。仅适用部分型号。
        • WDOG – 看门狗定时器 – 请参见上文的“系统监控外围设备”。

        系统加速器

        • DMA – 直接存储器访问 – 让外围设备通过彼此之间的内部数据总线完成数据传输,不调用内核。这个功能可让内核处理其他任务或将内核置于较低能耗的状态下运行,同时在后台自动进行数据传输。
        • PRS – 外围设备反射系统 – 在发生预编程事件时,让外围设备互相触发。可用于在发生特定事件的情况下实现系统响应自动化。
        • AES – 高级加密标准加速器 – 提供硬件加密服务,以便将此工作从内核和软件上卸下。仅适用部分型号。

        太神奇了!芯片虽小,五脏俱全。尽管学习如何使用所有这些接口的确需要花费一些功夫,但是当您发现这些模块不仅能够自动完成执行任务的流程,而且比仅使用软件编程的速度更快、更加节能,您就会觉得之前的努力并没有白费。

         

        您的项目适合哪一款 EFM32?

        您不必立即决定。Wonder Gecko 入门套件是一款含有几乎所有功能的模型,因此您可以了解到 EFM32 系列提供的所有功能。它的确缺乏 EFM32 系列中其他型号所支持的少数功能,但是提供了绝大部分的功能。一旦学会如何使用 MCU,您可以选择其他型号,并轻松地将您的软件连接到该模型。

         

        EFM32 系列共有六个基础型号,各个型号均有不同的 RAM、闪存和引脚数量配置。相关型号为 Zero Gecko、Tiny Gecko、Gecko、Leopard Gecko、Giant Gecko 和 Wonder Gecko。您可通过下方链接 了解不同型号的详细信息:

         

        重要注意事项:尽管能够使用所有这些外围设备是不错,而且某些型号的设备有着多个外围设备配置,但是请注意不一定要同时使用所有外围设备。例如,USART 能够搭配 SPI 协议、I2S 协议、UART 协议等使用。但是,一组引脚上同一时间只能使用其中一个协议。此外,USART 在其应用的引出线上有一些不同的“位置”,但是可能会与共用引脚的其他外围设备冲突。请不必担心,我会在 Configurator(帮助您配置所选设备引出线的工具)部分介绍该内容。


        http://www.silabs.com/SiteDocs/selector-guide/MCU/efm32-selector-guide.pdf

         

        您的软件现在应该已下载好,请开始安装,然后我们来讨论完成课程所需的材料。

         

        材料列表

        您所需要的最重要的组件是 Wonder Gecko 入门套件。此评估板含有 Wonder Gecko MCU 和 JTAG 编程工具,并已准备好您在课程中需要用到的 GPIO 引脚。它可通过随附的 USB 数据线与您的计算机相连。我们在第一节课中只会用到这张卡,并在后面的课程中将其连接到其他电路。

         

        下面的材料列表列出了您需要在前几次课程中用到的材料:

        组件

        零件号

        数量

        单价

        链接

        Wonder Gecko 入门套件

        EFM32WG-STK3800

        1

        $29.99

        Mouser

        无焊料面包板

        Sparkfun PRT-09567

        1

        $4.95

        Sparkfun

        带电流测量功能的电压电阻表

        TekPower TP4000ZC 不错,带自动量程功能。也可以使用价格较低的其他替代品。

        1

        $35.99

        Amazon

        跳线电线套装

        Schmartboard 920-0112-50

        1

        $25.00

        Mouser

        蓝色通孔 LED

        Vishay TLHB4201

        3

        $0.55

        Mouser

        12V LED 照明带

         

        1

         

         

        电阻分类,¼ 瓦特,通孔

        Amazon 860-pc 套件

        1

        $17.99

        Amazon

        12V 电池套装(8 节 AA 电池)

        Eagle 12BH382A-GR

        1

        $1.36  

        Mouser

        NPN 晶体管,1 Amp 额定功率

        Fairchild PN2222A

        3

        $0.20 

        Mouser

        通孔二极管

        Fairchild 1N4448

        3

        $0.10  

        Mouser

        自动喷淋器阀

        Sparkfun ROB-10456

        1

        $7.95  

        Sparkfun

        USB 串行端口

        TTL-232R-RPI

        1

        $15.00

        Mouser

        MicroSD 分线板

        Sparkfun BOB-00544

        1

        $9.95  

        Sparkfun

        MicroSD 卡与 SD 卡适配器

        Sparkfun COM-11609

        1

        $13.95

        Sparkfun

        加速计分线板

        ADXL345

        1

        $17.95

        Sparkfun

        LED 驱动器分线板

        TI TLC5940

        1

        $12.95

        Sparkfun

        电阻式触摸屏 LCD

        Newhaven NHD-1.8-128160EF-CTXI#-FT – 注意:必须添加 $5.00的 2x12 引脚排针

        1

        $17.44

        Newhaven

        扬声器,8-ohm,200mW

        支持 Adafruite 面包板

        1

        $1.95   

        Adafruit

        D 级放大器分线板

        Sparkfun TI TPA2005D1 分线板

        1

        $7.95  

        Sparkfun

         

        上表可帮助您入门。随着课程的深入,我会加入一些音频设备、电机和伺服系统。

         

        电子元件供应商

        在上述材料中,您会发现我通常在几家供应商处采购原型组件。我主要向以下几家供应商购买组件:

        • Sparkfun – 该网站有两个优势:分线板和评价部分。部件描述可提供基本信息,而客户可提供自己所有部件的大量实用信息,例如源代码和支持库的链接。该网站还有大量的学习资源,并且面向制造者。
        • Adafruit – 该网站与 Sparkfun 相同,针对的同样是制造者。我上 Adafruit 的频率不如 Sparkfun,但是不管原因如何,我的确在该网站上花费了很多时间来了解部件。
        • Mouser – 一家大型的组件商店。不到 Mouser 购物,您不会知道在线购物车能装多少东西。但是学会如何使用还需要一些练习。他们的商品玲琅满目,以至于您可能一时半会找不到自己想购买的商品。但是通过不断使用筛选器,最终还是可以找到的。对于电阻之类的小件物品,请务必保证至少 100 件的量。一次购买 100 或 1000 件实际上要比零售划算。有时您可能想要购买一整套的部件。装满购物车之后,店家会在中部标准时间晚上 8 点之前送货,但是非官方的送货结束时间通常为中部标准时间下午 6 点左右。由于网站位于德州达拉斯,因此我只需支付 $95的地面运费即可将部件于次日送达我位于德州奥斯汀的家中。
        • Digikey – 与 Mouser 相似的一个网站。两个网站通常具有相似的部件存货和定价,您可以比较这两家网站。Digikey 位于明尼苏达州,因此通常是我的第二选择,因为次日达运费较高。
        • Amazon – 您通常可以在 Amazon 上找到很多设备和分线板,其中很多商品都享受 Amazon Prime 服务,也就是说如果您是 Amazon Prime 会员,则可以享受非常价格低廉的次日达送货服务。客户评价可提供有关如何使用部件的实用信息。
        • Ebay – 商品不稳定,而且有时候送货较慢,因此我尽可能避免在 Ebay 上购物,但是有时候却能以最便宜的价格买到较为特殊的商品,甚至是唯一的购买渠道。

        安装好 Simplicity Studio 后,让我们来浏览一下 IDE。

         

        Simplicity Studio 集成开发环境 (IDE)

        首次启动 Simplicity Studio 时,系统会向您显示大量信息。能够使用这样的工具是一件很幸运的事。以往,我们很难找到 MCU 的此类信息。

        makersguidech2_2_1.png

         

        Simplicity Studio 启动视图

        我们不妨从左上方开始探索这款工具。首先,您需要输入正在或考虑使用的部件的编号。输入时,系统会向您提供建议,因此只需输入“EFM32”,然后选择即可。此外,如果您已将入门套件连接到计算机,则可以点击“检测已连接的设备…”系统会显示具体部件编号的所有详情,甚至还有购买/试用具体设备的按钮。

         

        您可以点击购买/试用按钮下方的按钮,打开特定处理器的参考手册或数据表 PDF 文件。这一点对我非常有帮助,因为要比浏览文件系统查找 PDF 文件快。

         

        参考手册含有适用于特定产品系列(即下文中的 Leopard 系列)中所有 EFM32 型号的信息。参考手册详细介绍了该产品系列支持的所有功能,包括硬件配置寄存器。因此,您的某些部件可能不具备参考手册中详述的某些功能。您需要查看上文的选择指南或下文解释的数据表。

         

        数据表中含有仅适用于“产品”字段中输入的具体部件编号的信息。数据表详细介绍了支持的具体功能、绝对和一般操作条件、电气和热能规范、引出线和包装尺寸。

         

        Cortex M 文档通用于所有型号,其中含有 MCU 中寄存的 ARM 内核的相关信息。该文档还详细介绍了机器指令。

         

        本课程期间,您会用到此欢迎屏幕上的很多“方块”。这些方块非常实用,而 Silicon Labs 会经常发布更新和错误修复。您可以将鼠标悬停在这些方块的上方,查看其功能并在需要时启动某一个方块。

        现在,我们将打开左上角的 Simplicity IDE 方块。 makersguidech2_2_2.png

         

        IDE 是您用于编写 MCU 代码的主要工具。打开后,我们不妨创建一个新项目并大致浏览一下。

        请从菜单中依次选择“文件-> 新建-> Silicon Labs MCU 项目”。系统将弹出一个窗口,询问您将为新项目使用的套件和/或部件类型。选择“Wonder Gecko 3800 入门套件”后,系统会自动选择部件。

         

        Simplicity Studio

         

        将项目名称改为“2_getting started”。

         

        makersguidech2_2_4.png

         

        现在,您看到的屏幕应该是这样的:

        makersguidech2_2_5.png

        在后面的课程中,我将解释所有这些按钮、菜单和窗口的用途。现在,我们来创建空白项目,以便您了解操作结果。为此,您需要点击 empty_project.c 的代码窗口。只需点击该窗口的任意位置,即可选择创建图标(类似一把小锤子)。点击该图标后,您会看到底部的“控制台”窗口。

         

        在构建过程中,您会看到一个弹出窗口:

        makersguidech2_2_7.png

        如果一切操作顺利,那么您的“控制台”窗口会与下图类似:

        makersguidech2_2_8.png

        进展如何?  是否看到了“完成构建”行?  我当然希望如此,因为我们只是在创建一个空白项目。

         

        注意:如果出于某些原因,您的控制台出错,请返回到缓冲区中的第一个错误消息并阅读错误内容。请勿在调试第一个错误或警告信息之前调试日志中的最后一个错误!错误信息可能表述不清,也可能非常详尽,具体取决于问题的类型。我们将在后面的课程中介绍如何解释这些错误消息。您也可以在 Silicon Labs 网站的知识库或论坛中搜索错误帮助。

         

        我希望大多数人能够顺利完成构建,如果您已顺利完成,那么恭喜您!您已准备好开始使用入门套件进行开发!不管您信不信,事情并不总是如此简单。过去,利用全新的“工具链”来编译空白项目可以算得上一项不小的成就。但是您无需编辑“生成文件”,也无需在命令行输入代码,就可以完成。您是多么幸运啊!

        如果您是一名老练的软件编程人员,或者喜欢挑战自己,当然也可以使用生成文件和命令行构建 EFM32 系列的目标,别人告诉我大概是这样。您可选择使用 vim 或 emacs 并绕过所有的 Simplicity IDE 编程功能。

         

        在下节课程中,我们会开始编写代码并运行第一个程序,这也是嵌入式编程人员通常编写的第一个程序:闪烁 LED,嵌入式编程的“Hello World”。

         

        前一章节 | 下一章节

      • 嵌入式开发入门系列博客之一:简介

        Siliconlabs | 09/266/2015 | 11:16 AM

        original.png

        本系列博客讲述了一本即将面世的图书的编写过程,该书介绍了使用 Silicon Labs EFM32 系列基于 ARM 的微控制器 (MCU) 进行入门级嵌入式开发的相关知识。嵌入式开发是指将计算机代码集成到电子产品中的过程。本系列从宏观角度助您快速上手,同时提供了利用业内主流传感器、执行机构、通信和接口 IC 编写和全面测试实际代码的案例。

         

        本博客/图书的目标读者为在 PC、Mac 或 Linux 等平台上对 Python、Ruby、Javascript、C 等较高级语言的编程具有一定经验、并且希望学习如何将制造实际产品所需的所有组件整合在一起的人员。另外,还会介绍电子学基础知识以及关于软件开发的快速入门指导。读者将了解到如何构建能够让程序感应并响应环境、以电池供电并与其他设备通信的电子电路。原型设计将在无焊料面包板上进行,同时还会说明将想法从设计图变为实物所需的制造过程。

         

        内容

        计划讲授的以下课题旨在向您介绍嵌入式开发中实现高效率所需的知识。后续还会添加更多课题。

        • 简介
        • 入门指南
        • 第一个嵌入式项目:Hello World!
        • 利用无焊料面包板控制外部组件
        • 利用中断衰减 LED
        • 创建后院喷淋器定时器
        • 利用串行接口向计算机发送消息
        • 在 SPI 闪存 ROM 或 SD 卡中存储大量数据
        • 如何通过 I2C 使用加速计
        • 利用 LED 控制器控制 RGB LED 阵列
        • 使用并行接口向 LCD 屏幕发送图像
        • 播放 WAV 文件中的高质量音频
        • 利用 FET 和扬声器创建语音模式
        • 利用 DAC 混合 WAV 文件中的声音
        • 通过电容式和电阻式传感技术捕获用户输入信息
        • 控制电机和伺服系统
        • 利用声光发送消息并检测距离

        作者信息

        About the Author

        我叫 David Lynch,是电子计分泡沫剑产品 Sabertron 的发明者。我创建的 Kickstarter 众筹活动截至 2014 年 6 月已筹得 $233,852,是目前为止来自德州奥斯汀的 Kickstarter 众筹项目中总筹资第 12 高的项目。此后,我潜心研究如何制作 Sabertron 实物,并一直学习大量有关嵌入式设计和开发流程的知识,这些知识帮助我实现了目标。

         

        从上世纪开始,我一直从事全职计算机工程专家的工作。在开发软件的过程中,我曾使用过包括移动设备和服务器在内的各类 PC 体系结构,另外还有 DDR 和 HyperTransport 等先进的高速数字接口、示波器和其他高端测量设备,以实现流程的自动化。我在软硬件方面都有着丰富的经验。不过,在最初使用嵌入式设计和开发时,我感到很困难。其实,它不应该也没有那么难。我将指导大家快速掌握这些技术,并获得比我之前更全面的理解,避免我走过的弯路。尽管我在计算机工程领域有很多经验,但是在嵌入式设计以及 EFM32 系列 MCU方面,我并不是专家。我希望在撰写本书的过程中扩展我的技能,进而能够为 Sabertron 产品实施更好的固件。通过汇总这些材料,希望大家能够从我这里学到知识,同时欢迎大家的提问,我本人也能从这些高质量的问题中有所收获。

         

        在开源软件和 code.org 举办的“Hour of Code(编码一小时)”(名人甚至总统都在推广这一理念)等计划的推动下,计算机编程从未像现在这般普及。我的假设前提是,多数希望构建嵌入式产品的人已对软件编程略知一二,但是在产品的原型设计、开发和上市方面仍存在巨大的差距。在本系列中,我会向大家演示如何为嵌入式迷你项目进行原型设计,其中包括电子硬件电路以及在硬件上运行的软件编程。我选择使用 Wonder Gecko 入门套件的 Silicon Labs EFM32 系列 ARM Cortex MCU 来讲授该系列课程。这些课程并非只适用于 Silicon Labs 的 MCU,也可用于其他 MCU,但以我的经验来看,Silicon Labs 的 MCU 是入门者的首选 MCU。您还将了解到如何在预算有限的情况下尽可能自己创建原型。您将了解如何构造将 ARM 处理器、加速计、LED 驱动器、通信 IC、功率调节电路甚至是模拟电路融为一体的物联网 (IoT) 设备。

         

        Wonder Gecko

        Silicon Labs Wonder Gecko 入门套件

         

        在后院与孩子们玩耍时,我受到了启发,随即从一名衣食无忧的工程专家成为了神经紧绷而又古怪的 DIY 创业者。当时,我们正在用泡沫包裹的 PVC 管玩击剑游戏。就在我们开始玩的时候,我习惯性地想到,这种体验有很大的提升空间。我立即在脑海里构思如何在击剑游戏中加入电子计分。一定有一种简洁的无线方式可以做到这一点,但是我能想到的所有方式都过于复杂或奇怪,我对这些方式的可行性不是很有把握。这是我最喜欢的一个想法,因此我想了很久。我在互联网上搜了个遍,最后只找到用于正规击剑运动的电子设备。我没有找到用于玩具/竞技游戏的任何工具。

         

        经过长达五年的构思之后,我突然在 2013 年 9 月有了一个想法,然后便开始行动。我想到了一种可以极大简化确定剑击检测机制的方法,即利用加速计和剑与剑之间的无线连接。我最终想到了一种计分的可行方法,于是便迫不及待地上网订购部件开始尝试。一两周后,我完成了第一把 Sabertron 剑的原型设计。虽然不完美,但是的确成功了。

         

        Prototypes

        Sabertron 原型的演变

         

        Arduino 拥有健全的社区和支持库,可以连接到加速计分线板,因此我使用 Arduino 完成了第一款原型。Arduino 虽然符合前三个原型的需求,但是已渐渐跟不上发展的步伐。其中一个问题以及撰写本书的动力在于支持库只能让我做特定的事情,而在尝试管理中断和多线程时,则会变得非常棘手。一旦我的操作偏离常规,“简化版”的 Arduino 界面就会迅速分解为 C++ 纯代码。Arduino 集成开发环境 (IDE) 中没有充分的故障排查支持,因而我无法获得推进体系结构所需的支持。我伏案于技术参数,不断审核寄存器定义并下调位数,这与我超过 15 年工程专家的工作非常相似。坦白说,如果没有在计算机工程方面的背景知识,我就无法独立完成原型设计。原本只是出于爱好的一个简单小项目,已经转变为一项全身心投入的工程。

         

        技术方面的一个问题在于工程师通常善于把握细节,并能够应对高度复杂的项目,但是很多人没有详尽记录自己的设计,没有工程背景的人可能无法理解。我之所以写这本书,是因为我具备很多工程师缺乏的素质,也就是以简单而直观的方式解释问题的能力。我喜欢传道授业,而且作为 Edward Tufte 的学生,我十分重视有效的直观化。

         

        Testing

        在示波器上测试 Sabertron

         

        我与妻子和五个孩子生活在德州奥斯汀的一处乡间住宅内。开发嵌入式产品之余,我会开开拖拉机、安装栅栏、建造石墙、改造房屋或者大型住宅需要的任何其他修缮工作。我是一名狂热的制造者、黑客和 DIY 人士。

         

        敬请为各期课程提供意见和建议,帮助我改善内容、示例和代码。我会参与讨论,并利用你们的反馈来改善最终出版的图书。

         

        前一章节 | 下一章节