利用51一个定时器输出4路频率一定PWM

[复制链接]
7158|19
 楼主| bingshuixichen 发表于 2013-8-16 16:48 | 显示全部楼层 |阅读模式
各位大侠,我利用51定时器想要输出4路频率为5K的PWM,占空比分别为25% 50% 75%  
我只写出50%的程序,其他的如何写呢?
void timer1() interrupt 3
{
        TH1=(65536-100)/256; //100us定时
        TL1=(65536-100)%256;
        count1++;
         OUT24=1;    //PWM输出
        if(count1>=1)         //时间到out24翻转
        {
                count1=0;
            OUT24=~OUT24;
       
       
        }
}                                             
草民 发表于 2013-8-16 17:16 | 显示全部楼层
给你一个25%的思路,75%的依样画葫芦。


void timer1() interrupt 3
{
        //原代码省略
        count2++;

         OUT25=1;    //PWM输出2
         //50%输出部分省略
        if(count2>=1)         
        {     
            OUT25=1;
            if(count2>=3)
            {
               OUT25=0;
               count2 = 0;
            }
        }
      
}   
lyjian 发表于 2013-8-16 19:11 来自手机 | 显示全部楼层
25%,50%,75%...
这不是才三路吗,那来四路
 楼主| bingshuixichen 发表于 2013-8-19 11:15 | 显示全部楼层
草民 发表于 2013-8-16 17:16
给你一个25%的思路,75%的依样画葫芦。

这样的话,频率是不是发生变化啦
草民 发表于 2013-8-19 11:35 | 显示全部楼层
bingshuixichen 发表于 2013-8-19 11:15
这样的话,频率是不是发生变化啦

频率当然会变,时基函数需要修改的。
比如你原来的if(count1>=1)         //时间到out24翻转
        {
                count1=0;
            OUT24=~OUT24;      
        }
改成if(count1>=2),再做判断,这样频率即缩小一倍,你再把定时器延时缩小一倍就OK。

这样不就兼顾到了?
创隆电子 发表于 2013-8-19 13:01 | 显示全部楼层
一般要两个时间的,频率与脉宽,也是你的PWM是多高频率,在一个周期内的控制高低电平地比例就是PWM了,你的这一种平率改变了,控制电机不适用
 楼主| bingshuixichen 发表于 2013-8-19 13:40 | 显示全部楼层
