共3条
1/1 1 跳转至页
pwm,time0 大家帮帮忙,为什么pwm选用time0时无效阿
问
#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左右呢.
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左右呢.
共3条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |