使用VSCode和VS2017编译调试STM32程序的实现

使用VSCode和VS2017编译调试STM32程序的实现

本文将介绍如何使用Visual Studio Code和Visual Studio 2017编译和调试STM32程序的实现。

一、开发环境搭建

在开始之前,需要确认电脑上是否已安装以下必要的软件:

  • Visual Studio Code (简称VSCode)
  • Visual Studio 2017 (简称VS2017)
  • GNU ARM Embedded Toolchain
  • ST-Link驱动程序
  • STM32CubeMX

其中,GNU ARM Embedded Toolchain用于生成可执行二进制文件,ST-Link驱动程序用于将生成的二进制文件下载到芯片上,STM32CubeMX用于生成项目代码框架和初始化。

下载完以上软件后,需要将GNU ARM Embedded Toolchain和STM32CubeMX的路径添加到系统环境变量PATH中。例如,假如将这两个软件安装在D:\Program Files目录下,则需要将D:\Program Files\GNU Tools ARM Embedded\7 2018-q2-update\bin和D:\Program Files\STMicroelectronics\STM32Cube\STM32CubeMX\bin路径添加到环境变量PATH中。

二、创建工程

1.打开STM32CubeMX,创建一个新工程。根据实际情况选择芯片类型和工作模式,在"Project Settings"中可以进行更详细的设置。

2.完成工程配置后,点击左上角的"Generate Code"按钮生成项目代码。

3.打开VSCode,从"File"菜单中选择"Open Folder",并打开STM32CubeMX生成的代码所在的文件夹。

4.在VSCode的"Explorer"中打开".vscode"文件夹,创建"launch.json"文件。将以下代码复制粘贴到"launch.json"文件中:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug STM32",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/Debug/${workspaceFolderBasename}.elf",
            "cwd": "${workspaceFolder}",
            "externalConsole": true,
            "debugServerArgs": "-d",
            "linux": {
                "MIMode": "gdb"
            },
            "windows": {
                "MIMode": "gdb"
            },
            "pipeTransport": {
                "pipeCwd": "${workspaceFolder}",
                "pipeProgram": "C:/WinGDB/bin/wingdb-remote.exe",
                "debuggerPath": "arm-none-eabi-gdb.exe",
                "pipeArgs": ["localhost:3333"],
                "filterStderr": true,
                "filterStdout": true,
                "stopOnEntry": false,
                "showDevDebugOutput": true
            },
            "sourceFileMap": { "/mnt/c": "C:"}
        }
    ]
}

该配置文件指示VSCode使用GNU ARM Embedded Toolchain的arm-none-eabi-gdb调试器,并连接到STM32芯片,可以正常执行程序。
注意,需要将"pipeProgram"和"debuggerPath"路径修改为实际路径。

完成"launch.json"文件的编辑后,保存并关闭。

三、编写代码

在VSCode的"Explorer"中,找到"Src"文件夹下的"main.c"文件。本文以一个简单的LED闪烁程序作为示例:

#include "stm32f1xx.h"

int main(void)
{
  RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
  GPIOC->CRH &= ~(GPIO_CRH_CNF13 | GPIO_CRH_MODE13);
  GPIOC->CRH |= GPIO_CRH_MODE13_0;

  while (1)
  {
    GPIOC->BSRR = GPIO_BSRR_BS13;
    for (int i = 0; i < 100000; i++);
    GPIOC->BSRR = GPIO_BSRR_BR13;
    for (int i = 0; i < 100000; i++);
  }
}

该代码实现了一个LED灯的闪烁,使用了STM32F103芯片的GPIOC13引脚输出信号。

完成代码编辑后,保存并关闭。

四、编译和调试

在VSCode中按下F5,或通过"Run"菜单中的"Start Debugging"选项,启动调试。在调试面板的控制台中可以看到调试器与STM32芯片的交互信息。

如果一切正常,程序会开始在芯片上执行,并实现LED灯的闪烁。

由此可见,使用VSCode和VS2017编译调试STM32程序还是比较简单的,只需要安装好相应的软件并进行简单的配置即可。

示例1

下面给出一个简单的USART1串口输出实例,只需在STM32CubeMX中进行USART1初始化配置,然后在main函数中添加如下代码即可:

#include "stm32f1xx.h"
#include <stdio.h>

void USART1_Init(void)
{
  RCC->APB2ENR |= RCC_APB2ENR_USART1EN | RCC_APB2ENR_IOPAEN;
  GPIOA->CRH &= ~(GPIO_CRH_CNF9 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10 | GPIO_CRH_MODE10);
  GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9 | GPIO_CRH_CNF10_0;
  USART1->BRR = 0x341; //115200@72M
  USART1->CR1 |= USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
}

int _write(int fd, char *ptr, int len)
{
  for (int i = 0; i < len; i++)
  {
    while (!(USART1->SR & USART_SR_TXE));
    USART1->DR = *ptr++;
  }

  return len;
}

int main(void)
{
  USART1_Init();

  printf("Hello, world!\n");

  while (1);
}

示例2

下面给出一个简单的I2C读写实例,只需在STM32CubeMX中进行I2C初始化配置,然后在main函数中添加如下代码即可:

