STM32(1)--Hello

1 前言

说来惭愧,因为我毕业比较早,我当年学的都是51单片机。然后再接触嵌入式,都是博通,高通,海思这些重型平台,都是直接上的Linux。

后面自学也是主要国际接轨,主要是Arduino和树莓派。看起来很多概念是很新很潮,但其实现在回头看看身边实际的工业项目,看起来还是STM32占比挺高的。另外看了下目前国内高校电子专业,用的主流也是STM32。

做一个对比如下:

指标 \ MCU STM32 系列 RP2350 (Raspberry Pi Pico 2) ESP32 系列 Nordic nRF52 / nRF53 TI MSP430 / C2000
核心架构 ARM Cortex-M0/M3/M4/M7/M33/M55 Dual Cortex-M4F Xtensa / RISC-V ARM Cortex-M4/M33 MSP430 / C28x
主频 32--480 MHz 240 MHz 160--240 MHz 64--128 MHz/ 128-- Application 8--100 MHz
浮点支持 M4/M7/M33(FPU) 有单精度FPU 有(部分) 有(部分) 无/有限
RAM 小到 16 KB ~ 大到 1 MB+ ~ 264 KB 320 KB 64--512 KB 2--128 KB
Flash/存储 16 KB ~ 多 MB ~ 16--32 MB 外挂 4--16 MB 外挂 ~ 256 KB--1 MB 16 KB--1 MB
ADC 精度 & 采样 12-16 bit 多通道 DMA 12-bit 12-bit 12-bit 10--16 bit(取决型号)
DMA 支持 完整
通信外设数量 丰富(USART/SPI/I2C/CAN/ FDCAN/USB/SPI) 丰富(UART/SPI/I2C/PIO) Wi-Fi/BT 内置 + UART/SPI/I2C BLE 内置 + UART/SPI/I2C UART/SPI/I2C/CAN(部分)
无线 需外挂模块 需外挂 Wi-Fi + BT 现成 BLE 现成 需外挂
超低功耗能力 优秀(L 系列特别出色) 中等 一般 优秀(低功耗 BLE 典型) 极优(MSP430) / 中等
实时性 很强 很强 好(RTOS) 很好 很强(C2000 强实时控制)
工程生态 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐⭐
供应 & 生命周期 长期稳定 好但更新快
成熟工业案例 极多 多(消费/IoT) 多(穿戴/BLE) 老牌工业/控制
工具链 CubeMX + HAL/LL + Keil/GCC CMake + GCC ESP IDF nRF SDK / Zephyr CCS / GCC
学习曲线 中等 中等 中等 低(MSP430) / 中等(C2000)
典型价格 广泛 很低 中低

STM32还是更成熟,更稳定。量产项目估计最后还是要它。。。

好吧,还是再学学。

2 环境搭建

手上有两个STM32,一个是新的STM32F411,另外一个是老的STM32F103。还有一个ST LINK V2。都是吃灰了好久的,这个周末翻出来玩玩。

查了一下STM32的环境流程,相对树莓派和arduino,不得不说,真的是很麻烦。。。

前前后后下载了几个G的软件,有CubeMX,有CubeProgrammer,有CubeIDE。然后在VSCode中还装了STM32插件。

根据我的习惯,然后网上的资料,我整理的我的开发流程。

1 创建工程。使用CubeMX,主要是指定芯片,设置IO,配置工程信息。

2 编辑代码。我还是习惯VSCode。

3 编译。使用VSCode STM插件。

4 烧写,使用CubeProgrammer。

现在挨个说一下遇到的坑:

1 STLink不工作。

死活报错。后面才查到配置界面里面的Shared一定要打开,然后才能识别祖国版的STLink。

折腾了两三个小时。

2 STM32F411死活连不上

AI给的意见是点击Connect的时候,同时点击板子上的RST,然后迅速松开。。。这个操作真的很迷很考验手速啊。。。试了无数次还是不行。。。

最后无奈换成更古早的STM32F103,好了,一下就连上了。我在想可能是手焊的SWD接口没对吧。。。

折腾了两三个小时。

3 配置工程要选Makefile

最开始我忘了在哪里看的,说是可以用CMake构建工程。结果在VSCode的STM32插件中,各种报错,解决来解决去也编不出来。最后回来又重新试了下Makefile,很顺利一下就过了。。。

折腾了一两个小时。

4 配置VSCode插件

进了这个插件首先要配置那几件套,就是arm-gcc,make,ninja等。它是自带了一套,但是也麻烦了,因为都在外网大概率要被墙,能不能下载成功只有看天。反正我是试了很久都不行。最后无奈换成Pico的那一套环境,最后终于是配出来了。而且可以看到功能也很有限。

折腾两个小时。

5 三只蓝鲸的LED口。

最开始看资料,都说点灯使用的PA13,但是死活就是不亮。最后没办法又跑回去找卖家要了资料,看到灯原来是PA6和PA7。

折腾两个小时。

说真的,这个环境折腾得我都无语了。真不知道那么多学生是怎么配置这个环境的。。。

3 结果

好在赶在睡觉之前还是亮了。。。

代码很简单,如下:

cpp 复制代码
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2026 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_6); 
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_7);
    
    HAL_Delay(500);
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* USER CODE BEGIN MX_GPIO_Init_1 */

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);

  /*Configure GPIO pin : LED_Pin */
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : PA6 PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USER CODE BEGIN MX_GPIO_Init_2 */

  /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

主要还是环境太折腾了,比起另外几家复杂不少。也许后面习惯了会好点吧。

STLink调试没有配置出来。。。空了再试试。

相关推荐
zhongvv2 小时前
对单片机C语言指针的一些理解
c语言·数据结构·单片机·指针·汇编语言
Jia shuheng2 小时前
STM32的一键下载CH340 DTR RTS与复位电路NRST的学习笔记
笔记·stm32·学习
2501_927773074 小时前
嵌入式51单片机
单片机·嵌入式硬件·51单片机
恶魔泡泡糖5 小时前
51单片机独立按键
单片机·嵌入式硬件·51单片机
炸膛坦客6 小时前
Cortex-M3-STM32F1 开发:(五十)软件模拟 IIC 和硬件 IIC 的区别,以及软件 IIC 配置步骤及相关函数,以及相关问题
stm32·单片机·嵌入式硬件
清风6666667 小时前
基于单片机的电流电压可调数控电源
单片机·毕业设计·课程设计·期末大作业
泡泡糖的中文规格书7 小时前
【无标题】
单片机·嵌入式硬件·规格说明书·datasheet
LongRunning7 小时前
【BLE】STM32WB55+CubeMAX_BLE配置
stm32
风雨中的蜜蜂7 小时前
SKY13330-397LF国产替代ATR5330 SPDT开关芯片
单片机·嵌入式硬件