xucilong 发表于 2011-6-10 16:10:13

pwm控制渐变led的问题

最近在做一个东西,要利用单片机实现23盏led不同时间的渐变。我写了一个程序,由于初学,写的比较冗长,大家能否帮我修改下,给点意见。还有就是程序基本功能是实现了,渐变也没什么问题,就是变化的时候有些灯会出现亮度跳变一下,但总体还是按着自动由亮到灭再由灭到亮的循环反复。希望大家多给意见,感激不尽!
#include<reg52.h>

#define uint unsigned int
#define uchar unsigned char
#define time 100

sbit p0=P1^0;
sbit p1=P1^1;
sbit p2=P1^2;
sbit p3=P1^3;
sbit p4=P1^4;
sbit p5=P1^5;
sbit p6=P1^6;
sbit p7=P1^7;
sbit p8=P2^0;
sbit p9=P2^1;
sbit p10=P2^2;
sbit p11=P2^3;
sbit p12=P2^4;
sbit p13=P2^5;
sbit p14=P2^6;
sbit p15=P2^7;
sbit p16=P0^0;
sbit p17=P0^1;
sbit p18=P0^2;
sbit p19=P0^3;
sbit p20=P0^4;
sbit p21=P0^5;
sbit p22=P0^6;

uchar cycle;
uchar pwm0,pwm1,pwm2,pwm3,pwm4,pwm5,pwm6,pwm7;
uchar pwm8,pwm9,pwm10,pwm11,pwm12,pwm13,pwm14,pwm15;
uchar pwm16,pwm17,pwm18,pwm19,pwm20,pwm21,pwm22;

