裸机开发VS单片机:架构与实战对比

裸机开发和单片机的区别:

|--------------|-------------------------------------------------------------------------|----------------------------------------------------------|
| 对比维度 | ARM 裸机开发(以 IMX6ULL 等 Cortex-A 系列为例) | 单片机开发(以 51/STM32 等 Cortex-M 系列为例) |
| 核心架构 | 基于 Cortex-A 系列,带MMU(内存管理单元)、Cache 缓存,支持虚拟内存,复杂多核 / 多总线架构 | 基于 Cortex-M/8051 等,无 MMU、无 Cache,单总线极简架构,纯实时控制 |
| 启动流程 | 必须手动编写启动文件(start.S),完成关看门狗、时钟树配置、栈初始化、重定位数据段、清 BSS 段后,才能跳转到 main 函数 | 上电直接执行,无需手动写启动文件,复位后直接进入 main 函数,流程极简 |
| 时钟配置 | 必须手动配置PLL、总线分频、时钟树,所有外设时钟需单独使能,否则外设无法工作 | 多数外设默认时钟已配置,仅需简单分频 / 使能,时钟树结构简单 |
| 开发方式 | 几乎无官方标准库,全程寄存器操作,所有驱动(UART/GPIO/ 定时器等)需从零编写 | 官方提供完善 HAL/LL 库 / 标准库,直接调用库函数开发,无需手动操作寄存器 |
| 工具链与编译 | 必须使用交叉编译工具链(如 arm-linux-gnueabihf-gcc),生成 bin 文件,通过 SD 卡 / USB 下载 | 直接使用 IDE(Keil/STM32CubeIDE)本地编译,通过 ST-Link/J-Link 一键下载调试 |
| 资源与寻址 | 4GB 完整寻址空间,片上资源丰富(大 Flash/RAM、多外设),外设地址分散,需复杂地址映射 | 小地址空间,Flash/RAM 容量小,外设直接挂内核,地址映射简单 |
| 应用场景 | 底层原理学习、Linux 驱动开发前置、高端嵌入式产品裸机开发 | 工业控制、物联网终端、小家电等实时控制类小项目 |
| 学习门槛 | 门槛高,需掌握 ARM 架构、汇编、时钟原理、链接脚本等底层知识 | 门槛低,上手快,专注应用层控制,无需深入架构原理 |
| 调试方式 | 多为离线调试,依赖串口打印、JTAG/SWD 调试成本高 | 支持在线实时调试,断点、变量查看等功能完善,调试便捷 |
| 可扩展性 | 可直接移植 Linux 系统,为上层系统开发打基础 | 仅支持裸机 / RTOS,无法移植完整 Linux 系统 |

DAY1

1 .RISC和CISC 是什么?

RISC(精简指令集)

指令少,简单,长度固定·

执行快,功耗低

常见代表:ARM,RISC-V

比如imx6ull /ARM9/Cortex-A都是RISC

CISC(复杂指令集)

指令多,复杂,长度不固定

功能强,但慢,费电

代表:x86(Intel / AMD )

总结ARM = RISC CPU = CISC

  1. pc lr sp cpsr spsr 寄存器的作用

pc 存下一条指令的地址。

lr 函数调用的时候,存返回地址----函数跑完,回通过他回到原来的位置

sp 栈顶指针,指向栈的顶部-----存临时变量,函数现场

cpsr 当前程序状态寄存器 -------存标志位(正负,进错位),工作模式,中断开关

spcr 进入异常时,备份程序的当前运行状态

3 .什么是MMU?

作用 :

管理虚拟内存到物理内存的映射

裸机必须关闭

linux驱动必须打开

4 . 什么是cache icache dcache ?

cache: CPU内部高速缓存

解决:CPU很快,内存很慢-----用cache 缓冲

icache :存指令

dcahe:存数据

cache 就是CPU的临时小书桌,比内存快几十倍

5 .单总线 VS多总线

单总线:

所有设备用一根总线

简单,便宜,慢,会堵塞

多总线;

高速设备一条,低速设备一条

快,不堵,结构复杂

总结:一个不堵,一个堵

6,AHB总线 VS APB总线

AHB:高速总线

给CPU RAM LCD 网卡

APB:低速总线

给 串口,定时器,GPIO, SPI, 12C

7 .编译程序需要哪几个步骤?

预处理:头文件,宏的展开

编译:生成汇编代码.s

汇编;生成机器码.o

链接:生成可执行程序

8 . imx6ull 内核与指令集

内核:cortex-A7

指令集:ARMv7-A

  1. ARM有几种工作模式?

User:用户工作模式

