vscode stm32cubemx 优雅开发stm32,最简单步骤教程

2023-05-16

配置安装环境

  1. 下载STM32cubeMX,这个大家可以自己在stm的官网下载到
  2. 下载VSCode
  3. 下载arm-none-eabi-gcc
  4. 下载MinGW-w64,为了实现里面的makefile 等功能
  5. 下载OpenOCD这里用来调试stm32,支持jlink stlink daplink

上述安装步骤1、安装步骤2在这里比较简单,就不赘述了

安装arm-none-eabi-gcc:

 此处我们下载zip包,方便安装。

以我为例,我们解压到 E:\Tools\ 目录下

安装MinGW-w64

此处我们同样下载zip包,安装比较方便,注意一定要安装上述划线的版本

 以我为例,我们解压到 E:\Tools\ 目录下

安装openocd

 此处我们下载最新的版本

以我为例,我们解压到 E:\Tools\ 目录下

通过stm32cubemx新建一个例程

这里以我的开发板为例,使用的是stm32f407vgt6,我们创建一个工程

配置一下SWD调试

 配置外部8mhz晶振

 配置PA1,用作测试LED

 配置usart1作为串口输出测试

 

 配置时钟,完成最后一步工作

 这里我们选择makefile,即可,点击generate code

通过vscode 生成刚刚用stm32cubemx 创建的工程

 在这里,我们在扩展中找到插件并安装

  • C/C++
  • Cortex-Debug
  • stm32-for-vscode

 刚刚下载的工具我都放在这个目录了,如图所示

 

 为了使用方便,我稍微改下名字

这样就舒服多了

 安装好stm32-for-vscode以后,我们会发现侧边栏增加了一个图标:

 按照上述提示,我们导入相应的工具

这里已经配置成我的路径了

重新打开vscode,即可看到变化

几个选项分别为

  • 编译
  • 全编译
  • 烧录到stm32
  • 调试stm32
  • 修改下载工具

 我简单演示一下,首先我们选择自己的编译工具,例如我这边使用的是dap-link

 我们看到这里已经选择成功了,那么我们先点击build

 已经生成成功了,我们看到编译速度是keil的指数级的提升

我们点击flash stm32,即可看到已经下载成功了!

最基本的操作已经可以了,编译下载一条龙,那么接下来我们试试调试功能。

 使用vscode调试

我们在代码里简单添加一些代码,作为调试的现象

不出意外的话,我们可以在debug中观察到i的变化

那么我们来试一下吧,点击build,再点击 debug在 printf 处添加断电

可以看到我们已经进入到调试的模式了,那么我们新增一个监视来监视i

 

 此时i的值为0,我们在全速运行两次次试试

 

可以看到,我们已经有i的值的变化,也在串口输出了值,符合我们的预期

这种开发方式已经可以替代keil了 

最后小结

那么我们知道,在keil中调用printf 只需要在前面增加putc函数即可,那在这种开发方式中,我们如何添加函数,使得可以printf。

很简单,只需要将下述代码复制到头,并且包含stdio.h即可

int _write(int fd, char *ch, int len)
{
  HAL_UART_Transmit(&huart1, (uint8_t*)ch, len, 0xFFFF);
  return len;
}

进一步更新使用C++

如果使用C++来编写工程的话,我们发现本来的printf不行了,怎么回事呢

很简单,这里借鉴可以新增两个文件 target.h,插入一下内容

#ifndef _RETARGET_H__
#define _RETARGET_H__
#include "stm32f4xx_hal.h"
#include <sys/stat.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

void RetargetInit(UART_HandleTypeDef *huart);
int _isatty(int fd);
int _write(int fd, char *ptr, int len);
int _close(int fd);
int _lseek(int fd, int ptr, int dir);
int _read(int fd, char *ptr, int len);
int _fstat(int fd, struct stat *st);

#ifdef __cplusplus
}
#endif

#endif //#ifndef _RETARGET_H__

再新增一个target.c

#include <_ansi.h>
#include <_syslist.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/times.h>
#include <retarget.h>
#include <stdint.h>
#if !defined(OS_USE_SEMIHOSTING)
#define STDIN_FILENO  0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2

UART_HandleTypeDef *gHuart;