void t0()interrupt 1
{
   static uchar count0,count1,count2,count3,count4,count5,count6,count7;
   static uchar count8,count9,count10,count11,count12,count13,count14,count15;
   static uchar count16,count17,count18,count19,count20,count21,count22;
   TH0=(65536-350)/256;
   TL0=(65536-350)%256;
   if(count0==pwm0){p0=0;}   
//////////////////////////////////////////////
   if(count1==pwm1){p1=0;}
//////////////////////////////////////////////
   if(count2==pwm2){p2=0;}
//////////////////////////////////////////////
   if(count3==pwm3){p3=0;}
//////////////////////////////////////////////
   if(count4==pwm4){p4=0;}
//////////////////////////////////////////////
   if(count5==pwm5){p5=0;}
//////////////////////////////////////////////
   if(count6==pwm6){p6=0;}
//////////////////////////////////////////////
   if(count7==pwm7){p7=0;}
//////////////////////////////////////////////
   if(count8==pwm8){p8=0;}   
//////////////////////////////////////////////
   if(count9==pwm9){p9=0;}
//////////////////////////////////////////////
   if(count10==pwm10){p10=0;}
//////////////////////////////////////////////
   if(count11==pwm11){p11=0;}
//////////////////////////////////////////////
   if(count12==pwm12){p12=0;}
//////////////////////////////////////////////
   if(count13==pwm13){p13=0;}
//////////////////////////////////////////////
   if(count14==pwm14){p14=0;}
//////////////////////////////////////////////
   if(count15==pwm15){p15=0;}
//////////////////////////////////////////////
   if(count16==pwm16){p16=0;}
//////////////////////////////////////////////
   if(count17==pwm17){p17=0;}
//////////////////////////////////////////////
   if(count18==pwm18){p18=0;}
//////////////////////////////////////////////
   if(count19==pwm19){p19=0;}
//////////////////////////////////////////////
   if(count20==pwm20){p20=0;}
//////////////////////////////////////////////
   if(count21==pwm21){p21=0;}
//////////////////////////////////////////////
   if(count22==pwm22){p22=0;}
//////////////////////////////////////////////
   count0++;count1++;count2++;count3++;count4++;count5++;count6++;count7++;
   count8++;count9++;count10++;count11++;count12++;count13++;count14++;count15++;
   count16++;count17++;count18++;count19++;count20++;count21++;count22++;
//////////////////////////////////////////////
   if(count0==cycle)
   {
       count0=0;
       if(pwm0!=0){p0=1;}
   }
//////////////////////////////////////////////
   if(count1==cycle)
   {
       count1=0;
       if(pwm1!=0){p1=1;}
   }
//////////////////////////////////////////////
   if(count2==cycle)
   {
       count2=0;
       if(pwm2!=0){p2=1;}
   }
//////////////////////////////////////////////
   if(count3==cycle)
   {
       count3=0;
       if(pwm3!=0){p3=1;}
   }
//////////////////////////////////////////////
   if(count4==cycle)
   {
       count4=0;
       if(pwm4!=0){p4=1;}
   }
//////////////////////////////////////////////
   if(count5==cycle)
   {
       count5=0;
       if(pwm5!=0){p5=1;}
   }
//////////////////////////////////////////////
   if(count6==cycle)
   {
       count6=0;
       if(pwm6!=0){p6=1;}
   }
//////////////////////////////////////////////
   if(count7==cycle)
   {
       count7=0;
       if(pwm7!=0){p7=1;}
   }
//////////////////////////////////////////////
   if(count8==cycle)
   {
       count8=0;
       if(pwm8!=0){p8=1;}
   }
//////////////////////////////////////////////
   if(count9==cycle)
   {
       count9=0;
       if(pwm9!=0){p9=1;}
   }
//////////////////////////////////////////////
   if(count10==cycle)
   {
       count10=0;
       if(pwm10!=0){p10=1;}
   }
//////////////////////////////////////////////
   if(count11==cycle)
   {
       count11=0;
       if(pwm11!=0){p11=1;}
   }
//////////////////////////////////////////////
   if(count12==cycle)
   {
       count12=0;
       if(pwm12!=0){p12=1;}
   }
//////////////////////////////////////////////
   if(count13==cycle)
   {
       count13=0;
       if(pwm13!=0){p13=1;}
   }
//////////////////////////////////////////////
   if(count14==cycle)
   {
       count14=0;
       if(pwm14!=0){p14=1;}
   }
//////////////////////////////////////////////
   if(count15==cycle)
   {
       count15=0;
       if(pwm15!=0){p15=1;}
   }
//////////////////////////////////////////////
   if(count16==cycle)
   {
       count16=0;
       if(pwm16!=0){p16=1;}
   }
//////////////////////////////////////////////
   if(count17==cycle)
   {
       count17=0;
       if(pwm17!=0){p17=1;}
   }
//////////////////////////////////////////////
   if(count18==cycle)
   {
       count18=0;
       if(pwm18!=0){p18=1;}
   }
//////////////////////////////////////////////
   if(count19==cycle)
   {
       count19=0;
       if(pwm19!=0){p19=1;}
   }
//////////////////////////////////////////////
   if(count20==cycle)
   {
       count20=0;
       if(pwm20!=0){p20=1;}
   }
//////////////////////////////////////////////
   if(count21==cycle)
   {
       count21=0;
       if(pwm21!=0){p21=1;}
   }
//////////////////////////////////////////////
   if(count22==cycle)
   {
       count22=0;
       if(pwm22!=0){p22=1;}
   }
//////////////////////////////////////////////
}

void delay(uint cnt)
{
   while(--cnt);
}

