嵌入式硬件设计 — 智能设备背后的隐形架构大师

目录

引言 

一、嵌入式硬件设计概述

(一)需求分析

(二)硬件选型

(三)电路设计

(四)PCB 制作与焊接

(五)硬件调试与测试

(六)软件移植与开发

二、嵌入式硬件选型

(一)微控制器(MCU)/ 微处理器(MPU)

(二)存储器

(三)传感器与执行器

(四)电源管理芯片

(五)通信接口芯片

三、嵌入式硬件代码开发

(一)开发环境搭建

(二)底层驱动程序开发


引言 

嵌入式系统已经渗透到我们生活的方方面面,从智能手机、智能家居到工业自动化、医疗设备等领域,都离不开嵌入式硬件的支持。嵌入式硬件设计作为构建这些系统的核心环节,涉及到多个学科领域的知识和技能,是一门综合性很强的技术。本文将深入探讨嵌入式硬件设计的各个方面,包括其基本概念、硬件选型、电路设计、代码开发以及调试与优化等内容,希望能为对嵌入式硬件设计感兴趣的读者提供一些有益的参考和指导。

一、嵌入式硬件设计概述

嵌入式系统是一种专门为特定应用而设计的计算机系统,它通常嵌入在其他设备或系统中,以实现特定的功能。与通用计算机系统相比,嵌入式系统具有体积小、功耗低、成本低、可靠性高、实时性强等特点。嵌入式硬件设计则是指根据嵌入式系统的功能需求和性能指标,选择合适的硬件组件,并进行电路设计和布局布线,以构建出满足要求的硬件平台。

嵌入式硬件设计的流程一般包括以下几个步骤:

(一)需求分析

在进行嵌入式硬件设计之前,首先需要对系统的功能需求、性能指标、应用环境等进行详细的分析和定义。例如,系统需要实现哪些功能,对处理速度、存储容量、功耗等有哪些要求,工作温度范围、电磁兼容性等环境因素如何等。只有明确了这些需求,才能为后续的硬件选型和设计提供依据。

(二)硬件选型

根据需求分析的结果,选择合适的硬件组件,如微控制器(MCU)、微处理器(MPU)、存储器(ROM、RAM)、传感器、执行器、电源管理芯片、通信接口芯片等。在选型时,需要考虑组件的性能、功能、成本、功耗、封装形式、供货渠道等因素,以确保所选组件能够满足系统的要求,并且具有良好的性价比和可采购性。

(三)电路设计

在确定了硬件组件之后,接下来进行电路设计。电路设计包括原理图设计和 PCB(Printed Circuit Board,印刷电路板)设计两个部分。原理图设计是根据所选组件的电气特性和连接关系,使用电路设计软件绘制出电路原理图,确定各个组件之间的电气连接方式和信号流向。PCB 设计则是将原理图转换为实际的 PCB 布局,包括确定各个组件在 PCB 上的位置、布线、设置过孔、添加电源层和地层等,以实现电路的物理连接和电气性能优化。

(四)PCB 制作与焊接

完成 PCB 设计后,将设计文件发送给专业的 PCB 制造商进行制作。制作完成的 PCB 需要进行元器件的焊接,通常可以采用手工焊接或回流焊等方式。在焊接过程中,需要确保元器件的焊接质量,避免出现虚焊、短路等问题。

(五)硬件调试与测试

在硬件平台搭建完成后,需要进行全面的调试与测试,以验证硬件设计的正确性和稳定性。调试过程中可能会使用到示波器、万用表、逻辑分析仪等工具,对电路的信号波形、电压、电流等参数进行测量和分析,查找并排除硬件故障。测试则包括功能测试、性能测试、可靠性测试、兼容性测试等,确保硬件平台能够满足系统的各项要求,并在各种环境条件下稳定运行。

(六)软件移植与开发

在硬件调试通过后,即可进行嵌入式软件的移植与开发。嵌入式软件通常包括底层驱动程序、操作系统(可选)、应用程序等。底层驱动程序用于实现对硬件设备的初始化、控制和数据交互,操作系统则提供任务管理、内存管理、文件系统等功能,应用程序则根据系统的具体功能需求进行开发。软件移植与开发需要根据硬件平台的特点和所选的软件开发工具链进行,确保软件能够在硬件上正确运行,并实现预期的功能。

