找回密码
 立即注册

QQ登录

只需一步,快速开始

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

C8051F411单片机产生PWM波

[复制链接]
跳转到指定楼层
楼主
ID:109750 发表于 2016-3-19 23:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. //-----------------------------------------------------------------------------
  2. // F41x_PCA0_8Bit_PWM_Output.c
  3. //-----------------------------------------------------------------------------
  4. // Copyright 2006 Silicon Laboratories, Inc.
  5. //
  6. // Program Description:
  7. //
  8. // This program sends a PWM waveform out of an I/O pin, using the PCA's
  9. // 8-bit PWM Output Mode.  The duty cycle of the waveform is modified
  10. // periodically within the main loop.
  11. //
  12. // In this example, PCA Module 0 is used to generate the waveform, and the   模块1
  13. // crossbar is configured to send the CEX0 pin out on P0.0.                  P0.0端口输出PWM波
  14. //
  15. // How To Test:
  16. //
  17. // 1) Download code to a 'F41x device which has an oscilloscope monitoring P0.0
  18. // 2) Run the program - the waveform should be visible on the oscilloscope.
  19. // 3) Verify that the duty cycle of the waveform varies smoothly between
  20. //    minimum and maximum values.                                               占空比在在最大值和最小值间平滑变化
  21. //
  22. //
  23. // FID:            41X000055
  24. // Target:         C8051F41x
  25. // Tool chain:     Keil C51 7.50 / Keil EVAL C51
  26. // Command Line:   None
  27. //
  28. //
  29. // Release 1.0
  30. //    -Initial Revision (BD)
  31. //    -10 MAR 2006
  32. //

  33. //-----------------------------------------------------------------------------
  34. // Includes
  35. //-----------------------------------------------------------------------------

  36. #include <c8051f410.h>                 // SFR declarations     头文件,单片机端口定义


  37. //-----------------------------------------------------------------------------
  38. // Global Constants
  39. //-----------------------------------------------------------------------------

  40. #define SYSCLK       24500000          // Internal oscillator frequency in Hz   单片机内部振荡频率

  41. //-----------------------------------------------------------------------------
  42. // Function Prototypes 振荡器初始化,端口初始化, PCA定时器初始化
  43. //-----------------------------------------------------------------------------

  44. void OSCILLATOR_Init (void);      
  45. void PORT_Init (void);         
  46. void PCA0_Init (void);            


  47. //-----------------------------------------------------------------------------
  48. // main() Routine  主函数
  49. //-----------------------------------------------------------------------------

  50. void main (void)                       
  51. {

  52.    unsigned int delay_count;           // Used to implement a delay      延时函数
  53.    bit duty_direction = 0;             // 0 = Decrease; 1 = Increase     定义占空比变化方向,0代表减小,1代表增大

  54.    PCA0MD = 0x00;                      // Disable watchdog timer        关闭看门狗,选择系统时钟的12分频作为时间基准

  55.    PORT_Init ();                       // Initialize crossbar and GPIO     端口初始化
  56.    OSCILLATOR_Init ();                 // Initialize oscillator            振荡器初始化
  57.    PCA0_Init ();                       // Initialize PCA0                 PCA定时器初始化

  58.    while (1)
  59.    {
  60.       // Wait a little while
  61.       for (delay_count = 30000; delay_count > 0; delay_count--);

  62.       if (duty_direction == 1)         // Direction = Increase
  63.       {
  64.          // First, check the ECOM0 bit      ECOM0位是PCA模块的比较器功能的使能模块,等于1时有比较器功能
  65.          if ((PCA0CPM0 & 0x40) == 0x00)   //与运算
  66.          {
  67.             PCA0CPM0 |= 0x40;          // Set ECOM0 if it is '0'    如果ECOM0等于0则将其置位,b|=a等效于b=b|a,按位或,将ECOM0位置1
  68.          }
  69.          else                          // Increase duty cycle otherwise   否则增加占空比
  70.          {
  71.             PCA0CPH0--;                // Increase duty cycle             增加占空比

  72.             if (PCA0CPH0 == 0x00)
  73.             {
  74.                duty_direction = 0;     // Change direction for next time    占空比变化反向
  75.             }
  76.          }
  77.       }
  78.       else                             // Direction = Decrease
  79.       {
  80.          if (PCA0CPH0 == 0xFF)
  81.          {
  82.             PCA0CPM0 &= ~0x40;         // Clear ECOM0
  83.             duty_direction = 1;        // Change direction for next time
  84.          }
  85.          else
  86.          {
  87.             PCA0CPH0++;                // Decrease duty cycle
  88.          }
  89.       }

  90.    };
  91. }


  92. //-----------------------------------------------------------------------------
  93. // Initialization Subroutines
  94. //-----------------------------------------------------------------------------

  95. //-----------------------------------------------------------------------------
  96. // OSCILLATOR_Init                  振荡器时钟初始化程序
  97. //-----------------------------------------------------------------------------
  98. //
  99. // Return Value : None
  100. // Parameters   : None
  101. //
  102. // This function initializes the system clock to use the internal oscillator
  103. // at 24.5 MHz.
  104. //
  105. //-----------------------------------------------------------------------------
  106. void OSCILLATOR_Init (void)
  107. {
  108.    OSCICN = 0x87;                      // Set internal oscillator to run  OSCICN是内部振荡器控制寄存器,将内部振荡器设为最大振荡频率
  109.                                        // at its maximum frequency

  110.    CLKSEL = 0x00;                      // Select the internal osc. as    CLKSEL是时钟选择寄存器,选择内部振荡器为系统时钟源
  111.                                        // the SYSCLK source
  112. }

  113. //-----------------------------------------------------------------------------
  114. // PORT_Init
  115. //-----------------------------------------------------------------------------
  116. //
  117. // Return Value : None
  118. // Parameters   : None
  119. //
  120. // This function configures the crossbar and GPIO ports.
  121. //
  122. // P0.0   digital   push-pull     PCA0 CEX0    端口初始化程序
  123. //
  124. //-----------------------------------------------------------------------------
  125. void PORT_Init (void)
  126. {
  127.    XBR0    = 0x00;                     //XBR0  端口I/O交叉控制开关0
  128.    XBR1    = 0x41;                     // Route CEX0 to P0.0,      交叉使能开关必须使能
  129.                                        // Enable crossbar and weak pull-ups   端口I/O交叉控制开关1,CEX0连接到端口引脚

  130.    P0MDOUT |= 0x01;                    // Set CEX0 (P0.0) to push-pull    设置P0.0口为推挽式输出,推挽式输出有较大的驱动电流
  131. }

  132. //-----------------------------------------------------------------------------
  133. // PCA0_Init
  134. //-----------------------------------------------------------------------------
  135. //
  136. // Return Value : None
  137. // Parameters   : None
  138. //
  139. // This function configures the PCA time base, and sets up 8-bit PWM output
  140. // mode for Module 0 (CEX0 pin).
  141. //
  142. // The frequency of the PWM signal generated at the CEX0 pin is equal to the
  143. // PCA main timebase frequency divided by 256.
  144. //
  145. // The PCA time base in this example is configured to use SYSCLK, and SYSCLK
  146. // is set up to use the internal oscillator running at 24.5 MHz.  Therefore,
  147. // the frequency of the PWM signal will be 24.5 MHz / 256 = 95.7 kHz.
  148. // Using different PCA clock sources or a different processor clock will
  149. // result in a different frequency for the PWM signal.
  150. //
  151. //    -------------------------------------------------------------------------
  152. //    How "8-Bit PWM Mode" Works:
  153. //
  154. //       The PCA's 8-bit PWM Mode works by setting an output pin low every
  155. //    time the main PCA counter low byte (PCA0L) overflows, and then setting
  156. //    the pin high whenever a specific match condition is met.
  157. //
  158. //    Upon a PCA0L overflow (PCA0L incrementing from 0xFF to 0x00), two things
  159. //    happen:
  160. //
  161. //    1) The CEXn pin will be set low.
  162. //    2) The contents of the PCA0CPHn register for the module are copied into
  163. //       the PCA0CPLn register for the module.
  164. //
  165. //    When the PCA0L register increments and matches the PCA0CPLn register for
  166. //    the selected module, the CEXn pin will be set high, except when the
  167. //    ECOMn bit in PCA0CPMn is cleared to '0'.  By varying the value of the
  168. //    PCA0CPHn register, the duty cycle of the waveform can also be varied.
  169. //
  170. //    When ECOMn = '1', the duty cycle of the PWM waveform is:
  171. //
  172. //       8-bit PWM Duty Cycle = (256 - PCA0CPLn) / 256
  173. //
  174. //    To set the duty cycle to 100%, a value of 0x00 should be loaded into the
  175. //    PCA0CPHn register for the module being used (with ECOMn set to '1').
  176. //    When the value of PCA0CPLn is equal to 0x00, the pin will never be
  177. //    set low.
  178. //
  179. //    To set the duty cycle to 0%, the ECOMn bit in the PCA0CPMn register
  180. //    should be cleared to 0.  This prevents the PCA0CPLn match from occuring,
  181. //    which results in the pin never being set high.
  182. //    -------------------------------------------------------------------------
  183. //
  184. //-----------------------------------------------------------------------------
  185. void PCA0_Init (void)         
  186. {
  187.    // Configure PCA time base; overflow interrupt disabled                   配置PCA定时器时钟基准,关闭溢出中断
  188.    PCA0CN = 0x00;                      // Stop counter; clear all flags      关闭PCA计数器,清除所有标志位
  189.    PCA0MD = 0x08;                      // Use SYSCLK as time base              使用系统时钟作为PCA定时器的时钟源,关闭PCA定时器溢出中断

  190.    PCA0CPM0 = 0x42;                    // Module 0 = 8-bit PWM mode          设置为8位PWM输出模式

  191.    // Configure initial PWM duty cycle = 50%
  192.    PCA0CPH0 = 256 - (256 * 0.5);                                设置初始的占空比为50%

  193.    // Start PCA counter                通过PCA0CN中的CR位打开PCA定时器
  194.    CR = 1;         
  195. }

  196. //-----------------------------------------------------------------------------
  197. // End Of File
  198. //-----------------------------------------------------------------------------
复制代码


评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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