找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STM32学习-使用DMA功能自动更新PWM的输出

  [复制链接]
跳转到指定楼层
楼主
ID:81272 发表于 2015-5-27 16:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
完整程序源代码工程文件下载地址: 使用DMA功能自动更新PWM的输出.RAR (253.23 KB, 下载次数: 181)


  1. //------------------------------------------------------------------------------
  2. #if        (RCC_PLLMul==2)             // ok
  3.         #define RCC_PLLMul_  RCC_PLLMul_2
  4. #elif (RCC_PLLMul==4)
  5.         #define RCC_PLLMul_  RCC_PLLMul_4
  6. #elif (RCC_PLLMul==8)
  7.         #define RCC_PLLMul_  RCC_PLLMul_8
  8. #elif (RCC_PLLMul==9)
  9.         #define RCC_PLLMul_  RCC_PLLMul_9
  10. #elif (RCC_PLLMul==16)
  11.         #define RCC_PLLMul_  RCC_PLLMul_16
  12. #else
  13.         error
  14. #endif

  15. #define SYSCLK  (float)(FREQ_HSE*RCC_PLLMul)

  16. //------------------------------------------------------------------------------
  17. #if        (RCC_AHB_Div==1)                     // ok
  18.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div1
  19. #elif (RCC_AHB_Div==2)
  20.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div2
  21. #elif (RCC_AHB_Div==4)
  22.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div4
  23. #elif (RCC_AHB_Div==8)
  24.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div8
  25. #elif (RCC_AHB_Div==16)
  26.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div16
  27. #elif (RCC_AHB_Div==64)
  28.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div64
  29. #elif (RCC_AHB_Div==128)
  30.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div128
  31. #elif (RCC_AHB_Div==256)
  32.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div256
  33. #elif (RCC_AHB_Div==512)
  34.         #define RCC_HCLK_Div_ RCC_SYSCLK_Div512
  35. #else
  36.         error
  37. #endif

  38. #define HCLK (float)(SYSCLK/RCC_AHB_Div)
  39. #define FCLK (float)(HCLK)
  40. //------------------------------------------------------------------------------

  41. #if (RCC_APB1_Div==1)                         // ok
  42.         #define RCC_PCLK1_Div_ RCC_HCLK_Div1
  43. #elif (RCC_APB1_Div==2)
  44.         #define RCC_PCLK1_Div_ RCC_HCLK_Div2
  45. #elif (RCC_APB1_Div==4)
  46.         #define RCC_PCLK1_Div_ RCC_HCLK_Div4
  47. #elif (RCC_APB1_Div==8)
  48.         #define RCC_PCLK1_Div_ RCC_HCLK_Div8
  49. #elif (RCC_APB1_Div==16)
  50.         #define RCC_PCLK1_Div_ RCC_HCLK_Div16
  51. #else
  52.         error
  53. #endif

  54. #define PCLK1 (float)(HCLK/RCC_APB1_Div)


  55. //------------------------------------------------------------------------------

  56. #if (RCC_APB2_Div==1)                         // ok
  57.         #define RCC_PCLK2_Div_ RCC_HCLK_Div1
  58. #elif (RCC_APB2_Div==2)
  59.         #define RCC_PCLK2_Div_ RCC_HCLK_Div2
  60. #elif (RCC_APB2_Div==4)
  61.         #define RCC_PCLK2_Div_ RCC_HCLK_Div4
  62. #elif (RCC_APB2_Div==8)
  63.         #define RCC_PCLK2_Div_ RCC_HCLK_Div8
  64. #elif (RCC_APB2_Div==16)
  65.         #define RCC_PCLK2_Div_ RCC_HCLK_Div16
  66. #else
  67.         error
  68. #endif

  69. #define PCLK2 (float)(HCLK/RCC_APB2_Div)

  70. //------------------------------------------------------------------------------

  71. #if (RCC_ADC_DIV==2)
  72.         #define RCC_ADC_DIV_ RCC_PCLK2_Div2
  73. #elif (RCC_ADC_DIV==4)
  74.         #define RCC_ADC_DIV_ RCC_PCLK2_Div4
  75. #elif (RCC_ADC_DIV==6)
  76.         #define RCC_ADC_DIV_ RCC_PCLK2_Div6
  77. #elif (RCC_ADC_DIV==8)
  78.         #define RCC_ADC_DIV_ RCC_PCLK2_Div8
  79. #else
  80.         error
  81. #endif

  82. //------------------------------------------------------------------------------

  83. #if (RCC_APB1_Div==1)
  84.         #define FACTOR_TIM234567        1
  85. #else
  86.         #define FACTOR_TIM234567        2
  87. #endif
  88. #define TIM234567CLK         (PCLK1*FACTOR_TIM234567)
  89. #define TIM2CLK                 TIM234567CLK
  90. #define TIM3CLK                 TIM234567CLK
  91. #define TIM4CLK                 TIM234567CLK
  92. #define TIM5CLK                 TIM234567CLK
  93. #define TIM6CLK                 TIM234567CLK
  94. #define TIM7CLK                 TIM234567CLK

  95. //------------------------------------------------------------------------------
  96. #if (RCC_APB2_Div==1)
  97.         #define TIM1CLK         (PCLK2)  
  98.         #define TIM8CLK         (PCLK2)  
  99. #else
  100.         #define TIM1CLK         (PCLK2*2)   
  101.         #define TIM8CLK         (PCLK2*2)   
  102. #endif

  103. //------------------------------------------------------------------------------
  104. #define ADCCLK                 ((float)PCLK2/RCC_ADC_DIV)  

  105. #define ADCCLKx10         (10*FREQ_HSE*RCC_PLLMul/(RCC_AHB_Div*RCC_APB2_Div*RCC_ADC_DIV))  // 仅仅用于下面的判断
  106. #if (ADCCLKx10<6)
  107.         error                     // adc的时钟最小为0.6MHz
  108. #elif (ADCCLKx10>140)
  109.         error                     // adc的时钟最大为14MHz
  110. #else
  111.                                         // 正常的adc频率范围
  112. #endif

  113. //------------------------------------------------------------------------------
  114. //------------------------------------------------------------------------------
  115. //------------------------------------------------------------------------------

