目錄
系統時鐘配置
PWM模塊初始化
ADC模塊配置
霍爾接口配置
速度環定時器
換相邏輯實現
主控制循環
系統時鐘配置
- 啟用72MHz主頻:RCC_Configuration()設置PLL
- 外設時鐘使能:TIM1/ADC/GPIO時鐘
#include "stm32f10x.h"void RCC_Configuration(void)
{// 時鐘復位配置RCC_DeInit();// 1. 開啟HSE并等待就緒RCC_HSEConfig(RCC_HSE_ON);while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);// 2. 配置PLL:HSE作為源,9倍頻RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);// 3. 設置FLASH預取指和等待周期(必須)FLASH_SetLatency(FLASH_Latency_2);FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);// 4. 時鐘分頻配置RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB=72MHzRCC_PCLK1Config(RCC_HCLK_Div2); // APB1=36MHzRCC_PCLK2Config(RCC_HCLK_Div1); // APB2=72MHz// 5. 啟動PLL并切換時鐘源RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource() != 0x08);// 6. 外設時鐘使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | // TIM1時鐘RCC_APB2Periph_ADC1 | // ADC1時鐘RCC_APB2Periph_GPIOA | // GPIOA時鐘(示例)RCC_APB2Periph_GPIOC, // GPIOC時鐘(示例)ENABLE);
}// 主函數初始化調用示例
int main(void)
{RCC_Configuration();// 其他初始化代碼...while(1);
}
PWM模塊初始化
- 定時器1通道1-3配置:
TIM_OCInitTypeDef.Pulse = 50%占空比
TIM_BDTRInitStruct配置死區時間(50-100ns) - 互補輸出使能:
TIM_CCxNCmd(TIM1, ENABLE)
#include "stm32f10x.h"void PWM_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStruct;TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;TIM_OCInitTypeDef TIM_OCStruct;TIM_BDTRInitTypeDef TIM_BDTRStruct;// 1. GPIO配置(以PA8/PA7為例)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_7; // CH1/CH1NGPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);// 2. 定時器基礎配置(72MHz時鐘)RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);TIM_TimeBaseStruct.TIM_Period = 1000-1; // ARR決定PWM頻率TIM_TimeBaseStruct.TIM_Prescaler = 0; // 無分頻TIM_TimeBaseStruct.TIM_ClockDivision = 0;TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);// 3. PWM通道配置(50%占空比)TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCStruct.TIM_Pulse = 500; // 50% of ARR(1000)TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OC1Init(TIM1, &TIM_OCStruct); // 通道1TIM_OC2Init(TIM1, &TIM_OCStruct); // 通道2TIM_OC3Init(TIM1, &TIM_OCStruct); // 通道3// 4. 死區時間配置(約55.5ns)TIM_BDTRStruct.TIM_DeadTime = 0x04; // DTG=4: 4*Tdts (Tdts=13.89ns@72MHz)TIM_BDTRStruct.TIM_Break = TIM_Break_Disable;TIM_BDTRStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF;TIM_BDTRStruct.TIM_OSSRState = TIM_OSSRState_Disable;TIM_BDTRStruct.TIM_OSSIState = TIM_OSSIState_Disable;TIM_BDTRStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;TIM_BDTRConfig(TIM1, &TIM_BDTRStruct);// 5. 互補輸出使能TIM_CCxNCmd(TIM1, TIM_Channel_1, ENABLE); // CH1NTIM_CCxNCmd(TIM1, TIM_Channel_2, ENABLE); // CH2NTIM_CCxNCmd(TIM1, TIM_Channel_3, ENABLE); // CH3N// 6. 啟動定時器TIM_Cmd(TIM1, ENABLE);TIM_CtrlPWMOutputs(TIM1, ENABLE); // MOE置位
}
ADC模塊配置
- 規則組通道選擇:
ADC_RegularChannelConfig(ADC1, ADC_Channel_x, 1...) - DMA循環模式設置:
DMA_InitStruct.Mode = DMA_Mode_Circular
// 示例:配置ADC1規則組的3個通道(順序:通道5→通道1→通道11)
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1); // 第1個轉換
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2); // 第2個轉換
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 3); // 第3個轉換ADC_InitTypeDef ADC_InitStruct;
ADC_InitStruct.ADC_NbrOfChannel = 3; // 規則組總通道數
ADC_Init(ADC1, &ADC_InitStruct);DMA_InitTypeDef DMA_InitStruct;
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; // 循環模式
DMA_InitStruct.DMA_BufferSize = 3; // 緩沖區大小(與規則組通道數匹配)
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外設地址固定
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; // 內存地址遞增
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 16位數據
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA1_Channel1, &DMA_InitStruct);// 設置外設地址(ADC數據寄存器)
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
// 設置內存地址(自定義緩沖區)
extern uint16_t adc_buffer[3];
DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)adc_buffer;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 啟動轉換DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DMACmd(ADC1, ENABLE); // 綁定ADC到DMA
霍爾接口配置
- GPIO輸入模式:
GPIO_Init(GPIOx, GPIO_Pin_x, GPIO_Mode_IPU) - EXTI中斷觸發:
EXTI_Trigger = EXTI_Trigger_Rising_Falling
霍爾傳感器 → GPIO上拉輸入 → EXTI雙沿中斷 → NVIC優先級配置 → 中斷服務函數 → 換向邏輯
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIO時鐘
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; // 霍爾傳感器連接的PA0/PA1/PA2
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; // 上拉輸入
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // 輸入模式下速度可忽略,但需設置
GPIO_Init(GPIOA, &GPIO_InitStruct);EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;// 將GPIO引腳映射到EXTI中斷線(以PA0為例)
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);EXTI_InitStruct.EXTI_Line = EXTI_Line0; // 對應PA0
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; // 中斷模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 雙沿觸發
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);// 配置NVIC中斷優先級
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
void EXTI0_IRQHandler(void) {if (EXTI_GetITStatus(EXTI_Line0) != RESET) {uint8_t hall_state = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); // 讀取霍爾信號// 執行換向邏輯(例如BLDC電機驅動)EXTI_ClearITPendingBit(EXTI_Line0); // 清除中斷標志}
}
速度環定時器
- 定時器2基礎配置:
TIM_TimeBaseInit(TIM2, 1kHz) - 中斷服務程序:
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE)
// 系統時鐘假設為72MHz(STM32F1系列)
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_InitStruct.TIM_Prescaler = 7200 - 1; // 分頻系數7200 → 72MHz/7200=10kHz
TIM_InitStruct.TIM_Period = 10 - 1; // 自動重載值 → 10kHz/10=1kHz
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上計數模式
TIM_TimeBaseInit(TIM2, &TIM_InitStruct);// 使能TIM2更新中斷
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 允許定時器溢出中斷[citation:9][citation:10]// 配置NVIC中斷優先級
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
void TIM2_IRQHandler(void) {if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {// 執行速度環PID計算或數據采集SpeedControl_Algorithm(); // 用戶自定義速度環處理函數TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // 清除中斷標志[citation:9][citation:10]}
}
換相邏輯實現
- Hall狀態機:
switch(Hall_Value & 0x07){
case 0b101: PWM_SetPhaseA_High();...
}
const PhaseAction phase_table[6] = {{0b101, PWM_A, OFF_C}, // 狀態0{0b100, PWM_B, OFF_A}, // 狀態1// ...其他狀態
};
switch(Hall_Value & 0x07) {case 0b101: // 對應霍爾狀態HA=1, HB=0, HC=1PWM_SetPhaseA_High(); // 上橋臂A相PWM調制,下橋臂B相常通PWM_SetPhaseB_Low();PWM_SetPhaseC_Off(); // C相關閉(互補邏輯)break;case 0b100: // 其他狀態類似調整// ...
}
主控制循環
- while(1){
ADC_Convert();
Speed_PID_Calc();
Current_Limit_Check();
}
void Current_Limit_Check() {if (ADC_Current > MAX_CURRENT) {PWM_Disable(); // 立即關閉功率輸出Fault_LED_On(); // 故障指示System_Reset(); // 可選:進入安全狀態或重啟}
}