周半梅 发表于 2024-10-10 07:40

基于STM32F103C8T6的GPIO与UART功能实现


STM32F103C8T6 是 ST 公司推出的一款基于 Cortex-M3 内核的微控制器,具有高性能、低功耗和丰富的外设资源。凭借其多种外设接口和较强的处理能力,它在工业控制、智能家居、物联网等领域有广泛的应用。本篇文章将通过具体代码演示如何在 STM32F103C8T6 上实现简单的 GPIO 控制和串口通信。

STM32F103C8T6的主要特性:
[*]32位ARM Cortex-M3内核,主频72MHz
[*]64KB Flash,20KB SRAM
[*]丰富的外设资源:GPIO、UART、SPI、I2C等
[*]低功耗特性

本帖将展示基于STM32F103C8T6实现以下功能:

[*]GPIO输出控制LED
[*]按键控制LED状态
[*]UART串口通信实现简单的数据传输

1. 硬件环境
[*]STM32F103C8T6开发板
[*]一个LED
[*]一个按键
[*]串口调试工具

2. 软件开发环境
[*]Keil MDK (ARM)
[*]STM32CubeMX(外设配置)

3. 项目代码实现下面的代码将展示如何配置STM32F103C8T6的GPIO引脚,用来控制LED点亮熄灭,同时使用UART实现串口通信,将数据通过串口发送至PC端。
#include "stm32f10x.h"// 包含STM32F103C8T6的外设库

// 系统时钟初始化函数
void SystemClock_Config(void) {
    RCC_DeInit();
    RCC_HSEConfig(RCC_HSE_ON);// 启用外部高速时钟
    while (!RCC_WaitForHSEStartUp());// 等待时钟稳定
    FLASH_SetLatency(FLASH_Latency_2);// 设置闪存访问等待周期
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);// 配置PLL倍频
    RCC_PLLCmd(ENABLE);// 使能PLL
    while (!RCC_GetFlagStatus(RCC_FLAG_PLLRDY));// 等待PLL稳定
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);// 选择PLL作为系统时钟
    while (RCC_GetSYSCLKSource() != 0x08);// 确认PLL作为系统时钟
}

// GPIO初始化函数
void GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    // 使能GPIOC时钟,配置PC13引脚为LED输出
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    // 使能GPIOA时钟,配置PA0为按键输入
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

// 串口初始化函数
void UART_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    // 使能USART1和GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    // 配置PA9为USART1_TX,PA10为USART1_RX
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1
    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);
}

// 按键控制LED状态
void ControlLED(void) {
    if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) {// 按键按下
      GPIO_ResetBits(GPIOC, GPIO_Pin_13);// 点亮LED
    } else {
      GPIO_SetBits(GPIOC, GPIO_Pin_13);// 熄灭LED
    }
}

// 串口发送字符串函数
void UART_SendString(char* str) {
    while (*str) {
      USART_SendData(USART1, *str++);
      while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
    }
}

// 主函数
int main(void) {
    SystemClock_Config();// 系统时钟初始化
    GPIO_Init();// GPIO初始化
    UART_Init();// 串口初始化

    while (1) {
      ControlLED();// 按键控制LED
      UART_SendString("Hello, STM32!");// 通过串口发送字符串
    }
}

代码解析
[*]系统时钟配置:系统时钟选择外部高速时钟(HSE)作为时钟源,并通过PLL倍频设置主频为72MHz。
[*]GPIO初始化:配置PC13为推挽输出模式用于LED控制,PA0为上拉输入模式用于按键读取。
[*]串口初始化:USART1配置波特率为9600,8位数据,1位停止位,无校验,串口用来与PC进行数据通信。
[*]按键控制LED:通过读取PA0的电平状态来控制PC13上LED的点亮与熄灭。
[*]串口发送数据:每次循环发送"Hello, STM32!"字符串到PC终端。

项目总结通过本项目,开发者可以快速上手STM32F103C8T6的GPIO和UART外设配置。GPIO控制和串口通信是嵌入式开发中最常用的功能,掌握这些基本操作为后续的更复杂开发奠定了基础。STM32系列凭借其丰富的外设资源和强大的处理能力,能够满足多种嵌入式项目的需求。

公羊子丹 发表于 2024-10-10 07:41

代码讲解得挺清楚的,照着写下来我板子也成功跑起来了

帛灿灿 发表于 2024-10-10 07:41

STM32果然是万金油,几乎所有项目都能用到

童雨竹 发表于 2024-10-10 07:41

可以加个中断方式的串口发送吗?轮询方式有点占用时间

万图 发表于 2024-10-10 07:42

PA0按键控制LED,简单又实用,正好适合我小项目

Wordsworth 发表于 2024-10-10 07:42

我之前还没搞懂PLL,现在明白了一些,谢啦

Pulitzer 发表于 2024-10-10 07:42

有没有更高波特率的串口通信例程?想传输大文件用

Bblythe 发表于 2024-10-10 07:42

这个GPIO部分能不能加个定时器来控制闪烁频率?

Uriah 发表于 2024-10-10 07:43

串口通信我遇到过乱码问题,波特率设错了,大家注意哈

Clyde011 发表于 2024-10-10 07:43

感谢分享,直接拿去当模板改改就能用,赞!

Stahan 发表于 2024-10-13 23:50

代码写的很清楚
页: [1]
查看完整版本: 基于STM32F103C8T6的GPIO与UART功能实现