#include "stm32f1xx.h"
#include <stdio.h>

void I2C_WriteByte(I2C_HandleTypeDef *hi2c, uint8_t addr, uint8_t data)
{
  while (hi2c->State != HAL_I2C_STATE_READY);
  HAL_I2C_Mem_Write(hi2c, addr, 0x00, 1, &data, 1, HAL_MAX_DELAY);
}

uint8_t I2C_ReadByte(I2C_HandleTypeDef *hi2c, uint8_t addr)
{
  uint8_t data = 0;
  while (hi2c->State != HAL_I2C_STATE_READY);
  HAL_I2C_Mem_Read(hi2c, addr, 0x00, 1, &data, 1, HAL_MAX_DELAY);
  return data;
}

int main(void)
{
  HAL_Init();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  __HAL_RCC_I2C1_CLK_ENABLE();

  I2C_HandleTypeDef hi2c1 = {0};
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }

  I2C_WriteByte(&hi2c1, 0x00, 0x01);
  uint8_t data = I2C_ReadByte(&hi2c1, 0x00);

  while (1);

  HAL_I2C_DeInit(&hi2c1);
}

至此,示例代码就讲解完毕了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用VSCode和VS2017编译调试STM32程序的实现 - Python技术站

(1)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • java异常:异常处理–try-catch结构详解

    Java异常: 异常处理–try-catch结构详解 在Java程序中,异常处理是一个非常重要的方面。Java异常是指程序在运行期间不正常的情况。当程序出现异常时,如果没有恰当的处理,它将使程序崩溃。Java提供了异常处理机制来解决这个问题。 异常 当Java程序在运行过程中遇到了异常时,它会产生一个异常对象。Java中的异常有两种类型: 检查异常和非检查…

    C 2023年5月23日
    00
  • python集合类型用法分析

    Python集合类型用法分析 Python中的集合类型可用于存储一组无序且不重复的元素。本篇攻略将详细讲解Python中常用的集合类型及其用法。 集合类型 Python中常用的集合类型有三种: set frozenset dict 其中,set和frozenset是用来存储一组无序且不重复的元素的,而dict则是用来存储键值对的。 set类型 set类型使用…

    C 2023年5月22日
    00
  • 华硕X450C系列笔记本怎么拆机清灰?

    下面是关于华硕X450C系列笔记本拆机清灰的完整攻略: 1. 准备工具和环境 在进行拆机清灰之前,我们需要准备好以下工具和环境: 一个适合拆开笔记本电脑的螺丝刀套装 一块软布或清洁刷子 一瓶压缩气罐或吸尘器 一个安静、平坦的操作环境,最好在桌子上放置一块软质材料,例如毯子或厚垫子,以防止刮伤电脑。 2. 确认拆机方式 在进行拆机清灰之前,你需要确定你的笔记本…

    C 2023年5月22日
    00
  • Java 多层嵌套JSON类型数据全面解析

    Java 多层嵌套JSON类型数据全面解析 什么是JSON JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,也易于机器解析和生成。JSON是一种完全独立于语言的数据交换格式,但是在实际应用中,JSON常常以字符串的形式进行传输。 解析JSON 在Java中要解析JSON,可以使用Jackson或者…

    C 2023年5月23日
    00
  • C++中replace() 函数的基本用法

    当我们在使用C++字符串(string)时,可能会需要对其中的某些字符进行替换操作。C++中的replace()函数可以完成这个任务,它可以在指定的位置上替换指定数量的字符为另外一组字符序列。下面我们就来具体了解一下replace()函数的用法。 函数原型 C++中replace()函数的原型如下: string replace(size_t pos, si…

    C 2023年5月23日
    00
  • C++实现管理系统的示例代码

    C++实现管理系统的示例代码包含以下步骤: 设计系统需求和功能 在开始写代码之前需要明确系统的需求和功能,这可以帮助我们更好地组织代码。例如,我们可以列出以下需求和功能: 系统应该能够添加、查看、修改和删除学生信息 学生信息应该包括姓名、年龄、性别等基本信息 系统应该能够按姓名、年龄、性别等信息对学生信息进行排序 系统应该能够将学生信息保存到文件中,并能够从…

    C 2023年5月23日
    00
  • 解析Node.js异常处理中domain模块的使用方法

    解析Node.js异常处理中domain模块的使用方法 在Node.js中,异常处理是一个非常重要的话题,因为错误的产生是运行环境的本质。Node.js提供了一系列的异常处理工具来帮助我们处理错误,其中就包括domain模块。 什么是domain模块 domain模块是Node.js用于处理异步代码中错误的模块。它允许我们将多个异步操作绑定到一个错误处理上下…

    C 2023年5月23日
    00
  • cmake 学习笔记

    CMake 学习笔记 CMake 是什么 CMake 是一个跨平台的自动化构建系统,使用 CMake 可以简化 C++ 项目的构建,CMake 脚本可以生成 Makefile、Visual Studio 项目和 Xcode 项目等构建文件。 CMake 的优势 CMake 有以下优点: 跨平台:CMake 可以在多个操作系统和编译器下运行。 系统独立性:CM…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部