目录
引言
从早期简单的微控制器驱动设备,到如今集成了复杂操作系统、人工智能算法和高速无线通信的智能终端,嵌入式技术经历了革命性的演进。这一演进的核心驱动力,是微电子技术的飞速进步(更小尺寸、更强性能、更低功耗)与应用需求的爆炸式增长(万物互联、智能控制、实时数据处理)。嵌入式系统作为硬件与软件的精密结合体,其设计哲学始终围绕着在严格约束(成本、功耗、尺寸、实时性)下实现特定功能的最优化。它们构成了物理世界与数字世界交互的底层桥梁,是实现自动化、智能化和物联网愿景的核心引擎。
现在从日常生活中随处可见的智能手机、智能家居设备,到工业领域中复杂精密的自动化生产线;从汽车中琳琅满目的电子辅助系统,到航空航天领域里承担关键任务的飞行控制与通信装置,嵌入式技术如同隐藏在现代科技背后的强大引擎,默默驱动着这一切的高效运行与协同工作,深刻地改变着我们对世界的认知以及与世界互动的方式。
嵌入式技术,作为一种将计算机技术、电子技术、传感器技术、控制技术等多种前沿技术深度融合后诞生的创新性技术形态,它具备高度的集成性、出色的实时性以及独特的专用性。这使得它能够巧妙地嵌入到各种不同类型、不同规模的设备和系统之中,为这些设备赋予智慧的“大脑”和敏锐的“感官”,使其具备自主感知、精准控制以及智能决策的能力,从而在各自的应用场景下发挥出不可替代的关键作用,满足人们对于高效性、便捷性、智能化生活的无尽追求。
接下来我们将简单介绍嵌入式的入门。
一、基本概念
嵌入式技术是把计算机硬件与软件、传感器、执行器等组件集成在一起,嵌入到其他设备或系统中,以实现特定功能的技术。例如,在智能家居系统中,嵌入式技术可以将微处理器、传感器(如温度传感器、光照传感器等)、控制电路等集成在一起,实现对家居环境的智能监测和控制。
二、嵌入式技术的主要组成部分
-
硬件层
- 处理器:嵌入式处理器是嵌入式系统的核心部件,它负责执行各种指令和任务。常见的嵌入式处理器有 ARM 处理器、MIPS 处理器、PowerPC 处理器等。根据功能和应用场景的不同,嵌入式处理器可以分为:微控制器(MCU)、微处理器(MPU)、数字信号处理器(DSP)等。ARM 处理器因其低功耗、高性能的特点,被广泛应用于移动设备、物联网设备等诸多领域。不同的应用场景需要选择合适的处理器架构,如ARM、MIPS、RISC-V等。
- 存储器:用于存储程序代码和数据,常见的有Flash、EEPROM、SRAM、DRAM等。Flash 存储器:非易失性存储器,常用于存储固件和应用程序。EEPROM:可电擦写编程的只读存储器,适用于保存少量关键数据。SRAM(静态随机存取存储器):速度快、无需刷新,常用于缓存或关键数据存储。DRAM(动态随机存取存储器):容量大但需周期性刷新,常用于运行内存。只读存储器(ROM):ROM 用于存储系统启动时所需的引导程序、固件等,这些数据在系统断电后不会丢失。随机存取存储器(RAM):RAM 则是用于临时存储正在运行的程序和数据,其读写速度较快,但断电后数据会丢失。
- 外围接口:如GPIO、UART、SPI、I2C、USB、CAN等,用于与其他设备或传感器进行通信。
- 其他外设:如 ADC(模数转换器)、DAC(数模转换器)、定时器 / 计数器等。ADC 可以将模拟信号(如温度传感器输出的模拟电压信号)转换为数字信号,以便嵌入式系统进行处理。
-
软件层
- 固件/驱动程序:直接控制硬件的底层软件,负责管理硬件资源并提供给上层应用程序使用。
- 操作系统:有实时操作系统(RTOS),如 FreeRTOS、VxWorks 等。FreeRTOS 是一款开源的实时操作系统,适用于资源有限的嵌入式设备。还有非实时操作系统,如 Linux 系统在一些高端嵌入式设备中的应用。对于需要处理多个任务的应用场景,RTOS可以提供更好的资源管理和任务调度能力。
- 中间件:提供一些通用的服务和API,如网络协议栈、文件系统等。通信中间件(蓝牙协议栈、Wi - Fi 协议栈等)、数据库中间件等。蓝牙协议栈使得嵌入式设备能够通过蓝牙与其他设备进行无线通信。
- 应用程序:实现具体的业务逻辑,根据需求完成特定的功能。这是根据具体应用场景编写的软件,用于实现嵌入式系统的特定功能。如在汽车的发动机控制系统中,应用程序根据传感器反馈的发动机状态数据,通过控制算法来调节燃油喷射量、点火时刻等。
-
开发工具链
- 编译器、链接器、调试器等工具,支持C/C++、汇编语言等编程语言。
- 集成开发环境(IDE),如Keil、IAR、Eclipse等。
- 物理调试工具,如JTAG、SWD接口的调试器。
三、特点
-
嵌入性
嵌入式系统通常是集成到其他设备或系统中的,其功能往往依附于该设备。例如,在家电中,如智能冰箱,嵌入式系统嵌入其中,主要为冰箱提供智能控制功能。 -
专用性
嵌入式系统一般是为了实现特定的功能而设计的。针对特定的应用设计,优化了性能、成本和功耗。以汽车的防抱死制动系统(ABS)为例,其嵌入式系统专门用于在紧急制动时控制车轮的制动力。 -
实时性
许多嵌入式系统要求能够对输入的事件做出快速响应。且很多应用场景对响应时间有严格的要求,必须在规定时间内完成指定的任务。在工业自动化领域,如机床的数控系统,当接收到加工程序的指令后,需要实时地控制机床的运动部件。 -
低功耗
由于许多嵌入式设备是电池供电或者需要在资源有限的环境中运行,所以低功耗是一个重要的特点。例如,在可穿戴设备如智能手环中,其嵌入式系统采用各种低功耗设计技术。 -
可靠性
由于许多嵌入式系统部署在关键环境中,如航空航天、医疗设备等,所以对系统的稳定性和可靠性有很高的要求。
四、应用领域
-
消费电子
智能手机、平板电脑等移动设备是嵌入式系统的典型应用。它们集成了高性能的处理器、各种传感器和复杂的软件系统。 -
工业控制
在工业自动化生产线上,嵌入式系统用于控制机器人的动作、监测生产过程中的各种参数。 -
汽车电子
汽车的各个系统几乎都离不开嵌入式系统,包括发动机控制系统、车身电子控制系统、车载娱乐系统等。 -
智能家居
智能照明系统、智能安防系统等都采用了嵌入式技术。通过手机应用程序或者语音控制,用户可以远程控制家中的灯光开关、监控摄像头的启动等。 -
医疗设备
如心电图仪、核磁共振成像(MRI)设备等医疗仪器中的嵌入式系统用于数据采集、图像处理和设备控制。 -
航空航天
飞机的飞行控制系统、卫星的姿态控制和通信系统等都包含嵌入式系统。
嵌入式系统的开发流程
一、需求分析
明确系统核心目标与约束条件,是后续设计的基础。
功能需求:确定数据采集(传感器类型、精度)、控制输出(执行器响应时间)、通信接口(UART、CAN等协议)及用户交互方式(触摸屏、按键)。
性能要求:系统的实时性、可靠性、功耗等要求。
约束条件:系统的硬件资源、成本、开发周期等限制。
二、系统设计
划分软硬件边界,选择关键技术栈。
硬件架构设计:
-
处理器选型:根据性能需求选择MCU(如STM32)、MPU(如ARM Cortex-A)或DSP(如TI C6000)。
-
外设与存储:配置Flash(存储固件)、SRAM(高速缓存)、ADC/DAC(信号转换)等模。
-
接口设计:规划GPIO、通信总线(CAN/以太网)及调试接口(JTAG)。
软件架构设计:
-
操作系统选择:实时系统(FreeRTOS、VxWorks)或Linux(需MMU支持)。
-
驱动与中间件:开发外设驱动,集成协议栈(TCP/IP、USB)。
-
应用层规划:定义任务调度、数据流处理逻辑。
三、硬件设计
硬件设计是根据系统设计结果,进行具体的硬件电路设计和实现。
原理图设计:绘制硬件电路的原理图,确定各元器件的连接关系。
PCB设计:进行印刷电路板(PCB)的设计和布局,确保电路的可制造性和可靠性。
制板与调试:焊接样机,测试电源稳定性、信号完整性,修复硬件缺陷。
四、软件设计
软件设计是根据系统设计结果,进行具体的软件开发和实现。
环境搭建:安装交叉编译器(如arm-linux-gcc)、配置调试工具(Minicom)。
系统底层开发:
Bootloader移植:适配U-Boot至目标板。
操作系统移植:根据硬件平台和需求,选择和移植合适的操作系统。
根文件系统构建:使用BusyBox定制,配置启动脚本(/etc/rc.S)
中间件开发:开发和配置设备驱动、通信协议栈和文件系统等中间件。
应用软件开发:根据功能需求,开发和测试应用软件。
五、系统集成与测试
系统集成与测试是将硬件和软件结合,进行系统级的集成和测试。
系统集成:将硬件和软件进行集成,确保各模块之间的接口和通信正确。
功能测试:测试系统的各项功能,确保实现需求分析中的功能需求。
性能测试:测试系统的实时性、可靠性和功耗等性能,确保满足性能要求。
稳定性测试:进行长时间运行和异常情况下的测试,确保系统的稳定性和可靠性。
嵌入式系统的开发工具
集成开发环境
集成开发环境(IDE)提供了代码编辑、编译、调试等一站式开发工具,常用的嵌入式IDE包括:
Keil:广泛应用于ARM处理器的开发,提供了强大的代码编辑和调试功能。
IAR Embedded Workbench:支持多种处理器架构,具有丰富的调试和分析功能。
Eclipse:开源的IDE,支持多种编程语言和嵌入式开发插件。
调试工具
调试工具用于测试和调试嵌入式系统,包括:
仿真器:如JTAG仿真器、SWD仿真器等,用于硬件级的调试和测试。
逻辑分析仪:用于分析和调试数字信号和通信接口。
示波器:用于测量和分析模拟信号和波形。
仿真工具
仿真工具用于模拟和验证嵌入式系统的运行,包括:
QEMU:开源的仿真器,支持多种处理器架构和嵌入式系统。
Proteus:集成了电路仿真和嵌入式系统仿真,适用于硬件和软件的联合仿真。
Multisim:用于模拟和验证模拟电路和数字电路的仿真工具。
实例
这里以STM32F103C8为例,各型号的板有区别,需要根据实际对应修改
仿真用的是Proteus