二、嵌入式硬件选型

嵌入式硬件选型是嵌入式硬件设计的关键环节之一,合适的硬件组件能够确保系统的性能、功能和可靠性,同时降低成本和功耗。以下是一些常见的嵌入式硬件组件及其选型要点:

(一)微控制器(MCU)/ 微处理器(MPU)

微控制器和微处理器是嵌入式系统的核心组件,负责整个系统的控制和数据处理。在选型时,需要考虑以下因素:

  • 性能指标:包括 CPU 内核类型、时钟频率、处理能力(如 MIPS、DMIPS 等)、存储容量(内部 Flash 和 RAM)等。根据系统的计算需求和数据处理量,选择具有合适性能的芯片。例如,对于一些简单的控制应用,如智能家居中的灯光控制、温度控制等,选用低功耗、低成本的 8 位或 16 位微控制器即可;而对于一些复杂的应用,如视频处理、图像处理、工业自动化控制系统等,则需要选择高性能的 32 位或 64 位微处理器。

  • 外设资源:微控制器 / 微处理器通常集成了丰富的外设资源,如通用输入输出接口(GPIO)、定时器 / 计数器、串口(UART、SPI、I2C 等)、中断控制器、模数转换器(ADC)、数模转换器(DAC)、USB 接口、以太网接口等。根据系统需要连接的外部设备和通信接口,选择具有相应外设资源的芯片,以减少外部扩展电路的复杂度和成本。例如,如果系统需要与多个传感器进行 I2C 通信,那么选择具有多个 I2C 接口的芯片会更加方便。

  • 工作电压和功耗:考虑芯片的工作电压范围是否与系统的电源设计相匹配,以及芯片的功耗特性。对于一些电池供电的便携式设备,如智能手环、无线传感器节点等,低功耗是至关重要的,需要选择具有低功耗模式和高效电源管理功能的芯片,以延长电池续航时间。

  • 封装形式:根据 PCB 设计的要求和空间限制,选择合适的芯片封装形式。常见的封装形式有 QFP(Quad Flat Package,四方扁平封装)、LQFP(Low-profile Quad Flat Package,薄型四方扁平封装)、BGA(Ball Grid Array,球栅阵列封装)等。QFP 和 LQFP 封装便于手工焊接和调试,但占用 PCB 面积较大;BGA 封装则具有更小的封装尺寸和更高的引脚密度,但需要专业的焊接设备和技术。

  • 成本:在满足系统性能和功能要求的前提下,成本是一个重要的考虑因素。不同品牌、不同型号的微控制器 / 微处理器价格差异较大,需要综合评估性价比,选择合适的芯片。

例如,意法半导体(ST)的 STM32 系列微控制器是目前应用非常广泛的一款产品。它采用 ARM Cortex-M 内核,具有丰富的外设资源,如多达数十个 GPIO 接口、多个串口、定时器、ADC、DAC 等,时钟频率最高可达数百 MHz,内部 Flash 和 RAM 容量也较大,能够满足多种不同应用场景的需求。同时,STM32 系列芯片的价格相对较为亲民,具有较高的性价比,并且有良好的开发工具支持和丰富的技术文档,方便开发者进行开发。

(二)存储器

