[STM32C5] 【NUCLEO-STM32C542RC开发板测评】环境搭建 + 定时器blink + printf + 按键调速

[复制链接]
10|0
怀揣少年梦 发表于 2026-9-18 23:54 | 显示全部楼层 |阅读模式
[i=s] 本帖最后由 怀揣少年梦 于 2026-9-18 23:58 编辑 [/i]

#申请原创# @21ic跑堂

板子:NUCLEO-C542RC(MB2213,STM32C542RCT6 / Cortex-M33 / 144 MHz)

软件:STM32CubeMX2 1.1.1 + STM32CubeIDE
从装软件一路走到板子跑起来:环境搭通、工程能编译能下载,然后点灯、跑通 printf,通过定时器控制IO翻转,按下按键还能切闪烁频率。

一、开箱

盒子很轻,里面就一块板加一张说明卡。板载 ST-LINK,USB 口直接接电脑就能用,Windows 下一般不用自己装驱动。C to C线要自备一根。

2.jpg

1.jpg

4.jpg

二、安装 STM32CubeMX2

1、软件下载

去官网:STM32CubeMX | Software - STMicroelectronics。页面里选 Windows,点下载。

file-20260813083634285.png

2、双击安装

file-20260813083738382.png

3、开始安装

Welcome 页直接 Continue。

file-20260813083804834.png

4、选安装位置

默认在 C 盘用户目录下,占 866MB 左右;C 盘紧的话点 Change 换到别的盘,我放 E 盘了。

file-20260813083816293.png

5、同意许可协议

许可协议拉到底,勾上同意,继续。

file-20260813083825084.png

6、完成安装

装完点 Launch 就能打开。

file-20260813083842777.png

三、第一次启动

CubeMX2 换了底层,是 Electron 套壳的,启动比以前快,几秒就进来了。

file-20260813084227308.png

主界面长这样。左边一竖排图标是各个功能页,右边是官方文档链接。

file-20260813084549001.png

四、按开发板新建工程

1、点 Board

首页中间三块:MCU、Board、Project。手上就是这块板,直接点 Board——按板子建工程,引脚和时钟它会先帮你打底。

file-20260813084642480.png

2、选开发板

列表里选 NUCLEO-C542RC,Continue。

file-20260813084701828.png

3、工程名与路径

起名字、选路径。我用的 led-demo,放在 E://stm32c542rc;下面那个 .ioc2 就是工程文件,后面所有配置都存它里面。

file-20260813084854907.png

4、创建工程

点 Create 之后它会联网装依赖(工具链、SDK 这些),等进度条走完。

file-20260813084927820.png

5、打开工程

装好点 Launch Project,工程就打开了。

file-20260813085859923.png

五、认几个页签

工程打开后顶上一排:Home、Pinout、Clock、Project settings、Pack manager。常用的就前两个。

Pinout 用得最多。左边挑外设,中间是 LQFP64 的引脚图——灰的没配、绿的配好了。这里注意 PA13 / PA14 是 SWD 调试口,默认就占着,别动,改了下回就烧不进程序。

file-20260813085912662.png

Pack manager 是管软件包的,环境搭建阶段用不上。

file-20260813090547002.png
file-20260813122750523.png

右上角能在"图形视图"和"表格视图"之间来回切。表格视图列得更清楚,哪根脚、什么信号、有没有被占用,一眼能扫完。

file-20260813090626920.png

Project settings 里要生成一次代码:IDE Project Generation 下面,Format 选 CMake、Toolchain 选 GCC,点 Generate IDE project。它会吐出一份 CMake 工程,等会儿就是拿它去 CubeIDE 编译的。

file-20260813122750523.png

六、导入 STM32CubeIDE

CubeMX2 负责配和生成,真正的编译下载还是回 CubeIDE 做。

1、点击导入工程

打开 CubeIDE,Project Explorer 里点 Import projects...,向导里选 STM32 Project →STM32 CMake Project

