关于PWM
STC8A8K32S4单片机,增强15位PWMPWMC=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开,
到第五个中断,才正常,
折腾了好几天,百思不得其解,
本帖最后由 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; //PWM2 在计数值为 T2 地方输出高电平,
PWM2T1= PWMT1; //PWM2 在计数值为 T1 地方输出低电平
//阀B
PWM3T2= PWMT2; //PWM3 在计数值为 T2 地方输出高电平,
PWM3T1= PWMT1; //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; //PWM2 在计数值为 T2 地方输出高电平,
PWM2T1= PWMT1; //PWM2 在计数值为 T1 地方输出低电平
//PWM2T2L= 99; //电磁阀可以通
//PWM2T1L= 0;
//阀B
PWM3T2= PWMT2; //PWM3 在计数值为 T2 地方输出高电平,
PWM3T1= PWMT1; //PWM3 在计数值为 T1 地方输出低电平
//PWM3T2L= 90; //PWM2 在计数值为 T2 地方输出高电平,
//PWM3T1L= 0; //PWM2 在计数值为 T1 地方输出低电平
P_SW2 &= B01111111; //恢复访问XRAM
//置标志,向上位机要下一个数据
PWMWantDataFlag = 1;
}
PWMT2[],PWMT1[],数组保存着下一个PWM触发点数据 每路PWM都可以单独设置输出高低电平的时刻。
PWM中断里设置的匹配值T1、T2,不影响当前的周期,下一个周期起作用。 本帖最后由 zanjun 于 2024-3-27 17:02 编辑
梁工 发表于 2024-3-27 16:03
每路PWM都可以单独设置输出高低电平的时刻。
PWM中断里设置的匹配值T1、T2,不影响当前的周期,下一个周期 ...
梁工,你好,
如果有时间,麻烦看看我的程序,我在中断里改T1和T2,有时不起作用,
最上面,说明了不正常的情况
zanjun 发表于 2024-3-27 17:00
梁工,你好,
如果有时间,麻烦看看我的程序,我在中断里改T1和T2,有时不起作用,
最上面,说明了不正常 ...
STC8A8K32S4单片机,增强15位PWM
PWMC=99
时钟=定时器T2=30ms,
我对PWM归零中断的理解是这样的,
设PWMC=99,当计数=99,计数器归零,发生归零中断,此时还需要一个30ms时钟,才真正完成一个PWM周期,也就是完整周期=100x30=3000ms
不知道,是不是这样 zanjun 发表于 2024-3-27 17:10
STC8A8K32S4单片机,增强15位PWM
PWMC=99
时钟=定时器T2=30ms,
周期计数计到设定值,下一个时钟就归0,同时装载T1、T2值,并发起中断。
类似应用可以参考:
1、输出SPWM,就是每个归0中断都改变占空比。
2、输出声音,就是每个归0中断都改变占空比。
完全没有问题的。 梁工 发表于 2024-3-27 18:36
周期计数计到设定值,下一个时钟就归0,同时装载T1、T2值,并发起中断。
类似应用可以参考:
1、输出SPWM ...
谢谢,梁工
目前,现象就是上面说的那样
1、目前,怀疑单片机,STC8A8K32S4,目前似乎停产了,明天试试STC8A8K48D4
2、改触发点的值,一些特殊值,如T2=0,T1=100,PWMC=99 zanjun 发表于 2024-3-27 20:25
谢谢,梁工
目前,现象就是上面说的那样
1、目前,怀疑单片机,STC8A8K32S4,目前似乎停产了,明天试试ST ...
本来不想再浪费时间去测试的,因为类似功能用得实在太多了。
但还是忍不住花时间测试了,为了观察明显,我Timer2用10ms,用30ms一样的效果,就是慢3倍。
占空比变化我也加大一些,你可以自己改回你要的占空比。
// u16 code T_PWM = {100, 95, 90, 85, 80}; //用户要求,但是观察不明显
u16 code T_PWM = { 80, 70, 60, 50, 40};
先看STC8A8K64S4A12,一上电P2.1有输出一个几ms的高电平,这个型号IO上电是准双向口输出高电平的。之后5个脉冲都正常:
再看STC8A8K64D4的,一切正常:
梁工 发表于 2024-3-27 21:23
本来不想再浪费时间去测试的,因为类似功能用得实在太多了。
但还是忍不住花时间测试了,为了观察明显, ...
再次感谢,明天试试你的程序, 梁工 发表于 2024-3-27 21:23
本来不想再浪费时间去测试的,因为类似功能用得实在太多了。
但还是忍不住花时间测试了,为了观察明显, ...
梁工好,
先设好第一组T1/T2,再启动PWM,此时会立即产生一个归零中断,在中断中设置第二组T1/T2,你上面说,不会影响上一个周期的T1/T2,这个T1/T2,还有影子寄存器?
除去启动那次的归零中断,之后的中断就好理解了,计数到设定值,产生中断,改T1/T2,前一个周期的T1/T2,已经没有用了。
页:
[1]
2