IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 1-1.PlatformIO+STM32CubeMX新建工程 -> 正文阅读

[嵌入式]1-1.PlatformIO+STM32CubeMX新建工程

PlatformIO简介

PlatformIO 是开源的物联网开发生态系统。它提供跨平台的代码构建器、集成开发环境(IDE),并且兼容 Arduino 和 MBED。它支持超过 200 个的开发板和超过 15 种的开发平台以及 10 中开发框架,绝大多数流行的开发板都是包含其中的。同时,它在收集整理了大量的开发库,另外,还有很多代码例程提供方便您入门单片机开发。

目前,官方推荐的IDE使用方案是 VSCode+PlatformIO IDE插件:

VSCode+PlatformIO 界面

PlatformIO安装

1、安装VSCode:VSCode官方下载链接

2、打开VSCode,在左侧工具栏中找到扩展,搜索PlatformIO,点击安装即可。

PlatformIO作为一个集成开发环境,只有其本身的安装包是托管在VSCode插件商店上,其他的资源需要从第三方网站下载,基本都是国外的网站,所以PlatformIO安装的过程以及第一次创建生成项目的过程会比较缓慢,请耐心等待。


PlatformIO+STM32CubeMX创建工程

1.PlatformIO新建工程

点击VSCode界面左下角的小房子图标,进入PlatformIO主界面,然后点击+New Project创建工程。填入工程名、对应的开发板/MUC型号、项目框架(STM32Cube),取消默认保存路径并选择自己要保存的路径,点击Finish即可。第一次创建该项目框架,PlatformIO需要下载对应框架所需的资源文件,创建过程会比较久。

PlatformIO创建新项目(STM32Cube框架)
创建完成时的界面

2.PlatformIO修改工程目录

因为使用STM32CubeMX生成工程文件时,源文件是存放在Src文件夹中,头文件是放在Inc文件夹中,所以需要修改PlatformIO生成的工程目录中的文件名,将“Include”修改为“Inc”,“src”修改为“Src”。同时需要在platformio.ini配置文件中进行修改。在platformio.ini配置文件中添加:

[platformio]
src_dir = ./
include_dir = Inc

3.STM32CubeMX生产工程文件

将配置好的STM32CubeMX工程保存在PlatformIO生产的工程根目录下,在ProjectManager中选择Toolchain/IDE为Makefile,在Code Generator中按图示勾选。然后点击右上角的GENERATE CODE生成项目源码。

ProjectManager中选择Toolchain/IDE为Makefile
Code Generator配置

?完成后再PlatformIO中打开项目,可以看到相关文件已经生产并导入到项目中。

STM32CubeMX生成的项目目录

4.PlatformIO修改配置文件

因为PlatformIO和STM32CubeMX的工作原理不同。(STM32CubeMX是解析用户在GUI界面上配置好的外设,生成使用了HAL库的项目源码,并将HAL库添加到该项目工程中;而PlatformIO是根据新建项目时所选择的STM32Cube框架下载了HAL库并将它保存在C:/.platformio目录下,在编译时引用C:/.platformio目录下的HAL库,并没有将HAL库添加到项目工程中)两者所使用的HAL库并不完全相同,所存在的细微差异会导致编译失败,或是编译成功但实现不了预期功能。所以需要在platformio.ini配置文件中,重新配置编译所使用的库。

platformio.ini配置文件????

?platformio.ini配置文件内容如下:

; ini文件中分号表示注释

; 修改工程目录
[platformio]
src_dir = ./
include_dir = Inc


[env:genericSTM32F407VGT6]
platform = ststm32
board = genericSTM32F407VGT6
; 注释掉下面framework这一行,表示不使用platformIO的HAL库
; framework = stm32cube

; 使用项目目录下的HAL库
build_flags = 
    -D STM32F407xx
    -IInc
    -IDrivers/CMSIS/Include
    -IDrivers/CMSIS/Device/ST/STM32F4xx/Include
    -IDrivers/STM32F4xx_HAL_Driver/Inc
    -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy

src_filter = +<Src/> +<startup_stm32f407xx.s> +<Drivers/>
; 使用项目目录下的链接文件
board_build.ldscript = ./STM32F407VGTx_FLASH.ld

到此,完成了PlatformIO+STM32CubeMX创建工程。


测试:使用printf向串口打印信息

在主函数中添加打印“Hello World!\n”的语句;

printf("Hello World!\n")

点击左下角的√Build,进行编译:

编译失败

查看报错可知,出现了 undefined reference to `_sbrk', `_write', `_lseek', `_read'的连接错误。

原因是,PlatformIO使用的是GCC FOR ARM进行编译,该编译链中不包含类似于printf、malloc、fopen、fread之类的嵌入式MCU平台并不支持的库函数。

解决方法:实现所需的库函数 或者 不使用不支持的库函数。

在STM32开发中,printf重定向是常用的一种开发调试方式,所以这里选择实现所需的库函数,并实现printf重定向到串口。

在Src目录下新建一个syscall.c文件:

#include <stdio.h>
#include <sys/stat.h>
#include "usart.h"
#include "stm32f4xx_hal.h"

#ifdef __cplusplus
extern "C"
{
#endif
    // 重定向到串口1
    int _write(int fd, uint8_t *pBuffer, int size)
    {
        for (int i = 0; i < size; i++)
        {
            while (!(USART1->SR & USART_SR_TXE))
            {
            }
            HAL_UART_Transmit(&huart1, &pBuffer[i], 1, 0xFFFF);
        }
        return size;
    }

    int _read(int fd, uint8_t *pBuffer, int size)
    {
        for (int i = 0; i < size; i++)
        {
            while ((USART1->SR & USART_SR_RXNE) == 0)
            {
            }
            pBuffer[i] = HAL_UART_Receive(&huart1, &pBuffer[i], 1, 0xFFFF);
        }
        return size;
    }

    caddr_t _sbrk(int increment)
    {
        extern char end asm("end");
        register char *pStack asm("sp");

        static char *s_pHeapEnd;

        if (!s_pHeapEnd)
            s_pHeapEnd = &end;

        if (s_pHeapEnd + increment > pStack)
            return (caddr_t)-1;

        char *pOldHeapEnd = s_pHeapEnd;
        s_pHeapEnd += increment;
        return (caddr_t)pOldHeapEnd;
    }

    int _close(int fd)
    {
        return -1;
    }

    int _lseek(int fd1, int fd2, int fd3)
    {
        return -1;
    }

    int _fstat(int fd, struct stat *pStat)
    {
        pStat->st_mode = S_IFCHR;
        return 0;
    }

    int _isatty(int fd)
    {
        return 1;
    }

#ifdef __cplusplus
}
#endif

?重新点击√Build,编译成功。

编译成功

点击√Build右边的→Upload,将程序烧写到开发板中。

烧写成功

?点击Serial Monitor,查看串口打印信息

Hello World!

?

?

?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章           查看所有文章
加:2021-07-29 23:29:35  更:2021-07-29 23:29:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/1 11:19:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码