0. 序
之前用定时器做了模拟PWM输出,得到的1k左右波形还行,到10k往上波形就特别难看,又是跳变又是长短不一。后来在参考手册上面看到stc15w4k系列自带pwm波形发生器,于是整了好久写出来了。今天因为业务需求要改代码,回头一看,好家伙,都不知道自己写的啥了。看了一会儿想起来,于是有了此文。
1. 简介
如图,如下介绍,他直接把PWM输出到IO口上面,我使用的是这两个,于是就用了PWM3和PWM2_2两个。
2. 分析
占坑,今天还要重构代码,改很多东西,暂时不分析了(2021.6.2)。
3. 代码
代码比较简单,我是照着这个写的 ,XDM自己去瞅瞅啊,我当时看了一早上才看明白。。
#include <STC15.H> //52头文件
#include <PWM.H>
u8 Tcount=0; //一个PWM周期内的:周期计数,占空比,方向
sbit PWM = P2^1; //PWM4口
sbit PWM2 = P2^7; //PWM2口
sbit NPWM1 =P5^4; //关闭PWM异常口
sbit NPWM2 =P5^4; //关闭PWM异常口
void setPWMWide(u8 Wide); //设置脉宽
#define CYCLE 0x800L//5khz //定义PWM周期(最大值为32767)
#define DUTY1 20 //定义占空比为20%
#define DUTY2 30 //定义占空比为30%
#define DUTY3 50 //定义占空比为50%
//主函数
void InitPWM()
{
InterruptInit();//初始化中断配置
}
void setPWMWide(u8 Wide)
{
P_SW2 |= 0x80; //使能访问XSFR
PWMIF=0x00;
PWMFDCR = 0x00; //关闭PWM异常检测,P5.4和P5.5在IIC中使用,如果不关闭会一直进入异常导致无法设置PWM占空比
PWMCFG = 0x00; //配置PWM的输出初始电平为低电平
PWMCKS = 0x00; //选择PWM的时钟为Fosc/(0+1)
PWMC = CYCLE; //设置PWM周期
//板子PWM4 芯片PWM2_2 P2.7
// PWM2T1 = 0x0000; //设置PWM2第1次反转的PWM计数
// PWM2T2 = CYCLE * DUTY / 100; //设置PWM2第2次反转的PWM计数
PWM2T1 = 0x0000; //设置PWM2第1次反转的PWM计数
PWM2T2 = CYCLE * (Wide) / 100; //设置PWM2第2次反转的PWM计数
PWM2CR |= 0x08; //选择PWM2输出到P2.7,不使能PWM2中断
PWM3T1 = 0x0000; //设置PWM2第1次反转的PWM计数
PWM3T2 = CYCLE * (Wide) / 100; //设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWM3CR = 0; //选择PWM2输出到P2.1
//使能
PWMCR = 0x03; //使能PWM信号输出
PWMCR |= 0x80; //使能PWM模块
P_SW2 &= ~0x80;
}
void SetPWM(u8 level) //设置风扇等级 1 2 3 4是自动不用管风速
{
// PutChar(speedFlag);
if(level==1) //1是9.8k
{
setPWMWide(DUTY1);
}
else if(level==2)
{
setPWMWide(DUTY2);
}
else if(level==3)
{
setPWMWide(DUTY3);
}
}
//中断初始化配置
void InterruptInit()
{
P2M1 &= 0<<1; //PWM4 P2.1 设置推挽
P2M0 |= 1<<1;
P2M1 &= 0<<7; //PWM4 P2.7 设置推挽
P2M0 |= 1<<7;
PWM=0;
PWM2=0;
P_SW2 |= 0x80; //使能访问XSFR
PWMIF=0x00;
PWMFDCR = 0x00; //关闭PWM异常检测,P5.4和P5.5在IIC中使用,如果不关闭会一直进入异常导致无法设置PWM占空比
PWMCFG = 0x00; //配置PWM的输出初始电平为低电平
PWMCKS = 0x00; //选择PWM的时钟为Fosc/(0+1)
PWMC = CYCLE; //设置PWM周期
//板子PWM4 芯片PWM2_2 P2.7
PWM2T1 = 0x0000; //设置PWM2第1次反转的PWM计数
PWM2T2 = CYCLE * DUTY1 / 100; //设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWM2CR |= 0x08; //选择PWM2输出到P2.7,不使能PWM2中断
//板子PWM2 芯片PWM3 P2.1
PWM3T1 = 0x0000; //设置PWM2第1次反转的PWM计数
PWM3T2 = CYCLE * DUTY1 / 100; //设置PWM2第2次反转的PWM计数
//占空比为(PWM2T2-PWM2T1)/PWMC
PWM3CR = 0; //选择PWM2输出到P2.1
//使能
PWMCR = 0x03; //使能PWM信号输出
PWMCR |= 0x80; //使能PWM模块
P_SW2 &= ~0x80;
}