编码用的是Keil
RX和TX的代码
#include "stm32f10x.h" // Device header
#include "gpio.h" // Device header
#include "string.h" // Device header
#include "delay.h"
#define LED1_GPIO GPIOB
#define LED1_PIN GPIO_Pin_6
#define LED2_GPIO GPIOB
#define LED2_PIN GPIO_Pin_7
#define LED3_GPIO GPIOB
#define LED3_PIN GPIO_Pin_8
#define LED_ALL_OFF GPIO_ResetBits(GPIOB, LED1_PIN | LED2_PIN | LED3_PIN)
#define LED_ALL_ON GPIO_SetBits(GPIOB, LED1_PIN | LED2_PIN | LED3_PIN)
void USART_Config(void);
void IO_Setup(void);
//void USART1_init(void);
void send(char a[]);
void USART1_IRQHandler(void);
void NVIC_usart1(void);
void delay(int i)
{
while(i--);
}
void send(char a[])
{
int i=0;
while(i<strlen(a))
{
USART_SendData(USART1,a[i++]);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
}
}
void NVIC_usart1()
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void USART1_IRQHandler()
{
ITStatus xxx=USART_GetITStatus(USART1,USART_IT_RXNE);
uint8_t received_data = USART_ReceiveData(USART1);
if(xxx==SET)
{
if(USART_ReceiveData(USART1)==0x06)
{//LED_ALL_OFF;
LED6_OFF;
// delay(100000);
LED6_ON;
USART_SendData(USART1,0x33);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
}
if(USART_ReceiveData(USART1)==0x07)
{//LED_ALL_OFF;
LED7_OFF;
// delay(100000);
LED7_ON;
USART_SendData(USART1,0x33);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
}
if(USART_ReceiveData(USART1)==0x08)
{//LED_ALL_OFF;
LED8_OFF;
// delay(100000);
LED8_ON;
USART_SendData(USART1,0x33);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
void USART_Config()
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置 USART1 的 TX(PA9)
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 速度 50MHz
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置 USART1 的 RX(PA10)
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置 USART1 参数
USART_InitStruct.USART_BaudRate = 9600; // 波特率 9600
USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 数据位 8 位
USART_InitStruct.USART_StopBits = USART_StopBits_1; // 停止位 1 位
USART_InitStruct.USART_Parity = USART_Parity_No; // 无校验位
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 使能接收和发送
// 初始化 USART1
USART_Init(USART1, &USART_InitStruct);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 使能 USART1
USART_Cmd(USART1, ENABLE);
}
int main(void)
{
USART_Config();
NVIC_usart1();
IO_Setup();
while (1)
{
// ???
}
#include "stm32f10x.h"
#include "gpio.h"
void IO_Setup(void){
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; // 正确写法
//GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
//GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_6|GPIO_Pin_10;
//GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
}
#define key1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)
#define key2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_6)
#define key3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)
#define LED6_ON GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define LED7_ON GPIO_SetBits(GPIOA,GPIO_Pin_6)
#define LED8_ON GPIO_SetBits(GPIOA,GPIO_Pin_7)
#define LED6_OFF GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define LED7_OFF GPIO_ResetBits(GPIOA,GPIO_Pin_6)
#define LED8_OFF GPIO_ResetBits(GPIOA,GPIO_Pin_7)
void IO_Setup(void);
#include "stm32f10x.h"
#include "delay.h"
int count;
void delayMS(int j)
{
count=j;
while(count);
}
//#include "stm32f10x.h"
void delayMS();
#include "stm32f10x.h" // Device header
#include "gpio.h" // Device header
#include "delay.h"
void USART_Config(void);
void IO_Setup(void);
void USART1_IRQHandler(void);
void NVIC_usart1(void);
void delay(int i)
{
while(i--);
}
int main(void)
{
NVIC_usart1();
// 初始化串口和IO
USART_Config();
IO_Setup();
int i;
while (1)
{
// 检测按键 key1
if (key1 == 0)
{
USART_SendData(USART1,0x06);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == 0); // 等待发送完成
}
// 检测按键 key2
if (key2 == 0)
{
USART_SendData(USART1,0x07);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == 0); // 等待发送完成
}
if (key3 == 0)
{
USART_SendData(USART1,0x08);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == 0); // 等待发送完成
}
i=0;
while(i++<1000)
{
if(USART_ReceiveData(USART1)==0x06)
{
LED6_ON;
delay(50000);
LED6_OFF;
}
}
}
while(i++<1000){}
}
void NVIC_usart1()
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void USART1_IRQHandler()
{
ITStatus xxx=USART_GetITStatus(USART1,USART_IT_RXNE);
if(xxx==SET)
{
if(USART_ReceiveData(USART1)==0x33){
LED6_ON;
delay(500000);
LED6_OFF;
}
}
}
void USART_Config()
{
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
//
// 使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置 USART1 的 TX(PA9)
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
// GPIO_InitStruct.GPIO_Pin = TX1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 速度 50MHz
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置 USART1 的 RX(PA10)
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
// GPIO_InitStruct.GPIO_Pin =RX1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置 USART1 参数
USART_InitStruct.USART_BaudRate = 9600; // 波特率 9600
USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 数据位 8 位
USART_InitStruct.USART_StopBits = USART_StopBits_1; // 停止位 1 位
USART_InitStruct.USART_Parity = USART_Parity_No; // 无校验位
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 使能接收和发送
// 初始化 USART1
USART_Init(USART1, &USART_InitStruct);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 使能 USART1
USART_Cmd(USART1, ENABLE);
}
void send(char a[])
{
int i=0;
while(i<strlen(a))
{
USART_SendData(USART1,a[i++]);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == 0);
}
}
1468

被折叠的 条评论
为什么被折叠?



