# STM32G4xx HAL 库函数文档 ## 项目简介 STM32G4xx HAL(Hardware Abstraction Layer,硬件抽象层)库是STMicroelectronics为STM32G4系列微控制器提供的标准化固件库。该库基于ARM Cortex-M4内核,专为电机控制、数字电源转换和高性能混合信号应用而设计。本文档库包含完整的HAL和LL(Low-Layer)驱动函数手册,提供了详细的API参考、数据结构定义和外设配置示例。 STM32G4系列微控制器运行频率高达170MHz,集成了高精度ADC(16位Σ-Δ和12位SAR)、数学加速器(CORDIC和FMAC)、高分辨率定时器(HRTIM,184ps分辨率)以及先进的通信接口(FDCAN、USB Type-C/PD)。该文档库专门针对大模型MCP协议优化,支持智能检索和代码生成,包含三个主要型号的用户手册:STM32G431xx、STM32G474xx和STM32G491xx。 ## API 文档与代码示例 ### GPIO 通用输入输出配置 GPIO(General Purpose Input/Output)是微控制器最基本的外设,用于控制引脚的输入输出状态。HAL库提供了完整的GPIO配置和操作函数,支持多种模式(输入、输出、复用功能、模拟)和不同的电气特性(上拉、下拉、开漏、推挽)。 ```c #include "stm32g4xx_hal.h" // 示例:配置LED和按钮 void GPIO_LED_Button_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; // 1. 使能GPIO时钟 __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); // 2. 配置LED引脚(PA5)为推挽输出 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); // 3. 配置按钮引脚(PC13)为输入,带上拉电阻 GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); // 4. 设置LED初始状态为关闭 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); } // LED控制和按钮读取 void GPIO_Control_Example(void) { // 点亮LED HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); // 翻转LED状态 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // 读取按钮状态 GPIO_PinState button_state = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13); if (button_state == GPIO_PIN_RESET) { // 按钮被按下(低电平) HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); } // 配置外部中断触发 GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发中断 GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2, 0); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); } // GPIO中断回调函数 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == GPIO_PIN_13) { // 按钮中断处理 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); } } ``` ### UART 串口通信 UART(Universal Asynchronous Receiver/Transmitter)用于串行通信,支持轮询、中断和DMA三种传输模式。HAL库提供了灵活的UART配置函数,支持多种波特率、数据位、停止位和校验位配置。 ```c #include "stm32g4xx_hal.h" #include UART_HandleTypeDef huart2; uint8_t rx_buffer[128]; uint8_t tx_buffer[128]; // UART初始化配置 HAL_StatusTypeDef UART_Init_Example(void) { // 1. 配置UART参数 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; huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; // 2. 初始化UART if (HAL_UART_Init(&huart2) != HAL_OK) { return HAL_ERROR; } return HAL_OK; } // UART轮询发送和接收 void UART_Polling_Example(void) { const char* msg = "Hello STM32G4!\r\n"; // 轮询发送数据(超时时间1000ms) HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 1000); // 轮询接收数据(等待接收10字节,超时5000ms) if (HAL_UART_Receive(&huart2, rx_buffer, 10, 5000) == HAL_OK) { // 接收成功,回显数据 HAL_UART_Transmit(&huart2, rx_buffer, 10, 1000); } } // UART中断模式 void UART_Interrupt_Example(void) { // 启动中断接收(接收1字节) HAL_UART_Receive_IT(&huart2, rx_buffer, 1); // 中断发送 const char* response = "Data received\r\n"; HAL_UART_Transmit_IT(&huart2, (uint8_t*)response, strlen(response)); } // UART接收完成回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART2) { // 回显接收到的字符 HAL_UART_Transmit_IT(&huart2, rx_buffer, 1); // 重新启动接收 HAL_UART_Receive_IT(&huart2, rx_buffer, 1); } } // UART DMA模式(高效传输大量数据) void UART_DMA_Example(void) { const char* large_data = "Large data transmission via DMA...\r\n"; // DMA发送 HAL_UART_Transmit_DMA(&huart2, (uint8_t*)large_data, strlen(large_data)); // DMA接收(接收128字节) HAL_UART_Receive_DMA(&huart2, rx_buffer, 128); } ``` ### ADC 模数转换器 STM32G4系列具有高性能ADC,包括12位SAR ADC(高速)和16位Σ-Δ ADC(高精度)。HAL库支持单次转换、连续转换、扫描模式和DMA传输,适用于多通道采样和高速数据采集。 ```c #include "stm32g4xx_hal.h" ADC_HandleTypeDef hadc1; uint32_t adc_value; uint32_t adc_values[4]; // 多通道采样缓冲区 // ADC单通道初始化 HAL_StatusTypeDef ADC_SingleChannel_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; // 1. 配置ADC基本参数 hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.GainCompensation = 0; hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc1.Init.LowPowerAutoWait = 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; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED; hadc1.Init.OversamplingMode = DISABLE; if (HAL_ADC_Init(&hadc1) != HAL_OK) { return HAL_ERROR; } // 2. 配置ADC通道(PA0 = ADC1_IN1) sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; sConfig.SingleDiff = ADC_SINGLE_ENDED; sConfig.OffsetNumber = ADC_OFFSET_NONE; sConfig.Offset = 0; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { return HAL_ERROR; } // 3. 校准ADC HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED); return HAL_OK; } // ADC单次转换 uint32_t ADC_Read_SingleConversion(void) { // 启动ADC转换 HAL_ADC_Start(&hadc1); // 等待转换完成(超时1000ms) if (HAL_ADC_PollForConversion(&hadc1, 1000) == HAL_OK) { // 读取转换结果(0-4095) adc_value = HAL_ADC_GetValue(&hadc1); } // 停止ADC HAL_ADC_Stop(&hadc1); return adc_value; } // ADC多通道扫描模式(使用DMA) HAL_StatusTypeDef ADC_MultiChannel_DMA_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; // 配置ADC扫描模式 hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.NbrOfConversion = 4; hadc1.Init.DMAContinuousRequests = ENABLE; if (HAL_ADC_Init(&hadc1) != HAL_OK) { return HAL_ERROR; } // 配置通道1 sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 配置通道2 sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = ADC_REGULAR_RANK_2; HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 配置通道3 sConfig.Channel = ADC_CHANNEL_3; sConfig.Rank = ADC_REGULAR_RANK_3; HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 配置通道4 sConfig.Channel = ADC_CHANNEL_4; sConfig.Rank = ADC_REGULAR_RANK_4; HAL_ADC_ConfigChannel(&hadc1, &sConfig); // 启动ADC DMA连续转换 HAL_ADC_Start_DMA(&hadc1, adc_values, 4); return HAL_OK; } // 将ADC值转换为电压(3.3V参考电压) float ADC_ToVoltage(uint32_t adc_val) { return (float)adc_val * 3.3f / 4096.0f; } // ADC转换完成回调 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if (hadc->Instance == ADC1) { // 处理采样数据 float voltage1 = ADC_ToVoltage(adc_values[0]); float voltage2 = ADC_ToVoltage(adc_values[1]); float voltage3 = ADC_ToVoltage(adc_values[2]); float voltage4 = ADC_ToVoltage(adc_values[3]); } } ``` ### TIM 定时器和PWM输出 定时器是STM32的核心外设之一,支持基本定时、PWM输出、输入捕获、输出比较等功能。STM32G4系列包含通用定时器(TIM2-4、TIM15-17)、高级定时器(TIM1/8)和高分辨率定时器(HRTIM)。 ```c #include "stm32g4xx_hal.h" TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim3; // 基本定时器配置(1ms中断) HAL_StatusTypeDef TIM_Basic_Init(void) { // 配置定时器2,1ms中断(假设系统时钟170MHz) htim2.Instance = TIM2; htim2.Init.Prescaler = 17000 - 1; // 分频:170MHz / 17000 = 10kHz htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 10 - 1; // 周期:10kHz / 10 = 1kHz (1ms) htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { return HAL_ERROR; } // 启动定时器中断 HAL_TIM_Base_Start_IT(&htim2); return HAL_OK; } // 定时器中断回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { static uint32_t counter = 0; if (htim->Instance == TIM2) { counter++; // 每1000ms(1秒)执行一次 if (counter >= 1000) { counter = 0; HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); } } } // PWM输出配置(用于LED调光、电机控制) HAL_StatusTypeDef TIM_PWM_Init(void) { TIM_OC_InitTypeDef sConfigOC = {0}; // 1. 配置定时器3,PWM频率1kHz htim3.Instance = TIM3; htim3.Init.Prescaler = 170 - 1; // 170MHz / 170 = 1MHz htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 1000 - 1; // 1MHz / 1000 = 1kHz PWM频率 htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) { return HAL_ERROR; } // 2. 配置PWM通道1(PA6 = TIM3_CH1) sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 500; // 占空比50%(500/1000) sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { return HAL_ERROR; } // 3. 启动PWM输出 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); return HAL_OK; } // 动态调整PWM占空比(0-100%) void TIM_SetPWM_DutyCycle(uint8_t duty_percent) { uint32_t pulse_value; // 限制占空比范围 if (duty_percent > 100) duty_percent = 100; // 计算脉冲值 pulse_value = (htim3.Init.Period + 1) * duty_percent / 100; // 更新比较寄存器(占空比) __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, pulse_value); } // PWM呼吸灯效果 void TIM_PWM_BreathingLED(void) { static uint8_t duty = 0; static int8_t direction = 1; // 调整占空比 TIM_SetPWM_DutyCycle(duty); // 改变方向 duty += direction * 5; if (duty >= 100) direction = -1; if (duty == 0) direction = 1; HAL_Delay(30); // 延时30ms } // 输入捕获模式(测量频率和占空比) HAL_StatusTypeDef TIM_InputCapture_Init(void) { TIM_IC_InitTypeDef sConfigIC = {0}; htim3.Instance = TIM3; htim3.Init.Prescaler = 170 - 1; // 1MHz时钟 htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 0xFFFF; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_IC_Init(&htim3) != HAL_OK) { return HAL_ERROR; } // 配置输入捕获通道1(上升沿触发) sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_1); // 配置输入捕获通道2(下降沿触发) sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_2); // 启动输入捕获 HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2); return HAL_OK; } ``` ### DMA 直接内存访问 DMA(Direct Memory Access)允许外设直接访问内存,无需CPU干预,极大提高数据传输效率。STM32G4系列具有双DMA控制器和DMAMUX请求路由器,支持灵活的通道配置。 ```c #include "stm32g4xx_hal.h" DMA_HandleTypeDef hdma_memtomem; uint32_t src_buffer[1024]; uint32_t dst_buffer[1024]; // DMA内存到内存传输 HAL_StatusTypeDef DMA_MemToMem_Init(void) { // 使能DMA时钟 __HAL_RCC_DMAMUX1_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); // 配置DMA hdma_memtomem.Instance = DMA1_Channel1; hdma_memtomem.Init.Request = DMA_REQUEST_MEM2MEM; hdma_memtomem.Init.Direction = DMA_MEMORY_TO_MEMORY; hdma_memtomem.Init.PeriphInc = DMA_PINC_ENABLE; hdma_memtomem.Init.MemInc = DMA_MINC_ENABLE; hdma_memtomem.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; hdma_memtomem.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_memtomem.Init.Mode = DMA_NORMAL; hdma_memtomem.Init.Priority = DMA_PRIORITY_HIGH; if (HAL_DMA_Init(&hdma_memtomem) != HAL_OK) { return HAL_ERROR; } // 注册DMA传输完成回调 HAL_DMA_RegisterCallback(&hdma_memtomem, HAL_DMA_XFER_CPLT_CB_ID, DMA_TransferComplete); return HAL_OK; } // 启动DMA传输 void DMA_StartTransfer(void) { // 填充源缓冲区 for (int i = 0; i < 1024; i++) { src_buffer[i] = i; } // 启动DMA传输(1024个字,4096字节) HAL_DMA_Start_IT(&hdma_memtomem, (uint32_t)src_buffer, (uint32_t)dst_buffer, 1024); } // DMA传输完成回调 void DMA_TransferComplete(DMA_HandleTypeDef *hdma) { // 验证数据传输正确性 for (int i = 0; i < 1024; i++) { if (src_buffer[i] != dst_buffer[i]) { // 传输错误 Error_Handler(); } } // 传输成功 } // ADC + DMA连续采样(高速数据采集) void ADC_DMA_ContinuousSampling(void) { uint32_t adc_buffer[1000]; // 配置ADC连续模式 hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DMAContinuousRequests = ENABLE; HAL_ADC_Init(&hadc1); // 启动ADC DMA采样(采集1000个样本) HAL_ADC_Start_DMA(&hadc1, adc_buffer, 1000); // DMA完成后自动触发回调HAL_ADC_ConvCpltCallback } ``` ### RCC 时钟配置 RCC(Reset and Clock Control)负责系统时钟配置和外设时钟使能。STM32G4支持多种时钟源(HSI、HSE、PLL)和灵活的时钟树配置,最高系统时钟可达170MHz。 ```c #include "stm32g4xx_hal.h" // 系统时钟配置为170MHz(使用HSE和PLL) void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // 1. 配置电源调节器输出电压(Boost模式支持170MHz) HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); // 2. 配置振荡器 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6; // 24MHz / 6 = 4MHz RCC_OscInitStruct.PLL.PLLN = 85; // 4MHz * 85 = 340MHz RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; // 340MHz / 2 = 170MHz RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } // 3. 配置系统时钟 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 170MHz RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 170MHz RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 170MHz if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8) != HAL_OK) { Error_Handler(); } } // 使能外设时钟 void RCC_PeripheralClock_Enable(void) { // GPIO时钟 __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); // 定时器时钟 __HAL_RCC_TIM2_CLK_ENABLE(); __HAL_RCC_TIM3_CLK_ENABLE(); // UART时钟 __HAL_RCC_USART2_CLK_ENABLE(); // ADC时钟 __HAL_RCC_ADC12_CLK_ENABLE(); // DMA时钟 __HAL_RCC_DMA1_CLK_ENABLE(); __HAL_RCC_DMAMUX1_CLK_ENABLE(); } ``` ### CORDIC 数学加速器 CORDIC(Coordinate Rotation Digital Computer)是STM32G4系列特有的硬件数学加速器,可在几个时钟周期内计算三角函数、双曲函数、平方根和模运算,极大提升计算密集型应用性能。 ```c #include "stm32g4xx_hal.h" #include CORDIC_HandleTypeDef hcordic; // CORDIC初始化 HAL_StatusTypeDef CORDIC_Init_Example(void) { // 使能CORDIC时钟 __HAL_RCC_CORDIC_CLK_ENABLE(); hcordic.Instance = CORDIC; if (HAL_CORDIC_Init(&hcordic) != HAL_OK) { return HAL_ERROR; } return HAL_OK; } // 计算正弦和余弦值(硬件加速) HAL_StatusTypeDef CORDIC_Calculate_Sin_Cos(float angle_rad, float* sin_val, float* cos_val) { int32_t input_q31; int32_t output_q31[2]; // 1. 配置CORDIC计算正弦和余弦 CORDIC_ConfigTypeDef sConfig; sConfig.Function = CORDIC_FUNCTION_COSINE; // 同时输出cos和sin sConfig.Precision = CORDIC_PRECISION_6CYCLES; // 6个周期,精度约0.1% sConfig.Scale = CORDIC_SCALE_0; // 输入范围[-1, 1]对应[-π, π] sConfig.NbWrite = CORDIC_NBWRITE_1; sConfig.NbRead = CORDIC_NBREAD_2; // 读取2个结果(cos和sin) sConfig.InSize = CORDIC_INSIZE_32BITS; sConfig.OutSize = CORDIC_OUTSIZE_32BITS; HAL_CORDIC_Configure(&hcordic, &sConfig); // 2. 转换角度为Q1.31格式(-1.0到1.0映射到-π到π) input_q31 = (int32_t)(angle_rad / M_PI * 2147483648.0f); // 3. 执行CORDIC计算(阻塞模式) if (HAL_CORDIC_Calculate(&hcordic, &input_q31, output_q31, 1, 1000) != HAL_OK) { return HAL_ERROR; } // 4. 转换Q1.31结果为浮点数 *cos_val = (float)output_q31[0] / 2147483648.0f; *sin_val = (float)output_q31[1] / 2147483648.0f; return HAL_OK; } // 计算模和相位(用于矢量控制) HAL_StatusTypeDef CORDIC_Calculate_Magnitude_Phase(float x, float y, float* magnitude, float* phase) { int32_t input_q31[2]; int32_t output_q31[2]; // 配置CORDIC计算模和相位 CORDIC_ConfigTypeDef sConfig; sConfig.Function = CORDIC_FUNCTION_PHASE; sConfig.Precision = CORDIC_PRECISION_6CYCLES; sConfig.Scale = CORDIC_SCALE_0; sConfig.NbWrite = CORDIC_NBWRITE_2; sConfig.NbRead = CORDIC_NBREAD_2; sConfig.InSize = CORDIC_INSIZE_32BITS; sConfig.OutSize = CORDIC_OUTSIZE_32BITS; HAL_CORDIC_Configure(&hcordic, &sConfig); // 转换输入为Q1.31格式 input_q31[0] = (int32_t)(x * 2147483648.0f); input_q31[1] = (int32_t)(y * 2147483648.0f); // 执行计算 if (HAL_CORDIC_Calculate(&hcordic, input_q31, output_q31, 1, 1000) != HAL_OK) { return HAL_ERROR; } // 转换结果 *magnitude = (float)output_q31[0] / 2147483648.0f; *phase = (float)output_q31[1] / 2147483648.0f * M_PI; return HAL_OK; } // 电机控制中的Clarke和Park变换(使用CORDIC加速) void Motor_Control_Clarke_Park_Transform(float Ia, float Ib, float theta, float* Id, float* Iq) { float sin_theta, cos_theta; float I_alpha, I_beta; // Clarke变换:三相到两相静止坐标系 I_alpha = Ia; I_beta = (Ia + 2.0f * Ib) / sqrtf(3.0f); // Park变换:静止坐标系到旋转坐标系(使用CORDIC加速) CORDIC_Calculate_Sin_Cos(theta, &sin_theta, &cos_theta); *Id = I_alpha * cos_theta + I_beta * sin_theta; *Iq = -I_alpha * sin_theta + I_beta * cos_theta; } ``` ### FDCAN 灵活数据速率CAN总线 FDCAN(Flexible Data-rate CAN)是CAN 2.0的升级版本,支持更高的数据速率和更大的数据载荷。STM32G4系列集成了FDCAN外设,适用于汽车电子和工业控制。 ```c #include "stm32g4xx_hal.h" FDCAN_HandleTypeDef hfdcan1; FDCAN_TxHeaderTypeDef TxHeader; FDCAN_RxHeaderTypeDef RxHeader; uint8_t TxData[64]; uint8_t RxData[64]; // FDCAN初始化配置 HAL_StatusTypeDef FDCAN_Init_Example(void) { // 1. 配置FDCAN基本参数 hfdcan1.Instance = FDCAN1; hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS; // FD格式,支持位速率切换 hfdcan1.Init.Mode = FDCAN_MODE_NORMAL; hfdcan1.Init.AutoRetransmission = ENABLE; hfdcan1.Init.TransmitPause = DISABLE; hfdcan1.Init.ProtocolException = DISABLE; // 2. 配置仲裁段位时序(1Mbps) hfdcan1.Init.NominalPrescaler = 10; hfdcan1.Init.NominalSyncJumpWidth = 1; hfdcan1.Init.NominalTimeSeg1 = 13; hfdcan1.Init.NominalTimeSeg2 = 2; // 3. 配置数据段位时序(5Mbps) hfdcan1.Init.DataPrescaler = 2; hfdcan1.Init.DataSyncJumpWidth = 1; hfdcan1.Init.DataTimeSeg1 = 13; hfdcan1.Init.DataTimeSeg2 = 2; // 4. 配置RAM分配 hfdcan1.Init.MessageRAMOffset = 0; hfdcan1.Init.StdFiltersNbr = 1; hfdcan1.Init.ExtFiltersNbr = 0; hfdcan1.Init.RxFifo0ElmtsNbr = 10; hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8; hfdcan1.Init.RxFifo1ElmtsNbr = 0; hfdcan1.Init.RxBuffersNbr = 0; hfdcan1.Init.TxEventsNbr = 0; hfdcan1.Init.TxBuffersNbr = 0; hfdcan1.Init.TxFifoQueueElmtsNbr = 10; hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8; if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK) { return HAL_ERROR; } // 5. 配置接收过滤器(接受ID为0x123的报文) FDCAN_FilterTypeDef sFilterConfig; sFilterConfig.IdType = FDCAN_STANDARD_ID; sFilterConfig.FilterIndex = 0; sFilterConfig.FilterType = FDCAN_FILTER_MASK; sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; sFilterConfig.FilterID1 = 0x123; sFilterConfig.FilterID2 = 0x7FF; // 精确匹配 if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK) { return HAL_ERROR; } // 6. 启动FDCAN if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK) { return HAL_ERROR; } // 7. 激活接收中断 if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK) { return HAL_ERROR; } return HAL_OK; } // FDCAN发送数据 HAL_StatusTypeDef FDCAN_Transmit_Data(uint32_t id, uint8_t* data, uint32_t len) { // 配置发送头 TxHeader.Identifier = id; TxHeader.IdType = FDCAN_STANDARD_ID; TxHeader.TxFrameType = FDCAN_DATA_FRAME; TxHeader.DataLength = len << 16; // 数据长度编码 TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE; TxHeader.BitRateSwitch = FDCAN_BRS_ON; // 使能位速率切换 TxHeader.FDFormat = FDCAN_FD_CAN; TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; TxHeader.MessageMarker = 0; // 发送数据 if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, data) != HAL_OK) { return HAL_ERROR; } return HAL_OK; } // FDCAN接收中断回调 void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) { if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != 0) { // 读取接收数据 if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) { // 处理接收到的数据 uint32_t id = RxHeader.Identifier; uint32_t dlc = RxHeader.DataLength >> 16; // 回显数据(将接收的数据发送回去) FDCAN_Transmit_Data(id + 1, RxData, dlc); } } } // FDCAN发送传感器数据示例 void FDCAN_SendSensorData(void) { uint8_t sensor_data[8]; uint16_t temperature = 2500; // 25.00°C(放大100倍) uint16_t pressure = 10132; // 1013.2 hPa // 打包数据(小端格式) sensor_data[0] = temperature & 0xFF; sensor_data[1] = (temperature >> 8) & 0xFF; sensor_data[2] = pressure & 0xFF; sensor_data[3] = (pressure >> 8) & 0xFF; sensor_data[4] = 0x00; sensor_data[5] = 0x00; sensor_data[6] = 0x00; sensor_data[7] = 0x00; // 发送CAN报文(ID=0x200) FDCAN_Transmit_Data(0x200, sensor_data, 8); } ``` ### HRTIM 高分辨率定时器 HRTIM(High-Resolution Timer)是STM32G4系列的高级特性,提供184ps的时间分辨率,专为电机控制、数字电源和开关电源应用设计,支持复杂的PWM波形生成和死区时间控制。 ```c #include "stm32g4xx_hal.h" HRTIM_HandleTypeDef hhrtim1; // HRTIM初始化(用于三相电机PWM输出) HAL_StatusTypeDef HRTIM_ThreePhase_PWM_Init(void) { HRTIM_TimeBaseCfgTypeDef pTimeBaseCfg = {0}; HRTIM_TimerCfgTypeDef pTimerCfg = {0}; HRTIM_OutputCfgTypeDef pOutputCfg = {0}; HRTIM_CompareCfgTypeDef pCompareCfg = {0}; // 1. 初始化HRTIM基础配置 hhrtim1.Instance = HRTIM1; hhrtim1.Init.HRTIMInterruptResquests = HRTIM_IT_NONE; hhrtim1.Init.SyncOptions = HRTIM_SYNCOPTION_NONE; if (HAL_HRTIM_Init(&hhrtim1) != HAL_OK) { return HAL_ERROR; } // 2. 配置定时器A时基(20kHz PWM频率) pTimeBaseCfg.Period = 0x2260; // 约17MHz / 0x2260 = 20kHz pTimeBaseCfg.RepetitionCounter = 0x00; pTimeBaseCfg.PrescalerRatio = HRTIM_PRESCALERRATIO_MUL32; pTimeBaseCfg.Mode = HRTIM_MODE_CONTINUOUS; if (HAL_HRTIM_TimeBaseConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, &pTimeBaseCfg) != HAL_OK) { return HAL_ERROR; } // 同样配置定时器B和C(三相电机) HAL_HRTIM_TimeBaseConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_B, &pTimeBaseCfg); HAL_HRTIM_TimeBaseConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_C, &pTimeBaseCfg); // 3. 配置定时器输出模式 pTimerCfg.InterruptRequests = HRTIM_TIM_IT_NONE; pTimerCfg.DMARequests = HRTIM_TIM_DMA_NONE; pTimerCfg.DMASrcAddress = 0x0000; pTimerCfg.DMADstAddress = 0x0000; pTimerCfg.DMASize = 0x1; pTimerCfg.HalfModeEnable = HRTIM_HALFMODE_DISABLED; pTimerCfg.StartOnSync = HRTIM_SYNCSTART_DISABLED; pTimerCfg.ResetOnSync = HRTIM_SYNCRESET_DISABLED; pTimerCfg.DACSynchro = HRTIM_DACSYNC_NONE; pTimerCfg.PreloadEnable = HRTIM_PRELOAD_ENABLED; pTimerCfg.UpdateGating = HRTIM_UPDATEGATING_INDEPENDENT; pTimerCfg.BurstMode = HRTIM_TIMERBURSTMODE_MAINTAINCLOCK; pTimerCfg.RepetitionUpdate = HRTIM_UPDATEONREPETITION_DISABLED; HAL_HRTIM_WaveformTimerConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, &pTimerCfg); HAL_HRTIM_WaveformTimerConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_B, &pTimerCfg); HAL_HRTIM_WaveformTimerConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_C, &pTimerCfg); // 4. 配置比较单元(初始占空比50%) pCompareCfg.CompareValue = 0x1130; // 50% duty cycle HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, &pCompareCfg); HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, &pCompareCfg); HAL_HRTIM_WaveformCompareConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_1, &pCompareCfg); // 5. 配置输出通道(带死区时间) pOutputCfg.Polarity = HRTIM_OUTPUTPOLARITY_HIGH; pOutputCfg.SetSource = HRTIM_OUTPUTSET_TIMPER; pOutputCfg.ResetSource = HRTIM_OUTPUTRESET_TIMCMP1; pOutputCfg.IdleMode = HRTIM_OUTPUTIDLEMODE_NONE; pOutputCfg.IdleLevel = HRTIM_OUTPUTIDLELEVEL_INACTIVE; pOutputCfg.FaultLevel = HRTIM_OUTPUTFAULTLEVEL_INACTIVE; pOutputCfg.ChopperModeEnable = HRTIM_OUTPUTCHOPPERMODE_DISABLED; pOutputCfg.BurstModeEntryDelayed = HRTIM_OUTPUTBURSTMODEENTRY_REGULAR; HAL_HRTIM_WaveformOutputConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_OUTPUT_TA1, &pOutputCfg); HAL_HRTIM_WaveformOutputConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_B, HRTIM_OUTPUT_TB1, &pOutputCfg); HAL_HRTIM_WaveformOutputConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_C, HRTIM_OUTPUT_TC1, &pOutputCfg); // 6. 配置死区时间(500ns) HRTIM_DeadTimeCfgTypeDef pDeadTimeCfg; pDeadTimeCfg.Prescaler = HRTIM_TIMDEADTIME_PRESCALERRATIO_MUL8; pDeadTimeCfg.RisingValue = 0x08; // 约500ns pDeadTimeCfg.RisingSign = HRTIM_TIMDEADTIME_RISINGSIGN_POSITIVE; pDeadTimeCfg.RisingLock = HRTIM_TIMDEADTIME_RISINGLOCK_WRITE; pDeadTimeCfg.RisingSignLock = HRTIM_TIMDEADTIME_RISINGSIGNLOCK_WRITE; pDeadTimeCfg.FallingValue = 0x08; pDeadTimeCfg.FallingSign = HRTIM_TIMDEADTIME_FALLINGSIGN_POSITIVE; pDeadTimeCfg.FallingLock = HRTIM_TIMDEADTIME_FALLINGLOCK_WRITE; pDeadTimeCfg.FallingSignLock = HRTIM_TIMDEADTIME_FALLINGSIGNLOCK_WRITE; HAL_HRTIM_DeadTimeConfig(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, &pDeadTimeCfg); // 7. 启动HRTIM输出 HAL_HRTIM_WaveformOutputStart(&hhrtim1, HRTIM_OUTPUT_TA1 | HRTIM_OUTPUT_TA2 | HRTIM_OUTPUT_TB1 | HRTIM_OUTPUT_TB2 | HRTIM_OUTPUT_TC1 | HRTIM_OUTPUT_TC2); // 8. 启动HRTIM计数器 HAL_HRTIM_WaveformCounterStart(&hhrtim1, HRTIM_TIMERID_TIMER_A | HRTIM_TIMERID_TIMER_B | HRTIM_TIMERID_TIMER_C); return HAL_OK; } // 动态调整HRTIM占空比(用于SVPWM矢量控制) void HRTIM_SetDutyCycle_ThreePhase(uint16_t duty_A, uint16_t duty_B, uint16_t duty_C) { // 更新比较值(占空比) __HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_A, HRTIM_COMPAREUNIT_1, duty_A); __HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_B, HRTIM_COMPAREUNIT_1, duty_B); __HAL_HRTIM_SETCOMPARE(&hhrtim1, HRTIM_TIMERINDEX_TIMER_C, HRTIM_COMPAREUNIT_1, duty_C); } // SVPWM矢量控制示例(空间矢量调制) void HRTIM_SVPWM_Control(float Valpha, float Vbeta, float Vdc) { float T1, T2, T0; float Ta, Tb, Tc; uint16_t duty_A, duty_B, duty_C; // 计算扇区和时间向量(简化版本) // ... SVPWM算法计算 ... // 计算三相占空比 Ta = 0.5f + (T1 + T2) / 2.0f; Tb = 0.5f + (T2 - T1) / 2.0f; Tc = 0.5f - (T1 + T2) / 2.0f; // 转换为HRTIM比较值 duty_A = (uint16_t)(Ta * 0x2260); duty_B = (uint16_t)(Tb * 0x2260); duty_C = (uint16_t)(Tc * 0x2260); // 更新PWM占空比 HRTIM_SetDutyCycle_ThreePhase(duty_A, duty_B, duty_C); } ``` ### I2C 总线通信 I2C(Inter-Integrated Circuit)是常用的两线式串行通信协议,广泛应用于传感器、EEPROM和其他外设通信。STM32G4的I2C支持标准模式(100kHz)、快速模式(400kHz)和快速模式增强(1MHz)。 ```c #include "stm32g4xx_hal.h" I2C_HandleTypeDef hi2c1; // I2C初始化(快速模式,400kHz) HAL_StatusTypeDef I2C_Init_Example(void) { hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x10909CEC; // 400kHz @ 170MHz SYSCLK 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; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { return HAL_ERROR; } // 配置模拟滤波器 if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { return HAL_ERROR; } // 配置数字滤波器 if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) { return HAL_ERROR; } return HAL_OK; } // I2C读取MPU6050加速度计和陀螺仪数据 HAL_StatusTypeDef I2C_Read_MPU6050(int16_t* accel_x, int16_t* accel_y, int16_t* accel_z, int16_t* gyro_x, int16_t* gyro_y, int16_t* gyro_z) { uint8_t data[14]; uint8_t reg_addr = 0x3B; // ACCEL_XOUT_H寄存器地址 #define MPU6050_ADDR (0x68 << 1) // MPU6050 I2C地址 // 1. 写入寄存器地址 if (HAL_I2C_Master_Transmit(&hi2c1, MPU6050_ADDR, ®_addr, 1, 1000) != HAL_OK) { return HAL_ERROR; } // 2. 读取14字节数据(加速度6字节 + 温度2字节 + 陀螺仪6字节) if (HAL_I2C_Master_Receive(&hi2c1, MPU6050_ADDR, data, 14, 1000) != HAL_OK) { return HAL_ERROR; } // 3. 解析数据(大端格式) *accel_x = (int16_t)((data[0] << 8) | data[1]); *accel_y = (int16_t)((data[2] << 8) | data[3]); *accel_z = (int16_t)((data[4] << 8) | data[5]); // data[6-7]是温度数据 *gyro_x = (int16_t)((data[8] << 8) | data[9]); *gyro_y = (int16_t)((data[10] << 8) | data[11]); *gyro_z = (int16_t)((data[12] << 8) | data[13]); return HAL_OK; } // I2C写入单个寄存器 HAL_StatusTypeDef I2C_Write_Register(uint8_t dev_addr, uint8_t reg_addr, uint8_t value) { uint8_t data[2]; data[0] = reg_addr; data[1] = value; return HAL_I2C_Master_Transmit(&hi2c1, dev_addr, data, 2, 1000); } // I2C读取单个寄存器 HAL_StatusTypeDef I2C_Read_Register(uint8_t dev_addr, uint8_t reg_addr, uint8_t* value) { // 方式1:使用Mem读写函数(推荐) return HAL_I2C_Mem_Read(&hi2c1, dev_addr, reg_addr, I2C_MEMADD_SIZE_8BIT, value, 1, 1000); } // I2C扫描总线上的设备 void I2C_Scan_Devices(void) { uint8_t found_devices = 0; for (uint8_t addr = 1; addr < 128; addr++) { // 尝试与设备通信 if (HAL_I2C_IsDeviceReady(&hi2c1, addr << 1, 1, 10) == HAL_OK) { // 找到设备,输出地址(假设有UART输出函数) printf("I2C device found at address 0x%02X\r\n", addr); found_devices++; } } printf("Total devices found: %d\r\n", found_devices); } ``` ## 主要用例和集成模式 STM32G4xx HAL库广泛应用于电机控制、数字电源、工业自动化和高性能嵌入式系统。在电机控制领域,结合HRTIM高分辨率定时器、CORDIC数学加速器和高精度ADC,可实现高效的FOC(Field-Oriented Control)矢量控制,支持无刷直流电机(BLDC)、永磁同步电机(PMSM)和步进电机的精确控制。HRTIM提供的184ps时间分辨率和可编程死区时间确保了功率开关的安全换流,而CORDIC加速器能在6个时钟周期内完成Clarke和Park变换所需的三角函数计算,相比软件实现提升了数十倍的性能。 在数字电源转换应用中,STM32G4的HRTIM和FMAC(Filter Math Accelerator)滤波器加速器协同工作,实现高精度的开关电源控制。FMAC可执行硬件级别的FIR和IIR滤波运算,用于电流环和电压环的PID控制,响应时间可达纳秒级。高精度16位Σ-Δ ADC提供准确的电压和电流采样,配合DMA实现零CPU开销的连续采样。FDCAN总线支持多电源模块的分布式控制和监控,实现高可靠性的电源管理系统。USB Type-C/PD接口使STM32G4能够直接实现USB供电协议,适用于笔记本电源适配器、充电桩等应用。所有这些特性通过HAL库统一的API接口实现,极大简化了复杂系统的开发流程,同时保持了跨STM32系列的代码可移植性。