标题: 51单片机怎么模拟PWM波(详解!带程序) [打印本页]

作者: dagu    时间: 2014-12-26 18:29
标题: 51单片机怎么模拟PWM波(详解!带程序)




51系列单片机无PWM输出功能,可以采用定时器配合软件的方法输出。对精度要求不高的场合,非常实用。

一般可以使用两个定时器来实现,如果单片机是S51的话使用T0和T1,如果是S52的话建议使用T0和T2,因为定时器在工作方式2的八位重装模式下定时比较准确,这里我们使用T0和T1
用T0定时器完成PWM输出,脉宽固定,T1来决定高平的宽带来进行PWM调制
具体程序如下:

其中晶振12M,载波频率20KHZ,直接用P0.1来驱动直流电机,直流电机正极接电源正,单片机低平驱动,这样灌电流大。
  1. #include < reg51.h >
  2. #include < intrins.h >

  3. sbit  K1 =P1^4 ;                    //增加键
  4. sbit  K2 =P1^5 ;                    //减少键
  5. sbit  P00 =P0^1;
  6. sbit  BEEP =P3^7 ;                //蜂鸣器
  7. unsigned char PWM=0xe7;   //赋初值

  8. void Beep();
  9. void delayms(unsigned char ms);
  10. void delay(unsigned char t);

  11. /*********************************************************/
  12. void main()
  13. {

  14.      P1=0xff;
  15.     TMOD=0x21 ;
  16.     TH0=0xff ;             //50us延时常数
  17.     TL0=0xce ;            //频率调节

  18.     TH1=PWM ;            //脉宽调节
  19.     TL1=0 ;

  20.      EA=1;
  21.      ET0=1;
  22.      ET1=1;
  23.    
  24.      TR0=1 ;

  25.    while(1)
  26.    {
  27.      do{
  28.             if(PWM!=0xff)
  29.            {PWM++ ;delayms(10);}
  30.            else Beep() ;
  31.          }
  32.      while(K1==0);

  33.      do{
  34.            if(PWM!=0xce)
  35.           {PWM-- ;delayms(10);}
  36.            else Beep() ;
  37.           }
  38.      while(K2==0);
  39.    }
  40. }

  41. void timer0() interrupt 1
  42. {
  43.     TR1=0 ;
  44.     TH0=0xff ;
  45.     TL0=0xce ;
  46.     TH1=PWM ;
  47.     TR1=1 ;
  48.     P00=0 ;      //启动输出
  49. }


  50. void timer1() interrupt 3
  51. {
  52.     TR1=0 ;
  53.     P00=1 ;     //结束输出
  54. }

  55. /*********************************************************/
  56. //蜂鸣器子程序
  57. /*********************************************************/

  58. void Beep()   
  59.   {
  60.       unsigned char i  ;
  61.       for (i=0  ;i<100  ;i++)
  62.         {
  63.           delay(100)  ;
  64.           BEEP=!BEEP  ;                //Beep取反
  65.         }
  66.      BEEP=1  ;                            //关闭蜂鸣器
  67.      delayms(100);
  68.   }

  69. /*********************************************************/
  70. // 延时子程序
  71. /*********************************************************/
  72. void delay(unsigned char t)
  73. {
  74.     while(t--)   ;
  75. }

  76. /*********************************************************/
  77. // 延时子程序
  78. /*********************************************************/
  79. void delayms(unsigned char ms)

  80. {
  81.     unsigned char i ;
  82.     while(ms--)
  83.      {
  84.         for(i = 0 ; i < 120 ; i++) ;
  85.      }
  86. }

  87. /*********************************************************/
复制代码





作者: szlaosong    时间: 2015-4-1 00:49
看看学习一下
作者: lb688    时间: 2015-4-3 14:31
这款程序在学习板上试了一下,不是很理想。硬件是调节LED灯的亮度变化。
作者: delay    时间: 2015-4-4 17:04
学习了,谢谢分享
作者: hwt616591    时间: 2015-4-4 23:22
谢谢分享
作者: youq2015    时间: 2015-6-21 10:24
看看效果如何,感谢分享
作者: WSY_    时间: 2017-4-1 18:03
谢谢分享
作者: JIN_zi    时间: 2017-4-4 14:08
终于明白了点儿了,不错,赞一个
作者: 不会哭的毛毛虫    时间: 2017-7-20 10:29
谢谢了
作者: 三四三    时间: 2017-8-5 15:26
很好 但是P00是什么意思

作者: dx3536    时间: 2017-12-4 21:30
不知道自己能不能学的会
作者: bbsbbc    时间: 2018-1-19 16:08
楼主分享
作者: 都市郎    时间: 2018-2-17 16:36
我把程序改到自己的开发板上实验效果不好,调节范围太小了.
作者: ECC    时间: 2018-3-13 19:20
TR1为什么不赋1.
作者: a50180    时间: 2018-3-13 19:36
不错用定时器实现的
作者: lizhendong    时间: 2018-4-27 23:47
学习学习,谢谢
作者: blossom99    时间: 2018-9-12 17:40
强烈建议加一个三极管驱动,8550之类的,这样很可能烧单片机,过几天可能的话我分享一下我的作品
作者: jizi    时间: 2018-10-8 13:36
超给力
作者: haiming8685    时间: 2018-10-8 16:48
请问这样做脉冲输出能占用单片机多少资源?比如我想做个30K的方波输出驱动,响应速度怎样
作者: haiming8685    时间: 2018-10-9 12:30
也可以用单片机直接驱动高速光耦再驱动其他器件,如三极管或mos管

作者: 大橘为重001    时间: 2019-2-26 15:42
学习学习




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1