找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机PWM控制LED实验程序

[复制链接]
跳转到指定楼层
楼主
ID:987419 发表于 2021-12-2 22:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include "STC15F2K60S2.H"
  2. #include "stdio.h"
  3. #include "board_init.h"
  4. #include "Led.h"
  5. #include "keyboard.h"
  6. #include "Timer.h"
  7. #include "seg.h"
  8. #include "Delay.h"
  9. #include "string.h"
  10. #include "iic.h"


  11. //函数声明区
  12. void Key_Proc(void);
  13. void Seg_Proc(void);
  14. void Led_Proc(void);

  15. unsigned char trans_function(unsigned char);
  16. unsigned char PWM_control();
  17. void BUZZ_control(void);
  18. void Delay(unsigned int num);


  19. long ms_Tick = 0;

  20. //定时器减速区变量
  21. unsigned int Key_Slow_Down;
  22. unsigned int Seg_Slow_Down;
  23. unsigned int Led_Slow_Down;

  24. //按键专用变量
  25. unsigned char Key_Value;
  26. unsigned char Key_Old;
  27. unsigned char Key_Down;

  28. //数码管专用变量
  29. unsigned char seg_string[10];
  30. unsigned char seg_string1[5];
  31. unsigned char seg_buf[8];
  32. unsigned char pos=0;

  33. //LED专用变量
  34. unsigned char ucLed;

  35. //其他变量定义
  36. bit State_flag = 0;
  37. unsigned char state = 1;
  38. unsigned char light_Lv[10]={0,1,1,1,1,1,1,1,1,1};
  39. unsigned char timer_count;  //pwm控制一个周期 20ms,放在计时器1中累加,20置零。
  40. unsigned char interface_state = 1;  //页面状态。   
  41. unsigned int  interface_timer = 0;
  42. bit BUZZ = 0; //用于限制蜂鸣器只关闭一次的变量。
  43. bit BUZZ1;
  44. unsigned char BUZZ_LV ;
  45. unsigned char timer_count1;
  46. unsigned char timer_count_2;
  47. sbit delay = P0^4;
  48. sbit Buzz = P0^6;

  49. bit sparkle;
  50. bit Error_waning;
  51. bit Led_control_state;
  52. unsigned int A;
  53. long ms_Tick_sparkle;
  54. unsigned char  V;



  55. void main(void)
  56. {
  57.         Cls_Periheral();
  58.         Timer1Init();       
  59.         Timer0Init();
  60.         EA = 1;
  61.         ucLed = 0xff;
  62.         IP = 0X01;  //0000 1000
  63.         while(1)
  64.         {
  65.                 Key_Proc();
  66.                 Led_Proc();
  67.                 BUZZ_control();
  68.                 V =  Pfc_8591_Adc(0x43)/2.55/4;
  69.         }
  70.        
  71. }

  72. /* Timer1_interrupt routine */
  73. void tm1_isr() interrupt 3
  74. {  
  75.         ms_Tick++;
  76.         if (++timer_count == 23)  timer_count = 0;//pwm 50HZ;
  77.         if (++timer_count_2 == 25)  timer_count_2 = 0;
  78.        
  79.         if (interface_timer == 10000)
  80.         {
  81.                 interface_state = 1;
  82.                 interface_timer = 0;
  83.         }       
  84.         if(Led_control_state == 0)
  85.         interface_timer ++;

  86.        
  87.        
  88.         if (++Key_Slow_Down == 10) Key_Slow_Down = 0;  //减速变量区,控制子函数的刷新频率
  89.         if (++Led_Slow_Down == 100) Led_Slow_Down = 0;
  90.         if (++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
  91.        
  92.         Seg_Disp(seg_buf,pos);    //用于数码管显示
  93.         if(++pos == 8)  pos=0;
  94.        
  95.         Seg_Proc();  
  96.        
  97.         ucLed = PWM_control();
  98.         Led_Disp(ucLed);         //用于LED显示
  99. }

  100. /* Timer0_interrupt routine */
  101. void tm0_isr() interrupt 1
  102. {

  103.                 if (++timer_count1 == A)                  timer_count1 = 0;

  104. }



  105. void Key_Proc()           
  106. {
  107.         if (Key_Slow_Down) return;
  108.         Key_Slow_Down=1;   
  109.        
  110.         Key_Value = Key_Read();
  111.         Key_Down = Key_Value & (Key_Old ^ Key_Value);
  112.         Key_Old = Key_Value;
  113.        
  114.         if(interface_state == 3) //PWM控制蜂鸣器声音大小
  115.         {
  116.                  switch(Key_Down)
  117.                  {
  118.                   case 4:   
  119.                                 BUZZ_LV = 0;        break;
  120.                         case 8:
  121.                                 BUZZ_LV = 1;        break;
  122.                         case 12:
  123.                                 BUZZ_LV = 2;        break;
  124.                         case 16:
  125.                                 BUZZ_LV = 3;        break;
  126.                         case 9:
  127.                                 BUZZ_LV = 4;        break;               
  128.                         case 13:
  129.                                 BUZZ_LV = 5;        break;
  130.                         case 17:
  131.                                 BUZZ_LV = 6;        break;
  132.                         case 10:
  133.                                 BUZZ_LV = 7;        break;
  134.                         case 14:
  135.                                 BUZZ_LV = 8;        break;
  136.                         case 18:
  137.                                 BUZZ_LV = 9;        break;               
  138.                 }
  139.         }
  140.         if(interface_state == 2)
  141.         {
  142.                 switch(Key_Down)
  143.                 {
  144.                         case 5 ://向右调节
  145.                         if(state == 8) state = 0;               
  146.                         state ++;       
  147.                         break;
  148.        
  149.                         case 6 ://向左调节
  150.                         if(state == 1) state = 9;               
  151.                         state --;       
  152.                         break;
  153.                        
  154.                         case 4:   
  155.                                 light_Lv[state] = 0;        break;
  156.                         case 8:
  157.                                 light_Lv[state] = 1;        break;
  158.                         case 12:
  159.                                 light_Lv[state] = 2;        break;
  160.                         case 16:
  161.                                 light_Lv[state] = 3;        break;
  162.                         case 9:
  163.                                 light_Lv[state] = 4;        break;               
  164.                         case 13:
  165.                                 light_Lv[state] = 5;        break;
  166.                         case 17:
  167.                                 light_Lv[state] = 6;        break;
  168.                         case 10:
  169.                                 light_Lv[state] = 7;        break;
  170.                         case 14:
  171.                                 light_Lv[state] = 8;        break;
  172.                         case 18:
  173.                                 light_Lv[state] = 9;        break;               

  174.   

  175.       case 11:  
  176.                                 Led_control_state = ~Led_control_state;
  177.                         break;
  178.                        
  179.                        
  180.                         case 15: //报警。
  181.                         case 19:
  182.                                 Error_waning = 1;
  183.                         break;
  184.                         }
  185.    }

  186.          if(Key_Down == 7)  //界面状态调节
  187.                 {                 
  188.                         if(interface_state == 3) interface_state = 0;
  189.                         interface_state ++;
  190.                 }
  191.                
  192.   if(Key_Down)  interface_timer = 0; //若有键盘按下,则重新计时返回主页面的时间。

  193. }

  194. void Led_Proc(void)
  195. {
  196.         if (Led_Slow_Down) return;
  197.         Led_Slow_Down = 1;   
  198.        
  199. }



  200. void Seg_Proc()
  201. {
  202.         if (Seg_Slow_Down) return;
  203.         Seg_Slow_Down = 1;
  204.                         
  205.         switch(interface_state)
  206.         {
  207.                  
  208.                 case 1: //主界面 亮度表格
  209.                         //因为sprintf打印%d超过4个会出现溢出,而keil5没有提供改进版,故分成两次打印。
  210.                         sprintf(seg_string,"%d%d%d%d",(unsigned int)light_Lv[1],(unsigned int)light_Lv[2],(unsigned int)light_Lv[3],(unsigned int)light_Lv[4]);
  211.                   sprintf(seg_string1,"%d%d%d%d",(unsigned int)light_Lv[5],(unsigned int)light_Lv[6],(unsigned int)light_Lv[7],(unsigned int)light_Lv[8]);
  212.                   strcat(seg_string,seg_string1);
  213.                 break;
  214.                
  215.                 case 2://当前选中闪烁

  216.                 if(Led_control_state == 0)
  217.                 {
  218.                   sprintf(seg_string,"%d%d%d%d",(unsigned int)light_Lv[1],(unsigned int)light_Lv[2],(unsigned int)light_Lv[3],(unsigned int)light_Lv[4]);
  219.                    sprintf(seg_string1,"%d%d%d%d",(unsigned int)light_Lv[5],(unsigned int)light_Lv[6],(unsigned int)light_Lv[7],(unsigned int)light_Lv[8]);
  220.                   strcat(seg_string,seg_string1);
  221.                
  222.                
  223.                  
  224.                                         if((ms_Tick - ms_Tick_sparkle)>=200)
  225.                        
  226.                                 ms_Tick_sparkle = ms_Tick;  
  227.                                 sparkle ^= 1;
  228.                                                        
  229.                                 if(sparkle ==1)
  230.                                 {
  231.                                         switch(state)
  232.                                         {
  233.                                                 case 1:
  234.                                                         seg_string[0] =  ' ';
  235.                                                 break;
  236.                                                
  237.                                                 case 2:
  238.                                                         seg_string[1] =  ' ';
  239.                                                 break;
  240.                                                
  241.                                                 case 3:
  242.                                                 seg_string[2] =  ' ';
  243.                                                 break;
  244.                                                
  245.                                                 case 4:
  246.                                                 seg_string[3] =  ' ';
  247.                                                 break;
  248.                                                
  249.                                                 case 5:
  250.                                                 seg_string[4] =  ' ';
  251.                                                 break;
  252.                                                
  253.                                                 case 6:
  254.                                                 seg_string[5] =  ' ';
  255.                                                 break;
  256.                                                
  257.                                                 case 7:
  258.                                                 seg_string[6] =  ' ';
  259.                                                 break;
  260.                                                
  261.                                                 case 8:
  262.                                                 seg_string[7] =  ' ';
  263.                                                 break;
  264.                                         }
  265.                                   
  266.                                 }
  267.                                                
  268.                         }
  269.                
  270.                
  271.                 else
  272.                 {
  273.                   sprintf(seg_string,"%03.0f    ",(float)(4*V));
  274.                 }
  275.                                                
  276.                         break;
  277.        

  278.                        
  279.                 case 3:
  280.                         sprintf(seg_string,"-------%d",(unsigned int)BUZZ_LV);
  281.                 break;
  282.                
  283.                
  284.         }
  285.          
  286.        
  287.          
  288.         Seg_Tran(seg_string,seg_buf);
  289. }




  290. /*****pwm亮度控制*****/
  291. unsigned char PWM_control()   
  292. {
  293.         unsigned char i = 0;
  294.         unsigned char j = 0;
  295.         unsigned char k = 5;
  296.         if(Error_waning == 0 && Led_control_state == 0)
  297.         {

  298.                 if(light_Lv[1] != 0) //不区分0亮度的话,灯熄灭不了。
  299.                 {
  300.                         if( timer_count <= light_Lv[1]*2.3 ) ucLed = ucLed | 0x01;                         //0000 0001
  301.                         else ucLed = ucLed & ~0x01;
  302.                 }
  303.                 else
  304.                         ucLed = ucLed & ~0x01;
  305.                
  306.                 if(light_Lv[2] != 0) //不区分0亮度的话,灯熄灭不了。
  307.                 {
  308.                         if( timer_count <= light_Lv[2]*2.3 ) ucLed = ucLed | 0x02;                         //0000 0010
  309.                         else ucLed = ucLed & ~0x02;
  310.                 }
  311.                 else
  312.                         ucLed = ucLed & ~0x02;
  313.                
  314.                                 if(light_Lv[3] != 0) //不区分0亮度的话,灯熄灭不了。
  315.                 {
  316.                         if( timer_count <= light_Lv[3]*2.3 ) ucLed = ucLed | 0x04;                         //0000 0100
  317.                         else ucLed = ucLed & ~0x04;
  318.                 }
  319.                 else
  320.                         ucLed = ucLed & ~0x04;
  321.                
  322.                 if(light_Lv[4] != 0) //不区分0亮度的话,灯熄灭不了。
  323.                 {
  324.                         if( timer_count <= light_Lv[4]*2.3 ) ucLed = ucLed | 0x08;                         //0000 1000
  325.                         else ucLed = ucLed & ~0x08;
  326.                 }
  327.                 else
  328.                         ucLed = ucLed & ~0x08;
  329.                
  330.                 if(light_Lv[5] != 0) //不区分0亮度的话,灯熄灭不了。
  331.                 {
  332.                         if( timer_count <= light_Lv[5]*2.3 ) ucLed = ucLed | 0x10;                         //0001 0000
  333.                         else ucLed = ucLed & ~0x10;
  334.                 }
  335.                 else
  336.                         ucLed = ucLed & ~0x10;
  337.                
  338.                 if(light_Lv[6] != 0) //不区分0亮度的话,灯熄灭不了。
  339.                 {
  340.                         if( timer_count <= light_Lv[6]*2.3 ) ucLed = ucLed | 0x20;                         //0010 0000
  341.                         else ucLed = ucLed & ~0x20;
  342.                 }
  343.                 else
  344.                         ucLed = ucLed & ~0x20;
  345.                
  346.                 if(light_Lv[7] != 0) //不区分0亮度的话,灯熄灭不了。
  347.                 {
  348.                         if( timer_count <= light_Lv[7]*2.3 ) ucLed = ucLed | 0x40;                         //0100 0000
  349.                         else ucLed = ucLed & ~0x40;
  350.                 }
  351.                 else
  352.                         ucLed = ucLed & ~0x40;
  353.                
  354.                 if(light_Lv[8] != 0) //不区分0亮度的话,灯熄灭不了。
  355.                 {
  356.                         if( timer_count <= light_Lv[8]*2.3 ) ucLed = ucLed | 0x80;                         //1000 0100
  357.                         else ucLed = ucLed & ~0x80;
  358.                 }
  359.                 else
  360.                         ucLed = ucLed & ~0x80;
  361.        
  362.   }
  363.         else if(Error_waning == 1 && Led_control_state == 0)               //LED闪烁报警
  364.         {
  365.                 while (k)
  366.                 {
  367.                          for(i=0;i<9;i++)    //控制亮度等级
  368.                  
  369.                          for(j=0;j<4;j++)   //控制当前亮度等级的循环次数
  370.                          {
  371.                                  Led_Disp(0Xff);   //全亮
  372.                                  Delay(i+1);       //亮的时间
  373.                                  Led_Disp(0x00);//        全灭
  374.                                  Delay(9-i);       //灭的时间
  375.                          }
  376.                         k--;
  377.           }                 
  378.           Error_waning = 0;
  379.          }
  380.        
  381.          else if (Led_control_state)
  382.          {
  383.                  if(timer_count_2 <= V) ucLed = 0xFF;        //
  384.                         else ucLed = 0x00;
  385.          }
  386.        
  387.         if(interface_state == 3)  //PWM调频控制蜂鸣器
  388.                 {
  389.                                 switch(BUZZ_LV)
  390.                         {
  391.                                 case 0:
  392.                                         BUZZ1 = 0;
  393.                                 break;
  394.                                
  395.                        
  396.                                 case 1 :
  397.                                         A = 200;
  398.           if(timer_count1<=A/2) BUZZ1 = 1;
  399.                                   else BUZZ1 = 0;                                break;
  400.                                        
  401.                                 case 2:
  402.                                   A = 100;
  403.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  404.                                   else BUZZ1 = 0;                                break;
  405.                                 break;               
  406.                                
  407.                                 case 3:
  408.                                   A = 50;
  409.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  410.                                   else BUZZ1 = 0;                                break;
  411.                                 break;               
  412.                        
  413.                                 case 4:
  414.                                 //  A = 30;
  415.                                 A = 300;
  416.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  417.                                   else BUZZ1 = 0;                                break;
  418.                                 break;               
  419.                                
  420.                                         case 5:
  421.                                   //A = 20;
  422.                                         A = 400;
  423.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  424.                                   else BUZZ1 = 0;                                break;
  425.                                 break;       
  426.                                        
  427.                                         case 6:
  428.                                   A = 14;
  429.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  430.                                   else BUZZ1 = 0;                                break;
  431.                                 break;       
  432.                                        
  433.                                         case 7:
  434.                                   A = 10;
  435.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  436.                                   else BUZZ1 = 0;                                break;
  437.                                 break;       
  438.                        
  439.                                         case 8:
  440.                                   A = 4;
  441.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  442.                                   else BUZZ1 = 0;                                break;
  443.                                 break;       
  444.                                        
  445.                                         case 9:
  446.                                   A = 2;
  447.                                   if(timer_count1<=A/2) BUZZ1 = 1;
  448.                                   else BUZZ1 = 0;                                break;
  449.                                 break;       
  450.                        
  451.                         }
  452.                 }
  453.        
  454.         return ucLed;
  455. }

  456. /*****蜂鸣器控制函数*****/
  457. void BUZZ_control(void)
  458. {
  459.           if(interface_state == 3  && BUZZ1 ==1 && BUZZ == 0)
  460.                 {
  461.                         BUZZ = 1;
  462.                         Buzz = 1;              //打开蜂鸣器
  463.                         delay = 0;
  464.             P2=P2 & 0X1F | 0Xa0; //Y5  开蜂鸣器
  465.             P2 &= 0X1F;
  466.                 }
  467.                
  468.                 if(interface_state == 3 && BUZZ1 == 0 && BUZZ == 1)
  469.                 {
  470.                         BUZZ = 0;
  471.                         Buzz = 0; //
  472.                         delay = 0;
  473.             P2=P2 & 0X1F | 0Xa0; //Y5  关蜂鸣器
  474.             P2 &= 0X1F;
  475.                 }
  476.                
  477.                 if(interface_state <3 && BUZZ == 1)
  478.                 {
  479.                         BUZZ = 0;
  480.                         Buzz = 0;
  481.                         delay = 0;
  482.             P2=P2 & 0X1F | 0Xa0; //Y5  关蜂鸣器
  483.             P2 &= 0X1F;
  484.                 }
  485. }




  486.        
  487. /*****延时函数*****/
  488. void Delay(unsigned int num)
  489. {
  490.         unsigned int i;
  491.         while(num--)
  492.         for(i=0;i<628;i++);     //晶振频率为12MHZ则震动一次周期为(1/12M)S\ 数量级为  um  执行628次,需要时间≈1ms
  493. }
复制代码

Keil代码下载: 程序源码.zip (151.44 KB, 下载次数: 13)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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