chensheng00 发表于 2013-3-12 12:02:52

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

我的目的是用定时器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;
}

chensheng00 发表于 2013-3-12 12:14:45

{:smile:}人工置顶

bbs2009 发表于 2013-3-12 14:47:59

chensheng00 发表于 2013-3-12 16:49:00

bbs2009 发表于 2013-3-12 14:47 static/image/common/back.gif
不理解 LZ 为何要用 2个定时器, 一个就够了

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

kcfoo1 发表于 2013-3-12 16:54:44

bbs2009 发表于 2013-3-12 14:47 static/image/common/back.gif
不理解 LZ 为何要用 2个定时器, 一个就够了

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

bbs2009 发表于 2013-3-12 17:03:33

chensheng00 发表于 2013-3-12 17:13:09

bbs2009 发表于 2013-3-12 17:03 static/image/common/back.gif
一个定时器只有一个中断岂不更好,
二次中断, 一次管 高电平段, 一次管低电平段。 二次时间之和为 PWM...

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

chensheng00 发表于 2013-3-12 17:13:33

kcfoo1 发表于 2013-3-12 16:54 static/image/common/back.gif
看lz的程序,定时器0是输出1,定时器1中断是输出0,只是lz没想好,定时器是同时工作的,其实lz只要让定时 ...

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

kcfoo1 发表于 2013-3-12 17:21:40

chensheng00 发表于 2013-3-12 16:49 static/image/common/back.gif
我是觉得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,

chensheng00 发表于 2013-3-12 17:49:13

kcfoo1 发表于 2013-3-12 17:21 static/image/common/back.gif
lz你的0和1 是同时工作的,如果0的时间比1少,那1永远也不能中断,因为0会重新刷新1的时间,即使比他多也 ...

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

chensheng00 发表于 2013-3-12 17:53:28

kcfoo1 发表于 2013-3-12 17:21 static/image/common/back.gif
lz你的0和1 是同时工作的,如果0的时间比1少,那1永远也不能中断,因为0会重新刷新1的时间,即使比他多也 ...

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

chensheng00 发表于 2013-3-12 17:54:28

chensheng00 发表于 2013-3-12 17:53 static/image/common/back.gif
我设置定时器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;
       
}

kcfoo1 发表于 2013-3-12 18:25:01

chensheng00 发表于 2013-3-12 17:54 static/image/common/back.gif
/*定时器赋初值----------------*/
unsigned char pwm_on;
sbit pwm_out=P2^4;//pwm输出端口


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

kcfoo1 发表于 2013-3-12 18:28:31

你用的是什么单片机呀,有2个16位定时器

chensheng00 发表于 2013-3-12 18:30:01

kcfoo1 发表于 2013-3-12 18:25 static/image/common/back.gif
t1中断要pwm_out=0;吧,另外你可以把运算放在中断外,不是没次中断都要计算吧, ...

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

chensheng00 发表于 2013-3-12 18:30:31

kcfoo1 发表于 2013-3-12 18:28 static/image/common/back.gif
你用的是什么单片机呀,有2个16位定时器

AT89C52啊

kcfoo1 发表于 2013-3-12 18:38:20

chensheng00 发表于 2013-3-12 18:30 static/image/common/back.gif
恩是的,T1的pwm_out=0;发的时候急了,但是改了之后pwm控制依然不行啊,还有你说的运算是说赋初值吗》 ...

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

chensheng00 发表于 2013-3-12 18:44:58

kcfoo1 发表于 2013-3-12 18:38 static/image/common/back.gif
关中断好像是ET0=0 吧,你把ET位控制也加进去试试,th0=da1; da1在住程序循环中计算就可以了, ...

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

chensheng00 发表于 2013-3-13 00:29:31

{:sad:}顶下,有人来么

takashiki 发表于 2013-3-13 07:33:13

chensheng00 发表于 2013-3-12 18:30 static/image/common/back.gif
AT89C52啊

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

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

下面是示例伪代码,我没有用Keil演算,直接手写的...大概就是这个意思...T2向上记数,与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比较讨厌,得自己手动清除标志
}

chensheng00 发表于 2013-3-13 09:45:24

takashiki 发表于 2013-3-13 07:33 static/image/common/back.gif
未验证,原理上应该是这样的,楼主验证一下。

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

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

takashiki 发表于 2013-3-13 10:21:08

chensheng00 发表于 2013-3-13 09:45 static/image/common/back.gif
如果把端口改了,我又要改其他元器件的接法,比较麻烦啊,可以指出来我的那个程序错在哪了吗!我怎么看都 ...

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

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

chensheng00 发表于 2013-3-13 10:32:12

takashiki 发表于 2013-3-13 10:21 static/image/common/back.gif
程序是没错,但是你的逻辑上错了。

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

谢谢你了,你可以帮我简单的写一下程序吗,由2个定时器控制脉冲的输出,逻辑冲突还是有点不理解,
页: [1]
查看完整版本: 单片机两个定时器控制输出pwm波