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

关于PWM

[复制链接]

该用户从未签到

1

主题

7

回帖

65

积分

注册会员

积分
65
发表于 2024-3-27 14:38:19 | 显示全部楼层 |阅读模式
STC8A8K32S4单片机,增强15位PWM
PWMC=99
时钟=定时器T2=30ms,
归零中断改高低电平触发点,下面是部分数据
1、PWM2T2=0,PWM2T1=100,PWM3T2=0,PWM3T1=0,
2、PWM2T2=0,PWM2T1=95,PWM3T2=95,PWM3T1=0,
3、PWM2T2=0,PWM2T1=90,PWM3T2=90,PWM3T1=0,
4、PWM2T2=0,PWM2T1=85,PWM3T2=85,PWM3T1=0,
5、PWM2T2=0,PWM2T1=80,PWM3T2=80,PWM3T1=0,
期望是,
1、PWM2开100个时钟,PWM3关
2、PWM2先开95个时钟,然后PWM3开5个时钟
3、PWM2先开90个时钟,然后PWM3开10个时钟
4、PWM2先开85个时钟,然后PWM3开15个时钟
5、PWM2先开80个时钟,然后PWM3开20个时钟
结果是1/2/3/4,只有PWM2开,
到第五个中断,才正常,
折腾了好几天,百思不得其解,

回复 送花

使用道具 举报

该用户从未签到

1

主题

7

回帖

65

积分

注册会员

积分
65
 楼主| 发表于 2024-3-27 15:08:30 | 显示全部楼层
本帖最后由 zanjun 于 2024-3-27 15:20 编辑




//30毫秒@22.1184MHz,PWM时钟=30ms,适应电磁阀开关响应时间
void Init_Timer2(void)               
{
        AUXR &= B11110011;                //T2定时方式,12T
        T2L = 0x00;                                                //设置定时初值
        T2H = 0x28;                                                //设置定时初值,30ms
        IE2 &= B11111011;                        //关定时器2中断
        AUXR |= B00010000;                //定时器2开始计时
}


//时钟T2=30ms,周期3000ms,计数100次,3000ms归零中断中修改4路PWM的高低电平位置和时间
//4路增强PWM,PWM2、PWM3、PWM4、PWM5
void Init_PWM(void)
{

        Init_Timer2();

        //在 PWM计数器计数的过程中, ENPWM 控制位被关闭时, PWM 计数会立即停止,当再次使能 ENPWM
        //控制位时, PWM 的计数会从 0 开始重新计数,而不会记忆 PWM 停止计数前的计数值
        PWMCR = 0;                                                        //关闭PWM波形发生器,关闭归零中断
        PWMCFG = 0;                                                 //清中断标志
        PWMIF = 0;                                                        //清反转中断标志
        PWMFDCR = 0;                                                //异常检测关


        P_SW2 |= B10000000;                        //访问XFR

        //PWM2,PWM3,PWM4,PWM5
        PWMCKS = B00010000;                        //PWM 时钟为T2溢出脉冲,30ms,

       
        PWMCH = 0;
        PWMCL = 99;                                                        //设置 PWM 周期为 100 个 PWM 时钟,3000ms,//2500ms


        PWM2CR = B10000000;                        //使能PWM2口输出(推挽),初始低电平,关通道中断,关触发点中断
        PWM2HLD = B00000000;                //正常输出,可以强制高电平,或低电平
        PWM3CR = B10000000;                               
        PWM3HLD = B00000000;                       

       

        //设定每个周期中输出PWM波形的2个触发点
        //当计数值=T1设定值,PWM输出低电平
        //当计数值=T2设定值,PWM输出高电平
        //当计数值=T1=T2,只输出低电平

        //阀A
        PWM2T2= PWMT2[0];                        //PWM2 在计数值为 T2 地方输出高电平,
        PWM2T1= PWMT1[0];                        //PWM2 在计数值为 T1 地方输出低电平

        //阀B
        PWM3T2= PWMT2[1];                        //PWM3 在计数值为 T2 地方输出高电平,
        PWM3T1= PWMT1[1];                        //PWM3 在计数值为 T1 地方输出低电平
                       

        P_SW2 &= B01111111;                        //恢复访问XRAM
       
        PWMCR = B11000000;                        //开启PWM波形发生器,和归零中断
        EA = 1;
}