存储器用于存储嵌入式系统的程序代码、数据和运行时的堆栈等信息。常见的存储器类型包括只读存储器(ROM)和随机存取存储器(RAM)。

  • 只读存储器(ROM)

    • Flash 存储器:是目前最常用的一种 ROM 类型,具有可擦写、非易失性等特点。在选型时,需要考虑 Flash 的容量、编程电压、编程速度、擦除寿命等因素。例如,对于一些小型的嵌入式系统,如简单的单片机应用,几 KB 到几十 KB 的 Flash 容量可能就足够了;而对于一些大型的嵌入式系统,如智能设备操作系统的存储,可能需要几百 KB 甚至数 MB 的 Flash 容量。同时,较低的编程电压和较快的编程速度可以提高生产效率和降低功耗,较长的擦除寿命则可以保证系统的可靠性和稳定性。

    • EEPROM(Electrically Erasable Programmable Read-Only Memory,电可擦除可编程只读存储器):主要用于存储一些少量的、需要经常修改的数据,如系统配置参数、校准数据等。EEPROM 的特点是可以按字节进行擦写,擦写速度相对较慢,但编程电压较低,擦写寿命较长。在选型时,需要根据数据存储量和擦写频率等要求选择合适容量和型号的 EEPROM 芯片。

  • 随机存取存储器(RAM)

    • SRAM(Static Random Access Memory,静态随机存取存储器):具有读写速度快、无需刷新等优点,但集成度相对较低,成本较高,功耗也较大。SRAM 通常用于缓存一些对速度要求较高的数据,如 CPU 的指令缓存和数据缓存等。在选型时,需要考虑 SRAM 的容量、速度、工作电压等因素,根据系统的缓存需求选择合适的芯片。

    • DRAM(Dynamic Random Access Memory,动态随机存取存储器):集成度高、成本低,但需要定期刷新,读写速度相对较慢。DRAM 主要用于大容量的主存储器应用,如计算机内存等。在嵌入式系统中,如果需要较大的内存容量且对成本较为敏感,可以考虑使用 DRAM。选型时需要关注 DRAM 的容量、速度、刷新方式、工作电压等参数,并配合相应的内存控制器进行设计。

例如,在一些基于 STM32 微控制器的嵌入式系统中,通常会使用内部集成的 Flash 存储器来存储程序代码,而使用外部的 SRAM 芯片来扩展内存,以满足系统对数据处理和存储的需求。

(三)传感器与执行器

传感器用于采集外部环境的各种物理量信息,如温度、湿度、压力、光照、加速度等,并将其转换为电信号供微控制器处理。执行器则根据微控制器的指令,对外界进行控制或驱动,如电机、继电器、显示屏、扬声器等。

  • 传感器选型要点

    • 测量范围和精度:根据系统需要测量的物理量范围和精度要求,选择合适的传感器。例如,如果需要测量环境温度,温度范围在 -40℃到 +80℃之间,精度要求在 ±0.5℃左右,那么可以选择一款适合该范围和精度的温度传感器,如 LM35 温度传感器,其测量范围为 -55℃到 +150℃,精度可达 ±0.5℃。

    • 输出信号类型:传感器的输出信号类型有模拟信号(如电压、电流)和数字信号(如 I2C、SPI、串口等)之分。如果微控制器具有相应的模数转换器(ADC),可以选择输出模拟信号的传感器,通过 ADC 进行采样和转换;如果希望简化电路设计和提高系统的抗干扰能力,可以选择输出数字信号的传感器,直接与微控制器进行通信。例如,DHT11 温湿度传感器就是一款输出数字信号的传感器,采用单总线通信协议,与微控制器连接非常方便。

    • 响应时间和稳定性:对于一些对实时性要求较高的应用,如工业自动化控制系统中的传感器,需要考虑传感器的响应时间,确保能够及时准确地采集到数据。同时,传感器的稳定性也非常重要,需要选择具有良好稳定性和可靠性的产品,以保证系统的长期稳定运行。

    • 尺寸、功耗和成本:根据系统的安装空间、功耗预算和成本限制,选择合适尺寸、功耗和成本的传感器。在一些小型化的嵌入式设备中,如可穿戴设备,传感器的尺寸和功耗是需要重点考虑的因素;而在一些大规模生产的消费电子产品中,成本则是一个关键因素。

  • 执行器选型要点

    • 驱动能力和负载要求:根据需要驱动的负载类型(如电机、继电器等)和负载大小(如电机的功率、继电器的线圈电流等),选择具有足够驱动能力的执行器。例如,如果要驱动一个直流电机,需要根据电机的额定电压、额定电流和转速等参数,选择合适的电机驱动芯片,如 L298N 电机驱动芯片,可以驱动两个直流电机,最大输出电流可达 2A。

    • 控制方式和接口:执行器的控制方式有多种,如电平控制、脉冲宽度调制(PWM)控制等,需要根据微控制器的控制能力和系统的控制要求选择合适的执行器。同时,执行器的接口类型也需要与微控制器相匹配,如 GPIO 接口、串口接口等。例如,对于一个需要通过 PWM 信号控制转速的直流电机,选择具有 PWM 输入接口的电机驱动芯片会更加方便。

    • 工作电压和环境适应性:确保执行器的工作电压范围与系统的电源设计相匹配,并考虑执行器在不同环境条件下的工作性能,如温度、湿度、振动等。例如,在一些工业环境中,执行器需要能够承受较高的温度和湿度,以及较强的电磁干扰,因此需要选择具有良好环境适应性的产品。

