【电力电子】STM32F103C8T6单片机双极性SPWM逆变技术详解(软件篇二)

【测试】STM32F103C8T6 双极性SPWM单相全桥逆变带载(阻性)测试

🧠 请为这个项目建立一份模块结构图,并解释每个模块的职责。
🧠 请列出这个项目中所有初始化流程的调用顺序。
🧠 请总结一下项目的主控逻辑和控制流程。


我来帮您分析这个STM32项目的结构和逻辑。首先让我查看项目的主要文件来了解完整的架构。
Read file: USER/main.c
Read file: USER/main.h
Search files…
Read file: USER/main.c
现在让我查看一些其他关键模块的头文件和定义:
Read file: HARDWARE/TIMER/timer.h
Read file: SYSTEM/usart/usart.h
Read file: HARDWARE/ADC/adc.h

让我查看一下常用的宏定义来了解项目中的硬件控制接口:
Ran tool
现在我已经掌握了项目的整体结构。让我为您创建模块结构图并进行详细分析
Ran tool

主控程序(main.c)

系统初始化模块

硬件驱动模块

用户功能模块

延时模块

(delay.c/h)

系统配置

(sys.c/h)

串口通信

(usart.c/h)

定时器模块

(timer.c/h)

ADC采样

(adc.c/h)

按键输入

(key.c/h)

OLED显示

(oled.c/h)

Flash存储

(stmflash.c/h)

LED控制

(led.c/h)

SPWM波形生成

频率/幅值控制

过流保护

电压电流检测

TIM1: PWM输出

(20KHz载波)

TIM2: SPWM中断

(波形更新)

TIM3: 定时中断

(1秒计时)

PA1: 输入电压检测

PA2: 输出电流检测

STM32外设库

(FWlib)

CMSIS核心层

项目模块结构分析

1. 各模块职责详解

