1.下载Visual Studio Community 2019

https://visualstudio.microsoft.com/zh-hans/vs/

2.添加vs上面的Linux工具,cmake工具,IOT开发工具 

3.stm32 工程配置

不推荐使用stm32 cubex 生成的makefile工程,因为我试过好多次编译出来的bin文件都不能运行,不知道为什么...

我这里用的芯片是STM32F103C8T6

所以需要用到stm32F1xx标准库:StdPeriph_Driver/inc, StdPeriph_Driver/src,这两个人文件夹里面的文件是所有外设的头文件和库

还要用到stm32F1系列系统文件 system_stm32f10x.c,system_stm32f10x.h,stm32f10x.h

此外需要用到cmsis内核文件

stm32给gcc用的启动文件 startup_stm32f103xb.s

stm32给gcc用的链接文件STM32F103C8Tx_FLASH.ld

我喜欢把系统文件都放到标准库里面去

新建user文件,把自己的main.c程序放进去,方便管理

4.启动vs2019

通过“打开本地文件夹(F)”来启动项目。

打开上面弄好的文件

4.点了“选择文件夹”后应该能看到,vs2019已经自动包含了里面的全部文件

5.添加CMakelits.txt

添加CMakelists.txt后,vs2019会自动配置cmake工程,同时会自行生成out文件夹,放工程信息

6.CMakelists.txt编写

设置工程名称, “#”相当于C语言里面的“//”,注释的意思

STM32_Templete是此次工程的名字

# Project name
project(STM32_Templete)

设置编译用的工具, arm-none-eabi-gcc是专门给arm开发的编译工具

set(AA BB)有点类似于#define AA BB,把AA 定义为BB,不过有些AA已经被编译器定义过了

# compiler tools
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_SIZE arm-none-eabi-size)

添加版本gcc说明

cmake_minimum_required(VERSION 3.15)

设置编译选项

-mcpu=cortex-m3,表明用cortex-m3内核的芯片

--specs=nano.specs --specs=nosys.specs,使用nano.specs,避免出来xx问题

-Os -g程序优化等级s级,可选-O0不优化,-O1,-O2,O3优化1,2,3

-Wall 全部警告

-ffunction-sections -fdata-sections给每个函数设置单独的空间,链接时不使用的函数不会链接,可以缩小代码体积

# compiler build flags
set(MCU_FLAGS "-mcpu=cortex-m3")
set(CMAKE_C_FLAGS "${MCU_FLAGS} --specs=nano.specs --specs=nosys.specs")
set(CMAKE_C_FLAGS_DEBUG "-Os -g -Wall -ffunction-sections -fdata-sections")
set(CMAKE_C_FLAGS_RELEASE "-Os")

选用DEBUG的选项

# cmake type
set(CMAKE_BUILD_TYPE "Debug")

添加头文件路径

把所有头文件的路径加进去

${CMAKE_CURRENT_SOURCE_DIR}是指根目录

include_directories(
    CMSIS
    StdPeriph_Driver/inc
    StdPeriph_Driver/src
    user
)

查找*.C文件

std_src存放所有标准库

user_src存放用户程序

