找回密码
 立即注册
查看: 110|回复: 12

STC32G8K48产生SPWM不正常

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:273
  • 最近打卡:2026-06-28 21:27:57

3

主题

22

回帖

47

积分

新手上路

积分
47
发表于 2026-6-24 16:08:40 | 显示全部楼层 |阅读模式
用STC32G8K48手册上的例程,
通过P2.4和P2.5管脚,用SPWMP生成50Hz正玄波,现在发现输出的还是方波,
怀疑是PWM没有进入中断改变占空比造成的。
看下中断设置也没有问题,麻烦帮看一下什么原因。



#include "STC32G.h"

//************************************************************************
#define PWMA_1            0x00      //P:P1.0  N:P1.1
#define PWMA_2            0x01      //P:P2.0  N:P2.1
#define PWMA_3            0x02      //P:P6.0  N:P6.1

#define PWMB_1            0x00      //P:P1.2  N:P1.3
#define PWMB_2            0x04      //P:P2.2  N:P2.3
#define PWMB_3            0x08      //P:P6.2  N:P6.3

#define PWM3_1            0x00      //P:P1.4  N:P1.5
#define PWM3_2            0x10      //P:P2.4  N:P2.5
#define PWM3_3            0x20      //P:P6.4  N:P6.5

#define PWM4_1            0x00      //P:P1.6  N:P1.7
#define PWM4_2            0x40      //P:P2.6  N:P2.7
#define PWM4_3            0x80      //P:P6.6  N:P6.7
#define PWM4_4            0xC0      //P:P3.4  N:P3.3

#define ENO1P             0x01      
#define ENO1N             0x02  
#define ENO2P             0x04      
#define ENO2N             0x08  
#define ENO3P             0x10      
#define ENO3N             0x20
#define ENO4P             0x40      
#define ENO4N             0x80  

//************************************************************************
//SPWM查表索引

u16 PWMA_Duty;
u8 PWM_Index;

//************************************************************************
unsigned int code T_SinTable[]=
{
        1220,1256,1292,1328,1364,1400,1435,1471,1506,1541,1575,1610,1643, 1677,1710,1742,1774,1805,1836,1866,
        1896,1925,1953,1981,2007,2033,2058,2083,2106,2129,2150,2171,2191, 2210,2228,2245,2261,2275,2289,2302,
        2314,2324,2334, 2342,2350,2356,2361,2365,2368,2369,2370,2369,2368,2365, 2361,2356,2350,2342,2334,2324,
        2314,2302,2289,2275,2261,2245,2228,2210,2191,2171,2150,2129,2106,2083,2058,2033,2007,1981,1953,1925,
        1896,1866,1836,1805,1774,1742,1710,1677,1643,1610,1575,1541,1506,1471,1435,1400,1364,1328,1292,1256,
        1220,1184,1148,1112,1076,1040,1005,969 ,934 ,899 ,865 ,830 ,797 ,763 ,730 ,698 ,666 ,635 ,604 ,574 ,
        544,515,  487, 459 ,433 ,407 ,382 ,357 ,334 ,311 ,290 ,269 ,249 ,230 ,212 ,195 ,179 ,165 ,151 ,138 ,
        126,116,  106,  98 ,90  ,84  ,79  ,75  ,72  ,71  ,70  ,71  ,72  ,75  ,79  ,84  ,90  ,106 ,98  ,116,
        126,138,  151, 165 ,179 ,195 ,212 ,230 ,249 ,269 ,290 ,311 ,334 ,357 ,382 ,407 ,433 ,459 ,487 ,515,
        544,574,  604, 635 ,730 ,763 ,797 ,666 ,698 ,830 ,865 ,899 ,934 ,969 ,1005,1040,1076,1112,1148, 1184
};        

//**********************************************************************
//功能:PWM3初始化
//入口:
//出口:

void Pwm3Init(void)
{        
        PWM_Index=0;        
        
        PWMA_Duty = 1220;   //占空比
        
        PWMA_CCER1 = 0x00;        //写 CCMRx 前必须先清零 CCxE 关闭
        PWMA_CCER2 = 0x00;
        
        //*************************捕获/比价模式寄存器1  P789
        PWMA_CCMR3 = 0x60;

        PWMA_CCER2 = 0x05;         //PWM3通道输出使能和极性

        PWMA_ARRH= 0x09;               //设置周期时间
        PWMA_ARRL= 0x60;
        
        PWMA_CCR3H=(u8)(PWMA_Duty >> 8);        //设置占空比时间
        PWMA_CCR3L = (u8)(PWMA_Duty);
        
        PWMA_DTR = 0x0C;                        //设置死区时间   12*T ck_psc

        PWMA_ENO = 0x00;
        PWMA_ENO |= ENO3P;
        PWMA_ENO |= ENO3N;
        
        PWMA_PS = 0x00;                  //高级 PWM 通道输出脚选择位
        PWMA_PS |= PWM3_2;        //选择 PWMA_3 通道P24 P25         
        
        //*****************************刹车寄存器
        PWMA_BKR= 0x80;         //使能主输出
        
        //*****************************PWMA中断使能寄存器  允许        PWM更新中断
        PWMA_IER= 0x01;         //使能中断   
        PWMA_CR1 |= 0x01;       //开始计时
        EA=1;                   //打开总中断
}        