FIQ:紧急中断

IRQ:外部中断

SVC; 复位或软中断

abort:存储异常

undef 执行未被定义的指令

system 系统模式----用户模式的特权模式

Linux 内核跑在 SVC

应用程序跑在 User

  1. ARM的异常处理流程

备份cpsr到spsr

lr保存返回地址

关闭中断(视为异常类型)

跳去异常向量表

执行异常处理

恢复spcr到cpsr---跳回lr继续执行

11 . ARM9 和 Cortex-A 各有多少寄存器?

ARM9: 37个

Cortex-A : 40个

DAY2

  1. 立即数如何判断?

数值范围在0-0xFF之间的8位基础数,并且最右边含有偶数个0.

  1. b / bl / bx 指令的区别?

b 无条件跳转,不保存lr.正负32MB,用于死循环,长跳转(不返回)

bl 带链接跳转,保存下一条指令地址存入正负32MB,用于函数调用(需要返回)

bx 带状态切换跳转(blx:可保存lr),任意32位地址,用于切换ARM状态,跳转绝对地址。

  1. 栈的分类及特性?

满递减栈:由高到低存储,sp指向最后一个有效数据 ARM默认 *--psr,先减再写数据。

空递减栈:由高到低存储,sp指向下一个空闲的位置 少见

满递增栈:由低到高存储 sp指向最后一个有效数据 x86常用

空递增栈:由低到高存储 sp指向下一个空闲位置 少见 先写数据,再挪动指针

  1. ARM汇编调用C函数,C函数调用汇编函数有什么规则?

ARM汇编调用C函数时:

import main

bl main

规则1:传参

前4个参数:用r0-r3(超过的话使用栈来传递)

返回值:用r0返回

规则2:栈操作规范

调用前:压栈保护现场:stmfd sp!,{r1-r12,lr}

掉用后:出栈恢复现场: ldmfd sp!,{r1-r2,lr}

C函数调用汇编里面的函数的时候

在main.c中的声明:

extern int asm_max(int a,int b);

_as,max(10,20)

在汇编程序中:

export asm_max

规则1:寄存器使用规范

参数接收:r0-r3接收C传递的前4个参数

返回值:用 r0 返回

返回指令:用bx lr返回,恢复C程序的执行

SOC:

核心定位:核心板的【大脑+主控】,相当于电脑的CPU

·本质:是把CPU,GPU,总线控制器,外设接口(UART,SPI,GPIO,I2C)等全部集结在一颗芯片里面的【超级芯片】

·我们所写的汇编启动代码,C语言程序,Linux系统,全部都在SOC中运行,他是整个系统的绝对核心。

·我们所写的代码里:中断向量表,复位函数,栈初始化,时钟配置,都是给soc写的,用来初始化这颗主控芯片。

RAM / DDR3 512MB (运行内存)

·核心定位:核心板的(运行内存),相当于内存条------读写速度快,掉电数据丢失

·SOC可以直接从内存上面读取数据

·用来存放程序的临时变量,栈空间,堆空间(代码里面的 ldr sp, =0x84000000),栈就放在DDR3里面

·Linux在运行的时候 ,所有进程,内存数据都存在这里。

EMMC / NAND FLASH 8GB(存储芯片 )

核心定位:核心板的【硬盘】,相当于电脑的SSD/机械硬盘

·本质:掉电数据不丢失,永久存储数据,文件,系统。

核心作用:

·用来存放我的裸机程序,uboot,linux内核,设备树,根文件系统

·相当于系统的仓库,芯片上电后,从EMMC里把程序加载到DDR3中运行

·8GB 容量用来存系统,文件,数据。

关键特性:

·属于NAND FLASH中的一种(EMMC是封装好的NAND Flash ,带主控)

·读/ 写速度比DDR3慢,掉电数据不丢失

核心板接口(邮票孔/ 插针接口)

本质:·把SOC的所有外设引脚(GPIO , UART , SPI , I2C , LCD , 网口)引出来,用来接底板或外设。

开始进行代码操作:

·配制异常向量表

·所有时钟初始化R0-R6-----打开所有的外设,相当于提前开

初始化led的模式

置电平,来控制led

复位入口:

SOC 通过读取控制灯的寄存器来点灯

DAY3

