打印

大家帮我分析一个用中断控制的PWM输出。

[复制链接]
2687|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xinmcu|  楼主 | 2010-10-19 17:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近在写一个用单片机控制音量程序,写的过程中遇到些问题,我还是新手。希望高手门一起来帮我看看。
目的:
1.单片机连接到音量控制电路的其中一个可以用线性电压控制音量大小的端口(音频电路图中的SPKSW端口)
2.由于51单片机不能直接输出线性电压,所以让我想到了PWM控制电压量。

问题:
1.不知道选择多大频率的PWM信号好;
2.写程序的时候发现不能修改TH0、TL0的赋值。

音频电路:
            [localimg=613,470]1[/localimg]


程序:(好简单的程序,高手们不要笑哦。。。。。。)
#include<reg52.h>

sbit PWM_Out =P1^5;
sbit Key_down=P1^1;
sbit Key_up    =P1^0;

unsigned  char x=0;
unsigned char Pwm_value=53;

void delay_1ms(unsigned char z)
{
         unsigned char i,j;
         for(i=z;i>0;i--)
                 for(j=110;j>0;j--);
}

void main()
{
            TMOD=0x11;
            TH0=(65536-30)/256;
            TL0=(65536-30)%256;
            TH1=(65536-50)/256;
            TL1=(65536-50)%256;
             EA=1;
            ET1=1;
            ET0=1;
            TR0=1;
            TR1=1;
        while(1)
        {
               if(Key_down==0)
             {
               delay_1ms(5);

                  if(Key_down==0)
                  {
                       Pwm_value=Pwm_value-100;
                      if(Pwm_value<=0)
                      {Pwm_value=0;}

                     while(!Key_down);   
                 }
             }


                  if(Key_up==0)
                 {
                        delay_1ms(5);
                        if(Key_up==0)
                         {
                                  Pwm_value=Pwm_value+100;
                                   if(Pwm_value>=65536)
                                   {Pwm_value=0;}

                                   while(!Key_up);   
                          }
                   }
    }
  
}


void PWM_timer0()  interrupt 1
{
TH0=(65536-30)/256;
TL0=(65536-30)%256;
PWM_Out=0;
}


void PWM_timer1()  interrupt 3
{
TH0=(65536-Pwm_value)/256;
TL0=(65536-Pwm_value)%256;
PWM_Out=1;   
}

按键操作,不能改变PWM输出的高电平占空比哦!!!!!!!!!!!

相关帖子

沙发
artxun| | 2010-10-19 20:09 | 只看该作者
你这个完全不用搞得那么复杂的,一个定时器就好了,
void PWM_timer1()  interrupt 3
{
TH0=(65536-?)/256;
TL0=(65536-?)%256;
设一个标志   
}
再写一个按键计数器的程序,根据按键的次数来设定输出L的时间,再用你想设的周期时间来减去L的时间,就得到H的时间。如此不停的循环。就得到一个连续可调脉宽的波形了。

使用特权

评论回复
板凳
免证入网| | 2010-10-19 22:05 | 只看该作者
不能传就用全局量x,主函数里根据要求改变x,然后每次中断中赋计数初值用(65535-x)%255……

使用特权

评论回复
地板
xinmcu|  楼主 | 2010-10-20 11:44 | 只看该作者
谢谢你们的建议:
              我按了2楼同志说的做了(其实之前也试过),效果还是一样;
              可最终问题还是想3楼说的“X”的值就是赋不了哦;

             继续等解救的办法!!

继续看看,这个我修改之后的程序:(一开始我以为每次改变的幅度太小了,造成频率没变化,现在修改之后,按键计数之后还是频率没变)
1:波形可以出来,频率是230HZ;
2:上升沿的时间达到1.5us了,下降沿时间80ns;

可最终问题还是一样的存在:
执行一下程序时,按键计数之后,波形的低电平占空比还是没用发生任何变化;

程序:
#include<reg52.h>

sbit PWM_Out =P0^4;
sbit Key_down=P1^1;
sbit Key_up  =P1^0;

unsigned  char x=0;
unsigned char temp;
void delay_1ms(unsigned char z)
{
        unsigned char h,k;
        for(h=z;h>0;h--)
                for(k=110;k>0;k--);       
}
void main()
{
    TMOD=0x01;
        TH0=(65536-100)/256;
        TL0=(65536-100)%256;

        EA=1;
        ET0=1;
    TR0=1;

        while(1)
        {
                PWM_Out=1;
                if(Key_down==0)
                {
                        delay_1ms(5);
                        if(Key_down==0)
                        {
                                    x--;       
                                if(x<=0)
                                {x=0;}
                                while(!Key_down);                       
                        }
                }
                if(Key_up==0)
                {
                        delay_1ms(5);
                        if(Key_up==0)
                        {
                                x++;
                                if(x>=8)
                                {x=0;}
                                while(!Key_up);                       
                        }       
                }
        }
               
}
void PWM_timer0()  interrupt 1
{
        switch(x)
        {
                case 0:
                                temp=100;
                                break;
                case 1:
                                temp=600;
                                break;
                case 2:
                                temp=1200;
                                break;
                case 3:
                                temp=2000;
                                break;
                case 4:
                                temp=3500;
                                break;
                case 5:
                                temp=5600;
                                break;
                case 6:
                                temp=8000;
                                break;
                case 7:
                                temp=10000;
                                break;
            default: break;
                          
        }
        TH0=(65536-temp)/256;
        TL0=(65536-temp)%256;
        PWM_Out=0;       
}

使用特权

评论回复
5
免证入网| | 2010-10-20 12:12 | 只看该作者
问题不在参数,参数是传进去了,;是你PWM_Out=0;你要实现什么请问?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

10

帖子

1

粉丝