//************************************************************************
//功能:PWM中断函数
//入口:
//出口:

void PWMA_ISR() interrupt 26
{        
        if(PWMA_SR1 & 0x02)
        {
                PWMA_SR1 &=~0x02;
                PWMA_Duty =T_SinTable[PWM_Index];
                if(++PWM_Index>=200)
                        PWM_Index=0;        

                PWMA_CCR1H = (u8)(PWMA_Duty >> 8);        //设置占空比时间
                PWMA_CCR1L=(u8)(PWMA_Duty);
        }
        PWMA_SR1 = 0;
}               


//*****************************************************************

void IoInit(void)
{
        P0M1 = 0xfd;   //1111 1101
        P0M0 = 0x02;   //0000 0010

        P1M1 = 0x13;   //0001  0011
    P1M0 = 0xEC;   //1110  1100

        P2M1 = 0x00;   //0000 0000
        P2M0 = 0x38;   //0011 1000
        PwmIn1=0;
        PwmIn2=0;
        
        P3M1 = 0xC1;     //1100 0001
    P3M0 = 0x3E;     //0011 1110
}


//*********************************************************

int main(void)
{
        WTST = 0;                //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
        EAXSFR();                //扩展SFR(XFR)访问使能
        CKCON = 0;      //提高访问XRAM速度
        Pwm3Init();
        EA = 1;
        while(1)
        {


        }
}


回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:394
  • 最近打卡:2026-07-05 12:28:34

83

主题

7889

回帖

1万

积分

超级版主

积分
16831
发表于 2026-6-24 16:34:16 | 显示全部楼层
示波器观察,占空比没有变化?
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:273
  • 最近打卡:2026-06-28 21:27:57

3

主题

22

回帖

47

积分

新手上路

积分
47
发表于 2026-6-24 16:35:19 | 显示全部楼层
占空比没有变化

点评

请下载下面的例程包,参考“11-PWMA-P2口输出3相互补SPWM变频驱动”,应该就是你想要的。 主频32.768MHz, PWM周期1422, 刷新频率23040Hz,死区0.5us, 输出3相正弦波频率为1~255Hz, 相位差120度. 正弦表使用360点, 幅  详情 回复 发表于 2026-6-24 20:18
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:273
  • 最近打卡:2026-06-28 21:27:57

3

主题

22

回帖

47

积分

新手上路

积分
47
发表于 2026-6-24 16:37:08 | 显示全部楼层
按照手册上的例程,我就是把IO口调整了,刚才AI说PWM3和PWMA的中断号不一样,我也没有看到用哪个中断号?
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:586
  • 最近打卡:2026-07-04 12:34:03
已绑定手机

112

主题

4958

回帖

1万

积分

荣誉版主

无情的代码机器

积分
10758
发表于 2026-6-24 16:41:56 | 显示全部楼层

简单例程可先问AI助手,也许一把就解了。
截图202606241642504637.jpg
截图202606241641462446.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:273
  • 最近打卡:2026-06-28 21:27:57

3

主题

22

回帖

47

积分

新手上路

积分
47
发表于 2026-6-24 17:05:36 | 显示全部楼层
谢谢,现在输出的波形占空比可以改变了。我的方案用芯片驱动一个50Hz的AC电机,但现在看出来的波形异常,不是一个正弦波,是不是PWM输出的频率和电机的L和外并的电容不匹配造成的?
截图202606241705347084.jpg

点评

图片附近无法访问。粘贴图片时,点一下上传的图插入编辑框中。然后视频,电路图什么的也可上传下,完了后电机问题可在2L点回复提醒梁工查看~  发表于 2026-6-24 18:03
看不到图,重新上传附件试试  发表于 2026-6-24 17:20
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-24 17:06:25 | 显示全部楼层
截图202606241706158777.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-24 17:06:55 | 显示全部楼层

我看到这个帖子的内容了。这是关于 STC32G8K48 使用 PWM3(P2.4/P2.5)产生 SPWM 却输出方波 的问题。问题核心在于 PWM3 是 PWMA 的通道3,不是独立的外设,从手册例程修改时需要相应调整多个寄存器配置。


