| 银杏科技有限公司旗下技术文档发布平台 | 
	
		| 技术支持电话 | 0379-69926675-801 | 
	
		| 技术支持邮件 | Gingko@vip.163.com | 
	
		| 版本 | 日期 | 作者 | 修改内容 | 
	
		| V1.0 | 2020-07-04 | gingko | 初次建立 | 
实验八:定时器PWM实验——呼吸灯
一、实验目的与意义
-  了解STM32 TIMER结构。 
-  了解STM32 TIMER 特征。 
-  掌握TIMER使用方法。 
-  掌握STM32 HAL库中TIMER属性的配置方法。 
-  掌握KEILMDK 集成开发环境使用方法。 
二、实验设备及平台
- 
- 
-  Micro USB线缆。 
-  Keil MDK 开发平台。 
-  STM32CubeMX开发平台。 
-  装有WIN XP(及更高版本)系统的计算机。 
 
三、实验原理
1、PWM简介
-  PWM(Pulse Width Modulation)即脉冲宽度调制,是一种模拟控制方式,其根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。 
-   PWM的主要应用:在STM32中如调节屏幕亮度、音调等应用都可以通过PWM控制占空比进行实现。下面我们会为大家举例介绍如何利用PWM控制LED的亮暗,以实现呼吸灯的效果。 
 
2、PWM的工作原理
-  脉宽调制基本原理:其控制方式就是对电路开关器件的通断进行控制,使输出端得到一系列幅值相等的脉冲,用这些脉冲来代替正弦波或所需要的波形。也就是在输出波形的半个周期中产生多个脉冲,使各脉冲的等值电压为正弦波形,所获得的输出平滑且低次谐波少。按一定的规则对各脉冲的宽度进行调制,即可改变电路输出电压的大小,也可改变输出频率。 
-  脉宽调制原理: 
-  脉宽调制模式可以生产一个由TIMx_ARR寄存器确定频率,由TIMx_CCRx确定占空比的信号。如下图所示: 
 
 
3、寄存器介绍
-  STM32F767的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出,这里我们仅使用TIM1的CH2产生一路PWM输出。 
-  要使STM32F767的定时器TIMx产生PWM输出,我们要用到几个寄存器来控制PWM。接下来我们简单介绍一下其中四个寄存器:捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)、断路和死区寄存器( TIMx_BDTR)。 
-  (1)捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器一般有2个:TIMx _CCMR1和 TIMx _CCMR2。 TIMx_CCMR1 控制 CH1 和2,而 TIMx_CCMR2 控制 CH3 和 4。TIM1_CCMR2寄存器各位描述如图。 
 
-  该寄存器的有些位在不同模式下,功能不一样,所以在图中,把寄存器分了2层,上面一层对应输出而下面的则对应输入。这里我们需要说明的是模式设置位OC4M,此部分由4位组成。总共可以配置成13种模式,我们使用的是PWM模式,所以这4位必须设置为0110/0111。这两种PWM模式的区别就是输出电平的极性相反。另外CC4S用于设置通道的方向(输入/输出)默认设置为0,就是设置通道作为输出使用。 
-  (2)捕获/比较使能寄存器(TIMx_CCER)该寄存器控制着各个输入输出通道的开关。该寄存器的各位描述如图所示: 
 
 
 
 
四、实验程序
1、主函数
int main(void)
{
  int brightness = 0;
  float temp = 0.0;
  int data = 0;
  /* MCU 配置*/
  /* 重置所有外围设备,初始化Flash接口和Systick */
  HAL_Init();
  /* 配置系统时钟 */
  SystemClock_Config();
  /* 初始化所有已配置的外围设备 */
  MX_GPIO_Init();
  MX_TIM1_Init();
  /* 无限循环 */
  while (1)
  {
        HAL_Delay(30);
        if(brightness == 100){
            brightness = 0;
        }
        temp =  199 * (sin(2 * PI / 99.0 * brightness) * 0.5 + 0.5);
        data = (int)temp;
        set_compare(data);
 
        brightness ++;
  }
}
 
2、开启TIM3和GPIO时钟
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle)
{
  if(tim_pwmHandle->Instance==TIM1)
  {
    /* TIM1时钟使能*/
    __HAL_RCC_TIM1_CLK_ENABLE();
  }
}
void MX_GPIO_Init(void)
{
  /* GPIO端口时钟使能 */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if(timHandle->Instance==TIM1)
  {
    /**TIM1 GPIO 配置    
    PA9 ------> TIM1_CH2 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;//复用推挽输出
    GPIO_InitStruct.Pull = GPIO_NOPULL;//上拉
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//低速
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;//PA9复用为 TIM1_CH2
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);//开始生成PWM信号
  }
}
 
3、控制占空比
int set_compare(int temp)
{
    __HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,temp);
    return 0;
}
 
五、实验步骤
-  把仿真器与iCore4的SWD调试口相连(直接相连或者通过转接器相连); 
-  把iCore4通过Micro USB线与计算机相连,为iCore4供电; 
-  打开Keil MDK 开发环境,并打开本实验工程; 
-  烧写程序到iCore4上; 
-  也可以进入Debug 模式,单步运行或设置断点验证程序逻辑。 
 
六、实验现象