【电力电子】基于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函数的初始化顺序:

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波形生成相关变量
c 复制代码
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
控制和状态变量
c 复制代码
int  Voltage=0;                   // 当前输入电压值(单位:0.1V)
int _voltage=0;                   // 输入电压暂存值,用于变化检测
uint16_t TimeCount2=0;            // 参数更新延时计数器
uint8_t  ShortFlag=0;             // 过流保护标志位

2. 关键函数功能分析

2.1 正弦波表生成函数 getSinTab()
c 复制代码
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()
c 复制代码
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 幅值系数计算
c 复制代码
Para = 1187/(Voltage/10);  // 计算1V对应的PWM脉宽值

计算逻辑:

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

3. SPWM更新机制

定时器中断服务函数 (timer.c)
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. 关键计算公式推导

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

计算过程:

复制代码
输入20V → ADC采样 → 滤波处理 → Voltage = 200 (单位:0.1V)
幅值系数计算
c 复制代码
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_SinTablei = 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: 输入电压检测
c 复制代码
void Get_Voltage()
{
    Voltage=(Filter())/100;  // 20V输入 → Voltage = 200
}
步骤2: 幅值系数计算
c 复制代码
// 在主循环中
Para=1187/(Voltage/10);  // Para = 1187/20 = 59
步骤3: 用户设置输出幅值

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

c 复制代码
// 按键控制中
if(keytemp==3) // 幅值加
{
    if(VolTemp<(Voltage/10))  // 最大20V
        VolTemp++;           // VolTemp = 15
}
步骤4: 生成正弦波表
c 复制代码
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: 频率控制
c 复制代码
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_SinTable400 启动50μs定时中断 PWM_Index++ 更新PWM占空比 TIM_SetCompare1(T_SinTablePWM_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参数,确保输出电压的准确性。

相关推荐
国科安芯16 小时前
航天器多路并联大功率电源系统设计与ASP4644均流特性分析
单片机·嵌入式硬件·fpga开发·安全性测试
茯苓gao18 小时前
嵌入式开发笔记:CANopen相关移位运算与通信协议术语详解
网络·嵌入式硬件·学习·信息与通信
梁朝辉21 小时前
STM32H750VBT6中ADCINP与INN什么区别
stm32·单片机·嵌入式硬件
省四收割者1 天前
一文详解信号完整性(1)
python·嵌入式硬件·数学建模·信息与通信·信号处理·智能硬件
崇山峻岭之间1 天前
单片机无感FOC驱动之ADC
单片机·嵌入式硬件
Ligocious1 天前
1.点亮一颗小小的LED
单片机·嵌入式硬件
KaifuZeng1 天前
通信与接口协议面试八、CAN通信
单片机·嵌入式硬件·面试·通信与接口协议
智源单片机设计1 天前
基于单片机的直流电机双闭环调速系统设计
单片机·嵌入式硬件
kebidaixu1 天前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片详解
stm32
kebidaixu1 天前
两轮车换电 BMS 的模拟前端中颖 SH367306 AFE 芯片调试实录:四个关键问题与解决方案
stm32