复制代码
  1. /*******************************************************************************
  2. 编译环境:        EWARM V5.30
  3. 硬件环境:        DZY2.PCB
  4. STM32 FW:   V3.0.0
  5. 作者        :        szlihongtao
  6. ******************************************************************************
  7. REV                :        V1.00
  8. DATE        :        2017-04-18
  9. NOTE        :  
  10. *******************************************************************************/
  11. #include "stm32f10x.h"
  12. #include "stm32_m.h"
  13. #include "dzy.h"   
  14. #include "myRCC.h"   
  15. //******************************************************************************
  16. #define TIM1_CCR3_Address    0x40012C3C

  17. bit f_tb;                                // 基本定时标志
  18. bit f_100ms,f_1000ms;                         
  19. INT16U cnt_test;                // 计数器,仅供软件调试使用
  20. float clk_sys;                        // 仅供软件调试使用
  21. #if 0
  22. uint16_t SRC_Buffer[]={72*5};// 由于载波频率取20kHZ,所以最大脉冲宽度不要超50us,即常数不要超过72*50
  23. #else
  24. uint16_t SRC_Buffer[]={72*2,72*5,72*10,72*20,72*40,72*10};// 由于载波频率取20kHZ,所以最大脉冲宽度不要超50us,即常数不要超过72*50
  25. #endif
  26. //******************************************************************************
  27. // 延时程序,单位为*1ms
  28. //******************************************************************************
  29. void delayms(INT16U cnt)
  30. {
  31. //#define          CONST_1MS  7333          // 72MhZ
  32. //#define          CONST_1MS 3588          // 32MhZ
  33. #define          CONST_1MS (105*FCLK)
  34.         
  35.         INT16U i;

  36.    __no_operation();
  37.         while(cnt--)
  38.                 for (i=0; i<CONST_1MS; i++);
  39. }
  40. //******************************************************************************
  41. // pcb上的指示灯
  42. //******************************************************************************
  43. static void led_toggle(void)
  44. {
  45.         GPIOC->ODR ^= GPIO_Pin_7;                // led2 toogle
  46.         GPIOC->ODR ^= GPIO_Pin_6;                // led3 toogle
  47. }
  48. //******************************************************************************
  49. // 时钟设置初始化
  50. //******************************************************************************
  51. static void RCC_Configuration(void)
  52. {
  53.   ErrorStatus HSEStartUpStatus;
  54. /*
  55. RCC_AdjustHSICalibrationValue 调整内部高速晶振(HSI)校准值
  56. RCC_ITConfig 使能或者失能指定的RCC中断
  57. RCC_ClearFlag 清除RCC的复位标志位
  58. RCC_GetITStatus 检查指定的RCC中断发生与否
  59. RCC_ClearITPendingBit 清除RCC的中断待处理位
  60. */
  61.           /* RCC system reset(for debug purpose) */
  62.           // 时钟系统复位
  63.           RCC_DeInit();

  64.         // 使能外部的8M晶振
  65.         // 设置外部高速晶振(HSE)
  66.           /* Enable HSE */
  67.           RCC_HSEConfig(RCC_HSE_ON);

  68.         // 使能或者失能内部高速晶振(HSI)
  69.         RCC_HSICmd(DISABLE);

  70.         // 等待HSE起振
  71.         // 该函数将等待直到HSE就绪,或者在超时的情况下退出
  72.           /* Wait till HSE is ready */
  73.           HSEStartUpStatus = RCC_WaitForHSEStartUp();

  74.           if(HSEStartUpStatus == SUCCESS)
  75.           {
  76.                 // 设置AHB时钟(HCLK)
  77.             RCC_HCLKConfig(RCC_HCLK_Div_);        // 36 MHz

  78.                 // 设置低速AHB时钟(PCLK1)
  79.             RCC_PCLK1Config(RCC_PCLK1_Div_);        // 2.25 MHz

  80.                 // 设置高速AHB时钟(PCLK2)
  81.             RCC_PCLK2Config(RCC_PCLK2_Div_);        // 2.25 MHz

  82.             /* ADCCLK = PCLK2/8 */
  83.                 // 设置ADC时钟(ADCCLK)
  84.                    RCC_ADCCLKConfig(RCC_ADC_DIV_);        // 0.281Mhz

  85.                 // 设置USB时钟(USBCLK)
  86.                 // USB时钟 = PLL时钟除以1.5
  87.                 //RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

  88.                 // 设置外部低速晶振(LSE)
  89.                 RCC_LSEConfig(RCC_LSE_OFF);

  90.                 // 使能或者失能内部低速晶振(LSI)
  91.                 // LSE晶振OFF
  92.                 RCC_LSICmd(DISABLE);

  93.                 // 设置RTC时钟(RTCCLK)
  94.                 // 选择HSE时钟频率除以128作为RTC时钟
  95.                 //RCC_RTCCLKConfig(RCC_RTCCLKSource_HSE_Div128);

  96.                 // 使能或者失能RTC时钟
  97.                 // RTC时钟的新状态
  98.                 RCC_RTCCLKCmd(DISABLE);

  99.             /* Flash 2 wait state */
  100.             FLASH_SetLatency(FLASH_Latency_2);

  101.             /* Enable Prefetch Buffer */
  102.             FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  103.             /* PLLCLK = 8MHz * 9 = 72 MHz */
  104.                 // 设置PLL时钟源及倍频系数
  105.             RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_);
  106.                
  107.             /* Enable PLL */
  108.                 // 使能或者失能PLL
  109.             RCC_PLLCmd(ENABLE);

  110.             /* Wait till PLL is ready */
  111.                 // 检查指定的RCC标志位设置与否
  112.             while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  113.             {
  114.             }

  115.             /* Select PLL as system clock source */
  116.                 // 设置系统时钟(SYSCLK)
  117.             RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  118.             /* Wait till PLL is used as system clock source */
  119.                 // 返回用作系统时钟的时钟源
  120.             while(RCC_GetSYSCLKSource() != 0x08)
  121.             {
  122.             }
  123.   }

  124.         // 使能或者失能AHB外设时钟
  125.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1
  126.                                                         |RCC_AHBPeriph_DMA2
  127.                                                         |RCC_AHBPeriph_SRAM
  128.                                                         |RCC_AHBPeriph_FLITF
  129.                                                         |RCC_AHBPeriph_CRC
  130.                                                         |RCC_AHBPeriph_FSMC
  131.                                                         |RCC_AHBPeriph_SDIO,DISABLE);
  132.         // 使能或者失能APB1外设时钟
  133.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL,DISABLE);

  134.         // 强制或者释放高速APB(APB2)外设复位
  135.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ALL,ENABLE);
  136.         // 退出复位状态
  137.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ALL,DISABLE);

  138.         // 强制或者释放低速APB(APB1)外设复位
  139.         RCC_APB1PeriphResetCmd(RCC_APB1Periph_ALL,ENABLE);

  140.         // 强制或者释放后备域复位
  141.         RCC_BackupResetCmd(ENABLE);

  142.         // 使能或者失能时钟安全系统
  143.         RCC_ClockSecuritySystemCmd(DISABLE);
  144. }
  145. //******************************************************************************
  146. // NVIC设置
  147. //******************************************************************************
  148. void NVIC_Configuration(void)
  149. {
  150.         NVIC_InitTypeDef  NVIC_InitStructure;

  151.           /* Configure one bit for preemption priority */
  152.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  153.         NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_IRQn;
  154.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  155.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  156.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  157.           //NVIC_Init(&NVIC_InitStructure);

  158.         NVIC_InitStructure.NVIC_IRQChannel=TIM1_CC_IRQn;
  159.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  160.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  161.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  162.           //NVIC_Init(&NVIC_InitStructure);
  163.        
  164.         NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel5_IRQn;
  165.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  166.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  167.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  168.           NVIC_Init(&NVIC_InitStructure);
  169. }
  170. //******************************************************************************
  171. // SysTick设置初始化
  172. //******************************************************************************
  173. static void SysTick_Config1(void)
  174. {
  175. #if 1
  176.         #define SystemFreq                (FCLK*1000000.0)    // 单位为Hz
  177.         #define TB_SysTick                (TIME_TB*1000)                // 单位为uS,与示波器实测一致

  178.         static INT32U ticks;

  179.         ticks=(INT32U)((TB_SysTick/1000000.0)*SystemFreq);
  180.         SysTick_Config(ticks);
  181. #endif       
  182. }
  183. //******************************************************************************
  184. // GPIO设置
  185. //******************************************************************************
  186. static void GPIO_Configuration(void)
  187. {
  188.         GPIO_InitTypeDef GPIO_InitStructure;

  189.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
  190.                                                         |RCC_APB2Periph_GPIOB
  191.                                                         |RCC_APB2Periph_GPIOC
  192.                                                         |RCC_APB2Periph_GPIOD
  193.                                                         |RCC_APB2Periph_AFIO, ENABLE);

  194. //------------------------------------------------------------------------------
  195.     GPIO_Write(GPIOA,0xffff);       
  196.    
  197.      /* GPIOA Configuration: Channel 3 as alternate function push-pull */
  198.     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10;
  199.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  200.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  201.     GPIO_Init(GPIOA, &GPIO_InitStructure);

  202.     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10;
  203.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  204.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  205.    // GPIO_Init(GPIOA, &GPIO_InitStructure);
  206.        
  207.     GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
  208.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  209.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  210.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  211. //------------------------------------------------------------------------------

  212.     GPIO_Write(GPIOB,0xffff);        // 11111101-11111111     
  213.    
  214.      /* GPIOB Configuration: Channel 3N as alternate function push-pull */
  215.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  216.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  217.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  218.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  219. //------------------------------------------------------------------------------
  220.        
  221.         GPIO_Write(GPIOC,0xff0f);        // 11111111-00001111

  222.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_4|GPIO_Pin_5;
  223.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  224.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  225.           GPIO_Init(GPIOC, &GPIO_InitStructure);
  226. //------------------------------------------------------------------------------
  227.         GPIO_Write(GPIOD,0xffff);        // 11111111-11111111   

  228.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_2;
  229.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  230.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  231.           GPIO_Init(GPIOD, &GPIO_InitStructure);
  232. }
  233. //******************************************************************************
  234. void DMA_Configuration(void)
  235. {
  236.         DMA_InitTypeDef DMA_InitStructure;

  237.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);                // dma1时钟使能
  238.        
  239.         DMA_DeInit(DMA1_Channel5);                        // DMA复位
  240.         DMA_StructInit(&DMA_InitStructure);// DMA缺省的参数

  241.           DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR3_Address;                //外设地址
  242.           DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_Buffer;//内存地址
  243.           DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;        //dma传输方向,单向
  244.           DMA_InitStructure.DMA_BufferSize = sizeof(SRC_Buffer)/2;                //设置DMA在传输时缓冲区的长度
  245.           DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA的外设递增模式,一个外设
  246.           DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//设置DMA的内存递增模式,
  247.           DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据字长
  248.           DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;                        //内存数据字长
  249.         //循环模式开启,Buffer写满后,自动回到初始地址开始传输
  250.         DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                //设置DMA的传输模式
  251.         DMA_InitStructure.DMA_Priority = DMA_Priority_High;        //设置DMA的优先级别
  252.           DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                //设置DMA的2个memory中的变量互相访问
  253.           DMA_Init(DMA1_Channel5, &DMA_InitStructure);

  254.         DMA_ClearFlag(DMA1_IT_TC5);
  255.         DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);

  256.           DMA_Cmd(DMA1_Channel5, ENABLE);
  257. }

  258. /* TIM1 DMA Transfer example -------------------------------------------------
  259.   TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz
  260.   The TIM1 Channel3 is configured to generate a complementary PWM signal with
  261.   a frequency equal to: TIM1 counter clock / (TIM1_Period + 1) = 17.57 KHz and
  262.   a variable duty cycle that is changed by the DMA after a specific number of
  263.   Update DMA request.
  264.   The number of this repetitive requests is defined by the TIM1 Repetion counter,
  265.   each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new
  266.   value defined by the SRC_Buffer .
  267.   -----------------------------------------------------------------------------*/
  268. //******************************************************************************
  269. void Tim1_Configuration(void)
  270. {
  271.         INT16U TIM_Prescaler,TIM_Period;
  272.         INT32U utemp;
  273.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  274.     TIM_OCInitTypeDef TIM_OCInitStructure;
  275.        
  276.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  277.        
  278.         TIM_DeInit(TIM1);         
  279.          
  280.         utemp=(INT32U)(TIM1CLK*1000000.0)/Freq_PWM;

  281.         TIM_Prescaler=utemp/65536;
  282.         ++TIM_Prescaler;                       // 注意这句话,一定要++

  283.         utemp=(INT32U)(TIM1CLK*1000000.0)/TIM_Prescaler;  // 分频后的定时器输入频率
  284.         TIM_Period=utemp/Freq_PWM;               // 周期常数
  285.   
  286.     TIM_TimeBaseStructure.TIM_Period = TIM_Period-1;
  287.         TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler-1;
  288.           TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  289.           TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  290.     TIM_TimeBaseStructure.TIM_RepetitionCounter = 1-1;// 每次直接更新
  291.           TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  292. //------------------------------------------------------------------------------
  293.         /* PWM1 Mode configuration: Channel1 */   
  294.           TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  295.           TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能输出比较状态
  296.           TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // 失能输出比较N状态
  297.           TIM_OCInitStructure.TIM_Pulse = 72;                
  298. /*           
  299.         TIM_OCMode_PWM2  TIM_OCPolarity_Low    正脉冲模式
  300.         TIM_OCMode_PWM2  TIM_OCPolarity_High   负脉冲模式

  301.         TIM_OCMode_PWM1  TIM_OCPolarity_Low    负脉冲模式
  302.         TIM_OCMode_PWM1  TIM_OCPolarity_High   正脉冲模式

  303.         TIM1_OCPolarity输出极性---TIM_OCPolarity_High,输出比较极性高,输出的是正脉冲
  304.         TIM1_OCPolarity输出极性---TIM_OCPolarity_Low, 输出比较极性低,输出的是负脉冲
  305. */
  306.           TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
  307.           TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; // 互补输出极性
  308.           // 选择空闲状态下的非工作状态
  309.           // 当MOE=0设置TIM1输出比较空闲状态      
  310.           // 默认输出位低电平               
  311.           TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  312.           // 选择空闲状态下的非工作状态
  313.           // 当MOE=0重置TIM1输出比较N空闲状态
  314.           TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  315.           TIM_OC3Init(TIM1, &TIM_OCInitStructure);
  316.           TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);// 使能TIMx在CCR1上的预装载寄存器

  317.       /* TIM1 Update DMA Request enable */         
  318.     TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);

  319.            //TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);        // 定时中断使能
  320.            //TIM_ITConfig(TIM1,TIM_IT_CC3,ENABLE);        // 定时中断使能
  321.     TIM_Cmd(TIM1, ENABLE);                                         // 定时器开始运行
  322.                  
  323.         // 这条语句必须要有!!!
  324.         TIM_CtrlPWMOutputs(TIM1, ENABLE);                 /* Main Output Enable */   
  325. }
  326. //******************************************************************************
  327. // 基本定时程序,周期为 TIME_TB
  328. //******************************************************************************
  329. static func_tb(void)
  330. {
  331.         static INT16U tmr_100ms;
  332.         static INT16U tmr_1000ms;
  333.        
  334.         if (!f_tb)                          
  335.                 return;
  336.         f_tb=0;
  337.    
  338.         if (++tmr_100ms>=(100/TIME_TB))
  339.         {
  340.                 tmr_100ms=0;
  341.                 f_100ms=1;     
  342.       
  343.             GPIOC->ODR ^= GPIO_Pin_4;                // led5 toogle         
  344.         }
  345.         if (++tmr_1000ms>=(1000/TIME_TB))
  346.         {
  347.                 tmr_1000ms=0;
  348.                 f_1000ms=1;
  349.             GPIOC->ODR ^= GPIO_Pin_5;                // led4 toogle      
  350.         }       
  351. }

  352. //******************************************************************************
  353. // 进入睡眠模式
  354. // 自行编写
  355. //******************************************************************************
  356. void myPWR_EnterSleepMode(void)
  357. {
  358.           //PWR->CR |= CR_CWUF_Set;        /* Clear Wake-up flag */

  359.           /* Set SLEEPDEEP bit of Cortex System Control Register */
  360.           //*(__IO uint32_t *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set;
  361.         /* This option is used to ensure that store operations are completed */

  362.         __WFI();                 /* Request Wait For Interrupt */
  363. }
  364. //******************************************************************************
  365. // 主程序
  366. //******************************************************************************
  367. void main(void)
  368. {         
  369.     int i;
  370.    
  371.         RCC_Configuration();   
  372.           GPIO_Configuration();
  373.         delayms(100);                        // 延时,等待电压稳定
  374.         Tim1_Configuration();     
  375.         DMA_Configuration();
  376.           SysTick_Config1();
  377.         NVIC_Configuration();       
  378. //------------------------------------------------------------------------------
  379.     for(i=0;i<6;++i)
  380.         {
  381.                 //i=0;
  382.                 //GPIOA->ODR ^= GPIO_Pin_10;                // led3 toogle
  383.                 //GPIOA->ODR ^= GPIO_Pin_11;                // led3 toogle
  384.        
  385.                 delayms(1);       
  386.         led_toggle();               
  387.     }
  388. //------------------------------------------------------------------------------        
  389.         for(;;)
  390.         {               
  391.                 //if (set_sw&0x01)
  392.                         //myPWR_EnterSleepMode(); // 休眠,降低功耗

  393.                 func_tb();
  394.     }
  395. }
  396. //******************************************************************************
  397. #ifdef  USE_FULL_ASSERT
  398. /**
  399.   * @brief  Reports the name of the source file and the source line number
  400.   *   where the assert_param error has occurred.
  401.   * @param file: pointer to the source file name
  402.   * @param line: assert_param error line source number
  403.   * @retval : None
  404.   */
  405. void assert_failed(uint8_t* file, uint32_t line)
  406. {
  407.   /* User can add his own implementation to report the file name and line number,
  408.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  409.   /* Infinite loop */
  410.   while (1)
  411.   {
  412.   }
  413. }
  414. #endif
  415. //******************************************************************************
  416. /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
  417. //******************************************************************************

  418. /*
  419.         LED2---------PC7
  420.         LED3---------PC6
  421.         LED4---------PC5
  422.         LED5---------PC4

  423.         KEY2---------PD3
  424.         KEY3---------PD4

  425. @par Example Description

  426. This example provides a description of how to use DMA with TIM1 Update request
  427. to transfer Data from memory to TIM1 Capture Compare Register3.

  428. TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz
  429. The TIM1 Channel3 is configured to generate a complementary PWM signal with
  430. a frequency equal to: TIM1 counter clock / (TIM1_Period + 1) = 17.57 KHz

  431. The TIM1 Channel3 is configured to generate a complementary PWM signal with
  432. a frequency equal to 17.578 KHz and a variable duty cycle that is changed
  433. by the DMA after a specific number of Update event.
  434. The number of this repetitive requests is defined by the TIM1 Repetion counter,
  435. each 3 Update Requests, the TIM1 Channel3 Duty Cycle changes to the next new value
  436. defined by the SRC_Buffer.

  437.   - STM3210E-EVAL and STM3210B-EVAL Set-up
  438.     - Connect the following pins to an oscilloscope to monitor the different waveforms:  
  439.         - TIM1 CH3  (PA.10)   pin69
  440.         - TIM1 CH3N (PB.15)   pin54
  441. */