例如,在一个智能家居系统中,可能会使用温湿度传感器来采集室内环境信息,使用红外传感器来检测人体活动,使用继电器来控制灯光、电器等设备的开关,使用显示屏来显示系统状态和信息等。这些传感器和执行器的合理选型和应用,能够实现智能家居系统的各种功能,提高生活的便利性和舒适性。

(四)电源管理芯片

电源管理芯片用于为嵌入式系统提供稳定、可靠的电源供应,并对电源进行管理和监控,如电压转换、电流限制、电池充电管理等。在选型时,需要考虑以下因素:

  • 输入电压范围和输出电压要求:根据系统的电源输入情况(如电池电压、外部电源适配器电压等)和各个硬件组件的工作电压要求,选择具有合适输入电压范围和能够输出所需电压的电源管理芯片。例如,如果系统采用单节锂电池供电,电压范围在 3.0V 到 4.2V 之间,而微控制器和其他组件需要 3.3V 和 1.8V 的工作电压,那么可以选择一款具有升压和降压功能的电源管理芯片,如 LM2596 系列芯片,可以将锂电池电压转换为 3.3V 和 1.8V 等不同电压输出。

  • 输出电流能力:确保电源管理芯片的输出电流能力能够满足系统中各个组件的电流需求总和。如果输出电流不足,可能会导致系统工作不稳定或组件无法正常工作。例如,对于一个需要驱动多个大功率负载的系统,如工业控制板上有多个电机和传感器同时工作,就需要选择输出电流较大的电源管理芯片,以保证系统的正常供电。

  • 电源转换效率:电源转换效率直接影响系统的功耗和电池续航时间。在选型时,应尽量选择转换效率高的电源管理芯片,以降低功耗和减少热量产生。例如,一些同步降压型电源管理芯片的转换效率可以达到 90% 以上,相比传统的非同步降压芯片,能够显著提高电源利用效率。

  • 电池充电管理功能:如果系统采用电池供电,并且需要对电池进行充电管理,如恒流充电、恒压充电、充电保护等,那么需要选择具有相应电池充电管理功能的电源管理芯片。例如,TP4056 是一款常用的锂电池充电管理芯片,具有涓流充电、恒流充电、恒压充电等功能,能够对单节锂电池进行安全、高效的充电管理。

  • 封装形式和尺寸:根据 PCB 设计的空间限制,选择合适封装形式和尺寸的电源管理芯片。一些小型化的嵌入式系统对 PCB 空间要求较高,可能需要选择采用 SOT23、QFN 等小型封装的电源管理芯片,以节省空间。

(五)通信接口芯片