系统初始化模块
  • 延时模块(delay): 提供ms/us级别的精确延时功能
  • 系统配置(sys): 配置系统时钟、中断优先级分组、GPIO位操作宏定义
  • 串口通信(usart): 实现串口通信,支持printf调试输出和参数设置
  • 硬件驱动模块
  • 定时器模块(timer):
  • TIM1: 生成20KHz的PWM载波,双通道互补输出带死区
  • TIM2: SPWM波形更新中断,控制输出频率
  • TIM3: 10ms*100 = 1秒定时中断,用于计时和显示刷新
  • ADC采样(adc): 双通道ADC采样,检测输入电压(PA1)和输出电流(PA2)
  • 按键输入(key): 4键输入,支持频率/幅值调节,包含IR2110使能控制
  • OLED显示(oled): I2C接口OLED屏幕显示系统状态
  • Flash存储(stmflash): 内部Flash读写,保存用户参数
  • LED控制(led): 状态指示LED控制
  • 用户功能模块
  • SPWM波形生成: 400点正弦查表,生成可调频率和幅值的正弦PWM
  • 频率/幅值控制: 频率范围2-200Hz,幅值可调0-输入电压峰值
  • 过流保护: 电流超过2A自动关断,低于0.12A延时5秒后恢复
  • 电压电流检测: 实时检测输入电压和输出电流,带滤波算法
  • 2. 初始化流程调用顺序

    根据main.c函数的初始化顺序:

    int main(void) {
        // 1. 基础系统初始化
        delay_init();                           // 延时函数初始化
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断优先级分组设置
        
        // 2. 硬件外设初始化
        KEY_Init();                             // 按键初始化
        Adc_Init();                             // ADC初始化
        uart1_init(9600);                       // 串口初始化
        
        // 3. 定时器初始化(关键)
        TIM2_Int_Init(100,48);                  // SPWM更新定时器(10KHz基准)
        getSinPlv(PlvTemp);                     // 根据频率设置TIM2周期
        getSinTab(400,VolTemp);                 // 生成正弦查表
        TIM3_Int_Init(100,4800);                // 1秒计时定时器
        TIM1_PWM_Init(1200,2);                  // PWM载波定时器(20KHz)
        
        // 4. 显示系统初始化
        OLED_Init();                            // OLED显示初始化
        OLED_Clear();                           // 清屏
        OLED_ShowString(...);                   // 显示初始界面
        
        // 5. 进入主循环
        while(1) { ... }
    }
    

    3. 主控逻辑和控制流程

    主循环控制流程:
    1. 显示更新: 每1秒刷新一次OLED显示(TimeCount1>1)
    2. 按键扫描: 实时检测按键输入,调节频率和幅值
    3. 串口命令: 处理串口接收的参数设置命令
    4. 过流保护:
    5. 电流>2A(ADC值>993): 立即关断输出
    6. 电流<0.12A(ADC值<60): 延时5秒后恢复输出
    7. 电压监测: 输入电压变化>2V时,重新计算PWM系数
    8. 参数更新: 按键无操作2秒后,应用新的频率/幅值设置
    SPWM生成原理:
    1. TIM1: 生成20KHz的PWM载波,双通道互补输出
    2. TIM2: 根据输出频率设置中断周期,每次中断更新PWM占空比
    3. 正弦查表: 400个点的正弦表,通过插值生成平滑的正弦波
    4. 幅值控制: 根据输入电压动态计算1V对应的PWM值
    5. 频率控制: 通过调整TIM2的中断周期实现频率调节
    安全保护机制:
  • 过流保护: 硬件电流检测+软件判断,双重保护
  • 死区设置: PWM输出带500ns死区,防止上下桥臂直通
  • 参数限制: 频率2-200Hz,幅值不超过输入电压
  • 滤波算法: 32点滑动平均滤波,提高检测精度
  • 这是一个典型的SPWM逆变电源控制系统,采用模块化设计,具有完善的保护机制和用户交互界面。


    🧠 “请结合代码分析SPWM生成相关的原理,解释各个变量和函数的功能,并说明各自在SPWM中的作用”


    基于您提供的代码,我来深入分析SPWM(正弦脉宽调制)生成的原理和实现机制。

    SPWM生成原理详解

    1. 核心变量分析

    SPWM波形生成相关变量
    unsigned int  T_SinTable[500];    // 正弦波查找表,存储400个正弦波采样点
    unsigned int  PWM_Index=0;        // SPWM查表索引,指向当前输出的波形点
    uint8_t  Para=0;                  // 幅值系数,1V对应的PWM脉宽值
    uint8_t  VolTemp=0;               // 用户设定的输出幅值(峰值电压)
    uint16_t PlvTemp=50;              // 用户设定的输出频率,默认50Hz
    
    控制和状态变量
    int  Voltage=0;                   // 当前输入电压值(单位:0.1V)
    int _voltage=0;                   // 输入电压暂存值,用于变化检测
    uint16_t TimeCount2=0;            // 参数更新延时计数器
    uint8_t  ShortFlag=0;             // 过流保护标志位
    

    2. 关键函数功能分析

    2.1 正弦波表生成函数 getSinTab()
    void getSinTab(u16 point,u16 maxnum)
    {
        u16 i=0; 
        float x=0.000,y=0.000;   // 弧度
        float jiao=0.000;        // 角度分度角
        jiao=360.000/point;      // 计算每个采样点的角度间隔
        
        maxnum=maxnum*Para;      // 用户设定幅值 × 1V系数 = 实际PWM幅值
        if(maxnum>1188)          // 限制最大PWM值(考虑死区时间)
           maxnum=1188;
    
        if(maxnum>0)
        {
            for(i=0;i<point;i++)
            {
                y=jiao*i;                    // 当前点的角度
                x=y*0.01745;                 // 角度转弧度 (π/180≈0.01745)
                
                // 生成正弦波PWM值:中心值600 + 幅值×sin(角度)
                T_SinTable[i]=600+(maxnum/2)*sin(x);
                
                // 限幅处理
                if(T_SinTable[i]>1188) T_SinTable[i]=1188;
                if(T_SinTable[i]<1) T_SinTable[i]=1;
            }
            // 使能PWM输出
            if(ShortFlag==0)
            {
                TIM_CtrlPWMOutputs(TIM1, ENABLE);
                ENA_Clr();   // 开启IR2110驱动
            }
        }
        else
        {
            ENA_Set();   // 关闭H桥
            TIM_CtrlPWMOutputs(TIM1, DISABLE);
        }
    }
    

    功能解析:

  • point=400: 一个正弦周期采样400个点
  • maxnum: 用户设定的输出幅值
  • Para: 根据输入电压动态计算的幅值系数
  • 600: PWM的中心值(占空比50%)
  • 1188: 考虑死区时间的最大PWM值
  • 2.2 频率控制函数 getSinPlv()
    void getSinPlv(uint16_t plv)
    {
        float cycle;
        unsigned int timeinit;
        cycle=2500/plv;              // 计算TIM2的中断周期
        timeinit=cycle;              // 浮点转整数
        TIM2_Int_Init(timeinit,48);  // 重新初始化TIM2定时器
    }
    

    频率计算原理:

  • 基准频率: 48MHz/48 = 1MHz
  • 中断周期: timeinit微秒
  • 输出频率: 1000000/(timeinit×400) Hz
  • 公式推导: cycle = 2500/plvfreq = 1000000/(2500×400/plv) = plv Hz
  • 2.3 幅值系数计算
    Para = 1187/(Voltage/10);  // 计算1V对应的PWM脉宽值
    

    计算逻辑:

  • Voltage: 输入电压×10 (例如24V显示为240)
  • 1187: 最大可用PWM范围
  • Para: 每1V输出对应的PWM增量
  • 3. SPWM更新机制

    定时器中断服务函数 (timer.c)
    void TIM2_IRQHandler(void)   // TIM2中断
    {
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
        {
            TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
            
            // 翻转PC13引脚(调试用)
            GPIO_WriteBit(GPIOC,GPIO_Pin_13,(BitAction)(1-(GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_13))));
            
            // 更新PWM占空比
            TIM_SetCompare1(TIM1,T_SinTable[PWM_Index]);  // 通道1
            TIM_SetCompare2(TIM1,T_SinTable[PWM_Index]);  // 通道2
            
            // 索引循环
            if(++PWM_Index>=400)
                PWM_Index=0;
        }
    }
    

    4. SPWM生成流程图

    Yes

    No

    频率

    幅值

    Yes

    No

    Yes

    系统初始化

    设置默认参数
    PlvTemp=50Hz
    VolTemp=0V

    检测输入电压
    Get_Voltage()

    计算幅值系数
    Para=1187/(Voltage/10)

    生成正弦表
    getSinTab(400,VolTemp)

    设置输出频率
    getSinPlv(PlvTemp)

    启动定时器
    TIM1:20KHz载波
    TIM2:SPWM更新

    TIM2中断
    (频率相关)

    更新PWM占空比
    TIM_SetCompare1/2

    索引递增
    PWM_Index++

    索引>=400?

    PWM_Index=0
    开始新周期

    用户调节

    按键/串口
    输入?

    更新PlvTemp
    调用getSinPlv()

    更新VolTemp
    调用getSinTab()

    保护机制

    电流检测
    Get_Current()

    Current>993
    (2A)?

    ShortFlag=1
    关闭输出
    ENA_Set()

    Current<60
    (0.12A)?

    延时5秒后
    恢复输出

    等待电流下降

    5. 关键参数计算示例

    50Hz正弦波输出计算:
  • TIM2中断周期: 2500/50 = 50微秒
  • 完整周期时间: 50μs × 400点 = 20ms = 50Hz
  • TIM1载波频率: 48MHz/2/1200 = 20KHz
  • 每个正弦点持续: 50μs,包含20KHz×50μs = 1000个载波周期
  • 电压幅值计算(假设24V输入):
  • 输入电压: Voltage = 240 (24.0V)
  • 幅值系数: Para = 1187/(240/10) = 1187/24 ≈ 49
  • 输出10V峰值: maxnum = 10×49 = 490
  • 正弦波幅值: ±490/2 = ±245 (相对中心值600)
  • 6. SPWM技术优势

    1. 高频载波: 20KHz载波频率,滤波后得到平滑正弦波
    2. 精确控制: 400点采样,0.9°角度分辨率
    3. 动态调节: 实时调节频率(2-200Hz)和幅值
    4. 死区保护: 500ns死区防止上下桥臂直通
    5. 过流保护: 硬件+软件双重保护机制

    这个SPWM实现方案采用查表法生成高精度正弦波,通过双定时器配合实现载波和调制波的精确控制,是一个典型的数字化逆变电源控制系统



    🧠用输入直流电压20V,输出频率50Hz,输出AC xx?推导整个过程,根据代码给出推导公式和计算过程。给出详细的计算过程和结果,给出计算过程的流程图。

    基于您提供的代码,我来详细分析输入20V直流电压,输出50Hz时的完整计算过程。

    计算前提和参数分析

    1. 系统参数

  • 输入电压: 20V直流
  • 输出频率: 50Hz
  • PWM载波频率: 20KHz
  • 正弦波采样点: 400点/周期
  • PWM计数范围: 0-1200
  • PWM中心值: 600 (50%占空比)
  • 2. 关键计算公式推导

    输入电压检测和处理
    // 电压检测滤波
    filter_buf[FILTER_N] = Get_Adc(1)*10.473;
    Voltage=(Filter())/100;
    

    计算过程:

    输入20V → ADC采样 → 滤波处理 → Voltage = 200 (单位:0.1V)
    
    幅值系数计算
    Para=1187/(Voltage/10);  // 计算1V对应的PWM脉宽
    

    推导公式:

    Para = 1187 ÷ (Voltage ÷ 10)
    Para = 1187 ÷ (200 ÷ 10) = 1187 ÷ 20 = 59.35 ≈ 59
    

    3. 完整计算流程

    输入: 20V直流

    ADC检测
    Voltage = 200
    (单位:0.1V)

    计算幅值系数
    Para = 1187/(200/10)
    Para = 59

    用户设置输出幅值
    VolTemp = ?V
    (峰值电压)

    计算实际PWM幅值
    maxnum = VolTemp × Para

    生成正弦波表
    T_SinTable[i] = 600 + (maxnum/2)×sin(θ)

    频率设置: 50Hz
    cycle = 2500/50 = 50μs
    TIM2中断周期

    PWM更新
    每50μs更新一次PWM占空比
    400个点 = 20ms = 50Hz

    不同VolTemp设置的计算结果:

    VolTemp = 10V峰值
    maxnum = 10×59 = 590
    PWM幅值 = ±295
    PWM范围: 305~895

    VolTemp = 15V峰值
    maxnum = 15×59 = 885
    PWM幅值 = ±442.5
    PWM范围: 157.5~1042.5

    VolTemp = 20V峰值(最大)
    maxnum = 20×59 = 1180
    限制到1188
    PWM幅值 = ±590
    PWM范围: 10~1190

    4. 具体计算过程和代码对应

    步骤1: 输入电压检测
    void Get_Voltage()
    {
        Voltage=(Filter())/100;  // 20V输入 → Voltage = 200
    }
    
    步骤2: 幅值系数计算
    // 在主循环中
    Para=1187/(Voltage/10);  // Para = 1187/20 = 59
    
    步骤3: 用户设置输出幅值

    假设用户通过按键设置输出15V峰值:

    // 按键控制中
    if(keytemp==3) // 幅值加
    {
        if(VolTemp<(Voltage/10))  // 最大20V
            VolTemp++;           // VolTemp = 15
    }
    
    步骤4: 生成正弦波表
    void getSinTab(u16 point,u16 maxnum)  // point=400, maxnum=15
    {
        maxnum=maxnum*Para;  // maxnum = 15×59 = 885
        
        for(i=0;i<400;i++)
        {
            y=jiao*i;        // 角度: 0°~359.1°
            x=y*0.01745;     // 转弧度
            
            // 生成正弦PWM值
            T_SinTable[i]=600+(885/2)*sin(x);  // 600 ± 442.5
            
            // 限幅处理
            if(T_SinTable[i]>1188) T_SinTable[i]=1188;
            if(T_SinTable[i]<1) T_SinTable[i]=1;
        }
    }
    
    步骤5: 频率控制
    void getSinPlv(uint16_t plv)  // plv = 50Hz
    {
        cycle=2500/plv;        // cycle = 2500/50 = 50
        timeinit=cycle;        // timeinit = 50μs
        TIM2_Int_Init(timeinit,48);  // 每50μs中断一次
    }
    

    5. 详细数值计算结果

    输入条件: 20V直流,50Hz输出
    参数 计算过程 结果
    输入电压检测 Voltage = 20V × 10 = 200 200 (0.1V单位)
    幅值系数 Para = 1187 ÷ 20 = 59.35 59
    TIM2中断周期 cycle = 2500 ÷ 50 = 50 50μs
    完整周期时间 50μs × 400点 = 20ms 50Hz ✓
    不同输出幅值设置的结果:

    情况1: VolTemp = 10V峰值

    maxnum = 10 × 59 = 590
    PWM幅值 = 590/2 = 295
    PWM范围 = 600 ± 295 = [305, 895]
    占空比范围 = [25.4%, 74.6%]
    

    情况2: VolTemp = 15V峰值

    maxnum = 15 × 59 = 885  
    PWM幅值 = 885/2 = 442.5
    PWM范围 = 600 ± 442.5 = [157.5, 1042.5]
    占空比范围 = [13.1%, 86.9%]
    

    情况3: VolTemp = 20V峰值(最大)

    maxnum = 20 × 59 = 1180
    限制后 maxnum = 1180 (未超过1188)
    PWM幅值 = 1180/2 = 590
    PWM范围 = 600 ± 590 = [10, 1190]
    占空比范围 = [0.8%, 99.2%]
    

    6. 输出电压计算

    理论输出电压(RMS值):

    峰值电压 = VolTemp (用户设置)
    RMS电压 = 峰值电压 ÷ √2 ≈ 峰值电压 × 0.707
    
    例如: VolTemp = 15V峰值
    输出RMS = 15V × 0.707 = 10.6V RMS
    

    7. 代码执行时序

    主循环

    TIM2中断

    TIM1(PWM)

    H桥输出

    检测输入电压(20V)

    计算Para=59

    用户设置VolTemp=15V

    生成正弦表T_SinTable[400]

    启动50μs定时中断

    PWM_Index++

    更新PWM占空比

    TIM_SetCompare1(T_SinTable[PWM_Index])

    输出20KHz PWM载波

    PWM占空比按正弦波变化

    PWM_Index = 0 (新周期)

    alt

    [PWM_Index >=

    400]

    loop

    [每50μs(50Hz输出)]

    完整周期: 400×50μs = 20ms = 50Hz

    主循环

    TIM2中断

    TIM1(PWM)

    H桥输出

    8. 最终答案

    对于输入20V直流,输出50Hz的设置:

    1. 系统自动计算的参数:

    2. 电压检测值: Voltage = 200
    3. 幅值系数: Para = 59
    4. 频率控制: 每50μs更新一次PWM
    5. 用户可设置的输出电压范围:

    6. 最小: 0V峰值 (关闭输出)
    7. 最大: 20V峰值 (输入电压)
    8. 步进: 1V
    9. 典型设置示例(15V峰值):

    10. 输出峰值: 15V
    11. 输出RMS: 10.6V
    12. PWM占空比范围: 13.1% ~ 86.9%
    13. 输出频率: 50Hz (精确)

    关键结论: 输出AC电压完全由用户通过VolTemp参数控制,可在0~20V峰值范围内任意设置,系统会自动根据输入电压计算对应的PWM参数,确保输出电压的准确性。

    作者:Naiva

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【电力电子】STM32F103C8T6单片机双极性SPWM逆变技术详解(软件篇二)

    发表回复