🔍 问题分析

根据 STC32G 手册第26章(高级PWM),STC32G 只有两组 PWM 定时器:

组别 包含通道 中断号
PWMA 通道14(PWM1PWM4) 中断26
PWMB 通道58(PWM5PWM8) 中断27

PWM3(P2.4/P2.5)属于 PWMA 的通道3,中断号仍然是 26,所以"中断号不对"不是根本原因。


🛠 例程用的是通道1,你需要改到通道3

手册例程 26.10.15 用的是 PWMA 通道1(PWM1P/P1.0, PWM1N/P1.1),你改成 PWM3(P2.4/P2.5)后,以下寄存器必须同步修改,不能只改引脚选择:

✅ 需要修改的地方对照表

项目 原例程(通道1) 改为通道3(P2.4/P2.5)
通道模式配置 PWMA_CCMR1 = 0x60; PWMA_CCMR3 = 0x60;
输出使能 PWMA_CCER1 = 0x05;(使能CC1P/CC1N) PWMA_CCER1 |= 0x50;(使能CC3P/CC3N
占空比寄存器 PWMA_CCR1H / PWMA_CCR1L PWMA_CCR3H / PWMA_CCR3L
输出使能IO PWMA_ENO |= ENO1P | ENO1N; PWMA_ENO |= ENO3P | ENO3N;
引脚选择 PWMA_PS |= PWMA_3;(P6.0/P6.1) PWMA_PS |= PWM3_2;P2.4/P2.5
中断中更新 更新 PWMA_CCR1 → 更新**PWMA_CCR3**

📝 修正后的关键代码示意

// ---- 引脚选择 ----
PWMA_PS |= PWM3_2;       // PWM3映射到 P2.4/P2.5

// ---- 通道3模式配置 ----
PWMA_CCER1 = 0x00;       // 先清通道使能
PWMA_CCER2 = 0x00;
PWMA_CCMR3 = 0x60;       // 配置通道3为PWM模式
PWMA_CCER1 |= 0x50;      // 使能通道3输出(CC3P=1, CC3NE=1)

// ---- 占空比用 CCR3 ----
PWMA_CCR3H = (u8)(PWMA_Duty >> 8);
PWMA_CCR3L = (u8)(PWMA_Duty);

// ---- 输出使能 ----
PWMA_ENO |= ENO3P;       // 使能 PWM3P 输出
PWMA_ENO |= ENO3N;       // 使能 PWM3N 输出

// ---- 中断仍然是 26 号 ----
void PWMA_ISR() interrupt 26
{
    if (PWMA_SR1 & 0x01)
    {
        PWMA_SR1 &= ~0x01;
        PWMA_Duty = T_SinTable[PWM_Index];
        if (++PWM_Index >= 200) PWM_Index = 0;
        PWMA_CCR3H = (u8)(PWMA_Duty >> 8);  // ← 关键:改为 CCR3
        PWMA_CCR3L = (u8)(PWMA_Duty);
    }
    PWMA_SR1 = 0;
}

🧪 快速自查清单

  1. PWMA_CCMR3 是否配置为 0x60?(不是 CCMR1)
  2. PWMA_CCER1 是否设置了 bit4(CC3P)和 bit5(CC3NE)?(即 0x50
  3. ❓ 占空比写入的是 PWMA_CCR3 而不是 PWMA_CCR1
  4. ❓ 中断函数中更新的是 PWMA_CCR3
  5. ❓ 输出使能 PWMA_ENO 用的是 ENO3P | ENO3N
  6. ❓ 引脚选择 PWMA_PS 写的是 PWM3_20x10)?

如果以上都改对了,SPWM 应该可以正常输出正弦波。你检查一下代码里哪些地方还没改过来?


🔍 搜索 "https://www.stcaimcu.com/thread-24296-1-1.html"

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:453
  • 最近打卡:2026-07-03 08:57:36

830

主题

1万

回帖

2万

积分

管理员

积分
23929
发表于 2026-6-24 17:09:02 | 显示全部楼层

截图202606241708573548.jpg


截图202606241708129523.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:299
  • 最近打卡:2026-07-04 00:01:55
已绑定手机

66

主题

808

回帖

3037

积分

论坛元老

DIY玩家

积分
3037
发表于 2026-6-24 17:22:23 | 显示全部楼层
fengyu*** 发表于 2026-6-24 16:37
按照手册上的例程,我就是把IO口调整了,刚才AI说PWM3和PWMA的中断号不一样,我也没有看到用哪个中断号? ...

可能没配对寄存器
AI助手可以分析外设配置
这类寄存器配置通常按照手册流程
永怀这学徒心
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-5 14:04 , Processed in 0.082970 second(s), 84 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表