嵌入式STM32使用PWM控制LED呼吸灯效果

实验的STM32型号:

STM32F103C8T6   48引脚

涉及到的知识:

RCC,GPIO,TIMER,PWM 设置

*RCC需打开外部时钟

*GPIO查表得知 PA3 默认复用引脚 TIM2_CH4

*TIMER使用默认的TIM2_CH4

*PWM的控制使用了动态的占空比来达到呼吸效果

下面给出代码:

[cpp] view plain copy
 
 print?
  1. #include "stm32f10x.h"  
  2.   
  3. void RCC_cfg(void);  
  4. void GPIO_cfg(void);  
  5. void TIMER_cfg(void);  
  6. void PWM_cfg(void);  
  7.   
  8. int led_fx=1;  
  9. int led_dt=0;  
  10.        
  11. void delay_ms(u16 time)  
  12. {      
  13.    u16 i=0;    
  14.    while(time--)  
  15.    {  
  16.       i=12000;    
  17.       while(i--) ;      
  18.    }  
  19. }  
  20.   
  21. int main(void)  
  22. {  
  23.    RCC_cfg();  
  24.    GPIO_cfg();  
  25.    TIMER_cfg();  
  26.    PWM_cfg();  
  27.    //使能TIM2计时器,开始输出PWM  
  28.    TIM_Cmd(TIM2, ENABLE);  
  29.    while(1)  
  30.          {  
  31.           delay_ms(5);  
  32.          if(led_fx==1)  
  33.          {  
  34.                  led_dt++;  
  35.          }  
  36.          else  
  37.          {  
  38.            led_dt--;  
  39.          }  
  40.          if(led_dt>500) led_fx=0;  
  41.          if(led_dt==0)   led_fx=1;  
  42.          TIM_SetCompare4(TIM2,led_dt);  
  43.    }     
  44. }  
  45.   
  46. void RCC_cfg(void)  
  47. {  
  48.        //定义错误状态变量  
  49.        ErrorStatus HSEStartUpStatus;  
  50.        //将RCC寄存器重新设置为默认值  
  51.        RCC_DeInit();  
  52.        //打开外部高速时钟晶振  
  53.        RCC_HSEConfig(RCC_HSE_ON);  
  54.        //等待外部高速时钟晶振工作  
  55.        HSEStartUpStatus = RCC_WaitForHSEStartUp();  
  56.        if(HSEStartUpStatus == SUCCESS)  
  57.        {  
  58.               //设置AHB时钟(HCLK)为系统时钟  
  59.               RCC_HCLKConfig(RCC_SYSCLK_Div1);  
  60.               //设置高速AHB时钟(APB2)为HCLK时钟  
  61.               RCC_PCLK2Config(RCC_HCLK_Div1);  
  62.               //设置低速AHB时钟(APB1)为HCLK的2分频  
  63.               RCC_PCLK1Config(RCC_HCLK_Div2);  
  64.               //设置FLASH代码延时  
  65.               FLASH_SetLatency(FLASH_Latency_2);  
  66.                //使能预取指缓存  
  67.               FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  
  68.               //设置PLL时钟,为HSE的9倍频 8MHz * 9 = 72MHz  
  69.               RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  
  70.               //使能PLL  
  71.               RCC_PLLCmd(ENABLE);  
  72.               //等待PLL准备就绪  
  73.               while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  
  74.               //设置PLL为系统时钟源  
  75.               RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  
  76.               //判断PLL是否是系统时钟  
  77.               while(RCC_GetSYSCLKSource() != 0x08);  
  78.        }  
  79.        //开启TIM2的时钟  
  80.        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);  
  81.        //开启GPIOB的时钟和复用功能  
  82.        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);  
  83. }  
  84.   
  85. void GPIO_cfg(void)  
  86. {  
  87.        GPIO_InitTypeDef GPIO_InitStructure;  
  88.     // GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);     //映射引脚,默认PA3 ->TIM2_CH4因此不用映射  
  89.        //选择引脚3  
  90.        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;  
  91.        //输出频率最大50MHz                                                          
  92.        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  93.        //复用推挽输出                                                
  94.        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
  95.          //PA  
  96.        GPIO_Init(GPIOA,&GPIO_InitStructure);  
  97. }  
  98.   
  99. void TIMER_cfg(void)  
  100. {  
  101.        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  
  102.        //重新将Timer设置为缺省值  
  103.        TIM_DeInit(TIM2);  
  104.        //采用内部时钟给TIM2提供时钟源  
  105.        TIM_InternalClockConfig(TIM2);  
  106.        //预分频系数为0  
  107.        TIM_TimeBaseStructure.TIM_Prescaler = 0;  
  108.        //设置计数溢出大小  
  109.        TIM_TimeBaseStructure.TIM_Period = 500;    
  110.        //设置计数器模式为向上计数模式(+1)  
  111.        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;    
  112.        //设置时钟分割  
  113.        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  
  114.        //将配置应用到TIM2中  
  115.        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);  
  116. }  
  117.   
  118. void PWM_cfg(void)  
  119. {  
  120.        TIM_OCInitTypeDef TimOCInitStructure;  
  121.        //设置缺省值  
  122.        TIM_OCStructInit(&TimOCInitStructure);  
  123.        //PWM模式1输出  
  124.        TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  
  125.        //设置占空比 (Led亮度)  
  126.        TimOCInitStructure.TIM_Pulse = 0;  
  127.        //TIM输出比较极性高  
  128.        TimOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  
  129.        //使能输出状态  
  130.        TimOCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  
  131.        //TIM2的CH4输出  
  132.        TIM_OC4Init(TIM2, &TimOCInitStructure);  
  133.        //设置TIM2的PWM输出为使能  
  134.        TIM_CtrlPWMOutputs(TIM2,ENABLE);  
  135. }  

    创客学院全新视频尽在:www.makeru.com.cn

   嵌入式学习交流群:561213221

原文地址:https://www.cnblogs.com/huan-huan/p/8335451.html