void RetargetInit(UART_HandleTypeDef *huart)
{
    gHuart = huart;
    /* Disable I/O buffering for STDOUT stream, so that
     * chars are sent out as soon as they are printed. */
    setvbuf(stdout, NULL, _IONBF, 0);
}
int _isatty(int fd)
{
    if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
        return 1;
    errno = EBADF;
    return 0;
}
int _write(int fd, char *ptr, int len)
{
    HAL_StatusTypeDef hstatus;
    if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
    {
        hstatus = HAL_UART_Transmit(gHuart, (uint8_t *) ptr, len, HAL_MAX_DELAY);
        if (hstatus == HAL_OK)
            return len;
        else
            return EIO;
    }
    errno = EBADF;
    return -1;
}
int _close(int fd)
{
    if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
        return 0;
    errno = EBADF;
    return -1;
}
int _lseek(int fd, int ptr, int dir)
{
    (void) fd;
    (void) ptr;
    (void) dir;
    errno = EBADF;
    return -1;
}
int _read(int fd, char *ptr, int len)
{
    HAL_StatusTypeDef hstatus;
    if (fd == STDIN_FILENO)
    {
        hstatus = HAL_UART_Receive(gHuart, (uint8_t *) ptr, 1, HAL_MAX_DELAY);
        if (hstatus == HAL_OK)
            return 1;
        else
            return EIO;
    }
    errno = EBADF;
    return -1;
}
int _fstat(int fd, struct stat *st)
{
    if (fd >= STDIN_FILENO && fd <= STDERR_FILENO)
    {
        st->st_mode = S_IFCHR;
        return 0;
    }
    errno = EBADF;
    return 0;
}
#endif //#if !defined(OS_USE_SEMIHOSTING)

就可以继续使用print了,甚至是cout也完全没有问题

  while (1)
  {
    /* USER CODE END WHILE */
    printf("test i = %d \n", i++);
    std::cout << 123 << std::endl;
    HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_1);
    HAL_Delay(1000);
    /* USER CODE BEGIN 3 */
  }

面对_exit等报错,我们这里需要在STM32-for-VSCode.config.yaml这个文件中新增选项,就可以没有报错了

# Compiler flags
cFlags: []
cxxFlags: []
assemblyFlags: []
linkerFlags: 
  - -specs=nano.specs
  - -Wl,--gc-sections
  - -ffreestanding -flto
  - -specs=nosys.specs #新增这个选项

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vscode stm32cubemx 优雅开发stm32,最简单步骤教程 的相关文章

  • 【大论文中注意事项】2022年11月3日记录

    大论文中注意事项 1 时间安排2 论文标题3 摘要4 自己的内容 重要 5 第一章的全文研究内容6 关于正文中的序号7 第一章的课题来源8 文章9 文献10 第一章的本文主要研究内容11 实验的对比12 每一章的小节13 章节正文开始14

