【STM32单片机C语言入门宝典】:从零到实战,快速掌握嵌入式开发
发布时间: 2024-07-03 09:18:17 阅读量: 3 订阅数: 14 ![](https://csdnimg.cn/release/wenkucmsfe/public/img/col_vip.0fdee7e1.png)
![](https://csdnimg.cn/release/wenkucmsfe/public/img/col_vip.0fdee7e1.png)
![【STM32单片机C语言入门宝典】:从零到实战,快速掌握嵌入式开发](https://img-blog.csdnimg.cn/5903670652a243edb66b0e8e6199b383.jpg)
# 1. STM32单片机基础**
STM32单片机是意法半导体公司推出的一系列基于ARM Cortex-M内核的32位微控制器。它具有高性能、低功耗、丰富的片上外设等特点,广泛应用于工业控制、消费电子、医疗器械等领域。
STM32单片机由处理器核心、片上外设和存储器组成。处理器核心负责执行程序代码,片上外设提供各种功能,如GPIO、定时器、ADC等,存储器用于存储程序代码和数据。
STM32单片机采用哈佛架构,即指令和数据存储在不同的存储器空间中,这可以提高程序执行效率。同时,STM32单片机还支持多种总线接口,如SPI、I2C、CAN等,方便与外部设备连接。
# 2. C语言编程基础**
C语言是一种结构化、通用编程语言,广泛用于嵌入式系统、操作系统和应用程序开发。本章节将介绍C语言的基本语法、数据类型、流程控制和函数的概念。
**2.1 C语言的基本语法和数据类型**
**2.1.1 变量和常量**
变量是用于存储数据的内存位置,而常量则是不可更改的值。变量的声明遵循以下语法:
```c
数据类型 变量名;
```
例如:
```c
int age;
```
声明了一个名为age的整型变量。
常量的声明使用const关键字:
```c
const int PI = 3.14;
```
**2.1.2 数据类型和转换**
C语言支持多种数据类型,包括:
| 数据类型 | 描述 |
|---|---|
| int | 整数 |
| float | 浮点数 |
| double | 双精度浮点数 |
| char | 字符 |
数据类型转换可以通过强制类型转换运算符进行:
```c
int num = (int) 3.14;
```
这将把浮点数3.14强制转换为整型3。
**2.2 C语言的流程控制**
**2.2.1 条件语句**
条件语句用于根据条件执行不同的代码块。最常见的条件语句是if-else语句:
```c
if (条件) {
// 条件为真时执行的代码
} else {
// 条件为假时执行的代码
}
```
**2.2.2 循环语句**
循环语句用于重复执行一段代码。最常见的循环语句是for循环、while循环和do-while循环:
```c
// for循环
for (int i = 0; i < 10; i++) {
// 执行循环体
}
// while循环
while (条件) {
// 执行循环体
}
// do-while循环
do {
// 执行循环体
} while (条件);
```
**2.2.3 函数和参数传递**
函数是可重用的代码块,可以接受参数并返回一个值。函数的声明遵循以下语法:
```c
返回类型 函数名(参数列表);
```
例如:
```c
int sum(int a, int b) {
return a + b;
}
```
函数可以通过调用语句执行:
```c
int result = sum(10, 20);
```
# 3.1 STM32单片机的内部结构
#### 3.1.1 处理器核心
STM32单片机采用ARM Cortex-M系列处理器核心,该核心具有以下特点:
- 基于32位RISC指令集,指令执行周期为1个时钟周期
- 采用哈佛架构,指令和数据存储器分离,提高了性能
- 具有浮点运算单元(FPU),支持浮点运算
- 支持多种低功耗模式,可降低功耗
#### 3.1.2 外设接口
STM32单片机集成了丰富的片上外设,包括:
- GPIO(通用输入/输出端口):用于连接外部设备,如LED、按钮、传感器等
- 定时器:用于产生定时脉冲、PWM波形等
- ADC(模数转换器):用于将模拟信号转换为数字信号
- DAC(数模转换器):用于将数字信号转换为模拟信号
- USART(通用异步收发器):用于串口通信
- I2C(串行外围接口):用于与I2C设备通信
- SPI(串行外围接口):用于与SPI设备通信
- USB(通用串行总线):用于与USB设备通信
### 3.2 STM32单片机的时钟系统
#### 3.2.1 时钟源和时钟树
STM32单片机的时钟系统由多个时钟源组成,包括:
- 内部高速振荡器(HSI):频率为8MHz
- 内部低速振荡器(LSI):频率为32kHz
- 外部时钟源(HSE):频率可配置,通常为8MHz或25MHz
时钟树将时钟源的时钟信号分配给单片机上的各个外设。时钟树的结构如下:
```mermaid
graph LR
subgraph 时钟源
A[HSI]
B[LSI]
C[HSE]
end
subgraph 时钟树
D[PLL]
E[SYSCLK]
F[HCLK]
G[PCLK1]
H[PCLK2]
end
A --> D
B --> D
C --> D
D --> E
E --> F
F --> G
F --> H
```
#### 3.2.2 时钟配置和管理
STM32单片机的时钟系统可以通过软件进行配置和管理。主要配置项包括:
- 时钟源的选择
- PLL(锁相环)的分频系数
- 时钟树的分频系数
时钟配置的代码示例:
```c
// 设置时钟源为HSE
RCC->CFGR |= RCC_CFGR_SW_HSE;
// 等待时钟源切换完成
while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_HSE);
// 设置PLL分频系数
RCC->PLLCFGR |= RCC_PLLCFGR_PLLM_3 | RCC_PLLCFGR_PLLN_16 | RCC_PLLCFGR_PLLP_2;
// 使能PLL
RCC->CR |= RCC_CR_PLLON;
// 等待PLL锁定完成
while ((RCC->CR & RCC_CR_PLLRDY) == 0);
// 设置时钟树分频系数
RCC->CFGR |= RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE1_DIV2 | RCC_CFGR_PPRE2_DIV4;
```
# 4. STM32单片机外设编程
本章节将介绍STM32单片机的外设编程,包括GPIO编程和定时器编程。
### 4.1 GPIO编程
#### 4.1.1 GPIO的基本原理
GPIO(General Purpose Input/Output)是STM32单片机上一种通用输入/输出接口,可以用来控制外部设备或读取外部信号。每个GPIO引脚都可以配置为输入、输出或模拟输入功能。
#### 4.1.2 GPIO的配置和操作
GPIO的配置和操作可以通过寄存器进行控制。STM32单片机上的GPIO寄存器主要包括以下几个:
- GPIOx_MODER:配置GPIO引脚的功能(输入、输出、模拟输入)
- GPIOx_OTYPER:配置GPIO引脚的输出类型(推挽输出、开漏输出)
- GPIOx_OSPEEDR:配置GPIO引脚的输出速度(低速、中速、高速)
- GPIOx_PUPDR:配置GPIO引脚的上下拉电阻(上拉、下拉、浮空)
- GPIOx_IDR:读取GPIO引脚的输入电平
- GPIOx_ODR:设置GPIO引脚的输出电平
**代码块:GPIO配置和操作示例**
```c
// 配置GPIOA的第5个引脚为输出模式
GPIOA->MODER |= GPIO_MODER_MODER5_0;
// 设置GPIOA的第5个引脚输出高电平
GPIOA->ODR |= GPIO_ODR_OD5;
```
**逻辑分析:**
- `GPIOA->MODER |= GPIO_MODER_MODER5_0;`:将GPIOA的第5个引脚配置为输出模式。
- `GPIOA->ODR |= GPIO_ODR_OD5;`:将GPIOA的第5个引脚输出高电平。
### 4.2 定时器编程
#### 4.2.1 定时器的基本原理
定时器是STM32单片机上一种用于产生精确时间间隔或脉冲的模块。STM32单片机上有多个定时器,每个定时器都可以独立配置和操作。
定时器的基本工作原理是:
- 定时器内部有一个计数器,当计数器达到预设值时,会产生一个中断。
- 定时器可以配置为不同的工作模式,包括:
- 单次模式:计数器达到预设值后停止计数。
- 周期模式:计数器达到预设值后重新从0开始计数。
- 脉冲模式:计数器只计数一次,达到预设值后停止计数。
#### 4.2.2 定时器的配置和操作
定时器的配置和操作可以通过寄存器进行控制。STM32单片机上的定时器寄存器主要包括以下几个:
- TIMx_CR1:控制定时器的基本功能(启动、停止、计数模式)
- TIMx_PSC:预分频器寄存器,用于设置定时器的时钟频率
- TIMx_ARR:自动重装载寄存器,用于设置定时器的计数上限
- TIMx_CNT:计数器寄存器,用于读取当前的计数值
- TIMx_DIER:中断使能寄存器,用于使能或禁止定时器中断
- TIMx_SR:状态寄存器,用于读取定时器的当前状态(中断标志、计数溢出标志等)
**代码块:定时器配置和操作示例**
```c
// 配置TIM2为周期模式,时钟频率为1MHz
TIM2->CR1 |= TIM_CR1_CEN;
TIM2->PSC = 72 - 1;
TIM2->ARR = 10000 - 1;
// 使能TIM2的中断
TIM2->DIER |= TIM_DIER_UIE;
```
**逻辑分析:**
- `TIM2->CR1 |= TIM_CR1_CEN;`:启动TIM2定时器。
- `TIM2->PSC = 72 - 1;`:设置TIM2的时钟频率为1MHz(系统时钟为72MHz)。
- `TIM2->ARR = 10000 - 1;`:设置TIM2的计数上限为10000。
- `TIM2->DIER |= TIM_DIER_UIE;`:使能TIM2的中断。
#### 4.2.3 定时器的中断处理
当定时器达到预设值时,会产生一个中断。中断处理程序可以用来执行特定的操作,例如:
- 更新LED的状态
- 读取传感器数据
- 发送数据到UART
**代码块:定时器中断处理示例**
```c
void TIM2_IRQHandler(void)
{
// 清除中断标志
TIM2->SR &= ~TIM_SR_UIF;
// 执行中断处理操作
// ...
}
```
**逻辑分析:**
- `void TIM2_IRQHandler(void)`:TIM2定时器的中断处理程序。
- `TIM2->SR &= ~TIM_SR_UIF;`:清除TIM2的中断标志。
- `// 执行中断处理操作`:执行中断处理操作。
# 5.1 LED闪烁程序
### 5.1.1 程序设计和实现
LED闪烁程序是一个简单的STM32单片机程序,它可以使连接到单片机的LED灯闪烁。该程序的实现步骤如下:
1. **初始化GPIO端口和引脚:**
- 使用 `RCC_AHB1PeriphClockCmd` 函数使能GPIO端口时钟。
- 使用 `GPIO_Init` 函数配置GPIO引脚为输出模式。
2. **配置LED引脚:**
- 使用 `GPIO_SetBits` 函数将LED引脚置为高电平,点亮LED。
- 使用 `GPIO_ResetBits` 函数将LED引脚置为低电平,熄灭LED。
3. **创建延时函数:**
- 使用 `SysTick_Config` 函数配置SysTick定时器,用于产生延时。
- 在延时函数中,使用 `while` 循环进行延时。
4. **编写主函数:**
- 在主函数中,初始化GPIO端口和引脚。
- 在无限循环中,点亮LED,延时,熄灭LED,延时。
```c
#include "stm32f10x.h"
int main(void)
{
// 初始化GPIO端口和引脚
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_Init(GPIOA, &(GPIO_InitTypeDef){
.GPIO_Pin = GPIO_Pin_5,
.GPIO_Mode = GPIO_Mode_Out,
.GPIO_OType = GPIO_OType_PP,
.GPIO_PuPd = GPIO_PuPd_NOPULL,
.GPIO_Speed = GPIO_Speed_50MHz
});
// 配置LED引脚
GPIO_SetBits(GPIOA, GPIO_Pin_5);
// 创建延时函数
SysTick_Config(SystemCoreClock / 1000);
void delay_ms(uint32_t ms)
{
uint32_t i;
while (ms--)
{
for (i = 0; i < 1000; i++)
;
}
}
// 主函数
while (1)
{
GPIO_SetBits(GPIOA, GPIO_Pin_5);
delay_ms(1000);
GPIO_ResetBits(GPIOA, GPIO_Pin_5);
delay_ms(1000);
}
}
```
### 5.1.2 程序调试和验证
1. 将程序下载到STM32单片机。
2. 连接LED到GPIO引脚。
3. 观察LED是否正常闪烁。
0
0
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)