找回密码
 立即注册

QQ登录

只需一步,快速开始

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

一个简单的PWM产生器频率占空比可调 单片机程序及仿真

[复制链接]
跳转到指定楼层
楼主
废话不多说直接上程序仿真图



仿真工程文件下载:
PWM.rar (25.81 KB, 下载次数: 100)

单片机源程序:
  1. #include <reg52.h>
  2. unsigned char HighRH = 0;  //高电平重载值的高位
  3. unsigned char HighRL = 0;  //高电平重载值的低位
  4. unsigned char LowRH  = 0;  //低电平重载值的高位
  5. unsigned char LowRL  = 0;  //低电平重载值的低位
  6. unsigned int cnt=0;        //记录T1中断次数
  7. unsigned int i=0;

  8. unsigned char dc=0;//PWM占空比
  9. unsigned char fr=0;  //PWM频率
  10. unsigned char out=0;  //PWM输出指示
  11. sbit PWMOUT=P3^7;        //PWM输出端口
  12. void ConfigPWM();
  13. void ClosePWM();


  14. sbit k0=P1^0;                //占空比+5
  15. sbit k1=P1^1;                //占空比-5
  16. sbit k2=P1^2;                //频率+
  17. sbit k3=P1^3;                // 频率-
  18. sbit k4=P1^4;                //输出PWM
  19. sbit k5=P1^5;                //停止输出PWM
  20. unsigned char code LEDChar[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  21. unsigned char code  LEDBuff[]={0xF7,0xFB,0x7F,0xBF};

  22. void delay(int ms)         //延时函数用于数码管的显示
  23. {
  24.         unsigned int x,y;
  25.         for(x=ms;x>0;x--)
  26.                 for(y=110;y>0;y--);
  27. }
  28. void LEDstate()
  29. {
  30.         P0=LEDBuff[0];
  31.         P2=LEDChar[dc%10];
  32.         delay(3);
  33.         P0=LEDBuff[1];
  34.         P2=LEDChar[dc/10];
  35.         delay(3);
  36.         P0=LEDBuff[2];
  37.         P2=LEDChar[fr%10];
  38.         delay(3);
  39.         P0=LEDBuff[3];
  40.         P2=LEDChar[fr/10];
  41.         delay(3);
  42.        

  43. }

  44. void Key(void)
  45. {
  46. if(out==0)
  47.                 {
  48.                   if(k0==0)                       //停止输出波形才能进行调整
  49.                   {
  50.                           if(dc<100)       //占空比+5
  51.                       dc+=5;
  52.                           while(k0==0);
  53.                   }
  54.                   if(k1==0)           //占空比-5
  55.                   {   
  56.                           if(dc=0)
  57.                            dc-=5;
  58.                           while(k1==0);
  59.                   }
  60.        
  61.                   if(k2==0)                       //频率+1
  62.                   {
  63.                       fr+=10;
  64.                           while(k2==0);
  65.                   }
  66.                   if(k3==0)         //频率-1
  67.                   {   
  68.                           if(fr!=0)
  69.                       fr-=10;
  70.                           while(k3==0);
  71.                   }
  72.                 }

  73.                   if(k4        == 0)      //输出波形
  74.                      out =1;

  75.                   if(k5        == 0)      //停止输出波形
  76.                      out =0;
  77. }

  78. void main()
  79. {  
  80.        
  81.          
  82.          
  83.     while (1)
  84.     {   
  85.                           LEDstate();
  86.                           Key();
  87.         ConfigPWM();    //调用PWM配置函数        
  88.                          /* if(out==0)
  89.                                 ClosePWM();
  90.                         */
  91.       
  92.     }
  93. }
  94. /* 配置PWM,fr频率,dc-占空比 */
  95. void ConfigPWM()
  96. {   
  97.     unsigned int  high, low;
  98.     unsigned long tmp;
  99.    
  100.     tmp  = (11059200/12)/100/fr;  //计算一个周期所需要的计数值
  101.     high = (tmp*dc)/100;      //计算高电平所需要的计数值
  102.     low  = tmp - high;          //计算低电平所需要的计数值
  103.     high = 65536 - high + 12;   //计算高电平的重载值并补偿中断延时
  104.     low  = 65536 - low  + 12;   //计算低电平的重载值并补偿中断延时
  105.     HighRH = (unsigned char)(high>>8); //高电平重载值拆分高低字节
  106.     HighRL = (unsigned char)high;
  107.     LowRH  = (unsigned char)(low>>8);  //低电平重载值拆分高低字节
  108.     LowRL  = (unsigned char)low;
  109.     TMOD &= 0xF0;   //清除T0的控制段?
  110.     TMOD |= 0x01;   //T0为模式1
  111.     TH0 = HighRH;   //加载T0重载值
  112.     TL0 = HighRL;
  113.     ET0 = 1;        //使能T0中断
  114.     TR0 = 1;        //启动T0
  115.           EA = 1;     //开关总使能
  116.     PWMOUT=1;     //输出高电平
  117. }
  118. /*关闭PWM */
  119. void ClosePWM()
  120. {
  121.     TR0 =0;     //停止定时器
  122.     ET0 =0;     //禁止中断
  123.     PWMOUT=1;  //输出高电平
  124. }
  125. /* T0中断服务程序,产生PWM波 */
  126. void InterruptTimer0() interrupt 1
  127. {
  128.     if (PWMOUT==1)  //当输出为高电平,加载低电平值并输出低电平
  129.     {
  130.         TH0 = LowRH;
  131.         TL0 = LowRL;
  132.         PWMOUT = 0;
  133.     }
  134.     else              //当输出为低电平,加载高电平值并输出高电平
  135.     {
  136.         TH0 = HighRH;
  137.         TL0 = HighRL;
  138.         PWMOUT = 1;
  139.     }
  140. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:372402 发表于 2018-8-31 14:01 | 只看该作者
好东西,谢谢分享,学习了~
回复

使用道具 举报

板凳
ID:372402 发表于 2018-9-1 10:19 | 只看该作者
请问楼主使用什么软件仿真?我用Proteus仿真会闪退~
回复

使用道具 举报

地板
ID:521024 发表于 2019-5-23 09:11 | 只看该作者
这个是Proteus仿真嘛
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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