这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » pwm,time0 大家帮帮忙,为什么pwm选用time0时无效阿

共3条 1/1 1 跳转至

pwm,time0 大家帮帮忙,为什么pwm选用time0时无效阿

院士
2006-09-17 18:14:16     打赏
pwm,time0 大家帮帮忙,为什么pwm选用time0时无效阿



关键词: time0     大家     帮帮忙     为什么     选用     无效    

院士
2006-12-22 22:43:00     打赏
2楼
问 #include<reg52.h>
void main(void)
{
AUXR = 0x80;   //问题在这里,为什么我定义的X12无效呢.
               //这个寄存器不管怎么设置都不能改变PWM的频率,
               //请问怎么样解决这个问题阿.
CMOD = 0x02; // Setup PCA timer
CL = 0x00;
CH = 0x00;
CCAP0L = 0xc0; //Set the initial value same as CCAP0H
CCAP0H = 0xc0; //25% Duty Cycle
CCAPM0 = 0x42; //0100,0010 Setup PCA module 0 in PWM mode
CR = 1; //Start PCA Timer.
while(1){};
} 1: cmod的问题
CMOD - PCA 模式 寄存器的位描述 (地址:D9H)
位    符号        描述
7     CIDL        空闲控制:CIDL=0 时,空闲模式下PCA计数器继 续工作。CIDL=1时,空闲模式下PCA 计数器停止工作。
6~3    保留        为将来之用。
2 - 1 CPS1,CPS0     PCA时钟源输入选择
      0       0     0,内部时钟,Fosc/12
      0       1     1,内部时钟,Fosc/2
      1       0    2,定时器0溢出,通过改变定时器0的溢出率,
                     可以实现可调频率的PWM输出
      1       1     3,ECI/P3.4脚的外部时钟输入(最大速率=Fosc/2)
0     ECF    PCA计数溢出中断使能: ECF= 1 时,
                  使能寄存器C C O N C F 位的中断。

而你的CMOD = 0x02,,实际CPS1,CPS0=0,1
所以PCA时钟源为内部时钟,Fosc/2 2: 谢谢了,不过我改过后仍然不能改变pwm的频率没看清楚真是惭愧.
现改为cmod=0x04;
用的是内部时钟源,time0为1T,time1为T12
发觉time1正常,但是time0不管是不是T1的还是T12的都是一样没有改变,不知道何呢? 3: 不好意思,问题出来了,已经可以调节但是好像对不上号,因为按照6M一个时钟周期算的,应该有23k左右的频率.
而我现在在示波器上看到的最小的周期为85us左右,就是只有11k左右,不知道是哪儿出问题了,另外这样设置后,time1不能中断响应了,不知道问题出在哪儿? 4: 是不是因为我的time0响应中断太多了#include<reg52.h>
所以time1没法响应中断呢

void time1() interrupt 3
{
TH1=0x15;
TL1=0xAF;
P1_0=!P1_0;    //每次进入中断处理就反转一次
}


void main(void)
{
AUXR = 0x80;   
CMOD = 0x04; // Setup PCA timer 这里改了后pwm频率
             // 可以改变了,但是不能达到最高频率,
             // 最后测得有11k左右.
CL = 0x00;
CH = 0x00;
CCAP0L = 0xc0; //Set the initial value same as CCAP0H
CCAP0H = 0xc0; //25% Duty Cycle
CCAPM0 = 0x42; //0100,0010 Setup PCA module 0 in PWM mode
CR = 1; //Start PCA Timer.

TMOD=0x12 ;            //定时器0的寄存器设置
TH0=0xff ;
TL0=0xff ;
ET0=1;                //开中断,time0准备工作
TR0=1;                //time0开始工作

TH1=0x15;    
TL1=0xAF;    
ET1=1;
TR1=1;

while(1){};
}


程序并没有进入过time1的中断处理程序段,就是P1_0没有闪烁.是不是time0完全占用了cpu的资源呢,要是这样怎么处理才可以得到最大pwm频率的同时又可以做其他的处理呢. 5: 程序改一下2条语句timer0是要工作在自动装载模式,并且初始值TH0=0xff; TL0=0xff;但不用打开中断

这种模式下,timer0是不会占用CPU运行资源的




void main(void)
{
AUXR = 0x80;   
CMOD = 0x04; // Setup PCA timer 这里改了后pwm频率
             // 可以改变了,但是不能达到最高频率,
             // 最后测得有11k左右.
CL = 0x00;
CH = 0x00;
CCAP0L = 0xc0; //Set the initial value same as CCAP0H
CCAP0H = 0xc0; //25% Duty Cycle
CCAPM0 = 0x42; //0100,0010 Setup PCA module 0 in PWM mode
CR = 1; //Start PCA Timer.

TMOD=0x12 ;            //定时器0的寄存器设置
TH0=0xff ;
TL0=0xff ;
/////////////////11111111111111111无需中断
//ET0=1;                //开中断,time0准备工作

TR0=1;                //time0开始工作

TH1=0x15;    
TL1=0xAF;    
ET1=1;
TR1=1;
///////////////222222222222222222总中断没有开
EA=1;                

while(1){};
} 6: timer0是要工作在自动装载模式,但不用打开中断timer0是要工作在自动装载模式,但不用打开中断
======完全正确 7: 谢谢两位了,难怪我觉得那么别扭还以为空着它就可以了,想不到这样也会令到它执行.而且其他的中断都很难相应. 8: 晕,不行噢用这个得到的是一个周期为160us的方波

