STC单片机PWM的实现方法与原理参考实例

  1. /*==============================================================
  2. at12c2052所带的PWM功能演示,内部公用了一个定时器,当启动PWM时PCA
  3. 定时器只工作在8位模式,匹配比较器也是按8位的。本程序演示了PWM启动
  4. 的设置和调节。
  5. 改用在tasking c51下面编译,并尝试了tasking 方便的在线汇编方式
  6. ------- 晓奇 2006.01.12
  7. ===============================================================*/
  8. #include "STC12C2052AD.h"
  9. /*#include<INTRINS.h>*/
  10. #define uint unsigned int
  11. #define uchar unsigned char
  12.  
  13. uint i;
  14. uchar upordn; /* 升降标志,1=上升 */
  15. void initall(void);
  16. _interrupt(1) void timers0(void);
  17. _interrupt (6) void PCA_LVD(void);
  18. void initall(void)
  19. {
  20. TMOD= 0x11; /* 0000 0001 T0作为16位计数器 */
  21. TH0 = 0xc0; /* 定时器0初始值装入 */
  22. TL0 = 0x00;
  23. ET0 = 1; //开中断
  24. IE |= 0x40; /* 使能PCA定时功能 */
  25. EA = 1;
  26. AUXR = 0x80;
  27. /* 1000 0000
  28. |||| ||++-保留
  29. |||| |+---低电压中断允许:0=禁止,1=允许,5V..3.7V,3V..2.4V以下
  30. |||| +----SPI中断允许位:0=禁止,1=允许
  31. |||+------ADC中断允许位:0=禁止,1=允许
  32. ||+-------串口模式0时时钟设定:0=传统1/12, 1=1/2 2分频;
  33. |+--------定时器ct1时钟源设定:0=传统1/12,1=1:1不分频;
  34. +---------定时器ct0时钟源设定:0=传统1/12,1=1:1不分频;
  35. */
  36. P1 = 0xff;
  37. P1M0 = 0x00; /* P1口用传统51准双向口模式 */
  38. P1M1 = 0x00;
  39. CMOD = 0x03; /* 内部时钟,Fosc/2, PCA计数溢出中断使能*/
  40. /* 0000 0011 PCA 模式寄存器
  41. |||| |||+--ECF...PCA计数溢出中断使能:ECF=1时,使能寄存器CCON CF位的
  42. |||| ||| 中断。ECF=0时,禁止该功能。
  43. |||| |++---CPS1,CPS0 选择PCA 时钟源输入(PCA计数脉冲选择)
  44. |||| | 0 0 0,内部时钟,Fosc/12
  45. |||| | 0 1 1,内部时钟,Fosc/2
  46. |||| | 1 0 2,定时器0溢出,由于定时器0可以工作在1T方式,
  47. |||| | 所以可以达到计一个时钟就溢出, 频率反而
  48. |||| | 是最高的,可达到Fosc
  49. |||| | 1 1 3,ECI/P3.4脚的外部时钟输入(最大速率=Fosc/2)
  50. |+++-+-----保留
  51. +----------CIDL...计数器阵列空闲控制:CIDL=0时,空闲模式下PCA计数器
  52. 继续工作。CIDL=1时,空闲模式下PCA计数器停止工作。
  53. */
  54.  
  55. CH = 0x00; /* PCA计数器初始值高8位 */
  56. CL = 0x00; /* PCA计数器初始值低8位 */
  57. CCAP0H = 0x00; /* 当出现捕获或比较时,它们用来保存16 位的计数值。
  58. 当PCA 模块用在PWM 模式中时,它们用来控制输出的
  59. 占空比。CCAP0H.CCAP0L分别为高低8位,组合使用
  60. */
  61. CCAP0L = 0x00;
  62.  
  63. CCAP1H = 0x00; /* 当出现捕获或比较时,它们用来保存16 位的计数值。
  64. 当PCA 模块用在PWM 模式中时,它们用来控制输出的
  65. 占空比。CCAP1H.CCAP1L分别为高低8位,组合使用
  66. */
  67. CCAP1L = 0x00;
  68.  
  69. CCAPM1 = 0x4c; /* PCA 比较/捕获模块寄存器1作为16位软件定时器。使能
  70. 比较器,PCA计数值与模块的比较/捕获寄存器的值的匹配将
  71. 置位CCON寄存器的中断标志位CCF1,使能CCF1中断 */
  72. /*
  73. 0100 1100 功能说明
  74. |||| |||+---ECCF1.. 使能CCF1中断。使能寄存器CCON的比较/捕获标志CCF1,
  75. |||| ||| 用来产生中断。
  76. |||| ||+----PWM1... 脉宽调节模式。当PWMn=1时,使能CEXn脚用作脉宽调节输出。
  77. |||| |+-----TOG1... 翻转。当TOG1= 1时, PCA计数值与模块的比较/捕获寄存
  78. |||| | 器的值的匹配将使CEXn脚翻转。(CEX1/P3.5)
  79. |||| +------MAT1... 匹配。当=1时, PCA计数值与模块的比较/捕获寄存器的值
  80. |||| 的匹配将置位CCON寄存器的中断标志位CCF1。
  81. |||+--------CAPN1.. 负捕获。CAPN1= 1时使能下降沿捕获。
  82. ||+---------CAPP1.. 正捕获。CAPP1= 1时使能上升沿捕获。
  83. |+----------ECOM1.. 使能比较器。ECOM1= 1时使能比较器功能。
  84. +-----------CCAPM1^7保留
  85.  
  86. 使用的机种基本模式组合:
  87. ECOM1 CAPP1 CAPN1 MAT1 TOG1 PWM1 ECCF1 模块功能
  88. 0 0 0 0 0 0 0 无此操作
  89. X 1 0 0 0 0 X 16位捕获模式,由CEX1的上升沿触发
  90. X 0 1 0 0 0 X 16位捕获模式,由CEX1的下降沿触发
  91. X 1 1 0 0 0 X 16位捕获模式,由CEX1的跳变触发
  92. 1 0 0 1 0 0 X 16位软件定时器
  93. 1 0 0 1 1 0 X 16位高速输出
  94. 1 0 0 0 0 1 0 8位PWM
  95. */
  96.  
  97. CCAPM0 = 0x42; /* PCA 比较/捕获模块寄存器0作为16位软件定时器。使能
  98. 比较器,PCA计数值与模块的比较/捕获寄存器的值的匹配将
  99. 置位CCON寄存器的中断标志位CCF0,使能CCF0中断 寄存器
  100. 位功能同上*/
  101. CR = 1; //Start PCA Timer.
  102. TR0 = 1; //启动计时
  103. i = 0;
  104. upordn = 1;
  105. }
  106.  
  107. /* ------------- 定时器0用来定时调节PWM的输出占空比 ------------- */
  108. _interrupt(1) void timers0(void)
  109. {
  110. TL0 = 0x00;
  111. TH0 = 0xc0;
  112.  
  113. CCAP0H = i>>8; /* CCAP0L不用赋值,他不参与工作 */
  114. if(upordn) /* 逐步加宽PWM、加快脉冲输出 */
  115. {
  116. if(++i==65535) /* 到头 */
  117. {
  118. upordn=0; /* 调头 */
  119. }
  120. }
  121. else /* 逐步减窄PWM、减慢脉冲输出 */
  122. {
  123. if(--i==0) /* 到头 */
  124. {
  125. upordn=1; /* 调头 */
  126. }
  127. }
  128.  
  129. P1 = ~(i>>8); /* 高8位输出LED指示,作监视用 */
  130. }
  131.  
  132. /* ------------ PCA 定时中断,负责清除溢出标志并赋初值 ------------- */
  133. /* 摇晃编程板可以看到P3.5连接的led闪亮频率的缓慢变化,虚线在变长变短 */
  134. _interrupt (6) void PCA_LVD(void)
  135. {
  136. CH = i>>8;
  137. CL = i&0xff;
  138. CF = 0;
  139. CCF0 = 0;
  140. // LedPCA ^= 1; /* 频率要求不高的时候这里可以插入用户代码 */
  141. }
  142.  
  143. void main(void)
  144. {
  145. initall();
  146.  
  147. // 测试tasking c51的在线汇编功能
  148. #pragma asm
  149. mov r0,#0f0h
  150. v1: nop
  151. nop
  152. djnz r0,v1
  153. nop
  154. #pragma endasm
  155. // 编译很顺利通过,不用作任何附加的设定
  156. while(1){};
  157. }
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值