file-20260915135116604.png

2、设置导入工程名与路径

工程名填 led-demo,位置指到刚才生成的 led-demo_cmake 目录。

file-20260915135201524.png

3、确认工具链

工具链确认一下:MCU ARM GCC / STM32C542RCTx / Cortex-M33,Finish。

file-20260915135226425.png

4、编译

导进来直接点击工具图标 Build,Build Finished. 0 errors, 0 warnings

file-20260915135310875.png

5、烧录

接上板子点 Debug,ST-LINK 连上,Download verified successfully——到这一步程序就进板子了,环境算通了。

file-20260915135423920.png

七、实现功能

有以下功能

  • 串口打印,实现日志打印
  • 按键中断,实现LEN闪烁频率
  • 定时器控制LED闪烁

先把要用的外设配好,代码见下一节。

1、串口配置

先把串口开起来。Pinout 里点 PA2,右键 Assign signal → USART2_TX,点击设置

file-20260915153843094.png

USART2 的 Mode 选 Asynchronous。

file-20260915153902446.png

参数保持默认:115200、8 位、无校验、1 位停止位、收发。这路串口走的是 ST-LINK 的虚拟串口,接上就能用。

file-20260915153918422.png

2、LED引脚配置

PA5 是板上的绿 LED,先把它从 Reserved 改成 Configured。

file-20260915154048887.png

Mode 选 Output。

file-20260915154100140.png

电平参数照图填:初始 High、推挽、高速。这块板 LED 是高电平亮。

file-20260915154125876.png

3、定时器配置

配个 TIM7 当定时器,预分频 143、输出 999Hz。

file-20260915171340162.png

4、外部中断引脚配置

PC13 是板上的按键引脚,先把它从 Reserved 改成 Configured。

file-20260918222925145.png

使能中断,配置为输入中断模式,上升沿触发

file-20260918223122203.png

八、编写代码

就两个文件,user_app.cuser_app.h

/*
 * user_app.c
 *
 * Created on: 2026年9月15日
 * Author: 10170
 */

#include "user_app.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "main.h"

/* Private define ------------------------------------------------------------*/

#define CONSOLE_BAUD 115200U
#define TICK_HZ 1000U /* TIM7 update frequency */
#define LED_HALF_PERIOD 500U /* toggle every 500 ms -> 1 Hz blink */
#define BTN_DEBOUNCE_MS 20U /* 按键消抖时间,由 TIM7 1ms tick 递减 */

/* Private variables ---------------------------------------------------------*/

static hal_uart_handle_t *g_console;
static hal_tim_handle_t *g_tim7;
static hal_exti_handle_t *g_btn; /* EXTI13:PC13 板载按键 B1 */

static uint16_t g_led_period[] = {1000U, 500U, 200U, 100U}; /* LED 半周期(ms),按键循环切换 */
static volatile uint8_t led_period_opt = 0;
static volatile uint32_t g_uptime_ms; /* incremented in ISR every 1 ms */
static volatile uint32_t g_led_toggles; /* incremented in ISR */
static volatile uint32_t g_led_divider = 0; /* wrap-safe countdown */
static volatile uint8_t g_btn_debounce_ms; /* 按键消抖计数器:>0 表示消抖中 */

/* Exported functions --------------------------------------------------------*/

/**
 * brief: write a raw buffer to the console UART (used by __io_putchar)
 */
void app_uart_write(const uint8_t *data, uint32_t size)
{
    (void)HAL_UART_Transmit(g_console, data, size, 100U);
}

/**
 * brief: newlib hook - printf() ends up here, one character at a time
 */
int __io_putchar(int ch)
{
    uint8_t byte = (uint8_t)ch;

    app_uart_write(&byte, 1U);
    return ch;
}

/**
 * brief: application init, called once from main() after mx_system_init()
 */