|------------------------------------------|-------------------------------|-----------------------------------------------|
| 工具 | 定义 | 核心作用 |
| gcc(arm-linux-gnueabihf-gcc) | GNU 交叉编译器,用于将 C / 汇编源码编译为目标文件 | 对.c/.S源码执行语法检查、代码生成,输出.o目标文件,仅编译不链接 |
| ld(arm-linux-gnueabihf-ld) | GNU 链接器,用于整合多个目标文件 | 按照链接脚本规则,将多个.o文件链接为 ELF 格式可执行文件,分配内存地址、解决函数引用 |
| objcopy(arm-linux-gnueabihf-objcopy) | GNU 格式转换器,用于 ELF 与二进制互转 | 将带符号 / 调试信息的 ELF 文件,转为裸机可烧录的纯二进制.bin文件,去除冗余信息 |
| objdump(arm-linux-gnueabihf-objdump) | GNU 反汇编器,用于代码分析调试 | 将 ELF 文件反汇编为汇编代码,用于查看代码逻辑、验证链接地址、排查错误 |

  1. 链接脚本 imx6ull.lds的核心配置

·程序入口:ENTRY_(_start),指定芯片上电第一行执行的代码(汇编启动文件的_start标签)

·代码段地址:-Ttext 0x87800000,指定代码在 IMX6ULL DDR 中的运行地址。

·段分配:定义 . text(代码段)分为:

rodata(只读数据段)

data(数据段),

bss(未初始化的数据)

·链接顺序:指定 start.o 优先链接,保证复位入口在代码最前端。

·栈地址:配置C语言运行所需的栈的空间地址,为C语言执行提供基础

  1. beep和led 实验

·led实验:配置GPIO_IO03的MUX(复用功能),PAD(电气属性),再通过GPIOS输出高低电平来控制。

·beep实验:配置对应的GPIO的MUX,PAD,再通过GPIO输出低电平,导通PNP三极管,驱动蜂鸣器发声。

完整的流程:编译(gcc)----->链接(ld)------->格式转换(objcopy)------>烧录到SD卡上,上电后程序运行,灯亮,器响。

DAY4:

上电复位

进入 start.S 的 _start 中断向量表入口

跳转到 _reset_handler 复位初始化

【1. 配置 CP15 协处理器】

关闭 ICache、配置内存相关

→ 目的:保证中断向量表不被缓存干扰

【2. 设置 IRQ 模式栈】

cps #0x12

ldr sp, =0x86000000

【3. 设置 System 模式栈(C语言用)】

cps #0x1F

ldr sp, =0x84000000

【4. 开启 CPU 总中断】

cpsie i

【5. 清空 bss 段(全局变量清0)】

bl _bss_clear

【6. 进入 C 语言 main 函数】

b main

=====================================

进入 main

【1. 中断系统初始化】

system_interrupt_init

├─ 设置中断向量表基地址 VBAR = 0x87800000

└─ 初始化 GIC 中断控制器

【2. 打开所有外设时钟】

enable_clocks

【3. 初始化 LED、蜂鸣器】

led_init、beep_init

【4. 按键中断初始化(核心配置)】

key_init

├─ 配置 GPIO1_IO18 复用为 GPIO

├─ 配置引脚电气属性

├─ 设置为输入模式 GDIR

├─ 设置中断触发方式 ICR2

├─ 打开 GPIO 中断屏蔽 IMR

├─ 设置 GIC 中断优先级

└─ 使能 GIC 对应中断号

【5. 主循环等待中断】

while(1) { delay(); }

=====================================

【外部事件:按键按下】

GPIO1_IO18 产生中断信号

中断发送到 GIC 中断控制器

GIC 仲裁优先级 → 发给 CPU

CPU 检测到 IRQ 中断请求

硬件自动跳转到 start.S 的 _irq_handler

=====================================

【中断响应流程】

  1. 修正返回地址

sub lr, lr, #4

  1. 保护现场(压栈 R0~R12, LR)

stmfd sp!, {r0-r12, lr}

  1. 从 GIC 读取当前中断号

  1. 进入 System 模式,方便调用 C 函数

  1. 保存 LR,调用 C 语言中断处理函数

bl system_interrupt_handler

=====================================

【C 语言中断服务流程】

  1. 判断中断号是否为 GPIO1 组中断

  1. 判断是否是 GPIO1_IO18 触发的中断

  1. 执行中断动作:led_on()

  1. 清除中断标志位 ISR

(必须,否则会重复进中断)

中断函数执行完毕,返回汇编

=====================================

【中断返回流程】

  1. 通知 GIC 中断处理完成

  1. 恢复现场(出栈 R0~R12, PC)

ldmfd sp!, {r0-r12, pc}

  1. CPU 自动恢复 CPSR、返回主程序断点

回到 main 的 while(1) 继续等待下一次中断

DAY5:

  1. 什么时PPL, Prescaler, FPD,他们各自的用途是什么?

·PPL:锁相环电路-----倍频

