文档
STM32G070RB Nucleo-64 代码例程
本文档覆盖 HAL 库例程,重点展示 G0 系列特色:HSI16 无晶振运行、LPUART 低功耗唤醒、双 Bank Flash OTA、Arduino 兼容编程。
一、STM32CubeIDE / HAL 库例程
1.1 64MHz HSI16 无晶振时钟配置
/* main.c - G070 使用 HSI16 + PLL = 64MHz(无需外部晶振!) */
#include "main.h"
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* 使用 HSI16,不需要 HSE */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; // HSI16 → PLL
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; // ÷1 = 16MHz
RCC_OscInitStruct.PLL.PLLN = 8; // ×8 = 128MHz
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // ÷2 = 64MHz
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; // ÷2 = 64MHz (SYSCLK)
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 64MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 64MHz
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2WS); // G0: 64MHz=2WS
}
1.2 LED 闪烁(板载 PA5 = Arduino D13)
/* G070 Nucleo LED Blink - 最简单的开始 */
#include "main.h"
static void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5; // LD1 用户LED
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_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(500);
}
}
1.3 用户按键 + LED 交互
/* B1 按键 (PC13) 控制 LED (PA5) */
#include "main.h"
static void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* PA5 - LED 输出 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
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);
/* PC13 - B1 按键输入(按下为低) */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP; // 内部上拉
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET)
{
HAL_Delay(20); // 消抖
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET); // 等待释放
}
}
}
}
1.4 USART2 虚拟串口通信(通过 ST-LINK VCP)
/* USART2 通过 ST-LINK VCP 与 PC 通信 */
/* PA2(TX), PA3(RX) - 已连接到板载 ST-LINK 虚拟串口 */
#include "main.h"
#include <stdio.h>
UART_HandleTypeDef huart2;
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
/* printf 重定向到 USART2 */
int __io_putchar(int ch)
{
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 10);
return ch;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_USART2_UART_Init();
uint32_t count = 0;
printf("STM32G070 Nucleo-64 Ready!\r\n");
printf("System Clock: %lu Hz\r\n", HAL_RCC_GetSysClockFreq());
while (1)
{
printf("Uptime: %lu seconds\r\n", count++);
HAL_Delay(1000);
}
}
1.5 LPUART 低功耗串口
/* LPUART1 - G0 特色:可在 STOP 模式下唤醒 MCU */
/* 典型应用:电池供电的传感器节点,平时休眠,串口收到数据时唤醒 */
#include "main.h"
LPUART_HandleTypeDef hlpuart1;
void LPUART1_Init(void)
{
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 9600; // LPUART 波特率有限
hlpuart1.Init.WordLength = LPUART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = LPUART_STOPBITS_1;
hlpuart1.Init.Parity = LPUART_PARITY_NONE;
hlpuart1.Init.Mode = LPUART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = LPUART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = LPUART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.Init.ClockPrescaler = LPUART_PRESCALER_DIV1;
hlpuart1.AdvancedInit.AdvFeatureInit = LPUART_ADVFEATURE_NO_INIT;
HAL_LPUART_Init(&hlpuart1);
/* 使能 LPUART 唤醒 STOP 模式 */
HAL_LPUARTEx_EnableStopMode(&hlpuart1);
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); /* 可选额外唤醒源 */
}
/* 进入 STOP 模式,等待 LPUART 唤醒 */
void Enter_StopMode(void)
{
printf("Entering STOP mode...\r\n");
HAL_Delay(10);
/* 挂起 SysTick 避免唤醒 */
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
/* 唤醒后恢复 */
SystemClock_Config(); // 重新配置时钟(STOP 后 HSI/PLL 停了)
HAL_ResumeTick();
printf("Woken up by LPUART!\r\n");
}
1.6 I2C OLED + Arduino 兼容编程
/* 使用 Arduino 兼容引脚 A4(PB7-SDA), A5(PB6-SCL) 驱动 SSD1306 OLED */
#include "main.h"
I2C_HandleTypeDef hi2c1;
/* I2C1 初始化 - 与 Arduino Shield 引脚兼容 */
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00707CBB; // 100KHz @ 64MHz (CubeMX 自动计算)
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c1);
}
/* SSD1306 简单测试 */
void SSD1306_Test(void)
{
uint8_t init_cmds[] = {
0x00, 0xAE, // Display OFF
0x00, 0xD5, 0x80, // Clock
0x00, 0xA8, 0x3F, // Mux
0x00, 0xD3, 0x00, // Offset
0x00, 0x40, // Start Line
0x00, 0x8D, 0x14, // Charge Pump
0x00, 0x20, 0x00, // Horizontal Mode
0x00, 0xA1, // Segment Remap
0x00, 0xC8, // COM Scan
0x00, 0xDA, 0x12, // COM Pins
0x00, 0x81, 0xCF, // Contrast
0x00, 0xD9, 0xF1, // Pre-charge
0x00, 0xDB, 0x40, // VCOMH
0x00, 0xA4, // Display All On Resume
0x00, 0xA6, // Normal Display
0x00, 0xAF // Display ON
};
for (int i = 0; i < sizeof(init_cmds); i += 2)
{
HAL_I2C_Master_Transmit(&hi2c1, 0x3C << 1,
&init_cmds[i + 1], 1, 100);
}
}
1.7 ADC 读取(PA0 = Arduino A0)
/* ADC 读取模拟量,通过 VCP 输出 */
ADC_HandleTypeDef hadc1;
static void MX_ADC1_Init(void)
{
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1; // 64MHz
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
HAL_ADC_Init(&hadc1);
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0; // PA0
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_160CYCLES_5; // 长采样提高精度
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
float Read_ADC_Voltage(void)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 10);
uint32_t val = HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
return val * 3.3f / 4096.0f;
}
二、Arduino IDE 编程(STM32duino)
Nucleo G070 同样支持 STM32duino,Board 选择
Nucleo-64 G070RB
/* Arduino 风格 - 完全兼容 Shield 生态 */
void setup()
{
pinMode(PA5, OUTPUT); // D13 用户 LED
pinMode(PC13, INPUT_PULLUP); // B1 用户按键
Serial.begin(115200); // 通过 ST-LINK VCP
}
void loop()
{
digitalWrite(PA5, !digitalRead(PA5)); // 翻转 LED
Serial.println("Nucleo G070 with Arduino!");
delay(500);
}
三、PlatformIO 配置
; platformio.ini - Nucleo G070RB
[env:nucleo_g070rb]
platform = ststm32
board = nucleo_g070rb
framework = arduino
; framework = stm32cube ; 使用 HAL 框架
upload_protocol = stlink
monitor_speed = 115200
; 使用内置 ST-LINK,无需额外烧录器
四、STM32CubeProgrammer 拖拽烧录
Nucleo ST-LINK 支持大容量存储烧录:
1. 编译生成 .bin 文件
2. 将 Nucleo 通过 USB 连接到电脑
3. 电脑出现 "NODE_G070RB" 虚拟 U 盘
4. 拖拽 .bin 文件到该 U 盘
5. 自动烧录并复位运行
无需安装任何软件!这是最快最方便的烧录方式。
五、G0 系列特色功能总结
| 功能 | 说明 |
|---|---|
| HSI16 ±1% | 无需外部晶振即可可靠运行串口通信 |
| LPUART | 支持 STOP 模式唤醒,电池供电神器 |
| 双 Bank Flash | 安全 OTA 固件升级 |
| USB PD 3.0 | 支持 USB Power Delivery(需外部 PHY) |
| 低功耗 | STOP < 2μA, STANDBY < 0.5μA |
| 快速 ADC | 0.4μs 转换时间,2.5Msps |