void app_init(void)
{
    g_console = mx_usart2_uart_gethandle();
    g_tim7 = mx_tim7_gethandle();
    g_btn = mx_gpio_default_exti13_gethandle();

    HAL_EXTI_Enable(g_btn, HAL_EXTI_MODE_INTERRUPT); /* 使能 EXTI13 中断 */
    HAL_TIM_Start_IT(g_tim7);
    HAL_Delay(1000);

    g_led_divider = g_led_period[led_period_opt];

    printf(
        "\r\n"
        "================================================\r\n"
        " STM32C5 evaluation / 01 - blink + printf\r\n"
        "------------------------------------------------\r\n"
        " board : NUCLEO-C542RC (STM32C542RCT6)\r\n"
        " core : %lu Hz system clock\r\n"
        " console: USART2 PA2(TX)/PA3(RX) @ %lu 8N1\r\n"
        " tim : TIM7 update interrupt @ %lu Hz\r\n"
        " led : PA5 toggles every %lu ms\r\n"
        "================================================\r\n",
        (unsigned long)SystemCoreClock,
        (unsigned long)CONSOLE_BAUD,
        (unsigned long)TICK_HZ,
        (unsigned long)LED_HALF_PERIOD);
}

void user_app(void)
{
    static uint32_t last_report_ms;

    if ((g_uptime_ms - last_report_ms) >= 1000U) {
        last_report_ms = g_uptime_ms;
        printf("[%6lu ms] alive, LED toggles = %lu, period = %lu ms\r\n",
               (unsigned long)g_uptime_ms,
               (unsigned long)g_led_toggles,
               (unsigned long)g_led_period[led_period_opt]);
    }
}

/**
 * brief: HAL callback fired on every TIM7 update event (1 ms)
 */
void HAL_TIM_UpdateCallback(hal_tim_handle_t *htim)
{
    if (htim != g_tim7) {
        return;
    }

    g_uptime_ms++; /* unsigned wrap-around is well-defined in C */

    /* ---- 按键消抖(TIM7 1ms tick 递减,非阻塞) ---- */
    if (g_btn_debounce_ms > 0U) {
        if (--g_btn_debounce_ms == 0U) {
            /* 消抖到期:确认按键仍为高电平(按下),则循环切换频率 */
            if (HAL_GPIO_ReadPin(HAL_GPIOC, HAL_GPIO_PIN_13) == 1U) {
                led_period_opt = (led_period_opt + 1U) %
                                 (uint8_t)(sizeof(g_led_period) / sizeof(g_led_period[0]));
                g_led_divider = g_led_period[led_period_opt]; /* 立即生效 */
            }
        }
    }

    /* ---- LED 闪烁 ---- */
    if (--g_led_divider == 0U) {
        g_led_divider = g_led_period[led_period_opt];
        HAL_GPIO_TogglePin(PA5_PORT, PA5_PIN);
        g_led_toggles++;
    }
}

/* 覆盖 HAL 弱回调 */
/**
 * brief: EXTI 触发回调(按键边沿),仅启动消抖;消抖期间的抖动边沿直接忽略
 */
void HAL_EXTI_TriggerCallback(hal_exti_handle_t *hexti, hal_exti_trigger_t trigger)
{
    STM32_UNUSED(trigger);

    if (hexti != g_btn) {
        return;
    }

    if (g_btn_debounce_ms == 0U) {
        g_btn_debounce_ms = BTN_DEBOUNCE_MS;
    }
}
/*
 * user_app.h
 *
 * Created on: 2026年9月15日
 * Author: 10170
 */

#ifndef USER_APP_H_
#define USER_APP_H_

void app_init(void);
void user_app(void);

#endif /* USER_APP_H_ */

九、下载验证

  • 点击调试按钮

file-20260918223500616.png

  • 切换调试窗口

file-20260918223516762.png

  • 串口输出

file-20260918223546939.png

串口日志

