【STM32单片机开发板入门指南】:零基础快速上手,开启嵌入式开发之旅
发布时间: 2024-07-01 17:00:05 阅读量: 71 订阅数: 31
![stm32单片机开发板](https://img-blog.csdnimg.cn/c3437fdc0e3e4032a7d40fcf04887831.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LiN55-l5ZCN55qE5aW95Lq6,size_20,color_FFFFFF,t_70,g_se,x_16)
# 1. STM32单片机开发板概述**
STM32单片机开发板是基于意法半导体STM32系列微控制器的开发平台,为嵌入式系统开发提供了灵活且易于使用的环境。这些开发板通常包含必要的硬件组件,如微控制器、存储器、I/O接口和调试接口,使开发人员能够快速原型设计和测试他们的嵌入式应用程序。
STM32单片机开发板具有广泛的应用,包括物联网设备、工业自动化、医疗保健和消费电子产品。它们为开发人员提供了一个经济高效且功能强大的平台,可以创建各种嵌入式系统解决方案。
# 2. STM32单片机开发环境搭建
### 2.1 IDE的选择和安装
#### 2.1.1 Keil MDK
Keil MDK(µVision Development Kit)是ARM公司官方推出的集成开发环境(IDE),专门针对ARM Cortex-M系列单片机开发。它提供了完整的开发工具链,包括编译器、汇编器、链接器、调试器和仿真器。
**安装步骤:**
1. 下载Keil MDK安装包。
2. 运行安装程序,按照提示完成安装。
3. 启动Keil MDK,创建新的工程。
#### 2.1.2 IAR Embedded Workbench
IAR Embedded Workbench是IAR Systems公司开发的另一个流行的ARM Cortex-M系列单片机IDE。它提供了强大的调试和仿真功能,以及丰富的库和外设驱动。
**安装步骤:**
1. 下载IAR Embedded Workbench安装包。
2. 运行安装程序,按照提示完成安装。
3. 启动IAR Embedded Workbench,创建新的工程。
### 2.2 开发板的连接和调试
#### 2.2.1 串口连接
串口连接是STM32单片机与计算机之间进行数据通信的常用方式。通过串口,可以将程序下载到单片机,并对单片机进行调试。
**连接步骤:**
1. 使用USB转串口模块或串口转接板连接STM32开发板的串口引脚(通常为TX和RX)与计算机的USB端口。
2. 在IDE中选择正确的串口号和波特率。
3. 打开串口终端,即可进行数据收发。
#### 2.2.2 JTAG调试
JTAG(联合测试动作组)是一种用于调试嵌入式系统的标准接口。通过JTAG,可以对单片机进行单步调试、断点设置和寄存器查看等操作。
**连接步骤:**
1. 使用JTAG调试器连接STM32开发板的JTAG引脚(通常为TDI、TDO、TCK、TMS和nTRST)。
2. 在IDE中选择正确的调试器类型和连接方式。
3. 启动调试器,即可进行调试操作。
**代码块:**
```c
#include "stm32f10x.h"
int main(void)
{
// 初始化GPIOA的第5位为输出模式
GPIOA->CRH &= ~(GPIO_CRH_MODE5);
GPIOA->CRH |= GPIO_CRH_MODE5_0;
while (1)
{
// 设置GPIOA的第5位为高电平
GPIOA->ODR |= GPIO_ODR_ODR5;
// 延时1秒
for (int i = 0; i < 1000000; i++);
// 设置GPIOA的第5位为低电平
GPIOA->ODR &= ~GPIO_ODR_ODR5;
// 延时1秒
for (int i = 0; i < 1000000; i++);
}
}
```
**逻辑分析:**
这段代码使用GPIOA的第5位控制LED的闪烁。首先,将GPIOA的第5位配置为输出模式,然后在循环中交替设置GPIOA的第5位为高电平和低电平,从而控制LED的闪烁。
**参数说明:**
* `GPIOA->CRH`:GPIOA的配置寄存器的高位寄存器。
* `GPIO_CRH_MODE5`:GPIOA的第5位的模式控制位。
* `GPIO_CRH_MODE5_0`:GPIOA的第5位配置为输出模式。
* `GPIOA->ODR`:GPIOA的输出数据寄存器。
* `GPIO_ODR_ODR5`:GPIOA的第5位的输出数据位。
**mermaid流程图:**
```mermaid
sequenceDiagram
participant User
participant STM32
User->STM32: Send data
STM32->User: Receive data
```
# 3. STM32单片机基础编程
### 3.1 C语言基础
#### 3.1.1 数据类型和变量
STM32单片机编程主要使用C语言,因此了解C语言的基础知识非常重要。C语言中,数据类型定义了变量可以存储的数据类型,常用的数据类型包括:
- 整型:int、short int、long int
- 浮点型:float、double
- 字符型:char
- 字符串型:char[]
变量用于存储数据,每个变量都有一个特定的数据类型和名称。例如:
```c
int num = 10;
float temp = 25.5;
```
#### 3.1.2 运算符和表达式
运算符用于对数据进行操作,表达式是包含运算符和操作数的组合。C语言中常用的运算符包括:
- 算术运算符:+、-、*、/、%
- 关系运算符:==、!=、<、>、<=、>=
- 逻辑运算符:&&、||、!
表达式可以用于计算值或进行比较,例如:
```c
int result = 10 + 5;
if (temp > 20) {
// 执行操作
}
```
### 3.2 STM32单片机寄存器编程
#### 3.2.1 GPIO寄存器
GPIO(通用输入/输出)寄存器控制着STM32单片机的引脚配置和输入/输出操作。每个GPIO寄存器对应一个GPIO端口,每个端口有16个引脚。
常用的GPIO寄存器包括:
- GPIOx_MODER:模式寄存器,配置引脚为输入或输出
- GPIOx_OTYPER:输出类型寄存器,配置引脚为推挽输出或开漏输出
- GPIOx_PUPDR:上拉/下拉寄存器,配置引脚的上拉/下拉电阻
例如,要将GPIOA端口的第5个引脚配置为推挽输出模式,可以执行以下操作:
```c
// 使能GPIOA时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
// 配置GPIOA第5个引脚为推挽输出模式
GPIOA->MODER &= ~(3 << (5 * 2));
GPIOA->MODER |= (1 << (5 * 2));
```
#### 3.2.2 定时器寄存器
定时器寄存器用于生成定时器中断和测量时间间隔。STM32单片机有多个定时器,每个定时器都有自己的寄存器组。
常用的定时器寄存器包括:
- TIMx_CR1:控制寄存器,配置定时器模式和时钟源
- TIMx_ARR:自动重装载寄存器,定义定时器溢出值
- TIMx_PSC:预分频器寄存器,分频时钟源
- TIMx_CNT:计数器寄存器,存储当前计数值
例如,要配置TIM2定时器为向上计数模式,溢出值为1000,时钟源为APB1时钟(72MHz),可以执行以下操作:
```c
// 使能TIM2时钟
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
// 配置TIM2为向上计数模式
TIM2->CR1 &= ~(TIM_CR1_DIR);
// 设置自动重装载寄存器为1000
TIM2->ARR = 1000;
// 设置预分频器为72,时钟源为APB1时钟
TIM2->PSC = 72;
```
# 4. STM32单片机外设应用
### 4.1 LED控制
#### 4.1.1 GPIO配置
**代码块:**
```c
// 初始化GPIOA的第5位为输出模式
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
```
**逻辑分析:**
* `GPIO_InitTypeDef`结构体定义了GPIO初始化参数。
* `GPIO_InitStructure.GPIO_Pin`指定要初始化的GPIO引脚,这里是GPIOA的第5位。
* `GPIO_InitStructure.GPIO_Mode`指定GPIO模式为推挽输出模式。
* `GPIO_InitStructure.GPIO_Speed`指定GPIO速度为50MHz。
* `GPIO_Init(GPIOA, &GPIO_InitStructure)`函数根据指定的参数初始化GPIOA的第5位。
#### 4.1.2 定时器中断
**代码块:**
```c
// 配置TIM3定时器,每1秒产生一次中断
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 1000;
TIM_TimeBaseStructure.TIM_Prescaler = 7200;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// 启用TIM3定时器中断
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
// 嵌套中断向量表配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
```
**逻辑分析:**
* `TIM_TimeBaseInitTypeDef`结构体定义了定时器初始化参数。
* `TIM_TimeBaseStructure.TIM_Period`指定定时器周期为1000,即每1秒产生一次中断。
* `TIM_TimeBaseStructure.TIM_Prescaler`指定定时器分频系数为7200。
* `TIM_TimeBaseStructure.TIM_ClockDivision`指定定时器时钟分频为1。
* `TIM_TimeBaseStructure.TIM_CounterMode`指定定时器计数模式为向上计数。
* `TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure)`函数根据指定的参数初始化TIM3定时器。
* `TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE)`函数启用TIM3定时器中断。
* `NVIC_InitTypeDef`结构体定义了嵌套中断向量表初始化参数。
* `NVIC_InitStructure.NVIC_IRQChannel`指定中断向量号为TIM3_IRQn。
* `NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority`指定中断抢占优先级为1。
* `NVIC_InitStructure.NVIC_IRQChannelSubPriority`指定中断子优先级为0。
* `NVIC_InitStructure.NVIC_IRQChannelCmd`指定中断使能。
* `NVIC_Init(&NVIC_InitStructure)`函数根据指定的参数初始化嵌套中断向量表。
### 4.2 按键检测
#### 4.2.1 外部中断配置
**代码块:**
```c
// 配置GPIOB的第12位为外部中断引脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
// 配置外部中断线12为下降沿触发
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line12;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// 嵌套中断向量表配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
```
**逻辑分析:**
* `GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12)`函数配置GPIOB的第12位为外部中断引脚。
* `EXTI_InitTypeDef`结构体定义了外部中断初始化参数。
* `EXTI_InitStructure.EXTI_Line`指定外部中断线为12。
* `EXTI_InitStructure.EXTI_Mode`指定外部中断模式为中断模式。
* `EXTI_InitStructure.EXTI_Trigger`指定外部中断触发方式为下降沿触发。
* `EXTI_InitStructure.EXTI_LineCmd`指定外部中断使能。
* `EXTI_Init(&EXTI_InitStructure)`函数根据指定的参数初始化外部中断线12。
* `NVIC_InitTypeDef`结构体定义了嵌套中断向量表初始化参数。
* `NVIC_InitStructure.NVIC_IRQChannel`指定中断向量号为EXTI15_10_IRQn。
* `NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority`指定中断抢占优先级为1。
* `NVIC_InitStructure.NVIC_IRQChannelSubPriority`指定中断子优先级为0。
* `NVIC_InitStructure.NVIC_IRQChannelCmd`指定中断使能。
* `NVIC_Init(&NVIC_InitStructure)`函数根据指定的参数初始化嵌套中断向量表。
#### 4.2.2 中断处理函数
**代码块:**
```c
void EXTI15_10_IRQHandler(void)
{
// 清除外部中断线12的中断标志位
EXTI_ClearITPendingBit(EXTI_Line12);
// 执行按键检测处理
// ...
}
```
**逻辑分析:**
* `EXTI15_10_IRQHandler`函数是外部中断线12的中断处理函数。
* `EXTI_ClearITPendingBit(EXTI_Line12)`函数清除外部中断线12的中断标志位。
* 在中断处理函数中可以执行按键检测处理,例如读取按键状态、触发事件等。
# 5.1 USART通信
### 5.1.1 USART配置
USART(通用异步收发传输器)是STM32单片机中用于串口通信的外设。它支持异步通信,可以与其他设备进行数据交换。
#### 配置步骤
1. **使能USART时钟:**使用`RCC_APB2PeriphClockCmd()`函数使能USART外设时钟。
2. **配置GPIO引脚:**使用`GPIO_InitTypeDef`结构体配置GPIO引脚为USART功能。
3. **初始化USART:**使用`USART_InitTypeDef`结构体初始化USART外设。
4. **使能USART:**使用`USART_Cmd()`函数使能USART外设。
#### 代码示例
```c
// 使能USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 配置GPIO引脚PA9为TX引脚,PA10为RX引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 初始化USART1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
// 使能USART1
USART_Cmd(USART1, ENABLE);
```
### 5.1.2 数据收发
USART配置完成后,即可进行数据收发操作。
#### 数据发送
```c
// 发送一个字节
USART_SendData(USART1, 0x55);
// 发送一个字符串
USART_SendString(USART1, "Hello World!\n");
```
#### 数据接收
```c
// 接收一个字节
uint8_t data = USART_ReceiveData(USART1);
// 接收一个字符串
char str[100];
USART_ReceiveString(USART1, str, 100);
```
0
0