[应用方案] 单片机PWM调节LED灯亮度

[复制链接]
4553|16
 楼主| Jessicakjdsl 发表于 2016-5-10 21:21 | 显示全部楼层 |阅读模式
通过无线遥控调节LED灯亮度的设计方案,我能需要做的很简单,只要通过无线按键控制增减调节灯得亮度,甚至只要通过按键实现一定范围变化的模拟变化量输出就OK了,回来上网搜索了一些资料,昨晚花了一晚上的时间写了一个很简单的通过单片机PWM调节LED灯亮度的代码,估计我想通过调节灯得亮度一般都是通过PWM来调节的,(网上一般都是这样的设计)
上午又写了个,主要是感觉昨晚的那个不怎么好,而且控制的不够精准,两个程序都贴出来吧,主要大家一起学习!这两个程序都是经过我亲自调试过!下载到自己使用只需要修改相关的控制引脚就OK了.......
昨晚的程序如下:
  1. // PWM 控制 LED 灯渐亮渐灭程序
  2. // 晶振为12M
  3. // 利用定时器控制产生占空比可变的 PWM 波
  4. // 按K1,PWM值增加,则占空比减小,LED 灯渐暗。
  5. // 按K2,PWM值减小,则占空比增加,LED 灯渐亮。
  6. // 当PWM值增加到最大值或减小到最小值时,蜂鸣器将报警。
  7. #include < reg51.h >
  8. sbit K1 =P3^0 ;                    //增加键
  9. sbit K2 =P3^1 ;
  10. sbit P10=P1^0 ;                  //减少键
  11. sbit BEEP =P3^7 ;                //蜂鸣器
  12. unsigned char PWM=0x7f;   //赋初值
  13. void Beep();
  14. void delayms(unsigned char ms);
  15. void delay(unsigned char t);
  16. void main()
  17. {
  18. /////////////////////////////初始化/////////////////////////
  19.     K1=1;
  20.     K2=1;
  21.     TMOD=0x21;
  22.     TH0=0xfc;             //1ms延时常数
  23.     TL0=0x18;            //频率调节
  24.     TH1=PWM;            //脉宽调节
  25.     TL1=0;
  26.      EA=1;
  27.      ET0=1;
  28.      ET1=1;
  29.      TR0=1;
  30. /////////////////////////////主循环//////////////////////////  
  31.    while(1)
  32.   {
  33.      if(K1==0)//递增按键考虑消抖..
  34.   {
  35.    delayms(20);
  36.     if(K1==0)
  37.    {   
  38.    if(PWM==255)
  39.     {
  40.      PWM=255;
  41.      Beep();
  42.     }
  43.    else PWM++;
  44.    }
  45.   }
  46.       if(K2==0)//递减按键
  47.   {
  48.    delayms(20);
  49.     if(K2==0)
  50.    {
  51.    if(PWM==0)
  52.     {
  53.      PWM=0;
  54.      Beep();
  55.     }
  56.    else PWM-- ;
  57.    }
  58.   }
  59. }
  60. }

  61. // 定时器0中断服务程序.

  62. void timer0() interrupt 1
  63. {
  64.     TH0=0xfc ;
  65.     TL0=0x18 ;
  66.     TH1=PWM ;//定时器自动重装值由PWM提供
  67.     TR1=1 ;
  68.     P10=0 ;      //启动输出
  69. }

  70. // 定时器1中断服务程序

  71. void timer1() interrupt 3
  72. {
  73. TR1=0;
  74.     P10=1 ;    //结束输出
  75. }

  76. //蜂鸣器子程序
  77. void Beep()   
  78. {
  79.       unsigned char i ;
  80.       for (i=0 ;i<100 ;i++)
  81.         {
  82.           delay(200) ;
  83.           BEEP=!BEEP ;                //Beep取反
  84.         }
  85.      BEEP=1 ;                            //关闭蜂鸣器
  86.      delayms(200);
  87. }

  88. // 延时子程序

  89. void delay(unsigned char t)
  90. {
  91.     while(t--)   ;
  92. }

  93. // 延时子程序

  94. void delayms(unsigned char ms)
  95. {
  96.     unsigned char i ;
  97.     while(ms--)
  98.      {
  99.         for(i = 0 ; i < 120 ; i++) ;
  100.      }
  101. }
  102. 上午的程序,也是从网上下修改修改的,通过示波器可以很明显的观察到PWM占空比的变化
  103. #include <reg51.H>  //模拟PWM输出控制灯的10个亮度级
  104. unsigned int scale;
  105. sbit K1 =P3^0 ;                    //增加键
  106. sbit K2 =P3^1 ;
  107. sbit P11=P1^2 ;
  108. sbit P10=P1^0 ;                  //减少键
  109. sbit BEEP =P3^7 ;                //蜂鸣器
  110. unsigned char PWM=20;   //赋初值  //占空比控制变量
  111. void Beep();
  112. void delayms(unsigned char ms);
  113. void delay(unsigned char t);
  114. void main(void)  // 主程序
  115. {
  116.     TMOD=0x02;  //定时器0,工作模式2(0000,0010),8位定时模式
  117.     TH0=0x06;  //写入预置初值6到定时器0,使250微秒溢出一次(12MHz)
  118.     TL0=0x06;  //写入预置值
  119.     TR0=1;   //启动定时器
  120.     ET0=1;   //允许定时器0中断
  121.     EA=1;   //允许总中断
  122.     while (1)  //无限循环,实际应用中,这里是做主要工作
  123.     {

  124.      if(K1==0)//递增按键
  125.   {
  126.    delayms(100);
  127.     if(K1==0)
  128.    {   
  129.    if(scale==40)
  130.     {
  131.      //PWM=255;
  132.      Beep();
  133.     }
  134.    else scale++; ;
  135.    }
  136.   }
  137.       if(K2==0)//递减按键
  138.   {
  139.    delayms(100);
  140.     if(K2==0)
  141.    {
  142.    if(scale==0)
  143.     {
  144.      //PWM=0;
  145.      Beep();
  146.     }
  147.    else scale-- ;
  148.    }
  149.   }
  150.     }
  151. }
  152. void timer0(void) interrupt 1 //定时器0中断服务程序
  153. {
  154.     static unsigned int n ; //n用来保存当前时间在一秒中的比例位置
  155.     n++;   //每250微秒增加1
  156.     if(n==40)  //1秒的时钟周期
  157.     {
  158.         n=0;  //使n=0,开始新的PWM周期
  159.         P10=0; //使LED灯亮
  160.     }
  161.     if(scale==n)  //按照当前占空比切换输出为高电平
  162.         P10=1; //使LED灯灭
  163. }
  164. //程序中从tt=0开始到scale为低电平,从scale开始到n=10为高电平,
  165. //由于scale是变量,所以改变scale就可以改变占空比。
  166. /////////////////////////下面的程序同上面一样///////////////////////////////////

  167. //蜂鸣器子程序
  168. void Beep()   
  169. {
  170.       unsigned char i ;
  171.       for (i=0 ;i<100 ;i++)
  172.         {
  173.           delay(200) ;
  174.           BEEP=!BEEP ;                //Beep取反
  175.         }
  176.      BEEP=1 ;                            //关闭蜂鸣器
  177.      delayms(200);
  178. }

  179. // 延时子程序

  180. void delay(unsigned char t)
  181. {
  182.     while(t--)   ;
  183. }

  184. // 延时子程序

  185. void delayms(unsigned char ms)
  186. {
  187.     unsigned char i ;
  188.     while(ms--)
  189.      {
  190.         for(i = 0 ; i < 120 ; i++) ;
  191.      }
  192. }