[21:29:53.841]收←◆[146036 ms] alive, LED toggles = 209, period = 1000 ms
[21:29:54.842]收←◆[147036 ms] alive, LED toggles = 210, period = 1000 ms
[21:29:55.842]收←◆[148036 ms] alive, LED toggles = 211, period = 1000 ms
[21:29:56.844]收←◆[149036 ms] alive, LED toggles = 212, period = 1000 ms
[21:29:57.845]收←◆[150036 ms] alive, LED toggles = 213, period = 1000 ms
[21:29:58.845]收←◆[151036 ms] alive, LED toggles = 214, period = 1000 ms
[21:29:59.846]收←◆[152036 ms] alive, LED toggles = 215, period = 1000 ms
[21:30:00.848]收←◆[153036 ms] alive, LED toggles = 216, period = 1000 ms
[21:30:01.848]收←◆[154036 ms] alive, LED toggles = 217, period = 500 ms
[21:30:02.849]收←◆[155036 ms] alive, LED toggles = 219, period = 500 ms
[21:30:03.851]收←◆[156036 ms] alive, LED toggles = 221, period = 500 ms
[21:30:04.853]收←◆[157036 ms] alive, LED toggles = 223, period = 500 ms
[21:30:05.852]收←◆[158036 ms] alive, LED toggles = 225, period = 500 ms
[21:30:06.855]收←◆[159036 ms] alive, LED toggles = 227, period = 500 ms
[21:30:07.855]收←◆[160036 ms] alive, LED toggles = 229, period = 500 ms
[21:30:08.856]收←◆[161036 ms] alive, LED toggles = 231, period = 500 ms
[21:30:09.856]收←◆[162036 ms] alive, LED toggles = 233, period = 500 ms
[21:30:10.857]收←◆[163036 ms] alive, LED toggles = 235, period = 500 ms
[21:30:11.859]收←◆[164036 ms] alive, LED toggles = 238, period = 200 ms
[21:30:12.860]收←◆[165036 ms] alive, LED toggles = 243, period = 200 ms
[21:30:13.861]收←◆[166036 ms] alive, LED toggles = 248, period = 200 ms
[21:30:14.861]收←◆[167036 ms] alive, LED toggles = 253, period = 200 ms
[21:30:15.863]收←◆[168036 ms] alive, LED toggles = 258, period = 200 ms
[21:30:16.863]收←◆[169036 ms] alive, LED toggles = 263, period = 200 ms
[21:30:17.864]收←◆[170036 ms] alive, LED toggles = 268, period = 200 ms
[21:30:18.866]收←◆[171036 ms] alive, LED toggles = 273, period = 200 ms
[21:30:19.867]收←◆[172036 ms] alive, LED toggles = 278, period = 200 ms
[21:30:20.867]收←◆[173036 ms] alive, LED toggles = 283, period = 200 ms
[21:30:21.870]收←◆[174036 ms] alive, LED toggles = 291, period = 100 ms
[21:30:22.870]收←◆[175036 ms] alive, LED toggles = 301, period = 100 ms
[21:30:23.871]收←◆[176036 ms] alive, LED toggles = 311, period = 100 ms
[21:30:24.871]收←◆[177036 ms] alive, LED toggles = 321, period = 100 ms
[21:30:25.872]收←◆[178036 ms] alive, LED toggles = 331, period = 100 ms
[21:30:26.874]收←◆[179036 ms] alive, LED toggles = 341, period = 100 ms
[21:30:27.874]收←◆[180036 ms] alive, LED toggles = 351, period = 100 ms
[21:30:28.876]收←◆[181036 ms] alive, LED toggles = 361, period = 100 ms
[21:30:29.877]收←◆[182036 ms] alive, LED toggles = 371, period = 100 ms
[21:30:30.877]收←◆[183036 ms] alive, LED toggles = 381, period = 100 ms
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:一切皆有可能

52

主题

495

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部
0