打印

用PWM控制LED灯的亮度变化

[复制链接]
10745|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
frank_1019|  楼主 | 2013-9-1 20:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
定义PWM的占空比为0-99,0最暗,LED闪烁频率为50HZ,以200us的整数倍改变LED亮灭状态,采用20ms微调一次占空比。

程序如下,烧录到51中,LED一直是最亮。
麻烦大家帮我找一下错误。

#include <reg52.h>
#define LED_PWM_MAX 99
#define LED_PWM_MIN 0
#define uchar unsigned char
uchar LED_PWM=0;
uchar num=0;
bit flag=0;//flag=0,由暗变亮,flag=1则由亮变暗

void T0_init() //定时200us
{
   TMOD=0x01;
   EA=1;
   ET0=1;
   TH0=(65536-200)/256;
   TL0=(65536-200)%256;
   TR0=1;
}

void TO_int() interrupt 1          //定时100次,20ms,调整一次LED的占空比
{
   TH0=(65536-200)/256;
   TL0=(65536-200)%256;
   num++;
   if(num==100)
     {
            num=0;
                if(flag==0)
                    {
                    LED_PWM++;       
                     if(LED_PWM==99)
                   flag=1;                   
                   }
                 if(flag==1)
              {
                   LED_PWM--;
                   if(LED_PWM==0)
                          flag=0;
              }
         }
}

void main()
{
    T0_init();
        while(1)
        {
                if(LED_PWM>=0)
                {
                      P1=0x00;
                          LED_PWM--;
                        }
                else
                    P1=0xff;


        }
}


相关帖子

沙发
sedatefire| | 2013-9-1 23:40 | 只看该作者
if(LED_PWM>=0)
{
     ....
}
其他的我没细看,单单就这句话来说
和   if  (1) 无异

使用特权

评论回复
板凳
sedatefire| | 2013-9-1 23:48 | 只看该作者
void TO_int() interrupt 1          //定时100次,20ms,调整一次LED的占空比
{
       TH0=(65536-200)/256;
       TL0=(65536-200)%256;
       num++;
       if (num==100)
       {
             num=0;
             /* 20ms才来一次,你如何进行200us为单位的IO翻转 */
        }
}



使用特权

评论回复
地板
sedatefire| | 2013-9-1 23:51 | 只看该作者
思路理清,才下手写代码
不要抓瞎乱写

初学者,建议1.2.3 先写注释厘清头绪,再写代码

使用特权

评论回复
5
frank_1019|  楼主 | 2013-9-2 09:18 | 只看该作者
sedatefire 发表于 2013-9-1 23:48

这个之前是while(1)

if语句中有LED_PWM--的语句
这样写是为了实现LED_PWM数值越大,输出的平均电压值越高,亮度越大的效果。

使用特权

评论回复
6
frank_1019|  楼主 | 2013-9-2 09:19 | 只看该作者
sedatefire 发表于 2013-9-1 23:48

关于这一段,我没说过要实现20us一次的翻转,况且我写的是渐渐变亮(暗)的程序,为什么要翻转?

使用特权

评论回复
7
frank_1019|  楼主 | 2013-9-2 09:24 | 只看该作者
sedatefire 发表于 2013-9-1 23:51
思路理清,才下手写代码
不要抓瞎乱写

首先,谢谢你的回复以及建议。

其次,我写程序的思路自认为还是很清晰的,只是你没有仔细读我的程序,或者我的表达不好让你误解的我思路了。

最后,thank you all the same

使用特权

评论回复
8
getmore| | 2013-9-2 10:06 | 只看该作者
2楼说的很清楚了,LED_PWM是uchar类型,所以用if判断,永远是>=0的,这和if(1)是没什么区别了

使用特权

评论回复
9
frank_1019|  楼主 | 2013-9-2 10:20 | 只看该作者
getmore 发表于 2013-9-2 10:06
2楼说的很清楚了,LED_PWM是uchar类型,所以用if判断,永远是>=0的,这和if(1)是没什么区别了 ...

哦,是这样的啊。
我把它换成了int型,运行还是全最亮的结果。不知道还有哪里出问题了?

使用特权

评论回复
10
fzkqi| | 2013-9-2 11:40 | 只看该作者
楼主完全思路不清,不知道自己在干什么,把你自己写的代码每句自己理解清楚了
你主程序改LED_PWM的值,就算你定时器+1了,你主程序又改为小于0了。LED_PWM基本一直处于<0状态
if(LED_PWM>=0)
                {
                      P1=0x00;
                          LED_PWM--;
                        }
                else
                    P1=0xff;

使用特权

评论回复
11
fzkqi| | 2013-9-2 11:42 | 只看该作者
好好看看PWM和灯渐渐变亮是什么原因造成的。你程序什么地方能实现LED_PWM数值越大,输出的平均电压值越高。你自己一厢情愿的吧

使用特权

评论回复
12
frank_1019|  楼主 | 2013-9-2 13:45 | 只看该作者
fzkqi 发表于 2013-9-2 11:42
好好看看PWM和灯渐渐变亮是什么原因造成的。你程序什么地方能实现LED_PWM数值越大,输出的平均电压值越高。 ...

