STM32F103C8T6 单片机入门基础知识及点亮第一个 LED 灯

发布于:2025-04-17 ⋅ 阅读:(40) ⋅ 点赞:(0)

目录

一、引言

二、STM32F103C8T6 基本特性

1. 内核与性能

2. 存储器

3. 时钟系统

4. GPIO(通用输入输出)

5. 外设

三、开发环境搭建

1. 硬件准备

2. 软件安装

四、点亮第一个 LED 灯

1. 硬件连接

2. 软件实现

(1)创建新工程

(2)配置时钟

(3)配置 GPIO

(4)编译与下载

五、代码解析

1. 时钟配置

2. GPIO 配置

3. LED 控制

六、总结

七、参考代码

八、常见问题与解答

1. 为什么 LED 灯不亮?

2. 如何更改 LED 灯的引脚?

3. 如何实现 LED 灯闪烁?


一、引言

STM32F103C8T6 是一款基于 ARM Cortex-M3 内核的 32 位微控制器,以其高性能、低功耗和丰富的外设资源而广泛应用于嵌入式系统开发。对于嵌入式开发初学者来说,掌握 STM32F103C8T6 的基本知识并实现简单的功能(如点亮 LED 灯)是迈向嵌入式开发的重要一步。本文将详细介绍 STM32F103C8T6 的基本特性、开发环境搭建以及如何通过 GPIO 控制点亮第一个 LED 灯。

二、STM32F103C8T6 基本特性

1. 内核与性能

STM32F103C8T6 采用 ARM Cortex-M3 内核,工作频率最高可达 72MHz,提供高性能处理能力。其哈佛架构的存储器系统支持高达 60MHz 的系统时钟,确保了高效的代码执行。

2. 存储器

  • Flash 存储器 :内置 64KB 的 Flash 存储器,用于存储程序代码和常量数据。

  • SRAM :提供 20KB 的 SRAM,用于存储变量和运行时数据。

3. 时钟系统

  • 内部时钟源 :包括 8MHz 的高速内部时钟(HSI)和 40KHz 的低速内部时钟(LSI)。

  • 外部时钟源 :支持 12MHz 的高速外部时钟(HSE)和 32.768KHz 的低速外部时钟(LSE)。

  • 时钟树结构 :通过配置时钟树,可以灵活调整系统时钟频率,满足不同应用的需求。

4. GPIO(通用输入输出)

  • 引脚数量 :具有 42 个 GPIO 引脚,分布在 5 个端口(A、B、C、D、E)。

  • 工作模式 :每个 GPIO 引脚可以配置为输入、输出、复用功能或模拟模式。

  • 输出模式 :输出模式下,可配置为推挽输出或开漏输出。

5. 外设

  • 定时器 :包含多个通用定时器和高级定时器,支持多种计时和 PWM 输出功能。

  • 通信接口 :支持 UART、SPI、I2C 等多种通信接口,方便与其他设备进行数据交换。

  • ADC(模数转换器) :提供 12 位 ADC,用于将模拟信号转换为数字信号。

三、开发环境搭建

1. 硬件准备

  • 开发板 :STM32F103C8T6 开发板,通常配备有 LED 灯、按键等基本外设。

  • 下载器 :用于将编译后的程序烧录到 STM32 芯片中,常见的下载器有 ST-Link、J-Link 等。

  • 电脑 :用于编写和编译代码。

2. 软件安装

  • 集成开发环境(IDE) :推荐使用 Keil uVision 或 STM32CubeIDE。Keil 是一款功能强大的 IDE,支持 STM32 系列芯片的开发;STM32CubeIDE 是由 ST 公司推出的免费 IDE,集成了丰富的开发工具。

  • 驱动库 :安装 STM32 标准外设库或 HAL 库,这些库提供了对 STM32 外设的封装函数,简化了开发过程。

四、点亮第一个 LED 灯

1. 硬件连接

  • 将开发板上的 LED 灯连接到 GPIO 引脚,例如 PA0 引脚。确保 LED 的正极连接到 GPIO 引脚,负极通过电阻连接到地(GND)。

2. 软件实现

(1)创建新工程
  • 打开 Keil uVision 或 STM32CubeIDE,创建一个新的 STM32 工程,选择 STM32F103C8T6 为目标芯片。

