最近想要写个更新航模接收机固件的小项目,移植opentx项目的部分代码到我的最小系统板上。不经意间发现vscode上也可以开发stm32了,于是,一个填坑行动开始了!!!
先写怎么才能编译调试吧!
环境:
windows10x64,8G内存,i5 4200
stlink v2
1.你要有个vscode,不用我说了。
2.在vscode上装platformio插件
安装完毕,点击重新加载。之后会提示正在安装PlatformIO 核心。
再次重新加载
3.安装完毕后,在vscode的左下角会有一个家的图标,可以从这里新件工程。第一次启动也会自动打开PIO Home页面。
4.新建工程。因为它是以开发板为选择,不是芯片,只能选择BluePill F103C8,这个关系不大,只是运行内存和Flash大小不同。记得选一个空目录。
5.打开工程,新建的工程会在PIO Home的下发列出。点击打开,如果打不开,关闭编辑器重新打开一次,或者直接用vscode打开那个目录。
6开打工程后,目录树中无源码,需要自己添加,按一下Ctrl+Alt+B,platformio自动下载编译组件。然后提示无文件可以编译。
.
我们添加一个main.c,然后再编译。
然后插上stlink,接上单片机,按CTRL+ALT+U,烧到单片机上(首次上传会安装stlink)。
-----------------------------------------------------------------分割线--------------------------------------------------------------------------
你以为就完了吗,那我写这个文章干嘛!
看起来编译完成,上传也通过了,然而,你的单片机并没有让c13口的灯闪亮,串口也并没有发送字母c!由于以前都是使用keil开发,对启动项目和内存定义并不清楚,加之platformio使用了arm-none-eabi-gcc编译,隐藏了太多的细节。经过一个礼拜的刻苦钻研,最终找到了解决方法。方法如下:
在你的电脑上找到这个文件,C:\Users\<你的用户名>\.platformio\packages\framework-stm32cube\platformio\ldscripts\STM32F103C8_DEFAULT.ld,打开。
把红框里的内容改为 _estack = 0x20005000; 加一个0,就这一个0,天大的坑的存在,对于熟悉使用gcc编译的人,可能并不很难,但对于我等新手,这个问题实在太难找!!!之后,把这个文件另存为STM32F103C8_flash.ld,不另存也可以,但我喜欢完美,Platformio的源码是先寻找_FLASH.ld再寻找DEFAULT.ld的。
好了,再编译,上传(CTRL+ALT+B,CTRL+ALT+U)。享受使用vscode编写stm32的乐趣吧!
main.c
#include <stm32f1xx_hal.h>#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#define LED_PIN GPIO_PIN_13
#define LED_GPIO_PORT GPIOC
#define LED_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
void SysTick_Handler(void)
{HAL_IncTick();HAL_SYSTICK_IRQHandler();
}
void SystemClock_Config(void)
{RCC_ClkInitTypeDef clkinitstruct = { 0 };RCC_OscInitTypeDef oscinitstruct = { 0 };/* Configure PLL ------------------------------------------------------*//* PLL configuration: PLLCLK = (HSI / 2) * PLLMUL = (8 / 2) * 16 = 64 MHz *//* PREDIV1 configuration: PREDIV1CLK = PLLCLK / HSEPredivValue = 64 / 1 = 64 MHz *//* Enable HSI and activate PLL with HSi_DIV2 as source */oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;oscinitstruct.HSEState = RCC_HSE_OFF;oscinitstruct.LSEState = RCC_LSE_OFF;oscinitstruct.HSIState = RCC_HSI_ON;oscinitstruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;oscinitstruct.PLL.PLLState = RCC_PLL_ON;oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL16;if (HAL_RCC_OscConfig(&oscinitstruct) != HAL_OK){/* Initialization Error */while (1); }/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1;clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1;clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2) != HAL_OK){/* Initialization Error */while (1); }
}
GPIO_InitTypeDef GPIO_InitStruct;
UART_HandleTypeDef com1;
int main(void)
{HAL_Init();SystemClock_Config();__GPIOC_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_13;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); com1.Instance = USART1;com1.Init.BaudRate = 9600;com1.Init.WordLength = UART_WORDLENGTH_8B;com1.Init.StopBits = UART_STOPBITS_1;com1.Init.Parity = UART_PARITY_NONE;com1.Init.HwFlowCtl = UART_HWCONTROL_NONE;com1.Init.Mode = UART_MODE_TX_RX;if (HAL_UART_Init(&com1) != HAL_OK){for (;;){HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);HAL_Delay(200);}}for (;;){uint8_t ch = 'c';HAL_UART_Transmit(&com1, (uint8_t *)&ch, 1, 0xFFFF);HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);HAL_Delay(1000);}
}#define USARTx_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE();
#define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()#define USARTx_FORCE_RESET() __HAL_RCC_USART1_FORCE_RESET()
#define USARTx_RELEASE_RESET() __HAL_RCC_USART1_RELEASE_RESET()/* Definition for USARTx Pins */
#define USARTx_TX_PIN GPIO_PIN_9
#define USARTx_TX_GPIO_PORT GPIOA
#define USARTx_RX_PIN GPIO_PIN_10
#define USARTx_RX_GPIO_PORT GPIOA
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{GPIO_InitTypeDef GPIO_InitStruct;/*##-1- Enable peripherals and GPIO Clocks #################################*//* Enable GPIO TX/RX clock */USARTx_TX_GPIO_CLK_ENABLE();USARTx_RX_GPIO_CLK_ENABLE();/* Enable USARTx clock */USARTx_CLK_ENABLE();/*##-2- Configure peripheral GPIO ##########################################*//* UART TX GPIO pin configuration */GPIO_InitStruct.Pin = USARTx_TX_PIN;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);/* UART RX GPIO pin configuration */GPIO_InitStruct.Pin = USARTx_RX_PIN;HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
}/*** @brief UART MSP De-Initialization* This function frees the hardware resources used in this example:* - Disable the Peripheral's clock* - Revert GPIO and NVIC configuration to their default state* @param huart: UART handle pointer* @retval None*/
void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
{/*##-1- Reset peripherals ##################################################*/USARTx_FORCE_RESET();USARTx_RELEASE_RESET();/*##-2- Disable peripherals and GPIO Clocks #################################*//* Configure UART Tx as alternate function */HAL_GPIO_DeInit(USARTx_TX_GPIO_PORT, USARTx_TX_PIN);/* Configure UART Rx as alternate function */HAL_GPIO_DeInit(USARTx_RX_GPIO_PORT, USARTx_RX_PIN);}