void main()
{
   bit flag0,flag1,flag2,flag3,flag4,flag5,flag6,flag7;
   bit flag8,flag9,flag10,flag11,flag12,flag13,flag14,flag15;
   bit flag16,flag17,flag18,flag19,flag20,flag21,flag22;
   TMOD=0x01;
   TH0=(65536-350)/256;
   TL0=(65536-350)%256;
   EA=1;
   ET0=1;
   TR0=1;
   p0=0;p1=0;p2=0;p3=0;p4=0;p5=0;p6=0;p7=0;
   p8=0;p9=0;p10=0;p11=0;p12=0;p13=0;p14=0;p15=0;
   p16=0;p17=0;p18=0;p19=0;p20=0;p21=0;p22=0;
   cycle=50;       //控制渐变等级数
   pwm0=0;pwm1=4;pwm2=8;pwm3=12;pwm4=16;pwm5=20;pwm6=24;pwm7=28;
   pwm8=32;pwm9=36;pwm10=40;pwm11=44;pwm12=48;pwm13=2;pwm14=6;pwm15=10;
   pwm16=14;pwm17=18;pwm18=22;pwm19=26;pwm20=30;pwm21=34;pwm22=38;
   while(1)
   {
   if(flag0==0)
   {
       delay(time);//控制渐变时间间隔
       pwm0++;
           if(pwm0==cycle) {flag0=1;}//                           delay(2000);
   }
   else if(flag0==1)
   {
       delay(time);
           pwm0--;
           if(pwm0==0){flag0=0;}
   }
///////////////////////////////////////////////////////////   
   if(flag1==0)
   {
       delay(time);//控制渐变时间间隔
       pwm1++;
           if(pwm1==cycle) {flag1=1;}//                           delay(2000);
   }
   else if(flag1==1)
   {
       delay(time);
           pwm1--;
           if(pwm1==0){flag1=0;}
   }
///////////////////////////////////////////////////////////
   if(flag2==0)
   {
       delay(time);//控制渐变时间间隔
       pwm2++;
           if(pwm2==cycle) {flag2=1;}//                           delay(2000);
   }
   else if(flag2==1)
   {
       delay(time);
           pwm2--;
           if(pwm2==0){flag2=0;}
   }
///////////////////////////////////////////////////////////   
   if(flag3==0)
   {
       delay(time);//控制渐变时间间隔
       pwm3++;
           if(pwm3==cycle) {flag3=1;}//                           delay(2000);
   }
   else if(flag3==1)
   {
       delay(time);
           pwm3--;
           if(pwm3==0){flag3=0;}
   }
///////////////////////////////////////////////////////////
   if(flag4==0)
   {
       delay(time);//控制渐变时间间隔
       pwm4++;
           if(pwm4==cycle) {flag4=1;}//                           delay(2000);
   }
   else if(flag4==1)
   {
       delay(time);
           pwm4--;
           if(pwm4==0){flag4=0;}
   }
///////////////////////////////////////////////////////////   
   if(flag5==0)
   {
       delay(time);//控制渐变时间间隔
       pwm5++;
           if(pwm5==cycle) {flag5=1;}//                           delay(2000);
   }
   else if(flag5==1)
   {
       delay(time);
           pwm5--;
           if(pwm5==0){flag5=0;}
   }
///////////////////////////////////////////////////////////
   if(flag6==0)
   {
       delay(time);//控制渐变时间间隔
       pwm6++;
           if(pwm6==cycle) {flag6=1;}//                           delay(2000);
   }
   else if(flag6==1)
   {
       delay(time);
           pwm6--;
           if(pwm6==0){flag6=0;}
   }
///////////////////////////////////////////////////////////   
   if(flag7==0)
   {
       delay(time);//控制渐变时间间隔
       pwm7++;
           if(pwm7==cycle) {flag7=1;}//                           delay(2000);
   }
   else if(flag7==1)
   {
       delay(time);
           pwm7--;
           if(pwm7==0){flag7=0;}
   }
///////////////////////////////////////////////////////////
   if(flag8==0)
   {
       delay(time);//控制渐变时间间隔
       pwm8++;
           if(pwm8==cycle) {flag8=1;}//                           delay(2000);
   }
   else if(flag8==1)
   {
       delay(time);
           pwm8--;
           if(pwm8==0){flag8=0;}
   }
///////////////////////////////////////////////////////////
   if(flag9==0)
   {
       delay(time);//控制渐变时间间隔
       pwm9++;
           if(pwm9==cycle) {flag9=1;}//                           delay(2000);
   }
   else if(flag9==1)
   {
       delay(time);
           pwm9--;
           if(pwm9==0){flag9=0;}
   }
///////////////////////////////////////////////////////////
   if(flag10==0)
   {
       delay(time);//控制渐变时间间隔
       pwm10++;
           if(pwm10==cycle) {flag10=1;}//                       delay(2000);
   }
   else if(flag10==1)
   {
       delay(time);
           pwm10--;
           if(pwm10==0){flag10=0;}
   }
///////////////////////////////////////////////////////////
   if(flag11==0)
   {
       delay(time);//控制渐变时间间隔
       pwm11++;
           if(pwm11==cycle) {flag11=1;}//                       delay(2000);
   }
   else if(flag11==1)
   {
       delay(time);
           pwm11--;
           if(pwm11==0){flag11=0;}
   }
///////////////////////////////////////////////////////////
   if(flag12==0)
   {
       delay(time);//控制渐变时间间隔
       pwm12++;
           if(pwm12==cycle) {flag12=1;}//                       delay(2000);
   }
   else if(flag12==1)
   {
       delay(time);
           pwm12--;
           if(pwm12==0){flag12=0;}
   }
///////////////////////////////////////////////////////////
   if(flag13==0)
   {
       delay(time);//控制渐变时间间隔
       pwm13++;
           if(pwm13==cycle) {flag13=1;}//                       delay(2000);
   }
   else if(flag13==1)
   {
       delay(time);
           pwm13--;
           if(pwm13==0){flag13=0;}
   }
///////////////////////////////////////////////////////////
   if(flag14==0)
   {
       delay(time);//控制渐变时间间隔
       pwm14++;
           if(pwm14==cycle) {flag14=1;}//                       delay(2000);
   }
   else if(flag14==1)
   {
       delay(time);
           pwm14--;
           if(pwm14==0){flag14=0;}
   }
///////////////////////////////////////////////////////////
   if(flag15==0)
   {
       delay(time);//控制渐变时间间隔
       pwm15++;
           if(pwm15==cycle) {flag15=1;}//                       delay(2000);
   }
   else if(flag15==1)
   {
       delay(time);
           pwm15--;
           if(pwm15==0){flag15=0;}
   }
///////////////////////////////////////////////////////////
   if(flag16==0)
   {
       delay(time);//控制渐变时间间隔
       pwm16++;
           if(pwm16==cycle) {flag16=1;}//                       delay(2000);
   }
   else if(flag16==1)
   {
       delay(time);
           pwm16--;
           if(pwm16==0){flag16=0;}
   }
///////////////////////////////////////////////////////////
   if(flag17==0)
   {
       delay(time);//控制渐变时间间隔
       pwm17++;
           if(pwm17==cycle) {flag17=1;}//                       delay(2000);
   }
   else if(flag17==1)
   {
       delay(time);
           pwm17--;
           if(pwm17==0){flag17=0;}
   }
///////////////////////////////////////////////////////////
   if(flag18==0)
   {
       delay(time);//控制渐变时间间隔
       pwm18++;
           if(pwm18==cycle) {flag18=1;}//                       delay(2000);
   }
   else if(flag18==1)
   {
       delay(time);
           pwm18--;
           if(pwm18==0){flag18=0;}
   }
///////////////////////////////////////////////////////////
   if(flag19==0)
   {
       delay(time);//控制渐变时间间隔
       pwm19++;
           if(pwm19==cycle) {flag19=1;}//                       delay(2000);
   }
   else if(flag19==1)
   {
       delay(time);
           pwm19--;
           if(pwm19==0){flag19=0;}
   }
///////////////////////////////////////////////////////////
   if(flag20==0)
   {
       delay(time);//控制渐变时间间隔
       pwm20++;
           if(pwm20==cycle) {flag20=1;}//                       delay(2000);
   }
   else if(flag20==1)
   {
       delay(time);
           pwm20--;
           if(pwm20==0){flag20=0;}
   }
///////////////////////////////////////////////////////////
   if(flag21==0)
   {
       delay(time);//控制渐变时间间隔
       pwm21++;
           if(pwm21==cycle) {flag21=1;}//                       delay(2000);
   }
   else if(flag21==1)
   {
       delay(time);
           pwm21--;
           if(pwm21==0){flag21=0;}
   }
///////////////////////////////////////////////////////////
   if(flag22==0)
   {
       delay(time);//控制渐变时间间隔
       pwm22++;
           if(pwm22==cycle) {flag22=1;}//                       delay(2000);
   }
   else if(flag22==1)
   {
       delay(time);
           pwm22--;
           if(pwm22==0){flag22=0;}
   }
///////////////////////////////////////////////////////////
   }
}