草民 发表于 2013-8-19 11:35
频率当然会变,时基函数需要修改的。
比如你原来的if(count1>=1)         //时间到out24翻转
        {

void timer1() interrupt 3
{
        TH1=(65536-100)/256; //100us定时
        TL1=(65536-100)%256;
        count1++;
        count2++;
        count3++;       
}
   void PWM30_OUT() //输出占空比为30%
{
        OUT20=1; // PWM输出

   if(count1>=3)         //时间到out24翻转
   {
      OUT20=0;
   }
   if(count1>=10)         //时间到out24翻转
        {
                count1=0;
            OUT20=1;       
        }

}       

void PWM50_OUT()         //输出占空比为50%
{
        OUT20=1; // PWM输出
   if(count2>=5)         //时间到out24翻转
        {
     OUT20=0;
           }

    if(count2>=10)
    { count2=0;
          OUT20=1;
        }

}
void PWM80_OUT()  //输出占空比为80%
{
        OUT20=1;
   if(count3>=8)       
   {
            OUT20=0;
   }

   if(count3>=10)         
   {
    OUT20=1;
        count3=0;
   }
}
这样 可以吗?                                             
 楼主| bingshuixichen 发表于 2013-8-19 13:43 | 显示全部楼层
草民 发表于 2013-8-19 11:35
频率当然会变,时基函数需要修改的。
比如你原来的if(count1>=1)         //时间到out24翻转
        {

我现在把频率固定在1K
草民 发表于 2013-8-19 13:43 | 显示全部楼层
看看这样如何?楼主参考一下,频率应该不会改变。

void timer1() interrupt 3
{
       static unsigned int count1,count2;
       TH1=(65536-50)/256; //注意!!改为50us定时  
        TL1=(65536-50)%256;


//---------------------------------------50%输出部分
       if(count1>=2)         //时间到out24翻转
        {           
            OUT24=1;
            if(count1>=4)               
            {
              count1=0;
              OUT24=0;     
            }                              
//--------------------------------------25%输出部分         
        if(count2>=1)         
        {     
            OUT25=1;
            if(count2>=2)
            {
               OUT25=0;
               if(conun2>=4)count2 = 0;
            }
        }
//------------------------------------75%部分类似25%
//
        count1++;
        count2++;                      //自增部分放在最后
}   
草民 发表于 2013-8-19 13:47 | 显示全部楼层
bingshuixichen 发表于 2013-8-19 13:40
void timer1() interrupt 3
{
        TH1=(65536-100)/256; //100us定时

是的,是这个思路。
 楼主| bingshuixichen 发表于 2013-8-19 14:09 | 显示全部楼层
草民 发表于 2013-8-19 13:47
是的,是这个思路。

在问一下,我以前把if(count>2)放到时基函数(void timer1() interrupt 3)中,但是定时器没反应,只有放到主函数while循环中,定时器才有反应。我现在把if(count>2)单独写成一个函数,应该没有什么问题吧,就像我上面写得那样。
草民 发表于 2013-8-19 14:18 | 显示全部楼层
bingshuixichen 发表于 2013-8-19 14:09
在问一下,我以前把if(count>2)放到时基函数(void timer1() interrupt 3)中,但是定时器没反应,只有 ...

“定时器没反应”,没能理解楼主这句话什么意思。
你的程序,输出怎么都是OUT20呢?
每一个函数里开始都写了: OUT20=1; // PWM输出
这样每次进该函数,不论你count加到几,都会置一下1.
DYCN 发表于 2013-8-19 14:32 | 显示全部楼层
尽量用自带的PWM引脚。性能好且好控制。
 楼主| bingshuixichen 发表于 2013-8-19 14:35 | 显示全部楼层
草民 发表于 2013-8-19 14:18
“定时器没反应”,没能理解楼主这句话什么意思。
你的程序,输出怎么都是OUT20呢?
每一个函数里开始都 ...

我用LCD显示秒表,把if(count>2)放到时基函数(void timer1() interrupt 3)中,LCD没有显示变化,放到主函数才有变化,我想问一下,单独写成一个函数有没有什么问题。sbit OUT20=P2^0;  我用I/O口控制电机的转速。在不同的条件下输出不同的占空比。OUT20=1,就是想让不同脉冲占空比开始时为高电平然后到一定的时间为低电平!
 楼主| bingshuixichen 发表于 2013-8-19 14:37 | 显示全部楼层
DYCN 发表于 2013-8-19 14:32
尽量用自带的PWM引脚。性能好且好控制。

刚开始使用STC的单片机,自带的PWM还不太会用,定时器还比较熟练一点
草民 发表于 2013-8-19 14:52 | 显示全部楼层
单独写成一个函数不会有什么问题,有问题可能是程序流程出错,或者定时器中断出现问题。

另外,单个IO进行电机调速的话,同一时刻只需要一种占空比的PWM,程序可以简化。
void PWM_OUT(unsigned char duty) //输出占空比为duty/10
{
   OUT20=1; // PWM输出
   if(count>=duty)               //时间到out24翻转
   {
      OUT20=0;
   }
   if(count>=10)                 //时间到out24翻转
        {
          count1=0;
          OUT20=1;      
        }
}

这样一个函数可以实现占空比10等分的PWM输出,设置参数duty值即可设置占空比,且定时器里只需要放一个count++,节省资源。如:输出30%占空比PWM只需调用void PWM_OUT(3)。
nuaabob 发表于 2013-8-19 16:33 | 显示全部楼层
STC有带PWM输出的型号,比如STC12C5628AD系列,带4路PWM输出。
we_4690 发表于 2014-4-20 16:39 | 显示全部楼层
9#的count1和count2初始值应改为1,同时清零的地方也应该改为1,不然占空比应该为40%和20%
chitu832 发表于 2016-1-4 11:05 | 显示全部楼层
学习了,受益匪浅!
梦在那 发表于 2016-1-7 22:29 | 显示全部楼层
收藏了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

27

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部