6.16(预计11月完成)
F1系统架构:四个主动单元+四个被动单元
主动单元
Cortex M3内核 DCode总线(D-Bus)
Cortex M3内核 DCode总线(D-Bus)
通用DMA1
通用DMA2
被动单元
内部FLASH
内部SRAM
FSMC
AHB到APB的桥,它连接的所有APB外设(AHB:高级高性能总线 APB:高级外围总线)
面试题
6.17
1、什么是嵌入式
嵌入式系统是专为特定应用场景设计的专用计算机系统,以微控制器(MCU)或微处理器(MPU)为核心,软硬件可裁剪。它通常对实时性、功耗、成本和可靠性有严格要求,区别于通用PC,典型特征是“软件固化在ROM中”且“软硬件强耦合”。
2、嵌入式最小系统由哪些部分组成
最小系统是指让MCU(微控制器)能够正常工作的最基本硬件电路集合。它通常由以下5个核心部分组成:1. 电源电路(供电)2. 时钟电路(心跳)3. 复位电路(重启)4. 调试/下载接口(烧录口)5. 启动模式选择电路(Boot)
3、嵌入式系统中常见的时钟源有哪些
本质上分为外部时钟源和内部时钟源两大类,具体常见类型如下:
1. 外部晶振/晶体(无源晶振,HSE/LSE)
高频晶振(HSE):通常为8MHz或25MHz,作为PLL(锁相环)的输入,经倍频后提供主频(如72MHz、168MHz)。
低频晶振(LSE):通常为32.768KHz,专门用于RTC(实时时钟)模块,因为该频率分频后(2^15)恰好能产生1秒的精确时钟。
2. 外部有源晶振(振荡器)
内部已包含振荡电路的完整时钟源,直接给MCU的OSC_IN引脚输入方波信号。它比无源晶振信号更稳定、抗干扰更强,但成本较高,常用于通信设备或对时钟抖动要求严苛的场景。
3. 内部RC振荡器(HSI/LSI)
由芯片内部的电阻电容构成,无需外接元器件。
高频内部时钟(HSI):通常为8MHz或16MHz。优点是启动快(微秒级)、节省引脚,但精度较低(温漂大),常用于低功耗唤醒或作为备用时钟。
低频内部时钟(LSI):通常为30KHz~40KHz左右,主要用于独立看门狗(IWDG)和低功耗模式的唤醒。
4. 外部时钟输入(GPIO直输)
直接由外部其他芯片(如蓝牙模块、GPS模块)产生的时钟信号从外部时钟输入引脚灌入,不经过晶振电路。
实际运行时,MCU很少直接使用原始时钟源,而是通过内部的PLL(锁相环)对HSE或HSI进行‘倍频’(如8MHz倍频到168MHz)后,再分频给内核、总线和各个外设使用。同时,为了保证系统可靠性,通常还会配置‘时钟安全系统(CSS),一旦检测到外部HSE失效,硬件自动切换到内部HSI,防止系统死机。
4、什么是时钟树
时钟树是MCU内部时钟系统的整体架构图,它描述了原始时钟源(晶振/RC)是如何经过一系列路径,最终分配给CPU、总线和各个外设使用的。
时钟树的核心处理流程是:时钟源 → 选择器(Switch)→ PLL(锁相环倍频)→ 分频器(Divider)→ 门控电路 → 外设/内核。
5、GPIO有哪些模式
一、输入浮空
特点:空闲时,IO状态不确定(高阻态),由外部环境决定
上下拉电阻关闭,双MOS管关闭,施密特触发器打开
二、输入上拉 key0,1,2
特点:空闲时,由于上拉电阻,IO呈现高电平
上拉电阻打开,下拉电阻关闭,施密特触发器打开,双MOS管不导通
三、输入下拉 key up按键
特点:空闲时,由于下拉电阻,IO呈现低电平
上拉电阻关闭,下拉电阻打开,施密特触发器打开,双MOS管不导通
四、模拟功能
特点:专门用于模拟信号输入或输出,ADC和DAC
上下拉关闭,施密特关闭,双MOS管不导通
输入的时候不能输出,但是输出的时候可以输入(输出模式,触发器打开)
五、开漏输出
特点:不能输出高电平,必须有外部上拉电阻才能输出高电平
上下拉电阻关闭,施密特触发器打开,P-MOS管始终不导通,往ORD对应位写0,N-MOS管导通,输出0;写1则P-MOS管不导通,呈现高阻态
六、推挽输出
特点:可输出高低电平,驱动能力强
上下拉电阻关闭,施密特触发器打开,往ORD对应位写0,N-MOS管导通,输出0;写1则P-MOS管导通,输出1
七、开漏输出复用模式
开漏输出P-MOS管永远不导通,所以不能输出高电平
八、推挽输出复用模式
来自片上外设的,都是复用模式
6、AHB总线时钟和APB总线时钟的关系?
AHB是APB的“父时钟”,APB时钟由AHB时钟经过“分频器”分频得到。
7、为什么外设使用前要使能时钟?
表层原因:为了降低功耗
但深层原因涉及寄存器操作的有效性。
1. 核心原因:时钟门控(Clock Gating)降低动态功耗
CMOS电路的功耗主要由动态功耗(翻转充放电)决定。MCU内部所有外设的数字逻辑(如寄存器、状态机)都需要时钟边沿触发才能工作。如果所有外设时钟默认全开,即使外设未使用,也会产生巨大的无效翻转电流。因此,芯片设计采用“时钟门控”技术——默认关闭所有外设时钟,使用时再通过RCC(复位和时钟控制)模块使能,从而大幅降低整机功耗。
2. 根本原理:寄存器写入需要有效时钟边沿
如果外设时钟未使能,其内部的总线接口(APB/AHB桥接器)处于休眠状态。此时,即使CPU通过总线向外设寄存器写入配置值,该写操作也无法被外设锁存(因为没有时钟边沿触发作保持),写入无效。读取时也会读到默认的复位值(或产生总线错误)。
3. 🔥 面试必杀技:避免进入HardFault(硬错误)
在Cortex-M内核中,如果外设时钟未使能而强行访问该外设的寄存器,在某些系列(如STM32F1/F4)中虽不会立刻HardFault,但寄存器写入无效,极易引发业务逻辑乱套;而在部分安全等级较高的MCU或某些总线配置下,此类非法访问会直接触发总线错误(Bus Fault),进而导致HardFault,使系统死机。
因此,正确的初始化顺序必须是:先使能RCC对应外设时钟(等待硬件稳定)→ 再配置GPIO复用功能 → 最后配置外设寄存器并使能外设本身。
6.18
输出控制,输入检测
头文件配置
#ifndef __LED_H #define __LED_H #include "stm32f10x.h" //寄存器配置 //宏定义函数 //PB5 低电平有效 #define LED0_ON() do{ GPIOB->ODR &= ~(0X01U << 5); }while(0) //开 #define LED0_OFF() do{ GPIOB->ODR |= (0X01U << 5); }while(0) //关 #define LED0_TOGGLE() do{ GPIOB->ODR ^= (0X01U << 5); }while(0) //翻转 //PE5 低电平有效 #define LED1_ON() do{ GPIOE->ODR &= ~(0X01U << 5); }while(0) //开 #define LED1_OFF() do{ GPIOE->ODR |= (0X01U << 5); }while(0) //关 #define LED1_TOGGLE() do{ GPIOE->ODR ^= (0X01U << 5); }while(0) //翻转 void Register_LED_Init(void); #endif#ifndef __BEEP_H #define __BEEP_H #include "stm32f10x.h" //PB8 高电平有效 //宏定义函数 #define BEEP_ON() do{ GPIOB->ODR |= (0X01U << 8); }while(0) //开 #define BEEP_OFF() do{ GPIOB->ODR &= ~(0X01U << 8); }while(0) //关 #define BEEP_TOGGLE() do{ GPIOB->ODR ^= (0X01U << 8); }while(0) //翻转 void Register_BEEP_Init(void); #endif#ifndef __KEY_H #define __KEY_H #include "stm32f10x.h" //按键读取 #define KEY_UP_READ() do{ (((GPIOA->IDR) & (1U << 0)) ? 1 : 0) ; }while(0) //开 #define KEY0_READ() do{ ((((GPIOE->IDR) & (1U << 4))==0U)? 1 : 0) ; }while(0) //关 #define KEY1_READ() do{ ((((GPIOE->IDR) & (1U << 3))==0U)? 1 : 0) ; }while(0) //翻转 #define KEY2_READ() do{ ((((GPIOE->IDR) & (1U << 2))==0U)? 1 : 0) ; }while(0) //翻转 void Register_KEY_Init(void); #endif