嵌入式系统通常需要与外部设备或其他系统进行通信,如与上位机进行数据传输、与传感器进行数据采集、与执行器进行控制指令发送等。常见的通信接口有串口(UART、SPI、I2C 等)、USB 接口、以太网接口、无线通信接口(如 Wi-Fi、蓝牙、ZigBee 等)等。根据不同的通信需求,需要选择合适的通信接口芯片。

  • 串口通信接口芯片

    • UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器):是一种简单、常用的串口通信接口,主要用于短距离、低速的数据传输。在选型时,需要考虑 UART 芯片的波特率范围、数据位、停止位、奇偶校验位等参数,以及芯片的工作电压、驱动能力等。例如,MAX3232 是一款常用的 UART 电平转换芯片,可以将微控制器的 TTL 电平转换为 RS-232 电平,以便与计算机等具有 RS-232 接口的设备进行通信,其波特率范围较宽,最高可达 1Mbps。

    • SPI(Serial Peripheral Interface,串行外设接口):是一种高速、全双工的同步串口通信接口,通常用于连接微控制器与外部 SPI 设备,如 Flash 存储器、传感器、显示屏等。SPI 接口芯片的选型需要考虑时钟频率、数据传输速率、片选信号数量、工作模式等因素。例如,W25Q64 是一款 64Mbit 的 SPI Flash 存储器芯片,其最高时钟频率可达 104MHz,支持标准的 SPI 通信协议,具有较快的数据读写速度,适合用于存储大量的数据。

    • I2C(Inter-Integrated Circuit,集成电路间总线):是一种多主从结构的低速同步串口通信接口,具有简单、易用、占用引脚少等优点,广泛应用于连接微控制器与各种 I2C 设备,如 EEPROM、传感器、RTC(实时时钟)等。在选型时,需要关注 I2C 芯片的地址设置、数据传输速率、总线负载能力等参数。例如,PCF8563 是一款常用的 I2C 接口 RTC 芯片,它可以提供精确的实时时钟功能,通过 I2C 接口与微控制器进行通信,方便在嵌入式系统中实现时间相关的功能。

  • USB 接口芯片:如果系统需要与计算机或其他 USB 设备进行高速数据传输,如数据存储设备、USB 摄像头等,就需要选择 USB 接口芯片。USB 接口芯片的选型需要考虑 USB 版本(如 USB 2.0、USB 3.0 等)、接口类型(如 USB Type-A、USB Type-C 等)、数据传输速率、是否支持主机 / 设备模式以及芯片的功耗和集成度等因素。例如,CH340 是一款常用的 USB 转串口芯片,可实现 USB 与串口之间的转换,方便在没有原生串口的计算机上与嵌入式设备进行串口通信,其支持 USB 2.0 标准,数据传输稳定,且成本较低,广泛应用于各类开发板和简易 USB 串口设备中。而对于需要更高速度和更复杂 USB 功能的系统,像 CY7C68013A 这类高性能的 USB 接口芯片则更为合适,它支持 USB 2.0 高速模式,具备丰富的端点配置和强大的数据处理能力,能够满足如高速数据采集卡、USB 音频设备等对数据传输要求苛刻的应用场景。

  • 以太网接口芯片:在需要嵌入式系统接入网络进行远程通信、数据传输或与其他网络设备交互的情况下,以太网接口芯片不可或缺。选型时要留意芯片支持的以太网标准(如 10/100Mbps 以太网、千兆以太网等)、MAC 层和 PHY 层功能集成度、网络接口类型(如 RJ45 等)以及芯片的功耗和稳定性。例如,W5500 是一款集成了 TCP/IP 协议栈的以太网控制器芯片,支持 10/100Mbps 以太网,内部集成了 MAC 和 PHY,使用简单方便,可大大降低网络开发的难度,适用于物联网网关、网络监控设备等需要以太网连接的嵌入式应用。对于更高性能要求的千兆以太网应用场景,则可以考虑使用 RTL8211 系列芯片,它提供了高速稳定的千兆以太网连接能力,并且具有良好的兼容性和可靠性,能够满足如工业以太网交换机、高性能网络服务器等设备的网络接口需求。

  • 无线通信接口芯片:随着物联网的兴起,无线通信在嵌入式系统中的应用越来越广泛。常见的无线通信技术包括 Wi-Fi、蓝牙、ZigBee 等,每种技术都有其特点和适用场景。

    • Wi-Fi 芯片:适用于需要长距离、高速率数据传输且有现成无线网络基础设施的场景,如智能家居中控设备、智能摄像头等与家庭网络或互联网的连接。在选择 Wi-Fi 芯片时,要考虑其支持的 Wi-Fi 标准(如 802.11n、802.11ac 等)、传输速率、工作频段(2.4GHz 或 5GHz)、信号强度和稳定性以及功耗管理功能。例如,ESP8266 是一款低成本、高集成度的 Wi-Fi 芯片,支持 802.11 b/g/n 标准,在智能家居、智能玩具等领域得到广泛应用,其能够方便地实现嵌入式设备的 Wi-Fi 联网功能,并且有丰富的开发资源和社区支持。而对于更高性能要求的企业级或工业级 Wi-Fi 应用,像 Qualcomm QCA9377 这样的芯片则更为合适,它支持 802.11ac 标准,具备更高的传输速率和更强的信号处理能力,可满足如工业无线 AP、企业级无线设备等对 Wi-Fi 性能和稳定性有严格要求的场景。
    • 蓝牙芯片:主要用于短距离、低功耗的数据传输和设备间的无线连接,如蓝牙耳机、蓝牙音箱、智能手环与手机之间的连接等。蓝牙芯片选型要关注其蓝牙版本(如蓝牙 4.0、蓝牙 5.0 等)、蓝牙协议支持(如经典蓝牙、低功耗蓝牙等)、传输距离、功耗以及与不同蓝牙设备的兼容性。例如,nRF52832 是 Nordic 公司推出的一款高性能蓝牙低功耗芯片,支持蓝牙 5.0 标准,具有极低的功耗和强大的处理能力,同时支持多种蓝牙协议,适用于可穿戴设备、智能健康监测设备等对功耗和性能都有较高要求的蓝牙应用场景。
    • ZigBee 芯片:适用于低速率、低功耗、自组网的短距离无线通信应用,如智能家居中的传感器网络、工业自动化中的无线传感网络等。在选择 ZigBee 芯片时,要考虑其支持的 ZigBee 协议版本(如 ZigBee 3.0 等)、网络拓扑结构支持(如星型、网状等)、节点容量、传输距离和功耗。例如,CC2530 是 Texas Instruments 公司生产的一款经典的 ZigBee 芯片,支持 ZigBee 2007/PRO 协议,具有较高的性价比,在智能家居、工业无线传感网络等领域有大量应用,能够方便地构建稳定可靠的 ZigBee 无线网络。