void PWM_Interrupt(void) interrupt 22
{

        PWMCFG = 0;                                         //清中断标志

        PWMIF = 0;                                        //C7IF,C6IF...C0IF
        P_SW2 |= B10000000;                //访问XFR
        
        //阀A
        PWM2T2= PWMT2[0];                //PWM2 在计数值为 T2 地方输出高电平,
        PWM2T1= PWMT1[0];                //PWM2 在计数值为 T1 地方输出低电平
        //PWM2T2L= 99;                //电磁阀可以通
        //PWM2T1L= 0;

        //阀B
        PWM3T2= PWMT2[1];                //PWM3 在计数值为 T2 地方输出高电平,
        PWM3T1= PWMT1[1];                //PWM3 在计数值为 T1 地方输出低电平
        //PWM3T2L= 90;                //PWM2 在计数值为 T2 地方输出高电平,
        //PWM3T1L= 0;                //PWM2 在计数值为 T1 地方输出低电平
        
        P_SW2 &= B01111111;                //恢复访问XRAM
        
        //置标志,向上位机要下一个数据
        PWMWantDataFlag = 1;
}

PWMT2[],PWMT1[],数组保存着下一个PWM触发点数据
回复 支持 反对 送花

使用道具 举报

该用户从未签到

46

主题

2927

回帖

6583

积分

超级版主

积分
6583
发表于 2024-3-27 16:03:51 | 显示全部楼层
每路PWM都可以单独设置输出高低电平的时刻。
PWM中断里设置的匹配值T1、T2,不影响当前的周期,下一个周期起作用。
回复 支持 反对 送花

使用道具 举报

该用户从未签到

1

主题

7

回帖

65

积分

注册会员

积分
65
 楼主| 发表于 2024-3-27 17:00:40 | 显示全部楼层
本帖最后由 zanjun 于 2024-3-27 17:02 编辑
梁工 发表于 2024-3-27 16:03
每路PWM都可以单独设置输出高低电平的时刻。
PWM中断里设置的匹配值T1、T2,不影响当前的周期,下一个周期 ...

梁工,你好,
如果有时间,麻烦看看我的程序,我在中断里改T1和T2,有时不起作用,
最上面,说明了不正常的情况
回复 支持 反对 送花

使用道具 举报

该用户从未签到

1

主题

7

回帖

65

积分

注册会员

积分
65
 楼主| 发表于 2024-3-27 17:10:57 | 显示全部楼层
zanjun 发表于 2024-3-27 17:00
梁工,你好,
如果有时间,麻烦看看我的程序,我在中断里改T1和T2,有时不起作用,
最上面,说明了不正常 ...

STC8A8K32S4单片机,增强15位PWM
PWMC=99
时钟=定时器T2=30ms,
我对PWM归零中断的理解是这样的,
设PWMC=99,当计数=99,计数器归零,发生归零中断,此时还需要一个30ms时钟,才真正完成一个PWM周期,也就是完整周期=100x30=3000ms
不知道,是不是这样

点评

周期计数计到设定值,下一个时钟就归0,同时装载T1、T2值,并发起中断。 类似应用可以参考: 1、输出SPWM,就是每个归0中断都改变占空比。 2、输出声音,就是每个归0中断都改变占空比。 完全没有问题的。  详情 回复 发表于 2024-3-27 18:36
回复 支持 反对 送花

使用道具 举报

该用户从未签到

46

主题

2927

回帖

6583

积分

超级版主

积分
6583
发表于 2024-3-27 18:36:28 | 显示全部楼层
zanjun 发表于 2024-3-27 17:10
STC8A8K32S4单片机,增强15位PWM
PWMC=99
时钟=定时器T2=30ms,

周期计数计到设定值,下一个时钟就归0,同时装载T1、T2值,并发起中断。
类似应用可以参考:
1、输出SPWM,就是每个归0中断都改变占空比。
2、输出声音,就是每个归0中断都改变占空比。
完全没有问题的。
回复 支持 反对 送花