# search *.c files
file(GLOB std_src StdPeriph_Driver\src*.c)
file(GLOB user_src user/*.c)

把找到的文件打包成静态库,std,user

# Drivers
add_library(
    std
    ${std_src}
)
# main source file
add_library(
    user
    ${std_src}
)

单独打包启动文件

# startup file
enable_language(ASM)
add_library(startup startup_stm32f103xb.s)
set_property(SOURCE startup_stm32f103xb.s PROPERTY LANGUAGE C)

设置链接文件

# linker script
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/STM32F103C8Tx_FLASH.ld)

设置链接选项

#link flags
#set(link_extraFlag "-u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid ")
set(link_extraFlag "-lc -lm -lgcc -lnosys")
set(CMAKE_EXE_LINKER_FLAGS
"${link_extraFlag} -T${LINKER_SCRIPT} -Wl,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map,--cref -Wl,--gc-sections -Wl,--entry=Reset_Handler"
)

链接时加入“ -Wl,--print-memory-usage ”编译器会输出内存使用情况

Memory region         Used Size  Region Size  %age Used
             FLASH:      120305 B       252 KB     46.62%
      FLASH_CONFIG:          0 GB         4 KB      0.00%
               RAM:       18396 B        40 KB     44.91%
               CCM:          2 KB         8 KB     25.00%

设置链接查找路径

# link directories
link_directories(
    CMSIS
    StdPeriph_Driver
    StdPeriph_Driver\inc
    StdPeriph_Driver\src
    user
)

设置要链接的库,前面打包好的静态库

#link librarise
link_libraries(
    startup
    std    
    user    
)

添加可执行文件,main函数所在的文件

#generate excutable file
add_executable(${PROJECT_NAME}.elf user/main.c)

设置输出文件,bin,hex,elf, hex输出有bug,咱不要了.(GNU Tools Arm Embedded更新至gcc version 9.2.1 20191025可解决生成hex问题)

#output hex and bin file
set(ELF_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf)
set(HEX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.bin)

生成并计算输出文件大小

#build hex and bin file and display size
add_custom_command(TARGET "${PROJECT_NAME}.elf" POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} -Obinary ${ELF_FILE} ${BIN_FILE}
    #COMMAND ${CMAKE_OBJCOPY} -Oihex  ${ELF_FILE} ${HEX_FILE}
    COMMENT "Building ${PROJECT_NAME}.bin and ${PROJECT_NAME}.hex"

#COMMAND ${CMAKE_COMMAND} -E copy ${HEX_FILE} "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.hex"
    COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.bin"

COMMAND ${CMAKE_SIZE} --format=berkeley ${PROJECT_NAME}.elf
    COMMENT "Invoking: Cross ARM GNU Print Size"
)

7.把工程设置为IOT工程

删除不是IOT的是

添加IOT

最后记得“Ctrl + S”保存!!!!!!!!!!!!!!

回到CMakelists.txt

再按一次Ctrl + S,看到这个就配置成功了

下面是CMakelists.txt的所有代码

# Project name
project(STM32_Templete)cmake_minimum_required(VERSION 3.15)# compiler tools
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
set(CMAKE_SIZE arm-none-eabi-size)# compiler build flags
set(MCU_FLAGS "-mcpu=cortex-m3")
set(CMAKE_C_FLAGS "${MCU_FLAGS} --specs=nano.specs --specs=nosys.specs")
set(CMAKE_C_FLAGS_DEBUG "-Os -g -Wall -ffunction-sections -fdata-sections")
set(CMAKE_C_FLAGS_RELEASE "-Os")# cmake type
set(CMAKE_BUILD_TYPE "Debug")# include path
include_directories(CMSISStdPeriph_Driver/incStdPeriph_Driver/srcuser
)# search *.c files
file(GLOB std_src StdPeriph_Driver/src/*.c)
file(GLOB user_src user/*.c)# Drivers
add_library(std${std_src}
)
# main source file
add_library(user${std_src}
)# startup file
enable_language(ASM)
add_library(startup startup_stm32f103xb.s)
set_property(SOURCE startup_stm32f103xb.s PROPERTY LANGUAGE C)# linker script
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/STM32F103C8Tx_FLASH.ld)#link flags
#set(link_extraFlag "-u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid ")
set(link_extraFlag "-lc -lm -lgcc -lnosys")
set(CMAKE_EXE_LINKER_FLAGS
"${link_extraFlag} -T${LINKER_SCRIPT} -Wl,-Map=${PROJECT_BINARY_DIR}/${PROJECT_NAME}.map,--cref -Wl,--gc-sections -Wl,--entry=Reset_Handler"
)# link directories
link_directories(CMSISStdPeriph_Driver/incStdPeriph_Driver/srcuser
)#link librarise
link_libraries(startupstd   user
)#generate excutable file
add_executable(${PROJECT_NAME}.elf user/main.c)#output hex and bin file
set(ELF_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.elf)
set(HEX_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.bin)#build hex and bin file and display size
add_custom_command(TARGET "${PROJECT_NAME}.elf" POST_BUILDCOMMAND ${CMAKE_OBJCOPY} -Obinary ${ELF_FILE} ${BIN_FILE}#COMMAND ${CMAKE_OBJCOPY} -Oihex  ${ELF_FILE} ${HEX_FILE}COMMENT "Building ${PROJECT_NAME}.bin and ${PROJECT_NAME}.hex"#COMMAND ${CMAKE_COMMAND} -E copy ${HEX_FILE} "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.hex"COMMAND ${CMAKE_COMMAND} -E copy ${BIN_FILE} "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.bin"COMMAND ${CMAKE_SIZE} --format=berkeley ${PROJECT_NAME}.elfCOMMENT "Invoking: Cross ARM GNU Print Size"
)

8.开始编程

按生成

不出意外的话,会有一堆问题,

可以在CMakelists.txt 那时加入声明,对了,忘了stm32的库要加入型号说明的,

#define STM32F10X_MD

#define USE_STDPERIPH_DRIVER

# mcu definitions
add_definitions(
    -DSTM32F10X_MD
    -DUSE_STDPERIPH_DRIVER
)

头文件里面还要添加RTE_Components.h,stm32f10x_conf.h,添加完成后需要在CMakelists.txt那里再点一次生成,每次添加新文件后都让,CMakelists.txt重新生成一次

再试下生成,就应该没问题了

根目录下也能看到生成的Bin文件

最后写个Printf函数

由于GCC没有提供_write(),和keil里面重定义putchar不一样的是,要重定义_write()

int _write(int fd, char* ptr, int len)
{
    uint16_t count = 0;
    count = len;
    usart_sendNbytes((uint8_t*)ptr, len);
    return count;
}

下面main.c的完整代码

#include "stm32f10x.h"
#include <stdio.h>
int _write(int fd, char* ptr, int len);
void RCC_Configuration(void)//时钟配置,8MHz晶振,72MHz系统时钟
{ErrorStatus HSEStartUpStatus;/* RCC system reset(for debug purpose) */RCC_DeInit();/* Enable HSE */RCC_HSEConfig(RCC_HSE_ON);while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);/* Wait till HSE is ready */HSEStartUpStatus = RCC_WaitForHSEStartUp();if (HSEStartUpStatus == SUCCESS){/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);/* HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* PLLCLK = 8MHz * 9 = 72 MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/* Enable PLL */RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while (RCC_GetSYSCLKSource() != 0x08){}}RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 串口 PORTA时钟//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);// 串口时钟//RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
}
void GPIO_Configuration(void)
{//USART1GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void USART1_Configuration(uint32_t buadrate)
{USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = buadrate;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);
}
void usart_sendByte(uint8_t b)
{USART_SendData(USART1, b);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);USART_ClearFlag(USART1, USART_FLAG_TC);
}
void usart_sendBytes(uint8_t* bs)
{while (*bs){usart_sendByte(*bs++);}
}
uint16_t usart_sendNbytes(uint8_t* bytes, uint16_t len)
{while (len--){usart_sendByte(*bytes++);}return len;
}
int _write(int fd, char* ptr, int len)
{uint16_t count = 0;count = len;usart_sendNbytes((uint8_t*)ptr, len);return count;
}
void main()
{RCC_Configuration();GPIO_Configuration();USART1_Configuration(115200);printf("All system ready!\n\n");while (1){printf("Hello world\n");}
}

