找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3313|回复: 21
打印 上一主题 下一主题
收起左侧

关于单片机pwm占空比让LED渐变的问题

  [复制链接]
跳转到指定楼层
楼主
ID:590194 发表于 2020-12-3 11:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
看了论坛,尝试了自己做led渐变的程序.

        yc=1000;
        led=0;
                while(1){
                  led=0;
                        a=yc-300;
                        if(a<0){a=0;}
                        Delay_us(a);
                        led=1;
                        b=1000-yc;
                        if(b<0){b=0;}
                        Delay_us(b);
                        yc=yc-1;
                        if(yc==0){led=1;break;}
                }
                while(1){
                  led=0;
                        a=yc-300;
                        if(a<0){a=0;}
                        Delay_us(a);
                        led=1;
                        b=1000-yc;
                        if(b<0){b=0;}
                        Delay_us(b);
                        yc=yc+1;
                        if(yc==1000){led=0;break;}
                }
               

不停的渐亮,渐暗,但是发现2个问题,
1.在渐亮的时候,最后会突然很亮.
2.渐变过程中,闪烁比较明显..
视频链接:http://www.56.com/u74/v_MTY4MDcwMDMx.html
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:311846 发表于 2020-12-3 15:31 | 只看该作者
//你这程序烂的很,不用定时器可以这样
while(1){
               led=0;
               Delay_us(a);
               led=1;
               Delay_us(1000-a);
                if(a++>1000)
                {a=0;break;}

             }
while(1){
               led=0;
               Delay_us(1000-a);
               led=1;
               Delay_us(a);
                if(a++>1000)
                {a=0;break;}

             }




回复

使用道具 举报

板凳
ID:687694 发表于 2020-12-3 22:55 | 只看该作者
led是压敏器件。。在达到阈值电压时会有自稳压特性,导致电流变化变小,所以均匀输出pwm并不会得到均匀光亮度增加。还有多理解pwm的意思,程序写的不太好。再优化一下吧。
回复

使用道具 举报

地板
ID:790408 发表于 2020-12-3 23:55 来自手机 | 只看该作者
可以参考一下自动控制原理这本书,
回复

使用道具 举报

