飞道的博客

51单片机——增强型PWM,使用自带PWM发生器

371人阅读  评论(0)

0. 序

之前用定时器做了模拟PWM输出,得到的1k左右波形还行,到10k往上波形就特别难看,又是跳变又是长短不一。后来在参考手册上面看到stc15w4k系列自带pwm波形发生器,于是整了好久写出来了。今天因为业务需求要改代码,回头一看,好家伙,都不知道自己写的啥了。看了一会儿想起来,于是有了此文。

1. 简介

如图,如下介绍,他直接把PWM输出到IO口上面,我使用的是这两个,于是就用了PWM3和PWM2_2两个。

 2. 分析

占坑,今天还要重构代码,改很多东西,暂时不分析了(2021.6.2)。

3. 代码

代码比较简单,我是照着这个写的 ,XDM自己去瞅瞅啊,我当时看了一早上才看明白。。


  
  1. #include <STC15.H> //52头文件
  2. #include <PWM.H>
  3. u8 Tcount= 0; //一个PWM周期内的:周期计数,占空比,方向
  4. sbit PWM = P2^ 1; //PWM4口
  5. sbit PWM2 = P2^ 7; //PWM2口
  6. sbit NPWM1 =P5^ 4; //关闭PWM异常口
  7. sbit NPWM2 =P5^ 4; //关闭PWM异常口
  8. void setPWMWide(u8 Wide); //设置脉宽
  9. #define CYCLE 0x800L//5khz //定义PWM周期(最大值为32767)
  10. #define DUTY1 20 //定义占空比为20%
  11. #define DUTY2 30 //定义占空比为30%
  12. #define DUTY3 50 //定义占空比为50%
  13. //主函数
  14. void InitPWM()
  15. {
  16. InterruptInit(); //初始化中断配置
  17. }
  18. void setPWMWide(u8 Wide)
  19. {
  20. P_SW2 |= 0x80; //使能访问XSFR
  21. PWMIF= 0x00;
  22. PWMFDCR = 0x00; //关闭PWM异常检测,P5.4和P5.5在IIC中使用,如果不关闭会一直进入异常导致无法设置PWM占空比
  23. PWMCFG = 0x00; //配置PWM的输出初始电平为低电平
  24. PWMCKS = 0x00; //选择PWM的时钟为Fosc/(0+1)
  25. PWMC = CYCLE; //设置PWM周期
  26. //板子PWM4 芯片PWM2_2 P2.7
  27. // PWM2T1 = 0x0000; //设置PWM2第1次反转的PWM计数
  28. // PWM2T2 = CYCLE * DUTY / 100; //设置PWM2第2次反转的PWM计数
  29. PWM2T1 = 0x0000; //设置PWM2第1次反转的PWM计数
  30. PWM2T2 = CYCLE * (Wide) / 100; //设置PWM2第2次反转的PWM计数
  31. PWM2CR |= 0x08; //选择PWM2输出到P2.7,不使能PWM2中断
  32. PWM3T1 = 0x0000; //设置PWM2第1次反转的PWM计数
  33. PWM3T2 = CYCLE * (Wide) / 100; //设置PWM2第2次反转的PWM计数
  34. //占空比为(PWM2T2-PWM2T1)/PWMC
  35. PWM3CR = 0; //选择PWM2输出到P2.1
  36. //使能
  37. PWMCR = 0x03; //使能PWM信号输出
  38. PWMCR |= 0x80; //使能PWM模块
  39. P_SW2 &= ~ 0x80;
  40. }
  41. void SetPWM(u8 level) //设置风扇等级 1 2 3 4是自动不用管风速
  42. {
  43. // PutChar(speedFlag);
  44. if(level== 1) //1是9.8k
  45. {
  46. setPWMWide(DUTY1);
  47. }
  48. else if(level== 2)
  49. {
  50. setPWMWide(DUTY2);
  51. }
  52. else if(level== 3)
  53. {
  54. setPWMWide(DUTY3);
  55. }
  56. }
  57. //中断初始化配置
  58. void InterruptInit()
  59. {
  60. P2M1 &= 0<< 1; //PWM4 P2.1 设置推挽
  61. P2M0 |= 1<< 1;
  62. P2M1 &= 0<< 7; //PWM4 P2.7 设置推挽
  63. P2M0 |= 1<< 7;
  64. PWM= 0;
  65. PWM2= 0;
  66. P_SW2 |= 0x80; //使能访问XSFR
  67. PWMIF= 0x00;
  68. PWMFDCR = 0x00; //关闭PWM异常检测,P5.4和P5.5在IIC中使用,如果不关闭会一直进入异常导致无法设置PWM占空比
  69. PWMCFG = 0x00; //配置PWM的输出初始电平为低电平
  70. PWMCKS = 0x00; //选择PWM的时钟为Fosc/(0+1)
  71. PWMC = CYCLE; //设置PWM周期
  72. //板子PWM4 芯片PWM2_2 P2.7
  73. PWM2T1 = 0x0000; //设置PWM2第1次反转的PWM计数
  74. PWM2T2 = CYCLE * DUTY1 / 100; //设置PWM2第2次反转的PWM计数
  75. //占空比为(PWM2T2-PWM2T1)/PWMC
  76. PWM2CR |= 0x08; //选择PWM2输出到P2.7,不使能PWM2中断
  77. //板子PWM2 芯片PWM3 P2.1
  78. PWM3T1 = 0x0000; //设置PWM2第1次反转的PWM计数
  79. PWM3T2 = CYCLE * DUTY1 / 100; //设置PWM2第2次反转的PWM计数
  80. //占空比为(PWM2T2-PWM2T1)/PWMC
  81. PWM3CR = 0; //选择PWM2输出到P2.1
  82. //使能
  83. PWMCR = 0x03; //使能PWM信号输出
  84. PWMCR |= 0x80; //使能PWM模块
  85. P_SW2 &= ~ 0x80;
  86. }

 


转载:https://blog.csdn.net/qq_35697978/article/details/117470530
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场