598330983 发表于 2016-5-11 10:59 | 显示全部楼层
无线采用的什么功能?蓝牙吗,通常如果没有无线电遥控器,就最好用蓝牙,这样方便手机控制。
捉虫天师 发表于 2016-5-11 15:07 | 显示全部楼层
还有一种调光方式就是控制不同数量的LED点亮。
zhuomuniao110 发表于 2016-5-11 22:05 | 显示全部楼层
我之前用ZigBee做过类似的,也就是通过无线传。
fang355 发表于 2016-6-15 15:09 | 显示全部楼层
感谢分享  已经下载过, 很好的。 在此追问楼主, 这里PWM值, 直接使用按键加10% 20% 30% 40% 。。。 100% 全亮, 反之到 10%最暗。 不用T0  T1定时功能(因为定时器功能已经由其他的派用),  就是单纯的安件控制   单片机可否也能起到你的效果!?
 楼主| Jessicakjdsl 发表于 2016-6-16 22:26 | 显示全部楼层
这么做出来的功能不就是呼吸灯吗
gejigeji521 发表于 2016-7-27 22:55 | 显示全部楼层
如果用51,只能使用IO来模拟这个功能。
chundidi 发表于 2016-11-29 11:49 | 显示全部楼层
请问有仿真图么?先看了你的博客,又来了这里看见你
bingkaiok 发表于 2016-11-30 00:23 | 显示全部楼层
感谢楼主分享
598330983 发表于 2016-12-3 14:40 | 显示全部楼层
用的频率是多少的?
zhuomuniao110 发表于 2016-12-4 15:15 | 显示全部楼层
电机调速也一般使用PWM操作。
goty2000 发表于 2017-3-12 09:37 | 显示全部楼层
感谢楼主分享,刚刚自己搭电路试了一下,在按住开关连续调光灯途中,会偶然遇到LED闪烁一下的情况。
zhuotuzi 发表于 2017-3-12 23:17 | 显示全部楼层
IO配合定时器模拟这个PWM。
heisexingqisi 发表于 2017-3-12 23:54 | 显示全部楼层
没有直接用PWM弄的方便,配置好就行了。
稳稳の幸福 发表于 2017-3-17 20:33 | 显示全部楼层
定时器做这个,考验人对这个PWM的理解深度。
zhuotuzi 发表于 2017-3-18 18:47 | 显示全部楼层
楼主可以试试新唐的M051,上面带PWM硬件。
huangcunxiake 发表于 2017-3-18 22:42 | 显示全部楼层
可以通过IO控制流水方向,实现那个很炫彩的效果。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

116

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部