(2)配置时钟
  • system_stm32f10x.c 文件中,配置系统时钟。通常使用 HSE(外部高速时钟)作为系统时钟源,并通过 PLL(锁相环)倍频到所需的频率,例如 72MHz。

void SystemInit(void)
{
    // 配置时钟
    SystemCoreClockUpdate();
    SetSysClock();
}

void SetSysClock(void)
{
    // 配置 HSE 和 PLL
    RCC_OscInitTypeDef RCC_OscInitStruct;
    RCC_ClkInitTypeDef RCC_ClkInitStruct;

    // 使能 HSE
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 12MHz * 9 = 108MHz
    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    // 配置系统时钟
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}
(3)配置 GPIO
  • 在主函数中,配置 PA0 引脚为输出模式。

#include "stm32f10x.h"

int main(void)
{
    // 初始化时钟
    SystemInit();

    // 配置 GPIOA 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 配置 PA0 引脚为推挽输出模式
    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(GPIOA, &GPIO_InitStructure);

    // 点亮 LED
    GPIO_SetBits(GPIOA, GPIO_Pin_0);

    while (1)
    {
        // 主循环
    }
}
(4)编译与下载
  • 编译工程,确保没有错误。使用下载器将编译后的程序烧录到 STM32 芯片中。如果一切正常,LED 灯将被点亮。

五、代码解析

1. 时钟配置

  • 时钟配置是 STM32 初始化的重要步骤。通过配置时钟树,可以确保系统时钟频率满足要求。在上述代码中,我们使用 HSE 作为时钟源,并通过 PLL 倍频到 72MHz。

2. GPIO 配置

  • GPIO 引脚需要先使能对应的时钟,然后通过 GPIO_InitTypeDef 结构体配置引脚模式和速度。在本例中,我们将 PA0 配置为推挽输出模式,速度为 50MHz。

3. LED 控制

  • 使用 GPIO_SetBits 函数将 PA0 引脚置为高电平,点亮 LED 灯。如果需要熄灭 LED,可以使用 GPIO_ResetBits 函数。

六、总结

通过本文的介绍,我们学习了 STM32F103C8T6 的基本特性、开发环境搭建以及如何通过 GPIO 控制点亮第一个 LED 灯。点亮 LED 灯是 STM32 开发的入门实验,掌握了这一基本操作后,可以进一步学习 STM32 的其他外设功能,如定时器、ADC、通信接口等。希望本文能够帮助初学者顺利入门 STM32 开发。

七、参考代码

以下是完整的代码示例,用于点亮 PA0 引脚上的 LED 灯:

#include "stm32f10x.h"

void SystemInit(void)
{
    // 配置时钟
    SystemCoreClockUpdate();
    SetSysClock();
}

void SetSysClock(void)
{
    // 配置 HSE 和 PLL
    RCC_OscInitTypeDef RCC_OscInitStruct;
    RCC_ClkInitTypeDef RCC_ClkInitStruct;

    // 使能 HSE
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 12MHz * 9 = 108MHz
    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    // 配置系统时钟
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}

int main(void)
{
    // 初始化时钟
    SystemInit();

    // 配置 GPIOA 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 配置 PA0 引脚为推挽输出模式
    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(GPIOA, &GPIO_InitStructure);

    // 点亮 LED
    GPIO_SetBits(GPIOA, GPIO_Pin_0);

    while (1)
    {
        // 主循环
    }
}

八、常见问题与解答

1. 为什么 LED 灯不亮?

  • 检查硬件连接是否正确,确保 LED 的正负极连接正确。

  • 检查程序是否正确配置了 GPIO 引脚。

  • 检查时钟配置是否正确,确保 GPIO 时钟已使能。

2. 如何更改 LED 灯的引脚?

  • 修改 GPIO 配置部分的代码,将 GPIO_Pin_0 更改为所需的引脚编号,例如 GPIO_Pin_1

  • 确保对应的 GPIO 时钟已使能。

3. 如何实现 LED 灯闪烁?

  • 在主循环中,使用延时函数交替调用 GPIO_SetBitsGPIO_ResetBits 函数,实现 LED 灯的闪烁。

while (1)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_0); // 点亮 LED
    for (int i = 0; i < 1000000; i++); // 延时
    GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 熄灭 LED
    for (int i = 0; i < 1000000; i++); // 延时
}


网站公告

今日签到

点亮在社区的每一天
去签到