随机推荐

  • 【文件上传】前端html上传 + 后端SpringBoot接收并保存

    1 前端页面 lt form gt 记得设置一下enctype 61 34 multipart form data 34 span class token doctype span class token punctuation lt sp
  • linux系统下,11款常见远程桌面控制软件

    远程控制能够给人们带来很多便利 xff0c 本文介绍了11款常见的Linux系统下的远程桌面控制工具 xff0c 总有一款能适合您 一 Grdc 它是一个用GTK 43 编写的 xff0c 适用于gnome桌面环境的远程桌面访问软件 看图
  • ubuntu远程桌面到Windows

    我知道的有两种方法 xff1a 1 xff09 使用Terminal Server Client 打开Applications gt Internet gt Terminal Server Client xff0c 在 General 选项
  • 交叉编译 WPA_Supplicant

    本文记录这个wifi配置工具的编译过程 xff0c 步骤不少 xff0c 涉及的开源代码包也比较多 xff0c 以后很容易忘 WPA Supplicant简介 首先 xff0c 稍稍介绍下wpa supplicant xff0c 这是一个控
  • UltraEdit 最新安装教程

    1 下载完成UltraEdit 之后 xff0c 双击应用程序 xff0c 选择安装位置 xff0c 点击安装 2 点击下一步 3 安装完成 4 首次登录 xff0c 提示输入许可证秘钥 5 输入激活码页面 xff0c 输入后点击激活
  • Pyside2 学习系列二:PyInstaller打包项目exe (超详细的Pyside2 攻略)

    继上一篇文章创建了项目后 xff0c 本章我们进行项目的打包工作 本项目的所有演示代码 xff1a github可在这里下载 打包只用的工具为PyInstaller 打包步骤 1 准备环境1 1 安装 96 PyInstaller 96 2
  • JSP中的四种范围属性

    JSP中的对象 xff0c 包括用户创建的对象 如JavaBean对象 和JSP的隐含对象 xff0c 都有一个范围属性 范围属性规定了这些对象的作用域 xff0c 定义了在什么时间内 xff0c 在哪一个JSP页面中可以被访问 在JSP中
  • 【xml】[Qt] 生成xml格式对象或xml字符串(速成 QT处理xml)

    本文为什么称为速成呢 xff0c 因为本人就是速成的 xff0c 接手的项目里有个关于xml的bug xff0c 对xml一无所知到解决bug xff0c 自己硬着头皮上 xff0c 速成成功了 xff0c 也就觉得有写点什么东西的必要了
  • Mysql8.0如何重置密码

    环境 xff1a mysql8 0以上版本 无密码登录 修改配置文件 xff1a etc my cnf xff0c 在 mysqld 后面任意一行添加 skip grant tables xff0c 这样登录时就可以跳过密码验证的过程 重启
  • 华为交换机配置SNMP

    SNMP参数详情 Quidway snmp agent community 为SNMPv1 amp SNMPv2c访问设置团体名group 设置基于用户安全模型的组local engineid 设置本地SNMP实体的引擎IDmib view
  • VMware设置虚拟机的网络为桥接模式,虚拟机使用主机的网段,虚拟机设置和主机一样的网关(网段)

    VMware设置虚拟机的网络为桥接模式 KeyValue电脑版本win 10 1909虚拟机版本 VMware 17 点击编辑虚拟机设置 这样虚拟机即可在和主机在同一个网段 验证 虚拟机的地址 xff1a 192 168 2 144 ip
  • Rust权威指南 读书笔记

    Rust权威指南 本书由 Rust 核心开发团队编写而成 xff0c 由浅入深地探讨了 Rust 语言的方方面面 从学习函数 选择数据结构及绑定变量入手 xff0c 逐步介绍所有权 trait 生命周期 安全保证等高级概念 xff0c 模式
  • Rust:使用libloader调用动态链接库 (DLL)

    掘金为同人创作 xff1a 掘金 最近需要使用Rust动态调用动态链接库 xff0c 本来打算是使用libloading的 xff0c 但是libloading在调用dll中的函数的时 xff0c 是必须要在编译时确定参数和return的类
  • 用flatpak安装程序(比如GIMP)的方法

    linux世界真的是无奇不有 xff0c 什么安装程序的方法都有 比如gimp xff0c 如果必要安装官网的最新版安装包 xff0c 你会发现他是flatpakref后缀的 xff0c 我刚开始懵了 xff0c 这是什么安装包 xff0c
  • 怎样查看本机打开的端口?

    怎样查看本机打开的端口 xff1f https zhidao baidu com question 203087246 html Netstat xff0c 显示协议统计和当前的 TCP IP 网络连接 a xff0c 显示所有连接和侦听端
  • webpack4基本使用

    基本使用 初始化一个package json文件 npm init yes 安装webpack以及webpack cli cnpm i webpack webpack cli save dev package json 34 scripts
  • C++中enum与字符串或CString互相转换的方法

    C 43 43 中没有专门为enum与字符串或CString互相转换的直接方法 xff0c 但是工作中会常遇到相互转换的场景 下面介绍一种自己实现的方法 xff0c 首先得定义一个enum类型 xff0c 同时 xff0c 定义一个与之对应
  • VC++标准化路径PathCanonicalize

    外部输入的参数不能直接作为文件路径 xff0c 防止被恶意攻击 xff0c 比如构造一个跨目录限制的文件路径 etc passwd或 boot ini xff0c 或构造一个指向系统关键文件的链接文件symlink 34 etc shado
  • 解决时间机器无法识别硬盘问题

    T7 SSD分区后做时光机器 xff0c 但无法识别 xff08 如图 xff09 xff0c 问题解决 一 问题描述 xff1a 当时没保存照片 xff0c 图片来自网络 问题详情 xff1a 硬盘没分区且是苹果可识别的格式 xff08
  • vscode stm32cubemx 优雅开发stm32,最简单步骤教程

    配置安装环境 下载STM32cubeMX xff0c 这个大家可以自己在stm的官网下载到下载VSCode下载arm none eabi gcc下载MinGW w64 xff0c 为了实现里面的makefile 等功能下载OpenOCD这里