三、嵌入式硬件代码开发

在嵌入式硬件平台搭建完成后,需要进行嵌入式软件的开发,以实现系统的功能。嵌入式软件通常包括底层驱动程序、操作系统(可选)和应用程序等。以下是嵌入式硬件代码开发的一些基本步骤和要点:

(一)开发环境搭建

  • 选择合适的集成开发环境(IDE):不同的微控制器和嵌入式系统可能需要不同的开发环境。例如,对于基于 ARM Cortex-M 系列微控制器的开发,可以选择 Keil MDK、IAR Embedded Workbench 等常用的 IDE。这些 IDE 提供了丰富的开发工具,如代码编辑器、编译器、调试器等,方便开发者进行代码编写、编译和调试。在选择 IDE 时,要考虑其对目标硬件平台的支持程度、开发工具的易用性、代码优化能力以及是否有良好的技术支持和社区资源。

  • 安装交叉编译工具链:由于嵌入式系统的资源有限,通常无法直接在目标硬件上进行代码编译,而是需要在主机上使用交叉编译工具链将代码编译成目标硬件能够执行的二进制文件。交叉编译工具链包括编译器、汇编器、链接器等工具,不同的微控制器架构需要不同的交叉编译工具链。例如,对于 ARM 架构的微控制器,需要安装 ARM 交叉编译工具链,如 gcc-arm-none-eabi 等。在安装交叉编译工具链时,要确保其路径设置正确,以便在 IDE 中能够正确调用。