·Prescaler: 预分频器------分频

·PFD:相位频率检测器----也可以分频也可以倍频

  1. IMX6ULL中有几个锁相环,几个相位分数分配器?

·7个独立的PPL:PPL1--PPL7

·PLL2和PLL3各含有4个相位频率检测器(PFD)

  1. 简述ARM PLL的配置
  1. IMX6ULL 中的EPIT和GPT的工作原理是什么?

|-------------|------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|
| 对比项 | EPIT 定时器 | GPT 定时器 |
| 全称 | Event Periodic Interrupt Timer事件周期性中断定时器 | General Purpose Timer通用定时器 |
| 计数方式 | 固定向下计数从装载值开始,减到 0 触发事件 | 可向上 / 向下计数更灵活,支持自由运行模式 |
| 核心工作原理 | 1. 选择时钟源(通常为 IPG_CLK) 2. 经过预分频得到计数时钟 3. 从 LR 寄存器加载初值并向下计数 4. 计到 0 时自动触发中断5. 自动重载 LR 值,循环定时 | 1. 可选多种时钟源 2. 经预分频后开始计数 3. 可配置为自由运行或比较匹配 4. 支持输入捕获、输出比较 5. 溢出或匹配时触发中断 |
| 主要功能 | 专注做周期性定时中断简单、稳定、适合系统节拍 | 功能更全:定时、输入捕获、PWM、脉冲测量 |
| 自动重载 | 支持,计到 0 自动重装 | 可自由配置是否重载 |
| 低功耗特性 | 支持停止模式下运行 | 一般不支持低功耗独立运行 |
| 典型用途 | 周期性任务、系统滴答、延时 | 测频率、测脉宽、输出方波 / PWM |
| 与你代码关系 | 依赖配置好的 IPG_CLK_ROOT | 同样使用 AHB/IPG 时钟,依赖时钟初始化 |

|--------------|----------------------------------------------------|----------------------------|
| 对比项目 | 同步通信 | 异步通信 |
| 是否有时钟线 | 有独立时钟线(SCLK、SCK、SCL) | 无时钟线,只有数据线 ± 地线 |
| 时钟来源 | 主机统一提供时钟,收发共用同一时钟 | 收发双方各自使用内部时钟,相互独立 |
| 时钟使用方式 | 以时钟边沿为基准,时钟一跳传一位 | 按约定波特率,用内部定时器定时采样 |
| 同步机制 | 时钟线同步:时钟决定何时采样、何时发送 | 帧格式同步:靠起始位对齐,之后按时间间隔采样 |
| 时钟线的作用 | 1. 统一收发时序,保证步调一致2. 明确告诉对方 "此刻数据有效"3. 从根本上避免数据错位、误码 | 无时钟线,依靠事先约定的波特率代替时钟功能 |
| 对时钟精度要求 | 极高,必须严格同源或高度同步 | 较低,只要频率接近、误差在容忍范围即可 |
| 数据传输特点 | 连续传输,效率高,适合高速通信 | 按帧传输,每帧带起始位 / 停止位,有额外开销 |
| 优点 | 速度快、协议简单、抗干扰强、不易出错 | 线路少、实现简单、适合远距离、布线方便 |
| 缺点 | 多一根线,布线复杂,远距离时钟易畸变 | 速度相对较低,帧结构占用额外带宽 |
| 典型硬件接口 | SPI、I2C、同步 UART、CAN (量化同步)、各类总线 | 标准 UART(串口)、蓝牙、USB (含特殊同步) |

1,单工:固定了通信的发送方和接收方。

半双工:通信双方都可以发送和接收数据,但不能同一时刻进行发送和接收。

全双工:通信双方可以同时进行数据的接手和发送。本质是收发分离。

2.串口通信:用一条线进行数据的传输,单次接收一长串的bit。

并行通信:用多条线进行数据的传输,多条线同时发送一个bit。

3,异步通信:通信双方按照起始位和约定好的波特率,利用各自时钟进行通信,不需要时钟线。

同步通信:通信双按照一条时钟线的频率,来进行特定周期通信。

4,串口通信属于异步串行全双工通信。

5,串口通信的电器表达:

电平标准:

TTL电平

RS-232电平

接口形式:

UART:仅需TX,RX,GND 三根线。

波特率的范围常见:115200,9600 频率越高抗干扰能力越差。

I2C时序传输:

问题 1:描述 IIC 通信的时序

