STM32单片机编程实战:C语言快速上手,打造你的第一个项目
发布时间: 2024-07-05 01:29:36 阅读量: 98 订阅数: 42
![STM32单片机编程实战:C语言快速上手,打造你的第一个项目](https://img-blog.csdnimg.cn/20200413203428182.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjUwNjkzOQ==,size_16,color_FFFFFF,t_70)
# 1. STM32单片机简介
STM32单片机是意法半导体公司生产的一系列32位微控制器,基于ARM Cortex-M内核,具有高性能、低功耗和丰富的外设。STM32单片机广泛应用于工业控制、物联网、医疗电子等领域。
STM32单片机具有以下特点:
- 基于ARM Cortex-M内核,性能强大
- 低功耗设计,适合电池供电设备
- 丰富的片上外设,如GPIO、定时器、ADC、DAC等
- 易于开发,支持多种开发工具和库
# 2. C语言基础
**2.1 数据类型和变量**
C语言中,数据类型决定了变量可以存储的值的类型和大小。基本数据类型包括:
| 数据类型 | 值类型 | 范围 |
|---|---|---|
| int | 整数 | 取决于编译器 |
| float | 浮点数 | 取决于编译器 |
| double | 双精度浮点数 | 取决于编译器 |
| char | 字符 | ASCII 码值 |
变量用于存储数据,其声明语法为:
```c
数据类型 变量名;
```
例如:
```c
int age; // 声明一个整数变量 age
```
**2.2 运算符和表达式**
运算符用于对操作数执行算术或逻辑操作。常见的运算符包括:
| 运算符 | 操作 |
|---|---|
| + | 加法 |
| - | 减法 |
| * | 乘法 |
| / | 除法 |
| % | 取余 |
| == | 等于 |
| != | 不等于 |
| > | 大于 |
| < | 小于 |
表达式是由运算符和操作数组成的,用于计算结果。例如:
```c
int result = 10 + 5; // result 为 15
```
**2.3 流程控制语句**
流程控制语句用于控制程序的执行流程。常见的流程控制语句包括:
| 语句 | 用途 |
|---|---|
| if-else | 条件判断 |
| switch-case | 多路选择 |
| while | 循环执行 |
| do-while | 先执行再判断的循环 |
| for | 循环执行 |
例如:
```c
if (age > 18) {
printf("成年");
} else {
printf("未成年");
}
```
**2.4 函数和数组**
函数是一组可重用的代码块,可接受参数并返回结果。函数声明语法为:
```c
返回类型 函数名(参数列表);
```
例如:
```c
int add(int a, int b) {
return a + b;
}
```
数组是一种数据结构,用于存储相同类型元素的集合。数组声明语法为:
```c
数据类型 数组名[大小];
```
例如:
```c
int numbers[5] = {1, 2, 3, 4, 5};
```
# 3. STM32单片机开发环境搭建
### 3.1 开发环境介绍
STM32单片机开发环境主要包括以下几部分:
- **集成开发环境(IDE):**用于编写、编译和调试代码,如Keil MDK、IAR Embedded Workbench、STM32CubeIDE等。
- **编译器:**将源代码编译成机器代码,如ARM Compiler、GCC等。
- **调试器:**用于调试代码,如J-Link、ST-Link等。
- **仿真器:**用于在计算机上模拟单片机运行,如QEMU、GDB等。
### 3.2 开发工具安装和配置
#### 3.2.1 安装Keil MDK
Keil MDK是一个流行的STM32单片机开发环境,安装步骤如下:
1. 下载Keil MDK安装包。
2. 运行安装程序并按照提示进行安装。
3. 安装完成后,打开Keil MDK并注册。
#### 3.2.2 安装ST-Link
ST-Link是一个用于STM32单片机调试和编程的工具,安装步骤如下:
1. 下载ST-Link驱动程序。
2. 将ST-Link连接到计算机。
3. 运行驱动程序安装程序并按照提示进行安装。
#### 3.2.3 配置Keil MDK
配置Keil MDK以使用ST-Link进行调试:
1. 打开Keil MDK,点击“Options for Target”按钮。
2. 在“Debug”选项卡中,选择“ST-Link”作为调试器。
3. 点击“Settings”按钮,配置ST-Link的端口和时钟频率。
### 3.3 项目创建和编译
#### 3.3.1 创建项目
在Keil MDK中创建STM32单片机项目:
1. 点击“File”菜单,选择“New”->“µVision Project”。
2. 在“New Project”对话框中,选择STM32设备型号和项目名称。
3. 点击“OK”按钮创建项目。
#### 3.3.2 编译项目
编译STM32单片机项目:
1. 点击“Build”菜单,选择“Compile”。
2. 编译成功后,会在项目目录下生成hex文件。
#### 3.3.3 下载程序
将hex文件下载到STM32单片机:
1. 点击“Flash”菜单,选择“Download”。
2. 选择hex文件并点击“OK”按钮。
3. 程序下载完成后,单片机将自动运行。
# 4. STM32单片机外设编程
### 4.1 GPIO编程
GPIO(通用输入/输出)是STM32单片机中最重要的外设之一,它允许单片机与外部设备进行交互。GPIO引脚可以配置为输入、输出或模拟功能。
**GPIO寄存器**
STM32单片机的GPIO外设通过一组寄存器进行控制,包括:
- **GPIOx_MODER**:模式寄存器,用于配置引脚模式。
- **GPIOx_OTYPER**:输出类型寄存器,用于配置引脚输出类型(推挽输出或开漏输出)。
- **GPIOx_OSPEEDR**:输出速度寄存器,用于配置引脚输出速度。
- **GPIOx_PUPDR**:上拉/下拉寄存器,用于配置引脚的上拉/下拉电阻。
- **GPIOx_IDR**:输入数据寄存器,用于读取引脚输入状态。
- **GPIOx_ODR**:输出数据寄存器,用于设置引脚输出状态。
**GPIO编程步骤**
1. **配置引脚模式:**使用`GPIOx_MODER`寄存器将引脚配置为输入、输出或模拟模式。
2. **配置输出类型:**使用`GPIOx_OTYPER`寄存器将引脚配置为推挽输出或开漏输出。
3. **配置输出速度:**使用`GPIOx_OSPEEDR`寄存器将引脚配置为低速、中速或高速输出。
4. **配置上拉/下拉电阻:**使用`GPIOx_PUPDR`寄存器将引脚配置为上拉、下拉或无电阻。
5. **读取引脚输入状态:**使用`GPIOx_IDR`寄存器读取引脚输入状态。
6. **设置引脚输出状态:**使用`GPIOx_ODR`寄存器设置引脚输出状态。
**代码示例**
以下代码示例展示了如何配置GPIO引脚为输出模式并输出高电平:
```c
#include "stm32f10x.h"
int main(void)
{
// 配置GPIOA引脚5为输出模式
GPIOA->MODER |= (1 << 10);
GPIOA->MODER &= ~(1 << 11);
// 设置GPIOA引脚5输出高电平
GPIOA->ODR |= (1 << 5);
while (1)
{
// 无限循环
}
}
```
### 4.2 定时器编程
定时器是STM32单片机中另一个重要的外设,它允许单片机生成精确的时间间隔和脉冲。STM32单片机有多个定时器外设,每个定时器都有不同的功能和特性。
**定时器寄存器**
STM32单片机的定时器外设通过一组寄存器进行控制,包括:
- **TIMx_CR1**:控制寄存器1,用于配置定时器基本功能。
- **TIMx_CR2**:控制寄存器2,用于配置定时器高级功能。
- **TIMx_PSC**:预分频寄存器,用于设置定时器时钟预分频因子。
- **TIMx_ARR**:自动重装载寄存器,用于设置定时器自动重装载值。
- **TIMx_CNT**:计数器寄存器,用于存储定时器当前计数值。
**定时器编程步骤**
1. **配置定时器时钟:**使用`TIMx_CR1`寄存器配置定时器时钟源和预分频因子。
2. **设置定时器自动重装载值:**使用`TIMx_ARR`寄存器设置定时器自动重装载值,该值决定了定时器溢出的时间间隔。
3. **配置定时器模式:**使用`TIMx_CR1`寄存器配置定时器模式,如向上计数、向下计数或中心对齐模式。
4. **启动定时器:**使用`TIMx_CR1`寄存器启动定时器。
5. **读取定时器计数值:**使用`TIMx_CNT`寄存器读取定时器当前计数值。
**代码示例**
以下代码示例展示了如何配置定时器3为向上计数模式并产生1秒的脉冲:
```c
#include "stm32f10x.h"
int main(void)
{
// 配置定时器3时钟
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
// 配置定时器3为向上计数模式
TIM3->CR1 |= TIM_CR1_DIR;
// 设置定时器3自动重装载值
TIM3->ARR = 84000000 / 1;
// 启动定时器3
TIM3->CR1 |= TIM_CR1_CEN;
while (1)
{
// 无限循环
}
}
```
### 4.3 串口通信编程
串口通信是STM32单片机与外部设备进行数据传输的一种常见方式。STM32单片机有多个串口外设,每个串口都有不同的功能和特性。
**串口寄存器**
STM32单片机的串口外设通过一组寄存器进行控制,包括:
- **USARTx_CR1**:控制寄存器1,用于配置串口基本功能。
- **USARTx_CR2**:控制寄存器2,用于配置串口高级功能。
- **USARTx_BRR**:波特率寄存器,用于设置串口波特率。
- **USARTx_DR**:数据寄存器,用于发送和接收数据。
- **USARTx_SR**:状态寄存器,用于获取串口状态信息。
**串口编程步骤**
1. **配置串口时钟:**使用`RCC`寄存器配置串口时钟源。
2. **配置串口引脚:**使用`GPIO`寄存器配置串口引脚为串口功能。
3. **配置串口波特率:**使用`USARTx_BRR`寄存器设置串口波特率。
4. **配置串口模式:**使用`USARTx_CR1`寄存器配置串口模式,如数据位、停止位和校验位。
5. **发送数据:**使用`USARTx_DR`寄存器发送数据。
6. **接收数据:**使用`USARTx_DR`寄存器接收数据。
**代码示例**
以下代码示例展示了如何配置串口1为8位数据位、1个停止位、无校验位模式并发送数据:
```c
#include "stm32f10x.h"
int main(void)
{
// 配置串口1时钟
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
// 配置串口1引脚
GPIOA->CRH |= GPIO_CRH_MODE8_1 | GPIO_CRH_CNF8_1;
// 配置串口1波特率
USART1->BRR = 84000000 / 9600;
// 配置串口1模式
USART1->CR1 |= USART_CR1_TE | USART_CR1_RE;
// 发送数据
USART1->DR = 'A';
while (1)
{
// 无限循环
}
}
```
# 5.1 LED闪烁程序
**目标:**编写一个程序,让STM32单片机的LED灯周期性闪烁。
**材料:**
* STM32单片机开发板
* LED灯
* 电阻
**步骤:**
1. **配置GPIO:**
- 初始化GPIOB的第0引脚为输出模式。
- 设置该引脚的输出类型为推挽输出。
```c
// 配置GPIOB的第0引脚为输出模式
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
```
2. **循环闪烁LED:**
- 在一个无限循环中,依次设置GPIOB的第0引脚为高电平和低电平,实现LED的闪烁。
```c
while (1)
{
// 设置GPIOB的第0引脚为高电平,LED点亮
GPIO_SetBits(GPIOB, GPIO_Pin_0);
// 延时1秒
Delay(1000);
// 设置GPIOB的第0引脚为低电平,LED熄灭
GPIO_ResetBits(GPIOB, GPIO_Pin_0);
// 延时1秒
Delay(1000);
}
```
**结果:**
运行程序后,STM32单片机的LED灯将周期性地闪烁,闪烁周期为2秒。
0
0