STMicroelectronics 系列:STM32WB 系列_(4).STM32WB系列软件开发环境
STM32WB系列软件开发环境
1. 概述
STM32WB系列是STMicroelectronics推出的集成了蓝牙低功耗(BLE)和Wi-Fi功能的微控制器(MCU)系列。这些MCU基于ARM Cortex-M4和Cortex-M0+双核架构,提供高性能和低功耗的解决方案。本节将详细介绍如何设置和配置STM32WB系列的软件开发环境,包括必要的工具和软件包。
2. 必需的工具和软件
2.1 STM32CubeIDE
STM32CubeIDE是由STMicroelectronics提供的集成开发环境(IDE),支持STM32系列的所有MCU。它集成了项目管理、代码编辑、编译、调试和编程功能,简化了开发流程。
安装步骤
-
访问STMicroelectronics官方网站,下载STM32CubeIDE的安装包。
-
运行安装包,选择安装路径。
-
在安装过程中,选择安装STM32WB系列的支持包。
-
安装完成后,启动STM32CubeIDE。
2.2 STM32CubeMX
STM32CubeMX是STMicroelectronics提供的图形化配置工具,用于初始化STM32的外设和中间件。它生成初始化代码,减轻开发人员的配置负担。
安装步骤
-
访问STMicroelectronics官方网站,下载STM32CubeMX的安装包。
-
运行安装包,选择安装路径。
-
安装完成后,启动STM32CubeMX。
2.3 JTAG/SWD调试器
STM32WB系列支持JTAG和SWD调试接口。常见的调试器包括ST-Link、J-Link等。确保你的调试器与STM32WB系列兼容。
配置步骤
-
将调试器连接到STM32WB系列的调试接口。
-
在STM32CubeIDE中配置调试器:
-
打开项目。
-
选择
Project
->Properties
。 -
选择
C/C++ Build
->Settings
->Tool Settings
。 -
在
Debug
选项卡中选择你的调试器。
3. 创建和配置项目
3.1 使用STM32CubeMX生成项目
步骤
-
打开STM32CubeMX。
-
选择
File
->New Project
。 -
选择你的STM32WB系列MCU型号,点击
Next
。 -
配置外设,例如GPIO、UART、SPI等。
-
生成初始化代码:
-
选择
Project
->Generate Code
。 -
选择
STM32CubeIDE
作为生成目标。 -
选择生成路径。
-
点击
Generate
。
生成的项目结构
生成的项目结构如下:
MyProject
├── Core
│ ├── Inc
│ └── Src
├── Drivers
│ ├── CMSIS
│ └── STM32WBxx_HAL_Driver
├── Middleware
├── User
│ ├── Inc
│ └── Src
├── .cproject
├── .project
└── STM32CubeMX
3.2 配置STM32CubeIDE项目
步骤
-
打开STM32CubeIDE。
-
导入生成的项目:
-
选择
File
->Import
。 -
选择
General
->Existing Projects into Workspace
。 -
选择生成的项目路径,点击
Finish
。 -
配置编译器和调试器:
-
选择
Project
->Properties
。 -
选择
C/C++ Build
->Settings
。 -
配置编译器选项,例如优化级别、预处理器宏等。
-
在
Debug
选项卡中配置调试器。
示例代码
以下是一个简单的GPIO配置和控制示例:
#include "stm32wbxx_hal.h"
// GPIO初始化函数
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置GPIOA的引脚0为输出模式
GPIO_InitStruct.Pin = GPIO_PIN_0;
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);
}
// 主函数
int main(void)
{
// 初始化HAL库
HAL_Init();
// 初始化系统时钟
SystemClock_Config();
// 初始化GPIO
GPIO_Init();
while (1)
{
// 翻转GPIOA的引脚0
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
// 延时500毫秒
HAL_Delay(500);
}
}
// 系统时钟配置函数
void SystemClock_Config(void)
{
// 配置系统时钟为默认值
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化外设时钟
HAL_RCC_OscConfig(RCC_OscInitStruct);
HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_1);
}
3.3 配置项目依赖
步骤
-
打开项目属性:
- 选择
Project
->Properties
。 -
配置C/C++ Build路径:
-
选择
C/C++ Build
->Settings
。 -
在
Tool Settings
选项卡中配置包括包含路径、库路径等。 -
配置预处理器宏:
-
选择
C/C++ General
->Paths and Symbols
。 -
在
Symbols
选项卡中添加预处理器宏,例如USE_FULL_LL_DRIVER
。
4. 编写和编译代码
4.1 编写代码
示例代码
以下是一个使用UART外设进行串口通信的示例:
#include "stm32wbxx_hal.h"
// USART1初始化函数
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
UART_InitTypeDef UART_InitStruct = {0};
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 使能USART1时钟
__HAL_RCC_USART1_CLK_ENABLE();
// 配置USART1的TX和RX引脚
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置USART1
UART_InitStruct.BaudRate = 115200;
UART_InitStruct.WordLength = UART_WORDLENGTH_8B;
UART_InitStruct.StopBits = UART_STOPBITS_1;
UART_InitStruct.Parity = UART_PARITY_NONE;
UART_InitStruct.HwFlowCtl = UART_HWCONTROL_NONE;
UART_InitStruct.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&huart1, &UART_InitStruct);
}
// 发送字符串函数
void UART1_SendString(const char *str)
{
HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), HAL_MAX_DELAY);
}
// 主函数
int main(void)
{
// 初始化HAL库
HAL_Init();
// 初始化系统时钟
SystemClock_Config();
// 初始化USART1
USART1_Init();
while (1)
{
// 发送字符串
UART1_SendString("Hello, STM32WB!\r\n");
// 延时1秒
HAL_Delay(1000);
}
}
// 系统时钟配置函数
void SystemClock_Config(void)
{
// 配置系统时钟为默认值
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化外设时钟
HAL_RCC_OscConfig(RCC_OscInitStruct);
HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_1);
}
4.2 编译代码
步骤
-
打开STM32CubeIDE。
-
打开项目。
-
点击
Build
按钮,编译项目。 -
查看编译结果,确保没有错误和警告。
5. 调试和编程
5.1 调试项目
步骤
-
连接调试器到STM32WB系列MCU。
-
在STM32CubeIDE中配置调试器。
-
设置断点。
-
点击
Debug
按钮,启动调试会话。 -
使用调试工具进行单步执行、查看变量值等操作。
5.2 编程项目
步骤
-
连接编程器到STM32WB系列MCU。
-
在STM32CubeIDE中配置编程器。
-
选择
Project
->Properties
->C/C++ Build
->Settings
。 -
在
Flasher
选项卡中选择编程器。 -
点击
Flash
按钮,将代码烧录到MCU中。
6. 示例项目
6.1 蓝牙低功耗(BLE)示例
步骤
-
在STM32CubeMX中选择
Connectivity
->B-L475E-IOT01
。 -
配置BLE外设。
-
生成初始化代码。
-
在STM32CubeIDE中编写BLE应用代码。
示例代码
以下是一个简单的BLE广播示例:
#include "stm32wbxx_hal.h"
#include "ble.h"
// BLE初始化函数
void BLE_Init(void)
{
// 初始化BLE外设
BLE_InitTypeDef ble_init_struct = {0};
ble_init_struct.p_ble_env = &BleEnv;
ble_init_struct.p_ble_gap = &BleGap;
ble_init_struct.p_ble_gatt = &BleGatt;
ble_init_struct.p_ble_hal = &BleHal;
ble_init_struct.p_ble_hci = &BleHci;
ble_init_struct.p_ble_l2cap = &BleL2cap;
ble_init_struct.p_ble_smp = &BleSmp;
HAL_BLE_Init(&ble_init_struct);
}
// 发送广播数据
void BLE_SendBroadcastData(void)
{
uint8_t broadcast_data[31] = "STM32WB BLE Example";
HAL_BLE_Gap_Advertise(&BleGap, broadcast_data, sizeof(broadcast_data));
}
// 主函数
int main(void)
{
// 初始化HAL库
HAL_Init();
// 初始化系统时钟
SystemClock_Config();
// 初始化BLE
BLE_Init();
while (1)
{
// 发送广播数据
BLE_SendBroadcastData();
// 延时1秒
HAL_Delay(1000);
}
}
// 系统时钟配置函数
void SystemClock_Config(void)
{
// 配置系统时钟为默认值
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化外设时钟
HAL_RCC_OscConfig(RCC_OscInitStruct);
HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_1);
}
6.2 Wi-Fi示例
步骤
-
在STM32CubeMX中选择
Connectivity
->B-L475E-IOT01
。 -
配置Wi-Fi外设。
-
生成初始化代码。
-
在STM32CubeIDE中编写Wi-Fi应用代码。
示例代码
以下是一个简单的Wi-Fi连接示例:
#include "stm32wbxx_hal.h"
#include "wifi.h"
// Wi-Fi初始化函数
void WiFi_Init(void)
{
// 初始化Wi-Fi外设
WiFi_InitTypeDef wifi_init_struct = {0};
wifi_init_struct.p_wifi_env = &WiFiEnv;
wifi_init_struct.p_wifi_hal = &WiFiHal;
HAL_WiFi_Init(&wifi_init_struct);
}
// 连接Wi-Fi网络
void WiFi_Connect(const char *ssid, const char *password)
{
HAL_WiFi_Connect(&WiFiEnv, ssid, password);
}
// 主函数
int main(void)
{
// 初始化HAL库
HAL_Init();
// 初始化系统时钟
SystemClock_Config();
// 初始化Wi-Fi
WiFi_Init();
// 连接Wi-Fi网络
WiFi_Connect("YourSSID", "YourPassword");
while (1)
{
// 检查Wi-Fi连接状态
if (HAL_WiFi_IsConnected(&WiFiEnv))
{
HAL_UART_Transmit(&huart1, (uint8_t *)"Wi-Fi Connected\r\n", 16, HAL_MAX_DELAY);
}
else
{
HAL_UART_Transmit(&huart1, (uint8_t *)"Wi-Fi Not Connected\r\n", 21, HAL_MAX_DELAY);
}
// 延时1秒
HAL_Delay(1000);
}
}
// 系统时钟配置函数
void SystemClock_Config(void)
{
// 配置系统时钟为默认值
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化外设时钟
HAL_RCC_OscConfig(RCC_OscInitStruct);
HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_1);
}
7. 常见问题及解决方法
7.1 项目编译失败
解决方法
-
检查项目依赖项是否正确配置。
-
确保所有必要的头文件和库文件已包含。
-
检查编译器选项和宏定义是否正确。
7.2 调试器无法连接
解决方法
-
检查调试器连接是否正确。
-
确保调试器驱动已安装。
-
检查电源和复位引脚是否正确配置。
7.3 BLE/Wi-Fi功能不正常
解决方法
-
检查外设配置是否正确。
-
确保固件库和中间件已正确安装。
-
检查外设时钟是否已使能。
8. 进阶配置
8.1 优化项目设置
步骤
-
配置编译器优化级别:
-
选择
Project
->Properties
->C/C++ Build
->Settings
。 -
在
Tool Settings
选项卡中选择ARM GCC Compiler
。 -
配置优化级别,例如
-O2
。 -
配置链接器选项:
-
选择
Project
->Properties
->C/C++ Build
->Settings
。 -
在
Tool Settings
选项卡中选择ARM GCC Linker
。 -
配置链接器脚本和库路径。
示例
假设你希望提高代码的执行效率,可以配置编译器优化级别为-O2
:
-
打开项目属性:
- 选择
Project
->Properties
。 -
选择
C/C++ Build
->Settings
。 -
在
Tool Settings
选项卡中选择ARM GCC Compiler
。 -
在
Optimization
部分,选择Optimization Level
为-O2
。
8.2 使用FreeRTOS
步骤
-
在STM32CubeMX中选择FreeRTOS:
-
打开STM32CubeMX。
-
选择
Middleware
->FreeRTOS
。 -
配置FreeRTOS参数,例如任务优先级、任务堆栈大小等。
-
生成初始化代码:
-
选择
Project
->Generate Code
。 -
选择
STM32CubeIDE
作为生成目标。 -
选择生成路径。
-
点击
Generate
。 -
在STM32CubeIDE中编写FreeRTOS任务:
-
打开生成的项目。
-
创建FreeRTOS任务。
示例代码
以下是一个简单的FreeRTOS任务示例:
#include "stm32wbxx_hal.h"
#include "freertos.h"
#include "task.h"
// 任务1
void Task1(void *pvParameters)
{
while (1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
// 任务2
void Task2(void *pvParameters)
{
while (1)
{
HAL_UART_Transmit(&huart1, (uint8_t *)"Task 2 Running\r\n", 16, HAL_MAX_DELAY);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
// 主函数
int main(void)
{
// 初始化HAL库
HAL_Init();
// 初始化系统时钟
SystemClock_Config();
// 创建任务1
xTaskCreate(Task1, "Task1", 128, NULL, 1, NULL);
// 创建任务2
xTaskCreate(Task2, "Task2", 128, NULL, 2, NULL);
// 启动调度器
vTaskStartScheduler();
// 应该不会到达这里
while (1)
{
}
}
// 系统时钟配置函数
void SystemClock_Config(void)
{
// 配置系统时钟为默认值
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化外设时钟
HAL_RCC_OscConfig(RCC_OscInitStruct);
HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_1);
}
8.3 使用ST-MEMS传感器
步骤
-
在STM32CubeMX中选择I2C外设:
-
打开STM32CubeMX。
-
选择
Peripherals
->I2C
。 -
配置I2C外设,连接到ST-MEMS传感器。
-
生成初始化代码:
-
选择
Project
->Generate Code
。 -
选择
STM32CubeIDE
作为生成目标。 -
选择生成路径。
-
点击
Generate
。 -
在STM32CubeIDE中编写传感器读取代码:
-
打开生成的项目。
-
编写读取传感器数据的代码。
示例代码
以下是一个简单的ST-MEMS传感器读取示例:
#include "stm32wbxx_hal.h"
#include "lsm6dsox.h"
// I2C初始化函数
void I2C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
I2C_InitTypeDef I2C_InitStruct = {0};
// 使能GPIOB时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
// 使能I2C1时钟
__HAL_RCC_I2C1_CLK_ENABLE();
// 配置I2C1的SCL和SDA引脚
GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置I2C1
I2C_InitStruct.Timing = 0x00C00A0A;
I2C_InitStruct.OwnAddress1 = 0;
I2C_InitStruct.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2C_InitStruct.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2C_InitStruct.OwnAddress2 = 0;
I2C_InitStruct.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2C_InitStruct.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c1, &I2C_InitStruct);
}
// 读取传感器数据
void ReadSensorData(void)
{
uint8_t data[6];
int16_t acc_x, acc_y, acc_z;
// 读取加速度计数据
lsm6dsox_read_reg(&hi2c1, LSM6DSOX_OUTX_L_XL, data, 6);
// 解析数据
acc_x = (int16_t)((data[1] << 8) | data[0]);
acc_y = (int16_t)((data[3] << 8) | data[2]);
acc_z = (int16_t)((data[5] << 8) | data[4]);
// 打印数据
char buffer[50];
sprintf(buffer, "Acc X: %d, Acc Y: %d, Acc Z: %d\r\n", acc_x, acc_y, acc_z);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
}
// 主函数
int main(void)
{
// 初始化HAL库
HAL_Init();
// 初始化系统时钟
SystemClock_Config();
// 初始化I2C
I2C_Init();
// 初始化UART
USART1_Init();
while (1)
{
// 读取传感器数据
ReadSensorData();
// 延时1秒
HAL_Delay(1000);
}
}
// 系统时钟配置函数
void SystemClock_Config(void)
{
// 配置系统时钟为默认值
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化外设时钟
HAL_RCC_OscConfig(RCC_OscInitStruct);
HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_1);
}
// USART1初始化函数
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
UART_InitTypeDef UART_InitStruct = {0};
// 使能GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 使能USART1时钟
__HAL_RCC_USART1_CLK_ENABLE();
// 配置USART1的TX和RX引脚
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置USART1
UART_InitStruct.BaudRate = 115200;
UART_InitStruct.WordLength = UART_WORDLENGTH_8B;
UART_InitStruct.StopBits = UART_STOPBITS_1;
UART_InitStruct.Parity = UART_PARITY_NONE;
UART_InitStruct.HwFlowCtl = UART_HWCONTROL_NONE;
UART_InitStruct.Mode = UART_MODE_TX_RX;
HAL_UART_Init(&huart1, &UART_InitStruct);
}
8.4 使用DFU(Device Firmware Update)功能
步骤
-
在STM32CubeMX中启用DFU:
-
打开STM32CubeMX。
-
选择
Project
->Settings
->USB
。 -
启用DFU功能。
-
生成初始化代码:
-
选择
Project
->Generate Code
。 -
选择
STM32CubeIDE
作为生成目标。 -
选择生成路径。
-
点击
Generate
。 -
在STM32CubeIDE中编写DFU相关代码:
-
打开生成的项目。
-
编写DFU相关的初始化和处理代码。
示例代码
以下是一个简单的DFU初始化示例:
#include "stm32wbxx_hal.h"
#include "usbd_dfu.h"
// DFU初始化函数
void DFU_Init(void)
{
// 初始化USB DFU外设
USBD_Init(&hUsbDeviceFS, &DFU_Desc, 0);
USBD_RegisterClass(&hUsbDeviceFS, USBD_DFU_CLASS);
USBD_DFU_RegisterInterface(&hUsbDeviceFS, (uint8_t *)&DFU_Interface);
}
// 主函数
int main(void)
{
// 初始化HAL库
HAL_Init();
// 初始化系统时钟
SystemClock_Config();
// 初始化DFU
DFU_Init();
while (1)
{
// DFU处理函数
USBD_DFU_Process(&hUsbDeviceFS);
// 翻转GPIOA的引脚0
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
// 延时500毫秒
HAL_Delay(500);
}
}
// 系统时钟配置函数
void SystemClock_Config(void)
{
// 配置系统时钟为默认值
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 初始化外设时钟
HAL_RCC_OscConfig(RCC_OscInitStruct);
HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_1);
}
9. 总结
通过上述步骤,你可以成功设置和配置STM32WB系列的软件开发环境,并编写、编译、调试和编程你的项目。STM32CubeIDE和STM32CubeMX提供了强大的工具支持,使开发过程更加高效和便捷。此外,通过使用FreeRTOS、ST-MEMS传感器和DFU功能,你可以进一步扩展你的应用,实现更复杂的功能和优化系统性能。
希望本文档对你的STM32WB系列开发有所帮助。如果你遇到任何问题,可以参考STMicroelectronics的官方文档和社区论坛,获取更多的技术支持和帮助。
作者:kkchenkx