chenyuqiu 发表于 2011-6-10 16:57:00

楼主,你的程序太笨拙了点吧?

chenyuqiu 发表于 2011-6-10 16:58:24

有些灯会闪烁一下那是因为你的程序没有处理好。通常是PWM的不对称性导致的。

titrwh 发表于 2011-6-10 16:58:48

要用函数,不然复杂点的程序这样写下去单片机就疯了。

chenyuqiu 发表于 2011-6-10 17:01:02

volatile unsigned short idata   
    wPwmCount,
    wRedLum,
    wGreenLum,
    wBlueLum,
    wWhiteLum,

    wRedTempLum,
    wGreenTempLum,
    wBlueTempLum,
    wWhiteTempLum;

sbit Red    = P0^0;
sbit Green= P0^1;
sbit Blue   = P0^2;
sbit White= P0^3;


void Timer0_IRQHandler(void) interrupt 1    // 10US中断一次,1000步的PWM调光灰度
{

    if ((-- wPwmCount) == 0)
{
   
Red    = 0;
Green= 0;
Blue   = 0;
White= 0;

wPwmCount = 1000;
   
wRedTempLum   = wRedLum;   
wGreenTempLum = wGreenLum;
wBlueTempLum= wBlueLum;
wWhiteTempLum = wWhiteLum;
   
}
else
{
    if (wPwmCount < wRedTempLum)
{
    Red = 1;
}
    if (wPwmCount < wGreenTempLum)
{
    Green = 1;
}
if (wPwmCount < wBlueTempLum)
{
    Blue = 1;
}

if (wPwmCount < wWhiteTempLum)
{
    White = 1;
}
}
}
只要你把各路的值分别赋给wRedLum,wGreenLum,wBlueLum,wWhiteLum,就可以了,如果四路还不够的话可以按照我的 程序架构再扩展更多的路数出来,但是请注意:中断我是用10US一次的,所以中断处理要保证有足够的时间才不会出错。