实际运行情况

下面是工程例程

http://download.csdn.net/download/u013866683/11998012

lalala

用Visual Studio 2019 开发stm32,cortex-m3, arm相关推荐

  1. 使用Visual Studio 2019开发Qt程序

    安装Qt 如标题,你首先需要到 http://download.qt.io/ 去下载并安装Qt,并在引导下安装MSVC组件(这里不做过多解释) Visual Studio 2019 配置 打开VS20 ...

  2. OpenCV 4.1.0 + Visual Studio 2019 开发环境搭建 超级简单

    先说一下其实根本无需修改环境变量等系统设置,只需要对 project 进行一些设置就好. 编译需要的是 .h 文件和 .lib 文件,运行需要的是 .dll 文件,调试需要的是代码源文件和 .pdb ...

  3. 【错误记录】Visual Studio 2019 中运行 Unity C# 脚本时报错 ( 根据解决方案, 可能需要安装额外的组件才能获得 | .NET 桌面开发 | 使用 Unity 的游戏开发 )

    文章目录 一.报错信息 二.解决方案 三.Visual Studio 2019 中运行 Unity C# 脚本需要的组件 1..NET 桌面开发 2.使用 Unity 的游戏开发 一.报错信息 Vis ...

  4. 【OpenGL】一、Visual Studio 2019 创建 Windows 桌面程序 ( Visual Studio Installer 安装 C++ 桌面开发库 | 创建桌面程序 )

    文章目录 一.Visual Studio Installer 安装 C++ 桌面开发库 二.Visual Studio 2019 创建 Windows 桌面程序 之前曾使用 Visual Studio ...

  5. 总结 Visual Studio 2019 发布以来 XAML 工具的改进

    不知不觉,Visual Studio 2019 已经出到 16.8 和 16.9 Preview 了.虽然每次更新都林林总总地一大堆新功能和改进,但关于 XAML 的内容总是,always,每次都只有 ...

  6. 关于在Visual Studio 2019预览版中的用户体验和界面的变化

    原文地址:https://blogs.msdn.microsoft.com/visualstudio/2018/11/12/a-preview-of-ux-and-ui-changes-in-visu ...

  7. 在visual studio 2019中使用msvc2015

    1.配置visual studio中的qt 下载相应版本的qt插件,这里用的是 qt-vsaddin-msvc2017-2.7.0.vsix 插件下载地址:https://download.qt.io ...

  8. 【Unity3D】Unity 脚本 ① ( 创建 C# 脚本 | Visual Studio 2019 中打开 C# 脚本 | 编译 C# 脚本 | 挂载 C# 脚本到游戏物体 | 运行脚本 )

    文章目录 一.创建 Unity 脚本 二.Visual Studio 2019 中打开 C# 脚本 三.编译 C# 脚本 四.挂载 C# 脚本到游戏物体 GameObject 1.添加组件方式 2.直 ...

  9. 【Unity3D】Unity 脚本 ② ( Visual Studio 2019 中的 Unity 编译环境配置 | Unity 编辑器关联外部 C# 脚本编辑器 Visual Studio )

    文章目录 一. Visual Studio 2019 中的 Unity 编译问题 二. Unity 编辑器中关联外部 C# 脚本编辑器 三. 设置游戏运行时脚本更新行为 一. Visual Studi ...

最新文章

  1. 【原创】WinCE下流驱动开发流程
  2. Laravel源码解析之从入口开始
  3. SAP Cloud for Customer upselling的前台实现
  4. 云计算设计模式(二)——断路器模式
  5. 动点四边形周长最短_初中几何--线段之和最小值 Part 1:通过点关于直线对称点得到两定点之间直线段长度最短。...
  6. Bootstrap 媒体对象
  7. php echo输出两个变量,php实现关于var_dump和echo输出多变量的测试
  8. 计算机二级考试能报考的科目,计算机二级考试有哪些科目可以选择报考?
  9. Spring.NET教程(三)——对象的创建(基础篇)
  10. 基于Caffe的人脸识别实现
  11. java pdf 中文_java pdf中文乱码怎么办
  12. AI(人工智能:一种现代的方法)学习之:基于信息的搜索策略(informed search)——启发式(heuristic)搜索、贪婪(greedy)搜索、A* (A star)搜索
  13. 多个mysql共存_双mysql共存(MySQL8.0与MySQL5.7)
  14. 微信扫码支付模式一 : 获取商户订单信息超时或者商户返回的httpcode非200
  15. 第四章、面向对象(2)
  16. 正反斜杠的区别_正斜杠(/)和反斜杠(\)的区别
  17. 「干货」Snort使用手册「详细版」
  18. Markdown小技巧:代码格式、缩进和字体大小
  19. 计算机显示器是输入,如果计算机显示器未显示视频输入怎么办
  20. php消息撤回,QQ怎么在撤回消息后面加字?QQ消息撤回修改内容

热门文章

  1. rxjs里的Observable对象如何消费
  2. odata.publish = true的CDS view激活之后,后台发生了什么事情
  3. when is completed field filled in the backend
  4. Create new Fiori catalog group via personalization
  5. 我做的小学二年级公开课《生命,生态和安全》的教案
  6. JavaScript debugger time out and defer.resolve
  7. 使用代码将指定的product加入新建的transaction
  8. SAP ABAP ALV list background render
  9. attachment绑相对url
  10. S/4HANA业务角色概览之订单到收款篇