使用道具 举报

该用户从未签到

1

主题

7

回帖

65

积分

注册会员

积分
65
 楼主| 发表于 2024-3-27 20:25:53 | 显示全部楼层
梁工 发表于 2024-3-27 18:36
周期计数计到设定值,下一个时钟就归0,同时装载T1、T2值,并发起中断。
类似应用可以参考:
1、输出SPWM ...

谢谢,梁工
目前,现象就是上面说的那样
1、目前,怀疑单片机,STC8A8K32S4,目前似乎停产了,明天试试STC8A8K48D4
2、改触发点的值,一些特殊值,如T2=0,T1=100,PWMC=99

点评

本来不想再浪费时间去测试的,因为类似功能用得实在太多了。 但还是忍不住花时间测试了,为了观察明显,我Timer2用10ms,用30ms一样的效果,就是慢3倍。 占空比变化我也加大一些,你可以自己改回你要的占空比。 //  详情 回复 发表于 2024-3-27 21:23
回复 支持 反对 送花

使用道具 举报

该用户从未签到

46

主题

2927

回帖

6583

积分

超级版主

积分
6583
发表于 2024-3-27 21:23:23 | 显示全部楼层
zanjun 发表于 2024-3-27 20:25
谢谢,梁工
目前,现象就是上面说的那样
1、目前,怀疑单片机,STC8A8K32S4,目前似乎停产了,明天试试ST ...

本来不想再浪费时间去测试的,因为类似功能用得实在太多了。

但还是忍不住花时间测试了,为了观察明显,我Timer2用10ms,用30ms一样的效果,就是慢3倍。
占空比变化我也加大一些,你可以自己改回你要的占空比。

//        u16        code T_PWM[5] = {100, 95, 90, 85, 80};   //用户要求,但是观察不明显
        u16        code T_PWM[5] = { 80, 70, 60, 50, 40};


先看STC8A8K64S4A12,一上电P2.1有输出一个几ms的高电平,这个型号IO上电是准双向口输出高电平的。之后5个脉冲都正常:
截图202403272119451122.jpg

再看STC8A8K64D4的,一切正常:
截图202403272120528451.jpg

STC8A8K64S4A12-2路互补输出SPWM-C语言.rar (44.75 KB, 下载次数: 8)

STC8A8K64D4-输出2路有相位差的PWM-C语言.rar (46.41 KB, 下载次数: 6)

回复 支持 反对 送花

使用道具 举报

该用户从未签到

1

主题

7

回帖

65

积分

注册会员

积分
65
 楼主| 发表于 2024-3-27 22:28:15 | 显示全部楼层
梁工 发表于 2024-3-27 21:23
本来不想再浪费时间去测试的,因为类似功能用得实在太多了。

但还是忍不住花时间测试了,为了观察明显, ...

再次感谢,明天试试你的程序,
回复 支持 反对 送花

使用道具 举报

该用户从未签到

1

主题

7

回帖

65

积分

注册会员

积分
65
 楼主| 发表于 2024-3-29 17:00:36 | 显示全部楼层
梁工 发表于 2024-3-27 21:23
本来不想再浪费时间去测试的,因为类似功能用得实在太多了。

但还是忍不住花时间测试了,为了观察明显, ...

梁工好,
先设好第一组T1/T2,再启动PWM,此时会立即产生一个归零中断,在中断中设置第二组T1/T2,你上面说,不会影响上一个周期的T1/T2,这个T1/T2,还有影子寄存器?
除去启动那次的归零中断,之后的中断就好理解了,计数到设定值,产生中断,改T1/T2,前一个周期的T1/T2,已经没有用了。

点评

这个T1/T2,还有影子寄存器? 是的,写入写的是影子寄存器(重装寄存器),这是为了你的操作不会影响当前的PWM占空比,否则可能会出现非常大的问题,比如烧管子。  详情 回复 发表于 2024-3-29 22:43
回复 支持 反对 送花

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 23:39 , Processed in 0.076909 second(s), 73 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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