复制代码





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

使用道具 举报

沙发
ID:82014 发表于 2015-6-4 13:54 | 只看该作者

东西不错啊。。。
回复

使用道具 举报

板凳
ID:103550 发表于 2016-1-17 11:40 | 只看该作者
谢谢分享,51黑有你更精彩!!
回复

使用道具 举报

地板
ID:110543 发表于 2016-3-24 14:56 | 只看该作者
所有的好东西我都要  哇哈哈哈哈
回复

使用道具 举报

5#
ID:110736 发表于 2016-3-26 09:46 | 只看该作者
谢谢分享
回复

使用道具 举报

6#
ID:159590 发表于 2017-1-3 13:55 | 只看该作者
正是我想要的,谢谢
回复

使用道具 举报

7#
ID:91907 发表于 2017-1-12 19:08 | 只看该作者
正是我想要的,谢谢
回复

使用道具 举报

8#
ID:159524 发表于 2017-2-24 09:46 | 只看该作者
支持一下
回复

使用道具 举报

9#
ID:232839 发表于 2017-9-13 12:10 | 只看该作者
木有黑币,下载不了源码
回复

使用道具 举报

10#
ID:232839 发表于 2017-9-13 16:06 | 只看该作者
你好~
这能改变PWM频率吗?还是只改变占空比?
回复

使用道具 举报

11#
ID:162417 发表于 2017-11-3 10:36 | 只看该作者
正在做自动改变PWM频率的项目,对我帮助很大,但下不了啊!
回复

使用道具 举报

12#
ID:123983 发表于 2018-5-20 22:25 | 只看该作者
好资源,谢谢
回复

使用道具 举报

13#
ID:98945 发表于 2018-8-16 08:49 | 只看该作者
支持楼主,好资源
回复

使用道具 举报

14#
ID:45330 发表于 2019-5-26 20:24 | 只看该作者
好东西要支持啊
回复

使用道具 举报

15#
ID:547896 发表于 2019-5-26 21:50 | 只看该作者
厉害
回复

使用道具 举报

16#
ID:524104 发表于 2019-5-27 14:14 | 只看该作者
在要使用这方面的功能,来做可控PWM脉冲数量的PWM输出。
回复

使用道具 举报

17#
ID:595170 发表于 2020-2-2 12:05 | 只看该作者
学习了,谢谢,很好的参考资料
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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