(二)底层驱动程序开发

  • 初始化硬件设备:底层驱动程序的首要任务是对硬件设备进行初始化,包括设置设备的寄存器、配置引脚功能、初始化时钟等。例如,对于一个 UART 串口驱动程序,需要设置 UART 控制器的波特率、数据位、停止位、奇偶校验位等寄存器,将相应的引脚配置为 UART 功能,并开启 UART 时钟。以下是一个简单的 STM32 UART 初始化代码示例:
    #include "stm32f10x.h"void UART_Init(void)
    {// 使能 USART1 时钟和 GPIOA 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);// 配置 USART1 的 TX 引脚为复用推挽输出GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置 USART1 的 RX 引脚为浮空输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置 USART1 的参数USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;USART_Init(USART1, &USART_InitStructure);// 使能 USART1USART_Cmd(USART1, ENABLE);
    }

    在上述代码中,首先使用 RCC_APB2PeriphClockCmd 函数使能 USART1 和 GPIOA 的时钟,然后分别配置 USART1 的 TX 引脚和 RX 引脚的功能和模式,接着使用 USART_Init 函数设置 USART1 的波特率、数据位、停止位等参数,最后使用 USART_Cmd 函数使能 USART1。

  • 实现数据读写操作:在硬件设备初始化完成后,驱动程序需要提供数据读写函数,以便应用程序能够与硬件设备进行数据交互。例如,对于 UART 驱动程序,需要实现发送数据函数 UART_SendData 和接收数据函数 UART_ReceiveData。以下是一个简单的 UART 发送数据函数示例:
    void UART_SendData(uint8_t data)
    {// 等待发送缓冲区为空while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);// 发送数据USART_SendData(USART1, data);
    }

    在这个函数中,首先使用 USART_GetFlagStatus 函数等待 USART1 的发送缓冲区为空,即 TXE 标志位被置位,然后使用 USART_SendData 函数将数据发送到 USART1 的发送缓冲区。

  • 处理中断和异常情况:许多硬件设备在数据传输完成或发生错误时会产生中断,底层驱动程序需要注册相应的中断处理函数,以便及时处理这些中断事件。例如,对于 UART 串口,如果接收到数据或发送完成,会产生中断,驱动程序需要在中断处理函数中读取接收到的数据或进行发送完成后的后续处理。同时,驱动程序还需要处理一些异常情况,如硬件设备故障、超时等,以确保系统的稳定性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889188.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[大数据]Hudi编译集成

1. Hudi概述 1.1 Hudi简介 What is Apache Hudi Apache Hudi is the next generation streaming data lake platform. Apache Hudi brings core warehouse and database functionality directly to a data lake. Hudi provides tables, transactions, efficient upserts/dele…

windows下 mysql开启 binlog日志

一、查看是否开启 binlog -- 方式一 show binary logs;-- 方式二 show VARIABLES like log_bin 说明没有开启 方式一 :you are not using binary logging 方式二:log_bin off 二、编辑 my.ini 配置文件 默认安装地点位于:C:\ProgramDat…

Java-22 深入浅出 MyBatis - 手写ORM框架3 手写SqlSession、Executor 工作原理

点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatis&#xff…

Android 逆向/反编译/Hook修改应用行为 基础实现

前言:本文通过一个简单的情景案例实现安卓逆向的基本操作 一、情景描述 本文通过一个简单的情景案例来实现安卓逆向的基本操作。在这个案例中所使用的项目程序是我自己的Demo程序,不会造成任何的财产侵害,本文仅作为日常记录及案例分享。实…

IDEA创建Spring Boot项目配置阿里云Spring Initializr Server URL【详细教程-轻松学会】

1.首先打开idea选择新建项目 2.选择Spring Boot框架(就是选择Spring Initializr这个) 3.点击中间界面Server URL后面的三个点更换为阿里云的Server URL Idea中默认的Server URL地址:https://start.spring.io/ 修改为阿里云Server URL地址:https://star…

基于MATLAB的信号处理工具:信号分析器

信号(或时间序列)是与特定时间相关的一系列数字或测量值,不同的行业和学科将这一与时间相关的数字序列称为信号或时间序列。生物医学或电气工程师会将其称为信号,而统计学家或金融定量分析师会使用时间序列这一术语。例如&#xf…

Plugin - 插件开发03_Spring Boot动态插件化与热加载

文章目录 Pre方案概览使用插件的好处流程CodePlugin 定义Plugin 实现Plugin 使用方动态加载插件类加载器注册与卸载插件配置文件启动类测试验证 小结 Pre 插件 - 通过SPI方式实现插件管理 插件 - 一份配置,离插件机制只有一步之遥 插件 - 插件机制触手可及 Plug…

ECharts柱状图-阶梯瀑布图,附视频讲解与代码下载

