標(biāo)題: C8051F411單片機(jī)產(chǎn)生PWM波 [打印本頁(yè)]

作者: xxmjamic    時(shí)間: 2016-3-19 23:28
標(biāo)題: C8051F411單片機(jī)產(chǎn)生PWM波
  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     頭文件,單片機(jī)端口定義


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

  40. #define SYSCLK       24500000          // Internal oscillator frequency in Hz   單片機(jī)內(nèi)部振蕩頻率

  41. //-----------------------------------------------------------------------------
  42. // Function Prototypes 振蕩器初始化,端口初始化, PCA定時(shí)器初始化
  43. //-----------------------------------------------------------------------------

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


  47. //-----------------------------------------------------------------------------
  48. // main() Routine  主函數(shù)
  49. //-----------------------------------------------------------------------------

  50. void main (void)                       
  51. {

  52.    unsigned int delay_count;           // Used to implement a delay      延時(shí)函數(shù)
  53.    bit duty_direction = 0;             // 0 = Decrease; 1 = Increase     定義占空比變化方向,0代表減小,1代表增大

  54.    PCA0MD = 0x00;                      // Disable watchdog timer        關(guān)閉看門狗,選擇系統(tǒng)時(shí)鐘的12分頻作為時(shí)間基準(zhǔn)

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

  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時(shí)有比較器功能
  65.          if ((PCA0CPM0 & 0x40) == 0x00)   //與運(yùn)算
  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                  振蕩器時(shí)鐘初始化程序
  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是內(nèi)部振蕩器控制寄存器,將內(nèi)部振蕩器設(shè)為最大振蕩頻率
  109.                                        // at its maximum frequency

  110.    CLKSEL = 0x00;                      // Select the internal osc. as    CLKSEL是時(shí)鐘選擇寄存器,選擇內(nèi)部振蕩器為系統(tǒng)時(shí)鐘源
  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交叉控制開關(guān)0
  128.    XBR1    = 0x41;                     // Route CEX0 to P0.0,      交叉使能開關(guān)必須使能
  129.                                        // Enable crossbar and weak pull-ups   端口I/O交叉控制開關(guān)1,CEX0連接到端口引腳

  130.    P0MDOUT |= 0x01;                    // Set CEX0 (P0.0) to push-pull    設(shè)置P0.0口為推挽式輸出,推挽式輸出有較大的驅(qū)動(dòng)電流
  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定時(shí)器時(shí)鐘基準(zhǔn),關(guān)閉溢出中斷
  188.    PCA0CN = 0x00;                      // Stop counter; clear all flags      關(guān)閉PCA計(jì)數(shù)器,清除所有標(biāo)志位
  189.    PCA0MD = 0x08;                      // Use SYSCLK as time base              使用系統(tǒng)時(shí)鐘作為PCA定時(shí)器的時(shí)鐘源,關(guān)閉PCA定時(shí)器溢出中斷

  190.    PCA0CPM0 = 0x42;                    // Module 0 = 8-bit PWM mode          設(shè)置為8位PWM輸出模式

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

  193.    // Start PCA counter                通過PCA0CN中的CR位打開PCA定時(shí)器
  194.    CR = 1;         
  195. }

  196. //-----------------------------------------------------------------------------
  197. // End Of File
  198. //-----------------------------------------------------------------------------
復(fù)制代碼







歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1