我确实不怎么懂,你说话也不用给人这么带刺的感觉吧。
我要是懂了,还在新手区,发个贴求助作甚?

我的定时器+1和我程序内部运行时同时进行的。不是说先定时再判断。
为什么你们这些所谓的高手都喜欢这样打击别人的编程热情?这样说话自己会感觉很爽的吗?

使用特权

评论回复
13
dengzhiyangren| | 2013-9-2 16:17 | 只看该作者
//定义PWM的占空比为0-99,0最暗,LED闪烁频率为50HZ,以200us的整数倍改变LED亮灭状态,采用20ms微调一次占空比。

//程序如下,烧录到51中,LED一直是最亮。
//麻烦大家帮我找一下错误。

#include <reg52.h>
#define LED_PWM_MAX 99
#define LED_PWM_MIN 0
#define uchar unsigned char
uchar LED_PWM=0;
uchar num=0,a=0;
bit flag=0;//flag=0,由暗变亮,flag=1则由亮变暗

void T0_init() //定时200us
{
   TMOD=0x01;
   EA=1;
   ET0=1;
   TH0=(65536-200)/256;
   TL0=(65536-200)%6;
   TR0=1;
}

void TO_int() interrupt 1          //定时100次,20ms,调整一次LED的占空比
{
   TH0=(65536-200)/256;
   TL0=(65536-200)%6;
   num++;
   a++;
   if(num==100)
     {
            num=0;
                if(flag==0)
                    {
                    LED_PWM++;        
                     if(LED_PWM==LED_PWM_MAX)
                   flag=1;                  
                   }
                 if(flag==1)
              {
                   LED_PWM--;
                   if(LED_PWM==LED_PWM_MIN)
                          flag=0;
              }
         }
}

void main()
{

    T0_init();
        while(1)
        {

           if(a<LED_PWM)P1=0x00;
              else  P1=0xff;
           if(a==100) a=0;
        }
}

使用特权

评论回复
14
dengzhiyangren| | 2013-9-2 16:19 | 只看该作者
改的看看行不行  大神  话说楼主要控制8个灯的暗灭吗?     

使用特权

评论回复
15
joyme| | 2013-9-2 17:13 | 只看该作者
LZ都没有理解占空比和周期的概念

LS的改动理论上是可以,实际也是有问题,每20ms就变化一次占空比,100级亮度,2秒钟就从最亮变为最暗,或从最暗变为最亮,基本没什么意义。LED_PWM这个值设计为自动变化则应该慢一下(比如1秒或更长时间变化一次),或者通过外部按键来变化亮度

使用特权

评论回复
16
frank_1019|  楼主 | 2013-9-2 19:04 | 只看该作者
dengzhiyangren 发表于 2013-9-2 16:19
改的看看行不行  大神  话说楼主要控制8个灯的暗灭吗?

运行是预期的结果
你是怎么想到要设置一个变量a来和PWM比较的?可能我的概念还不怎么清楚。

这只是看到一个word里面说用PWM控制LED亮暗程度,用来练习编程的,没实际意义。

使用特权

评论回复
17
frank_1019|  楼主 | 2013-9-2 19:06 | 只看该作者
joyme 发表于 2013-9-2 17:13
LZ都没有理解占空比和周期的概念

LS的改动理论上是可以,实际也是有问题,每20ms就变化一次占空比,100级 ...

是的,这是第一次用到PWM,之前也没看过别人的编程例子。概念上可能有些问题。

使用特权

评论回复
18
sysdriver| | 2013-9-2 22:06 | 只看该作者
LZ的思路不对,对PWM的理解好像也不深。

这个是软件模拟PWM功能,一般来说,PWM的频率最好在100HZ以上,慢的话会看见LED有抖动的效果的。渐明渐暗的这个过程=3S比较好,不快不慢。

思路:
假设频率为100HZ吧,占空比为0~99的话,那中断时间=10ms/100=100us,一个变量PWM_cnt作0~99的计数,一个变量PWM_data作占空比数。整个过程为3S的话,那就是3S/100=30ms改变占空比一次。用一个变量3S_time记录30ms计数。

实现:
main
{
           打开中断100us,然后死循环。
}

interrupt
{
        if( PWM_cnt>PWM_data) P1=0x00;      //输出PWM频率
       else   P1=0xff;
        if(++PWM_cnt<100) return;                       //10ms还没到
                PWM_cnt=0;
        if(++3S_time<3)  return;                            //30ms还没到
                3S_time=0;
        if(++PWM_data<=100) return;                 //这里只控制暗到最亮
                PWM_data=0;                                     //然后又最暗到最亮
}

使用特权

评论回复
19
sedatefire| | 2013-9-2 23:30 | 只看该作者
示波器搭上去看便知...

使用特权

评论回复
20
sedatefire| | 2013-9-2 23:44 | 只看该作者
我所说的IO翻转,意思如下:
根据你所说的50Hz, 可知20ms为周期,
亮度0~99,那么200us为时间控制单位,
于是就有
亮度99       亮200us*99     灭200us*1
亮度98       亮200us*98     灭200us*2
亮度n        亮200us*n      灭200us*(100-n)
.......

使用特权

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

本版积分规则

18

主题

66

帖子

0

粉丝