搜索
bottom↓
回复: 22

pwm控制渐变led的问题

[复制链接]

出0入0汤圆

发表于 2011-6-10 16:10:13 | 显示全部楼层 |阅读模式
最近在做一个东西,要利用单片机实现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;}
   }
///////////////////////////////////////////////////////////  
   }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-6-10 16:57:00 | 显示全部楼层
楼主,你的程序太笨拙了点吧?

出0入0汤圆

发表于 2011-6-10 16:58:24 | 显示全部楼层
有些灯会闪烁一下那是因为你的程序没有处理好。通常是PWM的不对称性导致的。

出0入0汤圆

发表于 2011-6-10 16:58:48 | 显示全部楼层
要用函数,不然复杂点的程序这样写下去单片机就疯了。

出0入0汤圆

发表于 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一次的,所以中断处理要保证有足够的时间才不会出错。

出0入0汤圆

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

出0入0汤圆

发表于 2011-6-10 17:14:05 | 显示全部楼层
学习一下

出0入0汤圆

 楼主| 发表于 2011-6-10 17:18:13 | 显示全部楼层
写程序是有点脑袋不会转弯啊
谢谢大家指点啊,按照你们的说法写着试试。

出0入0汤圆

发表于 2011-6-10 17:35:23 | 显示全部楼层
跟着学
头像被屏蔽

出0入0汤圆

发表于 2011-6-10 18:29:20 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2011-6-10 19:38:28 | 显示全部楼层
楼主加油!!

出0入0汤圆

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

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

出0入0汤圆

 楼主| 发表于 2011-6-10 21:57:50 | 显示全部楼层
回复【9楼】bbs2009
-----------------------------------------------------------------------

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

出0入0汤圆

 楼主| 发表于 2011-6-11 11:19:25 | 显示全部楼层
要沉了吗

出0入0汤圆

发表于 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

出0入0汤圆

发表于 2011-6-11 21:37:13 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-6-16 09:33:37 | 显示全部楼层
标记下。

出0入0汤圆

发表于 2011-6-23 08:52:19 | 显示全部楼层
很有耐心

出0入0汤圆

发表于 2011-6-23 11:51:05 | 显示全部楼层
LZ你把if(count0==pwm0)  {p0=0;}  这句改成if(count0>=pwm0)  {p0=0;}  相信可解决“就是变化的时候有些灯会出现亮度跳变一下”这个问题,原因就不多说了

出0入0汤圆

发表于 2013-10-5 17:40:29 | 显示全部楼层
强烈关注

出0入0汤圆

发表于 2013-10-5 23:16:59 | 显示全部楼层
关注 学习下

出0入0汤圆

发表于 2013-10-6 00:18:04 | 显示全部楼层
mark一下   一直对PWM很干兴趣的啊

出0入0汤圆

发表于 2013-10-6 00:58:52 | 显示全部楼层
买大点的MCU
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 14:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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