配置安装环境
- 下载STM32cubeMX,这个大家可以自己在stm的官网下载到
- 下载VSCode
- 下载arm-none-eabi-gcc
- 下载MinGW-w64,为了实现里面的makefile 等功能
- 下载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也完全没有问题文章来源:https://www.toymoban.com/news/detail-530744.html
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这个文件中新增选项,就可以没有报错了文章来源地址https://www.toymoban.com/news/detail-530744.html
# Compiler flags
cFlags: []
cxxFlags: []
assemblyFlags: []
linkerFlags:
- -specs=nano.specs
- -Wl,--gc-sections
- -ffreestanding -flto
- -specs=nosys.specs #新增这个选项
到了这里,关于vscode stm32cubemx 优雅开发stm32,最简单步骤教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!