用Visual Studio 2019 开发stm32,cortex-m3, arm
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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vivo门禁卡复制到手机上
- 下一篇: matlab矩阵如何运算相加(Matla