打印

请教一个STC 定时器方式PWM频率计算问题?

[复制链接]
11657|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhuyi2576|  楼主 | 2011-4-26 12:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhuyi2576 于 2011-4-26 15:13 编辑

用PCA模块PWM

我要产生自己的PWM频率。肯定要用到定时器T0益出做为PCA时钟源吧


比如我用12M晶掁 12T模式

定时器0 定时时间为 1us--65535us 也就是PCA时钟也就是1us---65535us可调

转化成频率就是1M--15.259Hz

根据PWM频率=PCA时钟频率/256  PWM范围就是3.9k----0.059Hz

对吗?频率也太低了吧,就算是1T模式,最大也就3.9*12=46.8K

请看我程序,假设最大情况下,实际测量并不是3.9K

unsigned char duty = 0x80;   //50%占空比
unsigned int fre = 0xffff;     //初值 1us中断,PCA频率=1MHz  PWM频率=1M/256=3.9KHz
void timer0_int (void) interrupt 1 using 1   
{   
TH0 = fre >> 8;  //定时器初值高位
TL0 = fre & 0xff; //低位  
// led = ~led;   
}
void timer0_init(void)   
{   
// TMOD &= 0xf0;   
TMOD |= 0x01;   
TH0 = 0xff;   
TL0 = 0xff;   
TR0 = 1;   
ET0 = 1;   
}   
void pwm_init(void)   
{   
CMOD = 0x05;   //计数时钟选择 使用T0,实现PWM频率可调
CL = 0x0;    //计数器清0
CH = 0x0;   
CCAP3H = duty;  //比较器高位,50%占空比 捕获比较计数器,PWM模式下用来控制输出占空比
CCAPM3 = 0x42;  //PWM模式,使能比较器,CEX0 输出
CR = 1;   //启动PCA计数
}   
void main(void)
{  
    pwm_init();   
timer0_init();   
EA = 1;
while(1)
{
   ;

}
}

相关帖子

沙发
o888888880| | 2012-12-18 15:43 | 只看该作者
我的11.0592M晶振实测只有1.199KZ

使用特权

评论回复
板凳
ygrong_2008| | 2015-9-16 15:17 | 只看该作者
楼主的问题解决了吗,我用的12M晶振,输出最大频率实测为46.78KHz,是不是在此晶振下就是最高的了呢

使用特权

评论回复
地板
无量寿经| | 2015-9-16 22:13 | 只看该作者

以下内容来源《51单片机轻松入门-基于STC15W4K系列》
4、脉宽调节模式
   PWM意为脉冲宽度调制,可用于调整输出直流平均电压,对于矩形波而言,输出平均压等于峰值电压×占空比,占空比是一个脉冲周期内高电平时间与周期的比值,例如,峰值电压等于5V,占空比等于50%的方波信号平均电压等于2.5V,也就是万用表直流档测量得到的电压值,8位PWM模式结构如图8-6所示, PWM输出不需要使用中断。
图8-6  8位PWM模式结构图
通过程序设定寄存器PCA_PWMn(n=0,1,2,下同)中的位EBSn_1及EBSn_0,使其工作于8位PWM或7位PWM或6位PWM模式,当[EBSn_1,EBSn_0]=[0,0](默认值)或[1,1]时,PCA模块n工作于8位PWM模式,此时将{0,CL[7:0]}与[EPCnL,CCAPnL[7:0]]进行比较,当{0,CL[7:0]}中的值小于{EPCnL,CCAPnL[7:0]}时,输出为低,当{0,CL[7:0]}中的值等于或大于{EPCnL,CCAPnL[7:0]}时,输出为高,当EPCnL=0且CCAPnL=00H时,PWM固定输出高,当EPCnL=1且CCAPnL=FFH 时,PWM固定输出低。当CL的值由FF变为00溢出时,{EPCnH,CCAPnH[7:0]}的内容自动装载到{EPCnL,CCAPnL[7:0]}中,这样可实现无干扰地更新PWM占空比,要使能PWM模式,模块CCAPMn寄存器的ECOMn和PWMn位必须置位。
PCA时钟输入源可以从以下8种中选择一种:SYSclk/12、SYSclk /8、SYSclk/6、SYSclk /4、SYSclk /2、SYSclk、定时器0的溢出、ECI/P1.2输入,PWM输出占空比由{EPCnL,CCAPnL[7:0]}确定。
8位PWM的周期 = 计数脉冲周期×256                             
8位PWM的频率 = 计数脉冲频率/256
8位PWM的脉宽时间(高电平时间)= 计数脉冲周期×(256-CCAPnL)
8位PWM的占空比 = 脉宽时间/PWM周期 = (1- CCAPnL/256) ×100%
如果要实现给定频率的PWM输出,可选择定时器0的溢出或者ECI(P1.2)脚的输入作为PCA的时钟输入源。所有PCA模块都可用作PWM输出,由于所有模块共用PCA定时器,所以它们的输出频率相同,各个模块的输出占空比是独立变化的,当某个I/O 口作为PWM使用时,该口的状态如表8-9所示。
表8-9  I/O口作为PWM使用时的状态

PWM之前的状态
PWM输出时的状态
弱上拉/准双向口
强推挽输出/强上拉输出,要加输出限流电阻1KΩ-10KΩ
强推挽输出/强上拉输出
强推挽输出/强上拉输出,要加输出限流电阻1KΩ-10KΩ
仅为输入/高阻
PWM无效
开漏
开漏

例8.5  利用PCA 模块实现占空比固定的PWM输出。
例8.5  利用PCA 模块实现占空比固定的PWM输出。
说明:利用PCA模块0实现在P1.1输出占空比固定的PWM信号,假设R/C时钟频率Fosc = 22.1184MHz。
#include"STC15W4K.H"   // 包含STC15W4K寄存器定义文件
void initPWM()
{
   CMOD=0x80;         // #10000000B   空闲模式下停止PCA计数器工作
                      // 选择PCA时钟源为Fosc/12,禁止PCA计数器溢出时中断     
   CCAPM0=0x42;        // 设置PCA模块为PWM输出方式。
   CR=1;               // PCA计数器开始运行
}
void main()
{
   initPWM();
   CCAP0H=0x20;         // 脉宽控制
   while(1);            //让程序停在这里。
}

实验结果:用万用表测量P1.1输出频率为7.210KHz,占空比为87.5%。理论计算P1.1频率=计数脉冲频率/256 = 22118400/12/256=7.2 KHz,占空比=(1- CCAPnL/256)×100%=(1-32/256)×100%=87.5%。可见理论计算与实际结果是一致的。







使用特权

评论回复
5
coody| | 2015-9-16 22:37 | 只看该作者
ygrong_2008 发表于 2015-9-16 15:17
楼主的问题解决了吗,我用的12M晶振,输出最大频率实测为46.78KHz,是不是在此晶振下就是最高的了呢 ...

对的,12000 / 12 = 46.875KHZ,8位PWM最高的频率了。
要更高的频率,就要使用24MHZ。

对于15系列的MCU,PCA做的PWM可以选择8位、7位、6位,则后两者输出频率是8位的2倍、4倍。假设使用24MHZ,6位PWM,最高频率为375KHZ。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

258

帖子

2

粉丝