【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(软件篇)(二)

发布于:2025-06-18 ⋅ 阅读:(24) ⋅ 点赞:(0)

【测试】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. 过流保护:
    • 电流>2A(ADC值>993): 立即关断输出
    • 电流<0.12A(ADC值<60): 延时5秒后恢复输出
  5. 电压监测: 输入电压变化>2V时,重新计算PWM系数
  6. 参数更新: 按键无操作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. 系统自动计算的参数:

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

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

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

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


网站公告

今日签到

点亮在社区的每一天
去签到