揭秘STM32单片机架构:深入剖析内部结构,掌握工作原理
发布时间: 2024-07-03 07:24:09 阅读量: 225 订阅数: 34
![揭秘STM32单片机架构:深入剖析内部结构,掌握工作原理](https://img-blog.csdnimg.cn/3ce6c8891127453d93c9442c628b4e10.png)
# 1. STM32单片机简介**
STM32单片机是意法半导体(STMicroelectronics)推出的32位微控制器系列,基于ARM Cortex-M内核。它具有高性能、低功耗和丰富的片上外设,广泛应用于工业控制、物联网、医疗电子等领域。
STM32单片机采用哈佛架构,具有独立的指令存储器和数据存储器,提高了指令执行效率。同时,其内部集成了丰富的片上外设,如定时器、串口、ADC等,无需外接电路即可实现各种功能。
STM32单片机支持多种开发环境,如Keil MDK、IAR Embedded Workbench等,提供丰富的软件库和开发工具,降低了开发难度,提高了开发效率。
# 2. STM32单片机内部结构
STM32单片机内部结构复杂,由处理器核心、存储器系统和外围设备组成。
### 2.1 处理器核心
处理器核心是单片机的中央处理单元,负责执行指令和处理数据。STM32单片机采用ARM Cortex-M系列处理器核心,具有高性能、低功耗的特点。
### 2.2 存储器系统
存储器系统负责存储程序和数据。STM32单片机采用哈佛结构,即程序存储器和数据存储器分开。
#### 2.2.1 Flash存储器
Flash存储器是一种非易失性存储器,用于存储程序代码。Flash存储器具有可擦除和可编程的特点,可以多次擦除和写入数据。
#### 2.2.2 SRAM存储器
SRAM存储器是一种易失性存储器,用于存储数据和变量。SRAM存储器具有速度快、功耗低的特点,但断电后数据会丢失。
### 2.3 外围设备
外围设备是单片机与外部世界交互的接口,包括定时器、串口、ADC等。
#### 2.3.1 定时器
定时器是一种用于生成精确时间间隔的设备。STM32单片机有多个定时器,可以用于生成脉冲、测量时间间隔和产生PWM信号。
#### 2.3.2 串口
串口是一种用于数据传输的设备。STM32单片机有多个串口,可以用于与其他设备进行通信。
#### 2.3.3 ADC
ADC是一种用于将模拟信号转换为数字信号的设备。STM32单片机有多个ADC,可以用于测量电压、电流和温度等模拟量。
**表格:STM32单片机外围设备一览**
| 外围设备 | 功能 |
|---|---|
| 定时器 | 生成时间间隔、测量时间间隔、产生PWM信号 |
| 串口 | 数据传输 |
| ADC | 模拟信号转数字信号 |
| GPIO | 通用输入输出 |
| I2C | 串行通信 |
| SPI | 串行通信 |
| DMA | 数据传输 |
**Mermaid流程图:STM32单片机内部结构**
```mermaid
graph LR
subgraph 处理器核心
ARM Cortex-M
end
subgraph 存储器系统
Flash存储器
SRAM存储器
end
subgraph 外围设备
定时器
串口
ADC
GPIO
I2C
SPI
DMA
end
处理器核心 --> 存储器系统
处理器核心 --> 外围设备
```
**代码块:STM32定时器初始化**
```c
#include "stm32f10x.h"
void TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 10000 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE);
}
```
**代码逻辑分析:**
* RCC_APB1PeriphClockCmd()函数使能TIM2定时器的时钟。
* TIM_TimeBaseStructure结构体配置定时器的时基参数。
* TIM_TimeBaseInit()函数初始化定时器的时基。
* TIM_Cmd()函数使能定时器。
**参数说明:**
* TIM2:定时器2
* &TIM_TimeBaseStructure:时基参数结构体指针
# 3. STM32单片机工作原理
### 3.1 时钟系统
STM32单片机采用多时钟源设计,包括内部时钟源和外部时钟源。内部时钟源主要有高速内部时钟(HSI)、低速内部时钟(LSI)和实时时钟(RTC)。外部时钟源主要有外部晶振(HSE)和外部低速晶振(LSE)。
时钟系统的主要功能是为单片机各模块提供稳定的时钟信号,保证系统正常运行。时钟系统通过时钟控制寄存器(RCC)进行配置和控制。
### 3.2 复位机制
STM32单片机具有多种复位机制,包括上电复位、外部复位、软件复位和看门狗复位。
* **上电复位(POR):**当单片机上电时,POR信号会将单片机复位。
* **外部复位(NRST):**当外部复位引脚上出现低电平时,NRST信号会将单片机复位。
* **软件复位(SWRST):**通过执行特定的指令,可以触发软件复位。
* **看门狗复位(WDR):**当看门狗定时器溢出时,WDR信号会将单片机复位。
复位机制确保单片机在异常情况下能够恢复到已知状态,保证系统的稳定性。
### 3.3 中断系统
STM32单片机具有强大的中断系统,支持多达数十个中断源。中断系统可以将外部事件或内部事件通知给单片机,并触发相应的处理程序。
中断系统主要由中断控制器和中断向量表组成。中断控制器负责管理中断请求,并根据中断优先级决定中断处理顺序。中断向量表存储着中断处理程序的地址,当发生中断时,单片机会根据中断源跳到相应的中断处理程序。
### 3.4 DMA控制器
DMA(直接存储器访问)控制器是一种硬件外设,可以实现数据在存储器和外设之间的直接传输,无需CPU参与。DMA控制器通过DMA通道进行配置,每个DMA通道可以连接一个外设和一个存储器区域。
DMA控制器可以提高数据传输效率,减轻CPU负担。在需要频繁数据传输的应用中,使用DMA控制器可以显著提升系统性能。
#### DMA控制器工作原理
DMA控制器的工作原理如下:
1. 配置DMA通道,指定数据源、数据目标、传输长度和传输方向。
2. 启动DMA传输,DMA控制器会自动将数据从数据源传输到数据目标。
3. 当传输完成时,DMA控制器会触发DMA传输完成中断。
#### DMA控制器参数说明
DMA控制器的主要参数如下:
* **通道号:**DMA通道的编号,用于标识不同的DMA通道。
* **数据源:**数据传输的源地址。
* **数据目标:**数据传输的目标地址。
* **传输长度:**要传输的数据长度。
* **传输方向:**数据传输的方向,可以是存储器到外设或外设到存储器。
#### DMA控制器代码示例
以下代码示例演示了如何使用DMA控制器传输数据:
```c
// 配置DMA通道
DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.Channel = DMA_Channel_1;
DMA_InitStruct.Direction = DMA_DIR_MemoryToPeripheral;
DMA_InitStruct.PeriphInc = DMA_PINC_Enable;
DMA_InitStruct.MemInc = DMA_MINC_Enable;
DMA_InitStruct.PeriphDataAlignment = DMA_PDATAALIGN_Byte;
DMA_InitStruct.MemDataAlignment = DMA_MDATAALIGN_Byte;
DMA_InitStruct.Mode = DMA_MODE_Normal;
DMA_InitStruct.Priority = DMA_PRIORITY_High;
DMA_Init(&DMA_InitStruct);
// 启动DMA传输
DMA_Cmd(DMA_Channel_1, ENABLE);
// 等待DMA传输完成
while (!DMA_GetFlagStatus(DMA_FLAG_TC1));
// 清除DMA传输完成标志位
DMA_ClearFlag(DMA_FLAG_TC1);
```
# 4.1 C语言编程
### 4.1.1 数据类型
STM32单片机使用C语言进行编程,C语言提供了丰富的**数据类型**,用于表示不同类型的数据。常见的数据类型包括:
- **整型:**int、short、long,用于存储整数。
- **浮点型:**float、double,用于存储小数。
- **字符型:**char,用于存储单个字符。
- **字符串:**char[],用于存储字符串。
- **布尔型:**bool,用于表示真或假。
### 4.1.2 运算符
C语言提供了各种**运算符**,用于对数据进行操作。常见运算符包括:
- **算术运算符:**+、-、*、/、%,用于进行加、减、乘、除、取余运算。
- **比较运算符:**==、!=、>、<、>=、<=,用于比较两个值的大小或相等性。
- **逻辑运算符:**&&、||、!,用于进行与、或、非逻辑运算。
- **位运算符:**&、|、^、<<、>>,用于进行位与、位或、位异或、左移、右移运算。
## 4.2 STM32库函数
STM32单片机提供了丰富的**库函数**,用于简化外设操作和编程。这些库函数由STMicroelectronics提供,包含了对STM32单片机外设的低级访问和控制。
### 4.2.1 外设初始化
外设初始化是使用STM32库函数的第一步。它涉及配置外设的寄存器,以使其处于所需的工作模式。例如,要初始化一个定时器,可以使用以下代码:
```c
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 1000;
TIM_TimeBaseStructure.TIM_Prescaler = 8400;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_Cmd(TIM2, ENABLE);
```
**参数说明:**
- RCC_APB1PeriphClockCmd():使能TIM2外设时钟。
- TIM_TimeBaseInitTypeDef:定时器基准初始化结构体。
- TIM_TimeBaseStructure.TIM_Period:定时器周期,单位为ms。
- TIM_TimeBaseStructure.TIM_Prescaler:定时器预分频器,用于分频时钟源。
- TIM_TimeBaseStructure.TIM_ClockDivision:定时器时钟分频器。
- TIM_TimeBaseStructure.TIM_CounterMode:定时器计数模式,这里设置为向上计数模式。
- TIM_TimeBaseInit():初始化定时器基准。
- TIM_Cmd():使能定时器。
### 4.2.2 外设操作
外设初始化后,可以使用STM32库函数对它们进行操作。例如,要设置定时器中断,可以使用以下代码:
```c
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
```
**参数说明:**
- TIM_ITConfig():配置定时器中断。
- TIM_IT_Update:定时器更新中断。
- ENABLE:使能中断。
- NVIC_InitTypeDef:NVIC初始化结构体。
- NVIC_InitStructure.NVIC_IRQChannel:中断通道号。
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority:中断抢占优先级。
- NVIC_InitStructure.NVIC_IRQChannelSubPriority:中断子优先级。
- NVIC_InitStructure.NVIC_IRQChannelCmd:中断使能。
- NVIC_Init():初始化NVIC。
# 5. STM32单片机应用实例
本章节将通过几个实际应用实例,展示STM32单片机的应用方法和编程技巧。
### 5.1 LED闪烁
LED闪烁是STM32单片机最基本的应用之一。通过控制LED的亮灭,可以实现各种指示灯、状态灯等功能。
**代码实现:**
```c
#include "stm32f10x.h"
int main(void)
{
// 初始化GPIO端口
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);
GPIOC->CRH |= GPIO_CRH_MODE13_0 | GPIO_CRH_CNF13_0;
while (1)
{
// 点亮LED
GPIOC->BSRR = GPIO_BSRR_BS13;
// 延时1秒
for (int i = 0; i < 1000000; i++);
// 熄灭LED
GPIOC->BSRR = GPIO_BSRR_BR13;
// 延时1秒
for (int i = 0; i < 1000000; i++);
}
}
```
**代码逻辑分析:**
* 初始化GPIO端口:首先需要初始化用于控制LED的GPIO端口,设置其模式为输出模式。
* 点亮LED:通过设置GPIO端口的BSRR寄存器,将LED对应的引脚置为高电平,即可点亮LED。
* 延时:通过循环计数的方式实现延时,单位为微秒。
* 熄灭LED:通过设置GPIO端口的BSRR寄存器,将LED对应的引脚置为低电平,即可熄灭LED。
### 5.2 按键检测
按键检测是STM32单片机的另一个常见应用。通过检测按键的按下和释放,可以实现各种控制和交互功能。
**代码实现:**
```c
#include "stm32f10x.h"
int main(void)
{
// 初始化GPIO端口
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH &= ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13);
GPIOC->CRH |= GPIO_CRH_MODE13_0 | GPIO_CRH_CNF13_0;
while (1)
{
// 检测按键是否按下
if ((GPIOC->IDR & GPIO_IDR_IDR13) == 0)
{
// 按下按键后执行的操作
// ...
}
}
}
```
**代码逻辑分析:**
* 初始化GPIO端口:首先需要初始化用于检测按键的GPIO端口,设置其模式为输入模式。
* 检测按键是否按下:通过读取GPIO端口的IDR寄存器,可以获取按键引脚的状态。如果按键按下,则对应的引脚电平为低电平。
* 按下按键后执行的操作:当检测到按键按下时,可以执行相应的操作,例如控制LED闪烁、显示信息等。
### 5.3 定时器中断
定时器中断是STM32单片机的一种重要中断源。通过配置定时器,可以实现周期性或单次中断,从而实现各种定时和控制功能。
**代码实现:**
```c
#include "stm32f10x.h"
int main(void)
{
// 初始化定时器
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 = 0;
TIM2->PSC = 7199;
TIM2->ARR = 999;
TIM2->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(TIM2_IRQn);
while (1)
{
// 定时器中断处理函数
// ...
}
}
void TIM2_IRQHandler(void)
{
// 清除中断标志位
TIM2->SR &= ~TIM_SR_UIF;
// 定时器中断处理逻辑
// ...
}
```
**代码逻辑分析:**
* 初始化定时器:首先需要初始化用于产生中断的定时器,设置其时钟源、分频系数、重装载值等参数。
* 配置中断:通过设置TIM2->DIER寄存器,可以使能定时器中断。
* 启用中断:通过调用NVIC_EnableIRQ函数,可以启用定时器中断。
* 定时器中断处理函数:当定时器中断发生时,会执行定时器中断处理函数。在该函数中,需要清除中断标志位,并执行相应的中断处理逻辑。
# 6. STM32单片机高级应用**
### 6.1 PWM输出
**6.1.1 PWM原理**
脉宽调制(PWM)是一种调制技术,通过改变脉冲的宽度来控制输出电压或电流的平均值。在STM32单片机中,PWM输出通常使用定时器外设实现。
**6.1.2 STM32定时器PWM配置**
```c
// 初始化定时器为PWM模式
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 8400; // 分频系数
TIM_TimeBaseStructure.TIM_Period = 1000; // 周期
TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 初始化PWM输出通道
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 输出使能
TIM_OCInitStructure.TIM_Pulse = 500; // 脉冲宽度
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
```
### 6.2 ADC采样
**6.2.1 ADC原理**
模数转换器(ADC)将模拟信号转换为数字信号。STM32单片机内置ADC外设,支持多种采样模式和分辨率。
**6.2.2 STM32 ADC配置**
```c
// 初始化ADC
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // 分辨率
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 单次转换模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 非连续转换模式
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; // 无外部触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 数据右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1; // 转换次数
ADC_Init(ADC1, &ADC_InitStructure);
// 配置ADC通道
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1Cycles5); // 通道0,采样时间1.5个周期
```
### 6.3 I2C通信
**6.3.1 I2C原理**
I2C(Inter-Integrated Circuit)是一种串行通信协议,用于连接多个设备。STM32单片机内置I2C外设,支持主从模式和多主模式。
**6.3.2 STM32 I2C配置**
```c
// 初始化I2C
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // I2C模式
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // 占空比2:1
I2C_InitStructure.I2C_OwnAddress1 = 0x0A; // 本机地址
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // 应答使能
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // 7位地址模式
I2C_Init(I2C1, &I2C_InitStructure);
```
0
0