按照 频率=系统时钟频率/256, 而程序上用了Tx12,就是用了振荡器频率,内置频率为6M,所以 频率=6000000/256=23437.5,即23k左右.

但是用上面程序得到的PWM方波周期为160us左右.为什么会差别那么大呢,是不是哪儿出错了?

能帮我测一下为什么会这样呢.
另外还有一个问题就是,即使time0用了方式2,自动加载时间常数,但是time1还是不能进入中断.
我用的是stc12c2052ad内置晶振.编程时看到下载程序的晶振为5.820264M. 9: 同样这段程序,在另外一片为95us又试过一片,还是得到85-90us,算下来就是10k左右了,为什么跟原来公式算出来的刚刚差了一半呢,是不是我哪儿没有设好?有没有朋友身边有2052ad的,帮我测试一次可以吗. 10: .不是fosc/2吗?我怎么感觉你是用fosc在算? 11: 你看清楚了哦,我是用time0文档78页上是这样计算的

当我选用time0,而且选用1T不分频时,常数TH0=0xFF;TL0=0xff;
这样我就应该得到最大的pwm了,但是一直都不是预算值范围内呢. 12: .如果不是自动装载模式(8位),不是还要进定时器中断给它设初值吗?一个时钟周期能设好吗? 13: 你应该没有看我上面给出的程序吧我就是用方式2的.这样ff才可以1T中断阿. 14: 建议你再把程序贴上来一下,还有先外接6M的晶振至于timer1没有进入中断,想问一下 总中断是否开启

EA=1; 15: EA=1;是我忘记写进来了,原来程序不在身边就直接写了,忘记了程序本身是有的,只是漏了在这里.
我不知道这里有多少人在用PWM,说实在的,PWM是很好用的,但是我一直没弄明白为什么用time0会这样怪的结果,没有人用过吗?
当我用1/2时钟时,程序很正常的运行,P1_0可以正常反转.
但是当改为time0做PWM时钟源时,time1就不再响应了,也就是P1_0不再闪烁.
这个程序相当简单的,只是一些配置PWM、time0和time1的语句,照例而来的,
但是始终没有得到07/08资料上说的,当使用time0时,可以达到1T的周期!!

在这里我也想请姚工看看,为什么资料显示的数据和实验数据相差那么大呢。
不知道贵公司这方面是否做过详细测试?我觉得PWM这个功能在这个芯片上的
价值却是不错的,但是无法驾驭,有点可惜了。刚刚涉足单片机很多不会的,
望指教一二,感谢了。

#include<reg52.h>
所以time1没法响应中断呢

void time1() interrupt 3
{
TH1=0x15;
TL1=0xAF;
P1_0=!P1_0;    //每次进入中断处理就反转一次
}


void main(void)
{
AUXR = 0x80;  //time0时钟选择是不分频模式.time1是12分频模式.

CMOD = 0x04; // Setup PCA timer 这里改了后pwm频率
             // 可以改变了,但是不能达到最高频率,
             // 最后测得有11k左右.
CL = 0x00;    //真想这两个常数是可设置的,这样就可以PWM分频了.
CH = 0x00;    //
CCAP0L = 0xc0; //Set the initial value same as CCAP0H
CCAP0H = 0xc0; //25% Duty Cycle
CCAPM0 = 0x42; //0100,0010 Setup PCA module 0 in PWM mode
CR = 1; //Start PCA Timer.
EA=1;

TMOD=0x12 ;            //定时器0的寄存器设置为方式2,常数自动加载。
TH0=0xff ;
TL0=0xff ;
ET0=1;                //开中断,time0准备工作
TR0=1;                //time0开始工作

TH1=0x15;    
TL1=0xAF;    
ET1=1;
TR1=1;


while(1){};
}

以上请gfs0521大哥等过目,帮我看看是不是哪儿错了,先谢谢了.

这里很少见过百跟帖的帖子,真希望可以看到,很多论坛跟帖过万也不少呢,这里多点人来就好了. 16: 另外我试过外接晶振了 17: 上帖出问题没有发完当用11.0592M的外部时钟,不分频用time0做PWM的时钟源,结果是比内部时钟刚好频率是快一倍.20k左右.

也就是说并不是内部时钟源的错.用内部的和外部的时钟是一样的.所以排除了内部时钟源出错的嫌疑.



另.如果是stc的芯片都是1T时钟运行的,我想应该是带PWM的stc芯片都可以运行上面这个程序做测试的.不知道大家是怎么样使用PWM的呢.没有人检测过芯片的最大PWM输出频率吗?stc出来好长时间了哦.上面的程序帮我下载一下到你们的仿真器测一下吧,道个结果讨论一下阿.

18: 问题再于你对我们的回答没有认真看待/////////////////11111111111111111无需中断
//ET0=1;                //开中断,time0准备工作

把上面这条屏蔽掉 19: 确实是我没看清楚,抱歉了time1已经正常.谢谢了
不过呢,pwm的频率还是10k左右无法调快了.

gfs0521兄,能不能麻烦你看看程序是不是哪儿还可以调快点的呢.
就上面程序撤掉ET0=1;后只是令到其它中断可以正常工作了,但是pwm的频率并没有因而而提高?输出仍然是10k左右呢.

专家
2022-08-03 22:22:59     打赏
3楼

感谢分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]