chenyuqiu 发表于 2011-6-10 17:01:50

我的PWM程序中一定得用   
    wRedTempLum,
    wGreenTempLum,
    wBlueTempLum,
    wWhiteTempLum;
这四个缓冲变量,不然调光时偶尔会有闪烁现象,以我的经验来说这种现象应该是PWM要有对称性才不会有闪烁。我看别人模拟的都是直接与基时比较,而不用一个缓冲变量,这样是不行的。以上是我个人的经验,错误之处还请指教!!!

strange 发表于 2011-6-10 17:14:05

学习一下

xucilong 发表于 2011-6-10 17:18:13

写程序是有点脑袋不会转弯啊./emotion/em007.gif
谢谢大家指点啊,按照你们的说法写着试试。

wcm_e 发表于 2011-6-10 17:35:23

跟着学

bbs2009 发表于 2011-6-10 18:29:20

lrbdh 发表于 2011-6-10 19:38:28

楼主加油!!

chenyuqiu 发表于 2011-6-10 19:54:37

回复【9楼】bbs2009
回lz
个人愚见:
建议中断程序pwm 计算部分用汇编写。改善实时性。
回 【4楼】 chenyuqiu 小陈
个人愚见:
即使是 1t 的 51 , 30m 时钟, 10us也只能 执行 约200 条指令。 1000步的pwm调光灰度,实现 20多路调光可能不太现实。
-----------------------------------------------------------------------

呵呵,是的,我用的AVR模拟PWM时就是用汇编的。

xucilong 发表于 2011-6-10 21:57:50

回复【9楼】bbs2009
-----------------------------------------------------------------------

可是我不会汇编啊   明天就要用了悲哀哦

xucilong 发表于 2011-6-11 11:19:25

要沉了吗./emotion/em015.gif

hzr0071 发表于 2011-6-11 11:44:06

lz还是看看我以前的这个帖子,希望对你有帮助
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4731857&bbs_page_no=1&search_mode=3&search_text=hzr0071&bbs_id=9999

hu7215 发表于 2011-6-11 21:37:13

学习

killin 发表于 2011-6-16 09:33:37

标记下。

880705lpdhr 发表于 2011-6-23 08:52:19

很有耐心

hnjill 发表于 2011-6-23 11:51:05

LZ你把if(count0==pwm0){p0=0;}这句改成if(count0>=pwm0){p0=0;}相信可解决“就是变化的时候有些灯会出现亮度跳变一下”这个问题,原因就不多说了

yangbing2020 发表于 2013-10-5 17:40:29

强烈关注

lh5566 发表于 2013-10-5 23:16:59

关注 学习下

xou822 发表于 2013-10-6 00:18:04

mark一下   一直对PWM很干兴趣的啊

cxning 发表于 2013-10-6 00:58:52

买大点的MCU
页: [1]
查看完整版本: pwm控制渐变led的问题