引言: 在数据可视化的世界里,ECharts凭借其丰富的图表类型和强大的配置能力,成为了众多开发者的首选。今天,我将带大家一起实现一个柱状图图表,通过该图表我们可以直观地展示和分析数据。此外,我还将提供…

C/C++流星雨

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C/C…

ModelScope-Agent(1): 基于开源大语言模型的可定制Agent系统

目录 简介快速入门 简介 github地址 快速入门 看前两篇,调用千问API和天气API # 选用RolePlay 配置agent from modelscope_agent.agents.role_play import RolePlay # NOQArole_template 你扮演一个天气预报助手,你需要查询相应地区的天气&#x…

【模型对比】ChatGPT vs Kimi vs 文心一言那个更好用?数据详细解析,找出最适合你的AI辅助工具!

在这个人工智能迅猛发展的时代,AI聊天助手已经深入我们的工作与生活。你是否曾在选择使用ChatGPT、Kimi或是百度的文心一言时感到一头雾水?每款AI都有其独特的魅力与优势,那么,究竟哪一款AI聊天助手最适合你呢?本文将带…

微信小程序uni-app+vue3实现局部上下拉刷新和scroll-view动态高度计算

微信小程序uni-appvue3实现局部上下拉刷新和scroll-view动态高度计算 前言 在uni-appvue3项目开发中,经常需要实现列表的局部上下拉刷新功能。由于网上相关教程较少且比较零散,本文将详细介绍如何使用scroll-view组件实现这一功能,包括动态高度计算、下拉刷新、上拉加载等完整…

SQL——DQL分组聚合

分组聚合: 格式: select 聚合函数1(聚合的列),聚合函数2(聚合的列) from 表名 group by 标识列; ###若想方便分辨聚合后数据可在聚合函数前加上标识列(以标识列进行分组) 常见的聚合函数: sum(列名):求和函数 avg(列名)…

maven打包时出现找不到符号的错误如何解决

在maven打包的时候有时会出现找不到符号的情况,具体原因是由于引用的BaseEntity是framework模块下的实体类,所以需要将framework重新clean再install,成功后再将我们的模块打包就成功了

openGauss开源数据库实战二十一

文章目录 任务二十一 使用JDBC访问openGauss数据库任务目标实施步骤一、准备工作 二、下载并安装JavaSE81 下载JavaSE8安装Java8SE并配置环境变量 三、下载并安装eclipse四、下载并安装openGauss的JDBC驱动包五、使用IDEA编写JDBC测试程序1 使用IDEA的SSH连接虚拟机2 创建项目并…

Git:常用命令

一、查看当前分支 git branch 二、查看所有分支 git branch -a 三、切换到远程分支 git checkout origin/分支名 示例:git checkout origin/dev 四、拉取远程分支代码 git pull origin 分支名 示例:git pull origin dev 五、常用指令 查看暂存区…

运维实战:K8s 上的 Doris 高可用集群最佳实践

今天我们将深入探讨::如何在 K8s 集群上部署 Compute storage coupled(存算耦合) 模式的 Doris 高可用集群? 本文,我将为您提供一份全面的实战指南,逐步引导您完成以下关键任务: 配…

在GITHUB上传本地文件指南(详细图文版)

这份笔记简述了如何在GITHUB上上传文件夹的详细策略。 既是对自己未来的一个参考,又希望能给各位读者带来帮助。 详细步骤 打开目标文件夹(想要上传的文件夹) 右击点击git bash打开 GitHub创立新的仓库后,点击右上方CODE绿色按…

Vue框架入门

Author:Dawn_T17?? 目录 什么是框架 一.Vue 的使用方向 二.Vue 框架的使用场景 (TIP)MVVM思想 三.Vue入门案例 TIP:插值表达式 四.Vue-指令? (1)v-bind 和 v-model? ? (2&#x…

FPGA 遍历读 LMK04803 寄存器

主要思路: 1.使用 VIO 输出信号控制什么时候开始读LMK04803寄存器 2.遍历LMK04803所有寄存器,将读到的每个寄存器的值显示在VIO上。 3.遍历指的是 从 R0 开始读,R0读完接着读 R1,一直到R31 结束 4.注意的是写寄存器是 32bit &…