PWM输出

基础知识

PWM脉冲宽度调制:利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。

占空比:高电平所占整个周期的时间。

程序控制

要求:在P34管脚上输出PWM信号,要求频率1KHZ,占空比10%~90%可调

占空比1KHZ,所以高低电平时间之和为1ms

占空比是10%,高电平是0.1ms,低电平是0.9ms

占空比是90%,高电平是0.9ms,低电平是0.1ms

编程思路:

  1. 将1ms的周期切成10份,每份让0.1ms

  1. 将定时器2该成0.1ms的定时器中断,即中断的频率为10KHZ

  1. 定义pwm_cnt变量,在定时器2中断服务函数中将pwm_cut++,相当于0.1ms加一次,加10次等于周期1ms

  1. 根据占空比,来计算高低电平时间,再来操作IO口输出电平

//在P34管脚上输出PWM信号,要求频率1KHZ,占空比10%~90%可调
#include <STC15F2K60S2.H>

//PWM输出函数,放在0.1ms中断里执行
u8 cnt_pwm=1;
u8 pwm_duty = 90;
void PWM_Prcocess()
{
    cnt_pwm = cnt_pwm % 10 + 1;    //cnt_pwm的范围是1~10,共10个数,即定义了PWM的周期为1ms
    if(cnt_pwm <= (pwm_duty/10))
    {
        P34 = 1;
    }        
    else
    {
        P34 = 0;
    }
}
}

void Timer2Init(void)        //100微秒@12.000MHz
{
    AUXR &= 0xFB;        //定时器时钟12T模式
    T2L = 0x9C;        //设置定时初始值
    T2H = 0xFF;        //设置定时初始值
    AUXR |= 0x10;        //定时器2开始计时
    IE2 |= 0x04;                    //开定时器2中断
    EA = 1;
}


void main()
{
    Timer2Init();    
    while(1)
    {
    
    }

}

void t2int() interrupt 12           //中断入口
{
    PWM_Prcocess();

}

ps:这里没有加LED、蜂鸣器、继电器等的外设控制的初始化等函数,我有点懒得写。

LED亮度调节

注意事项:

  1. LED调光的频率最好为1KHZ,太小的频率会导致LED闪烁

  1. 占空比调节可以控制LED的亮度,但是注意由于LED是共阳极的,占空比越高,反而亮度越低

  1. 上面的代码中高电平是P34=1,在对LED控制时,可以对字节进行赋值,即led_ctrl=0xff

//PWM输出按键调节LED和数码管亮度
#include <STC15F2K60S2.H>
#include <system.H>
#include <Smg.H>
#include <keyboard.H>
#include <PWM.H>

u8 cnt_pwm=1;
u8 pwm_duty = 90;
void PWM_Prcocess()
{
    cnt_pwm = cnt_pwm % 10 + 1;    //cnt_pwm的范围是1~10,共10个数,即定义了PWM的周期为1ms
    if(cnt_pwm <= (pwm_duty/10))
    {
        device_ctrl(0x80,0xff);
    }        
    else
    {
        device_ctrl(0x80,0);
    }
}




u8 keyboard_cnt;
u8 keyboard_val;
void keyboard_process()
{
    if(keyboard_cnt>=10)
    {
        keyboard_cnt=0; 
        keyboard_read();
        keyboard_val=cont;
        if(keyboard_val==0x88)
        {
            pwm_duty=pwm_duty+1;
            if(pwm_duty>=10)
            {
                pwm_duty=0;
                
            }
            
        
        }
        if(keyboard_val==0x11)
        {
            pwm_duty=pwm_duty-1;
            if(pwm_duty<=0)
            {
                pwm_duty=10;
                
            }
        }
    }


}


void SMG_process()
{
    SMG_buf[0]=t_display[keyboard_val/16%16];
    SMG_buf[1]=t_display[keyboard_val%16];
    SMG_buf[2]=0;
    SMG_buf[3]=0;
    
    SMG_buf[4]=0;
    SMG_buf[5]=0;
    SMG_buf[6]=0;
    SMG_buf[7]=0;

}


void Timer2Init(void)        //100微秒@12.000MHz
{
    AUXR &= 0xFB;        //定时器时钟12T模式
    T2L = 0x9C;        //设置定时初始值
    T2H = 0xFF;        //设置定时初始值
    AUXR |= 0x10;        //定时器2开始计时
    IE2 |= 0x04;                    //开定时器2中断
    EA = 1;
}


void main()
{
    system_init();
    Timer2Init();
    
    
    while(1)
    {
        SMG_process();
        keyboard_process();
    }

}

void t2int() interrupt 12           //中断入口
{
    
    keyboard_cnt++;
    SMG_dispaly();
    PWM_Prcocess();
}

数码管亮度调节

//PWM输出按键调节LED和数码管亮度
#include <STC15F2K60S2.H>
#include <system.H>
#include <Smg.H>
#include <keyboard.H>
#include <PWM.H>



u8 keyboard_cnt;
u8 keyboard_val;
void keyboard_process()
{
    if(keyboard_cnt>=10)
    {
        keyboard_cnt=0; 
        keyboard_read();
        keyboard_val=cont;
        if(keyboard_val==0x88)
        {
            pwm_duty=pwm_duty+1;
            if(pwm_duty>=10)
            {
                pwm_duty=0;
                
            }        
        }
        if(keyboard_val==0x11)
        {
            pwm_duty=pwm_duty-1;
            if(pwm_duty<=0)
            {
                pwm_duty=10;
                
            }
        }
    }
}



u8 cnt_pwm=1;
u8 pwm_duty = 90;
void PWM_Prcocess()
{
    cnt_pwm = cnt_pwm % 10 + 1;    //cnt_pwm的范围是1~10,共10个数,即定义了PWM的周期为1ms
    if(cnt_pwm <= (pwm_duty/10))
    {
        SMG_buf[0]=t_display[keyboard_val/16%16];
        SMG_buf[1]=t_display[keyboard_val%16];
        SMG_buf[2]=0;
        SMG_buf[3]=0;
        
        SMG_buf[4]=0;
        SMG_buf[5]=0;
        SMG_buf[6]=0;
        SMG_buf[7]=0; 
    }        
    else
    {
         SMG_buf[0]=0;
        SMG_buf[1]=0;
        SMG_buf[2]=0;
        SMG_buf[3]=0;
        
        SMG_buf[4]=0;
        SMG_buf[5]=0;
        SMG_buf[6]=0;
        SMG_buf[7]=0; 
    }
}

void SMG_process()
{
    

}


void Timer2Init(void)        //100微秒@12.000MHz
{
    AUXR &= 0xFB;        //定时器时钟12T模式
    T2L = 0x9C;        //设置定时初始值
    T2H = 0xFF;        //设置定时初始值
    AUXR |= 0x10;        //定时器2开始计时
    IE2 |= 0x04;                    //开定时器2中断
    EA = 1;
}


void main()
{
    system_init();
    Timer2Init();
    
    
    while(1)
    {
        SMG_process();
        keyboard_process();
    }

}

void t2int() interrupt 12           //中断入口
{
    
    keyboard_cnt++;
    SMG_dispaly();
    PWM_Prcocess();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值