IIC 是双线同步通信,核心时序有四个:起始是 SCL 高时 SDA 高变低,停止是 SCL 高时 SDA 低变高;数据在 SCL 低时变化、高时采样,高位在前;每字节后紧跟应答位,ACK 为低表示继续,NACK 为高表示停止。通信分为写操作(发地址 + 数据)和读操作(先写地址定位,再发重复起始读数据),通过 ACK 保证传输可靠。

问题 2:AT24C02 实验代码调试要点

首先完成硬件调试,检查上拉电阻、接线和电源,用逻辑分析仪验证 100kHz 时钟和时序正常;然后调试代码,实现 I2C 基础时序函数和 AT24C02 的字节写、页写、随机读、连续读驱动,添加 ACK 校验和写周期延时;最后验证读写功能,确保数据掉电不丢失,页写不溢出,连续读逻辑正确。

流程细节:

总线空闲时:

时钟线SCL和数据线SDA都为高电平,谁先在数据线上产生一个低电平0,谁就赢得了总线的控制权(总线抢占),即认为发送了一个start信号,通信开始,作为主机(发送方);

主机发送数据时:

遵循MSB优先原则

在SCL为低电平时,只能发送方改变SDA,接收方不能采样SDA

SCL为高电平时,只能接收方采样SDA,发送方需保证SDA稳定

每一次通信都是先发送从机地址(7位)+数据流向位(0:主发从接;1:从发主接)

发送完8位数据时,在第9个时钟周期必须发送应答类型(ACK/NACK)

数据传输:(都先要主机发送从机地址+数据流向位(0:主发从接)+要写、读的寄存器地址)

写时序(主机发送,从机应答):主机发送一字节数据,从机回复一个应答类型,从机接收到ACK就继续向从机发送数据,直到收到NACK应答类型

读时序(从机发送,主机应答):重新发送start信号;再次发送从机地址,主机切换数据流向位(1:从发主接),开始连续读取数据(先应答,再读取数据,发ACK告诉从机我开始读了,你发送数据),直到主机读到倒数第二个数据时,发给从机NACK,告诉从机,下一个数据是最后一个了,你不用再发送数据了),读取结束发送stop

stop停止:SCL保持高电平时,SDA从低到高,并保持稳定,视为通信停止

  1. 什么是ADC?

把模拟信号转换成数字信号的转换器。

  1. 什么是ADC的基准电压?

是ADC进行模数转换时的参考电压,他决定了ADC输入电压的量程范围。

  1. ADC的工作原理是什么?

·采样:在特定的时间点对于模拟信号进行采取,获取该时刻的电压值。

·保持:把采集到的电压保持一段时间,便于后续处理。

·量化:根据参考电压的值和保持的电压进行比较,并且把他转换成离散的数字等级。

·编码:把量化后的等级转换为对应的二进制数字输出。

逐次逼近法:

核心是把连续变化的电压或电流,转换成离散的二进制代码。

  1. 什么是ADC的分辨率?常见的分辨率有哪些?

ADC的分辨率指的是ADC能够分辨的最小模电压变化量,分辨率越高对于,量化的误差越小,转换结果越接近真实的模拟电压值。

常见的分辨率有:8位,10位,12位,14位,16位,24位等。

·8位:可以区分 2^8 = 256 个不同的电压等级。

  1. 假设采用12位分辨率,基准电压为3.3v,量化结果为n时的实际电压应该如何计算?

n * 3.3 / 2^12 = n/4096 *3.3

相关推荐
gscsded21 分钟前
C2000 GPIO 配置笔记
单片机
Sakuyu4346825 分钟前
STM32基础
stm32·单片机·嵌入式硬件
gscsded43 分钟前
C2000 CPU Timer 学习笔记
单片机
iCxhust2 小时前
AD0808调试笔记
笔记·单片机·嵌入式硬件·操作系统·微机原理·8088单板机
木子单片机2 小时前
基于51单片机的步进电机调速系统设计
单片机·嵌入式硬件·51单片机·keil
三易串口屏4 小时前
实验10 物理按键实验
单片机·51单片机·串口屏·串口协议·uart 通信·嵌入式 ui
深圳光特通信豆子4 小时前
10Mb/s TTL单模双纤光收发模块技术规格手册
单片机·嵌入式硬件
一路往蓝-Anbo4 小时前
第六章:RTOS 任务 —— 任务逻辑与并发的 TDD 路径
网络·stm32·单片机·嵌入式硬件·tdd
星夜夏空994 小时前
STM32单片机学习(20) —— 利用中断实现串口通信(填前面的坑)
stm32·单片机·学习
wengqidaifeng4 小时前
2026年电赛校赛备战MSPM0G3507+keil讲解(上)-----2025年电赛E题小车篇
单片机·嵌入式硬件·电赛