搜索
bottom↓
回复: 22

单片机两个定时器控制输出pwm波

[复制链接]

出0入0汤圆

发表于 2013-3-12 12:02:52 | 显示全部楼层 |阅读模式
我的目的是用定时器0控制pwm的周期,固定它。然后定时器1控制pwm的占空比,可是问题是定时器1根本不工作啊,还有一大部分程序运行时间都浪费到了定时器0里面

        /*定时器赋初值----------------*/
unsigned char pwm_on;
sbit pwm_out=P2^4;//pwm输出端口
void TimerInit(void)
{       
       
        TMOD=0x11;//定时器0和定时器1工作于模式一
        TH0=(65536-50)/256;//初值50us,pwm频率为20khz
        TL0=(65536-50)%256;
        ET0=1;//打开定时器中断
        TR0=1;//启动定时器0
        PT0=0;//定时器0优先级低
       
        TR1=0;
        ET1=1;
        PT1=1;

        EA=1;//开总中断
       
}


void main()
{
        pwm_on=25;//占空比设置
        pwm_out=0;
        Lcd_Init();//LCD初始化
        TimerInit();
        while(1)
        {
                DataProcessing ();//数据处理
                Display();
        }
}

//中断控制pwm
void Timer0irp (void) interrupt 1
{
        pwm_out=1;
        TH0=(65536-50)/256;
        TL0=(65536-50)%256;//定时器0设置为50ms的周期
        TH1=(65536-pwm_on)/256;       
        TL1=(65536-pwm_on)%256;;//由定时器1设置占空比
        TR1=1;
       
//        CLK=~CLK;
       
}
void Timer1irp (void) interrupt 3
{
        TR1=0;
        pwm_out=0;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2013-3-12 12:14:45 | 显示全部楼层
人工置顶
头像被屏蔽

出0入0汤圆

发表于 2013-3-12 14:47:59 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2013-3-12 16:49:00 | 显示全部楼层
bbs2009 发表于 2013-3-12 14:47
不理解 LZ 为何要用 2个定时器, 一个就够了

我是觉得2个定时器简单方便,一个不好调,所以就用来2个,问题出在哪了呢

出0入4汤圆

发表于 2013-3-12 16:54:44 | 显示全部楼层
bbs2009 发表于 2013-3-12 14:47
不理解 LZ 为何要用 2个定时器, 一个就够了

看lz的程序,定时器0是输出1,定时器1中断是输出0,只是lz没想好,定时器是同时工作的,其实lz只要让定时器轮流工作就可以了。在定时器0中断时关0开1中断,在定时器1中断时关1开0中断,只是这样浪费了个定时器而已
头像被屏蔽

出0入0汤圆

发表于 2013-3-12 17:03:33 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

 楼主| 发表于 2013-3-12 17:13:09 | 显示全部楼层
bbs2009 发表于 2013-3-12 17:03
一个定时器只有一个中断岂不更好,
二次中断, 一次管 高电平段, 一次管低电平段。 二次时间之和为 PWM  ...

好的,我试试这个方法,谢谢

出0入0汤圆

 楼主| 发表于 2013-3-12 17:13:33 | 显示全部楼层
kcfoo1 发表于 2013-3-12 16:54
看lz的程序,定时器0是输出1,定时器1中断是输出0,只是lz没想好,定时器是同时工作的,其实lz只要让定时 ...

谢谢,我也觉得浪费,只是觉得这样方便啊

出0入4汤圆

发表于 2013-3-12 17:21:40 | 显示全部楼层
chensheng00 发表于 2013-3-12 16:49
我是觉得2个定时器简单方便,一个不好调,所以就用来2个,问题出在哪了呢 ...

lz你的0和1 是同时工作的,如果0的时间比1少,那1永远也不能中断,因为0会重新刷新1的时间,即使比他多也会让1时间刷新,你不仅要在0中断控制1中断开还要关0中断,同样1中断时也如此,同时0中断时刷1时间。1中断也要刷0时间,其实用1个定时器还可以输出任意多组pwm,只要把定时器当个时基就可以办到,比如1个中断时为1us,那你累加到10个时基输出高电平,然后在累加到10个时基输出低电平,就可输出20us的占空50%的pwm,

出0入0汤圆

 楼主| 发表于 2013-3-12 17:49:13 | 显示全部楼层
kcfoo1 发表于 2013-3-12 17:21
lz你的0和1 是同时工作的,如果0的时间比1少,那1永远也不能中断,因为0会重新刷新1的时间,即使比他多也 ...

你看我改成这样了,还是不行,我用k软件仿真了下,发现程序作死的运行在2个中断程序中,而运行其他的 程序的时间很少,pwm波也不好控制

出0入0汤圆

 楼主| 发表于 2013-3-12 17:53:28 | 显示全部楼层
kcfoo1 发表于 2013-3-12 17:21
lz你的0和1 是同时工作的,如果0的时间比1少,那1永远也不能中断,因为0会重新刷新1的时间,即使比他多也 ...

我设置定时器0控制周期的,定时器1是控制占空比,所以定时器一定比定时器0的时间少啊

出0入0汤圆

 楼主| 发表于 2013-3-12 17:54:28 | 显示全部楼层
chensheng00 发表于 2013-3-12 17:53
我设置定时器0控制周期的,定时器1是控制占空比,所以定时器一定比定时器0的时间少啊 ...


/*定时器赋初值----------------*/
unsigned char pwm_on;
sbit pwm_out=P2^4;//pwm输出端口
void TimerInit(void)
{       
       
        TMOD=0x11;//定时器0和定时器1工作于模式一
        TH0=(65536-pwm_on)/256;//设置占空比为pwm_on,
        TL0=(65536-pwm_on)%256;
        ET0=1;//打开定时器中断
        TR0=1;//启动定时器0
       
        TR1=0;
        ET1=1;

        EA=1;//开总中断
       
}


void main()
{
        pwm_on=20;//占空比设置
        pwm_out=1;
        Lcd_Init();//LCD初始化
        TimerInit();
        while(1)
        {
                DataProcessing ();//数据处理
                Display();
        }
}

//中断控制pwm
void Timer0irp (void) interrupt 1
{       

                TR0=0;
                pwm_out=1;
                TH1=(65536-50+pwm_on)/256;       
                TL1=(65536-50+pwm_on)%256;//由定时器0设置占空比,周期为50us
                TR1=1;

       
}
void Timer1irp (void) interrupt 3
{       
                TR1=0;
                pwm_out=1;
                TH0=(65536-pwm_on)/256;//
                TL0=(65536-pwm_on)%256;
                TR0=1;
       
}

出0入4汤圆

发表于 2013-3-12 18:25:01 | 显示全部楼层
chensheng00 发表于 2013-3-12 17:54
/*定时器赋初值----------------*/
unsigned char pwm_on;
sbit pwm_out=P2^4;//pwm输出端口

t1中断要pwm_out=0;吧,另外你可以把运算放在中断外,不是没次中断都要计算吧,

出0入4汤圆

发表于 2013-3-12 18:28:31 | 显示全部楼层
你用的是什么单片机呀,有2个16位定时器

出0入0汤圆

 楼主| 发表于 2013-3-12 18:30:01 | 显示全部楼层
kcfoo1 发表于 2013-3-12 18:25
t1中断要pwm_out=0;吧,另外你可以把运算放在中断外,不是没次中断都要计算吧, ...

恩是的,T1的pwm_out=0;发的时候急了,但是改了之后pwm控制依然不行啊,还有你说的运算是说赋初值吗》

出0入0汤圆

 楼主| 发表于 2013-3-12 18:30:31 | 显示全部楼层
kcfoo1 发表于 2013-3-12 18:28
你用的是什么单片机呀,有2个16位定时器

AT89C52啊

出0入4汤圆

发表于 2013-3-12 18:38:20 | 显示全部楼层
chensheng00 发表于 2013-3-12 18:30
恩是的,T1的pwm_out=0;发的时候急了,但是改了之后pwm控制依然不行啊,还有你说的运算是说赋初值吗》 ...

关中断好像是ET0=0 吧,你把ET位控制也加进去试试,th0=da1; da1在住程序循环中计算就可以了,

出0入0汤圆

 楼主| 发表于 2013-3-12 18:44:58 | 显示全部楼层
kcfoo1 发表于 2013-3-12 18:38
关中断好像是ET0=0 吧,你把ET位控制也加进去试试,th0=da1; da1在住程序循环中计算就可以了, ...

根本问题没有解决啊,pwm还是不能控制,主程序不怎么会写

出0入0汤圆

 楼主| 发表于 2013-3-13 00:29:31 | 显示全部楼层
顶下,有人来么

出0入93汤圆

发表于 2013-3-13 07:33:13 | 显示全部楼层
chensheng00 发表于 2013-3-12 18:30
AT89C52啊

未验证,原理上应该是这样的,楼主验证一下。

52的T2定时器工作在脉冲输出状态时,可以等效为一个残废的PWM,软件控制下就好了。
T2的脉冲输出时,是占空比为50%的方波,我们可以在T2溢出中断调整T2的捕获时间,这样就实现了占空比的调节。
T2定时器很牛X的,用在你这个问题上有点大材小用了。

下面是示例伪代码,我没有用Keil演算,直接手写的...大概就是这个意思...T2向上记数,[TH2、TL2]与T2CAP匹配了就将P1_1反向,并从0开始计数。
void Timer2irp (void) interrupt 5       //忘了中断号是多少了
{        
      if(P1_1)                               //T2好想必须由这个IO输出脉冲
            T2CAP = pwm_on;
      else
            T2CAP = 50us - pwm_on;
      TF2 = 0;                              //T2比较讨厌,得自己手动清除标志
}

出0入0汤圆

 楼主| 发表于 2013-3-13 09:45:24 | 显示全部楼层
takashiki 发表于 2013-3-13 07:33
未验证,原理上应该是这样的,楼主验证一下。

52的T2定时器工作在脉冲输出状态时,可以等效为一个残废的 ...

如果把端口改了,我又要改其他元器件的接法,比较麻烦啊,可以指出来我的那个程序错在哪了吗!我怎么看都是对得,但是一调试就是错的

出0入93汤圆

发表于 2013-3-13 10:21:08 | 显示全部楼层
chensheng00 发表于 2013-3-13 09:45
如果把端口改了,我又要改其他元器件的接法,比较麻烦啊,可以指出来我的那个程序错在哪了吗!我怎么看都 ...

程序是没错,但是你的逻辑上错了。

你用的12M晶振吧,这样每个指令周期就是1us。然后你要求pwm_out=1; pwm_on=20us,对于这个单片机来说,是无法完成的,建议就只有换单片机。
pwm_out对应于1us,即一条指令周期,这么点时间给定时器赋值都不够。

出0入0汤圆

 楼主| 发表于 2013-3-13 10:32:12 | 显示全部楼层
takashiki 发表于 2013-3-13 10:21
程序是没错,但是你的逻辑上错了。

你用的12M晶振吧,这样每个指令周期就是1us。然后你要求pwm_out=1; p ...

谢谢你了,你可以帮我简单的写一下程序吗,由2个定时器控制脉冲的输出,逻辑冲突还是有点不理解,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 12:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表