[MM32软件] 【MM32 eMiniBoard测评报告】四、PWM

[复制链接]
 楼主| lisingch 发表于 2020-5-15 11:22 | 显示全部楼层 |阅读模式
     本次实验利用开发板上的LD2、LD3、LD4所在的端口PB3、PB4、PB5输出同一频率、不同占空比的PWM波,使LD2、LD3、LD4呈现出不同的亮度。当然也可以让这三个LED呈现“呼吸”灯状态显示,输出固定占空比主要是方便对波型进行简单的定量分析。
2020-05-13_164009.png
2020-05-13_182954.png

从上图可以看到这三个端口可以被TIM2_CH2、TIM3_CH1、TIM3_CH2三个通道复用。TIM2、TIM3两个定时器都属“通用”定时器,但区别为TIM2为32位;TIM3为16位。下面是对这两个定时器更加具体的描述:
2020-05-15_104313.png
2020-05-15_104034.png
2020-05-15_104249.png
2020-05-15_103940.png

实验代码参考了官方DEMO。主要代码如下:
  1. void TIM3_PWM_Init(u16 arr,u16 psc)
  2. {  
  3.         GPIO_InitTypeDef GPIO_InitStructure;
  4.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  5.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  6.        
  7.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //开启TIM3时钟
  8.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);          //开启GPIOB时钟

  9.         GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_1);
  10.         GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_1);

  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;         //TIM3_CH1 TIM3_CH2
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                                  //复用推挽输出
  13.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  15.          
  16.         /*定时器时钟频率 = 48MHz/psc = 48MHz/(47+1)=1MHz
  17.           定时时间 = 1MHz/arr = 1HMz/(999+1) = 1KHz = 0.001s = 1ms
  18.         */
  19.         TIM_TimeBaseStructure.TIM_Period = arr;                                 //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         80K
  20.         TIM_TimeBaseStructure.TIM_Prescaler =psc;                         //设置用来作为TIMx时钟频率除数的预分频值  不分频
  21.         TIM_TimeBaseStructure.TIM_ClockDivision = 0;                 //设置时钟分割:TDTS = Tck_tim
  22.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  23.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
  24.        
  25.         TIM_OCStructInit(&TIM_OCInitStructure);
  26.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                                                 //选择定时器模式:TIM脉冲宽度调制模式2
  27.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  28.         TIM_OCInitStructure.TIM_Pulse = 0;                                                                                                                 //设置待装入捕获比较寄存器的脉冲值
  29.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;                 //输出极性:TIM输出比较极性高
  30.        
  31.         TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
  32.         TIM_OC2Init(TIM3, &TIM_OCInitStructure);
  33.        
  34.         TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH1预装载使能         
  35.         TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH2预装载使能
  36.        
  37.         TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM3在ARR上的预装载寄存器
  38.        
  39.         TIM_Cmd(TIM3, ENABLE);  //使能TIM1
  40. }
  1. void TIM2_PWM_Init(u16 arr,u16 psc)
  2. {  
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  5.     TIM_OCInitTypeDef  TIM_OCInitStructure;
  6.    
  7.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        //开启TIM2时钟
  8.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);          //开启GPIOB时钟
  9.        
  10.                 GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_2);                //开启PB3端口复用

  11.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;                                                 //TIM2_CH2
  12.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                          //复用推挽输出
  13.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  14.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  15.    
  16.     TIM_TimeBaseStructure.TIM_Period = arr;                                         //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         80K
  17.     TIM_TimeBaseStructure.TIM_Prescaler =psc;                                 //设置用来作为TIMx时钟频率除数的预分频值  不分频
  18.     TIM_TimeBaseStructure.TIM_ClockDivision = 0;                         //设置时钟分割:TDTS = Tck_tim
  19.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  20.                 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  21.                
  22.     TIM_OCStructInit(&TIM_OCInitStructure);
  23.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;                                                 //选择定时器模式:TIM脉冲宽度调制模式2
  24.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  25.     TIM_OCInitStructure.TIM_Pulse = 0;                                                                                                                 //设置待装入捕获比较寄存器的脉冲值
  26.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;                 //输出极性:TIM输出比较极性低
  27.    
  28.                 TIM_OC2Init(TIM2, &TIM_OCInitStructure);
  29.                
  30.                 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);                                                  //CH2预装载使能

  31.     TIM_ARRPreloadConfig(TIM2, ENABLE);                                                                                                         //使能TIM2在ARR上的预装载寄存器
  32.                
  33.     TIM_Cmd(TIM2, ENABLE);                                                                                                                                                          //使能TIM2
  34. }
  1. int main(void)
  2. {
  3.         delay_init();       

  4.         TIM2_PWM_Init(999,47);
  5.         TIM3_PWM_Init(999,47);
  6.        
  7.         TIM3->CCR1 = 700;//PB4 LD4
  8.         TIM3->CCR2 = 400;//PB5 LD3
  9.         TIM2->CCR2 = 100;//PB3 LD2       
  10.         while(1)
  11.         {
  12.   }       
  13. }

从上面的配置中可以看出,定时器时钟频率使用了48分频,即48MHz/(47+1)=1MHz,周期值为1000,这样在这三个输出通道上即可产生频率为1KHz的PWM波。TIM3两个通道定时器输出比较极性为“高”;TIM2为“低”,其它部分两个定时器配置一样。另外还要注意就是配置中别忘记打开输出端口的“复用”。
2020-05-15_103516.png

阅读手册中关于GPIO端口复用寄存器的描述:
2020-05-13_134959.png
2020-05-13_135031.png
2020-05-13_135225.png
其中对于端口复用功能高位寄存器(GPIOx_AFRH)(x = A..D)的描述中[AF7:AF0]是不是应该写成[AF15:AF8]?也可能是我理解有误。

下面是逻辑分析仪抓取的波型,实验结果符合代码配置要求。
2020-05-15_111915.png

PWM(TIM2 TIM3).rar (257.74 KB, 下载次数: 18)


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

本版积分规则

99

主题

15005

帖子

19

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