5#
ID:590194 发表于 2020-12-4 03:29 来自手机 | 只看该作者
权威人物 发表于 2020-12-3 15:31
//你这程序烂的很,不用定时器可以这样
while(1){
               led=0;

你不觉得这程序简单,上手特容易吗?你的这个程序没有多大改变
回复

使用道具 举报

6#
ID:590194 发表于 2020-12-4 03:34 来自手机 | 只看该作者
lovexulu 发表于 2020-12-3 22:55
led是压敏器件。。在达到阈值电压时会有自稳压特性,导致电流变化变小,所以均匀输出pwm并不会得到均匀光亮 ...

难怪最后一秒突然很亮,是因为最亮的时候需要电流小 一下达到阈值。谢谢。那我问下, pwm不就是不停的开关,输出方波吗?
回复

使用道具 举报

7#
ID:213173 发表于 2020-12-4 07:48 | 只看该作者
sq8422779 发表于 2020-12-4 03:34
难怪最后一秒突然很亮,是因为最亮的时候需要电流小 一下达到阈值。谢谢。那我问下, pwm不就是不停的开 ...

PWM调光与线性调光是两回事。给你一个极简单且不用定时器的呼吸灯示例参考。
  1. #include<reg52.h>
  2. typedef unsigned char uchar;
  3. typedef unsigned int uint;
  4. sbit led=P1^0;
  5. uint count=0,time0=0,time1=0,DIR=0;

  6. void main( )
  7. {       
  8.         while (1)
  9.         {
  10.                 time0++;
  11.                 count++;
  12.                 if(count>=80)
  13.                 {
  14.                         count=0;
  15.                         if(DIR==0)
  16.                         time1++;
  17.                         else
  18.                         time1--;               
  19.                 }
  20.                 if(time1>=500)
  21.                         DIR=1;
  22.                 if(time1==0)
  23.                         DIR=0;
  24.                 if(time0>=500)
  25.                         time0=0;
  26.                 if(time0<=time1)
  27.                         led=0;
  28.                 else
  29.                         led=1;
  30.         }
  31. }
复制代码
回复

使用道具 举报

8#
ID:568565 发表于 2020-12-4 09:13 | 只看该作者
sq8422779 发表于 2020-12-4 03:34
难怪最后一秒突然很亮,是因为最亮的时候需要电流小 一下达到阈值。谢谢。那我问下, pwm不就是不停的开 ...

应该是均匀的改变占空比,理论上是均匀的改变占空比亮度也会变化,如果用MOS管搭一个BUCK电路用普通灯泡就可以看到均匀的变化效果
回复

使用道具 举报

9#
ID:568565 发表于 2020-12-4 09:15 | 只看该作者
这是我之前写的采用中断方式呼吸灯效果:
#include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit pwm =P2^1;
uint count=0,timer1=0,value=0;
bit DIR=1;
void main()
{
TMOD=1;
    TH0=(65536-1)/256;
TL0=(65536-1)%256;
EA=1;//开总中断
ET0=1;//开定时器0中断
   TR0=1;//TR0置位,启动定时器


while(1)
{
  
  if(timer1>value)
  {
   pwm=0;
  }
  else
  {
  pwm=1;
  }

}
}

void time0() interrupt 1 using 1
{
TH0=(65536-1)/256;
TL0=(65536-1)%256;
timer1++;
count++;
if(timer1>500)
{
timer1=0;
}
if(count>100)
  {
  count=0;
   if(DIR==1)
{
  value++;
}
if(DIR==0)
{
  value--;
}
  }

  if(value==500)
  {
     DIR=0;
  }
  if(value==0)
  {
    DIR=1;
  }

}
回复

使用道具 举报

10#
ID:568565 发表于 2020-12-4 09:16 | 只看该作者
这个是不用中断呼吸灯的代码:
#include "reg52.h"

sbit LED = P2^0;

#define TIME 300


int main()
{
        unsigned int set  =10,time = 0;
        while(1)
        {
                for(time = 0;time < TIME;time++)
                {
                        if(time > set)
                        {
                                LED = 0;       
                        }
                        else
                        {
                                LED = 1;
                        }
                }
                set++;       
                if(set == TIME)
                {
                        for(;set>0;set--)
                        {
                                for(time = 0;time < TIME;time++)
                                {
                                        if(time > set)
                                        {
                                                LED = 0;       
                                        }
                                        else
                                        {
                                                LED = 1;
                                        }
                                }
                        }
                }
        }
}
回复

使用道具 举报

11#
ID:748788 发表于 2020-12-4 10:25 | 只看该作者
在led两端并个电容应该有改善
回复

使用道具 举报

12#
ID:854274 发表于 2020-12-4 11:09 | 只看该作者
为什么我看不懂..
回复

使用道具 举报

13#
ID:406879 发表于 2020-12-7 16:40 | 只看该作者
不要那么多while(1)!要不然你以后会死很惨。。。
回复

使用道具 举报

14#
ID:590194 发表于 2020-12-8 10:04 | 只看该作者
wulin 发表于 2020-12-4 07:48
PWM调光与线性调光是两回事。给你一个极简单且不用定时器的呼吸灯示例参考。

代码简单易懂,渐变效果也很理想,只是不能停留在一个恒定的渐变状态,如停留就会出现闪烁..看来是没办法通过PWM来调光了..我看看能不能加个电感 二极管 电容来达到.....
回复

使用道具 举报

15#
ID:280000 发表于 2021-1-4 09:12 | 只看该作者
利用单片机的定时器来实现即可,在一段时间内输出低电平,然后随着时间的增加逐渐输出高电平
回复

使用道具 举报

16#
ID:390416 发表于 2021-1-4 10:09 | 只看该作者
需要用到定时器或者增强型的PWM模块,参考这个贴子http://www.51hei.com/bbs/dpj-200820-1.html
回复

使用道具 举报

17#
ID:89515 发表于 2021-1-5 12:31 来自手机 | 只看该作者
就小功率led而言,绝对不应该出现你说的问题。好好研究一下你的程序和硬件
回复

使用道具 举报

18#
ID:590194 发表于 2021-1-28 15:02 | 只看该作者
wulin 发表于 2020-12-4 07:48
PWM调光与线性调光是两回事。给你一个极简单且不用定时器的呼吸灯示例参考。

这代码好厉害,我拆解了2个小时都没看懂..佩服的!!!继续努力中..
回复

使用道具 举报

19#
ID:638887 发表于 2021-2-7 16:41 | 只看该作者
我也用定时器做过可调PWM调节LED灯玩,一键加亮,另一键加暗,循环,你讲的可能是LED电压与亮度非线性吧,调整一下程序,叁数试试
回复

使用道具 举报

20#
ID:290576 发表于 2021-2-7 20:07 | 只看该作者
        PWM_COUNT++;
        if(255 == lamp1)
        {
           if(PWM_COUNT <= pwm){lamp=1;}      //判断是否到了点亮LED的时候          
           else{lamp=0;}
           if(PWM_COUNT>=115){PWM_COUNT=0;}
        }
        else{lamp=0;}
回复

使用道具 举报

21#
ID:280000 发表于 2021-3-19 23:57 | 只看该作者
单片机的定时中断判断就行
回复

使用道具 举报

22#
ID:420836 发表于 2021-3-20 08:56 | 只看该作者
用于控制LED亮度的pwm方法已被许多人使用,搜索示例并学习如何编写代码。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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