PWM
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。
占空比:占空比是指在一个脉冲循环内,通电时间(可能是高电平,可以低电平)相对于总时间所占的比例。
PWM产生框架图
PWM产生的流程:
通用定时器需要添加的库函数文件:stm32f4xx_tim.c
- 理解电路原理图
LED0连接在PF9,低电平灯亮;高电平,灯灭
TIM14_CH1(TIM14 -- APB1 16位 84MHZ)
(2)使能定时器14和相关IO口时钟。
使能定时器14时钟:RCC_APB1PeriphClockCmd();
使能GPIOF时钟:RCC_AHB1PeriphClockCmd ();
(3)初始化IO口为复用功能输出。
函数:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
(4)GPIOF9复用映射到定时器14
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
- 初始化定时器:ARR,PSC等:
TIM_TimeBaseInit();
- 初始化输出比较参数:
TIM_OC1Init();
- 使能预装载寄存器:
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);
- 使能自动重装载的预装载寄存器允许位
TIM_ARRPreloadConfig(TIM14,ENABLE);
(9)使能定时器。
(10)不断改变比较值CCRx,达到不同的占空比效果:
TIM_SetCompare1();
函数说明:
/**
* @brief Changes the mapping of the specified pin.
* @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32F405xx/407xx and STM32F415xx/417xx devices
* x can be (A..I) to select the GPIO peripheral for STM32F42xxx/43xxx devices.
* x can be (A, B, C, D and H) to select the GPIO peripheral for STM32F401xx devices.
* @param GPIO_PinSource: specifies the pin for the Alternate function.
* This parameter can be GPIO_PinSourcex where x can be (0..15).
* @param GPIO_AFSelection: selects the pin to used as Alternate function.
* This parameter can be one of the following values:
* @arg GPIO_AF_RTC_50Hz: Connect RTC_50Hz pin to AF0 (default after reset)
* @arg GPIO_AF_MCO: Connect MCO pin (MCO1 and MCO2) to AF0 (default after reset)
* @arg GPIO_AF_TAMPER: Connect TAMPER pins (TAMPER_1 and TAMPER_2) to AF0 (default after reset)
* @arg GPIO_AF_SWJ: Connect SWJ pins (SWD and JTAG)to AF0 (default after reset)
* @arg GPIO_AF_TRACE: Connect TRACE pins to AF0 (default after reset)
* @arg GPIO_AF_TIM1: Connect TIM1 pins to AF1
* @arg GPIO_AF_TIM2: Connect TIM2 pins to AF1
* @arg GPIO_AF_TIM3: Connect TIM3 pins to AF2
* @arg GPIO_AF_TIM4: Connect TIM4 pins to AF2
* @arg GPIO_AF_TIM5: Connect TIM5 pins to AF2
* @arg GPIO_AF_TIM8: Connect TIM8 pins to AF3
* @arg GPIO_AF_TIM9: Connect TIM9 pins to AF3
* @arg GPIO_AF_TIM10: Connect TIM10 pins to AF3
* @arg GPIO_AF_TIM11: Connect TIM11 pins to AF3
* @arg GPIO_AF_I2C1: Connect I2C1 pins to AF4
* @arg GPIO_AF_I2C2: Connect I2C2 pins to AF4
* @arg GPIO_AF_I2C3: Connect I2C3 pins to AF4
* @arg GPIO_AF_SPI1: Connect SPI1 pins to AF5
* @arg GPIO_AF_SPI2: Connect SPI2/I2S2 pins to AF5
* @arg GPIO_AF_SPI4: Connect SPI4 pins to AF5
* @arg GPIO_AF_SPI5: Connect SPI5 pins to AF5
* @arg GPIO_AF_SPI6: Connect SPI6 pins to AF5
* @arg GPIO_AF_SAI1: Connect SAI1 pins to AF6 for STM32F42xxx/43xxx devices.
* @arg GPIO_AF_SPI3: Connect SPI3/I2S3 pins to AF6
* @arg GPIO_AF_I2S3ext: Connect I2S3ext pins to AF7
* @arg GPIO_AF_USART1: Connect USART1 pins to AF7
* @arg GPIO_AF_USART2: Connect USART2 pins to AF7
* @arg GPIO_AF_USART3: Connect USART3 pins to AF7
* @arg GPIO_AF_UART4: Connect UART4 pins to AF8
* @arg GPIO_AF_UART5: Connect UART5 pins to AF8
* @arg GPIO_AF_USART6: Connect USART6 pins to AF8
* @arg GPIO_AF_UART7: Connect UART7 pins to AF8
* @arg GPIO_AF_UART8: Connect UART8 pins to AF8
* @arg GPIO_AF_CAN1: Connect CAN1 pins to AF9
* @arg GPIO_AF_CAN2: Connect CAN2 pins to AF9
* @arg GPIO_AF_TIM12: Connect TIM12 pins to AF9
* @arg GPIO_AF_TIM13: Connect TIM13 pins to AF9
* @arg GPIO_AF_TIM14: Connect TIM14 pins to AF9
* @arg GPIO_AF_OTG_FS: Connect OTG_FS pins to AF10
* @arg GPIO_AF_OTG_HS: Connect OTG_HS pins to AF10
* @arg GPIO_AF_ETH: Connect ETHERNET pins to AF11
* @arg GPIO_AF_FSMC: Connect FSMC pins to AF12
* @arg GPIO_AF_FMC: Connect FMC pins to AF12 for STM32F42xxx/43xxx devices.
* @arg GPIO_AF_OTG_HS_FS: Connect OTG HS (configured in FS) pins to AF12
* @arg GPIO_AF_SDIO: Connect SDIO pins to AF12
* @arg GPIO_AF_DCMI: Connect DCMI pins to AF13
* @arg GPIO_AF_LTDC: Connect LTDC pins to AF14 for STM32F429xx/439xx devices.
* @arg GPIO_AF_EVENTOUT: Connect EVENTOUT pins to AF15
* @retval None
*/
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
函数说明:复用引脚配置
返回值:无
GPIO_TypeDef* GPIOx:哪组GPIO
uint16_t GPIO_PinSource:哪个引脚
uint8_t GPIO_AF:复用功能
小项目
实现电机小轮加速、减速、暂停、方向改变
main.c
#include "stm32f4xx.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "beep.h"
#include "delay.h"
#include "tim.h"
#include "pwm.h"
#include "motor.h"
//这是一个主函数
int main(void)
{
//分为第二组:抢占优先级范围:0~3,响应优先级范围:0~3
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Delay_Init();
Exti_PA0_Init();
Exti_PE2_Init();
Exti_PE3_Init();
Exti_PE4_Init();
Pwm_PA2_Init();
Pwm_PA3_Init();
TIM_SetCompare3(TIM2, 0);
TIM_SetCompare4(TIM2, 0);
while(1)
{
delay_s(1);
}
return 0;
}
exti.c
#include "exti.h"
u8 car_flag = 0; //car_flag = 1正转, car_flag = 0 反转
u8 stop_cont_flag = 0; //stop_cont_flag = 1继续, stop_cont_flag =0 暂停
u32 speed = 300;
void delay(int n)
{
int i, j;
for(i=0; i<n; i++)
for(j=0; j<40000; j++);
}
/*****************************
引脚说明:
KEY0 -- PA0 -- EXTI0
KEY1 -- PE2 -- EXTI2
KEY2 -- PE3 -- EXTI3
KEY3 -- PE4 -- EXTI4
设置为下降沿触发
KEY0 -- 正/反转
KEY1 -- 加速
KEY2 -- 减速
KEY3 -- 暂停/继续
*****************************/
void Exti_PA0_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//使能SYSCFG时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//打开GPIOA组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //引脚0
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA, &GPIO_InitStruct);
//设置IO口与中断线的映射关系。PA0 -- EXTI0
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
EXTI_InitStruct.EXTI_Line = EXTI_Line0; //中断线0
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling; //下降沿
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; //中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
void Exti_PE2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//使能SYSCFG时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//打开GPIOE组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; //引脚2
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE, &GPIO_InitStruct);
//设置IO口与中断线的映射关系。PE2 -- EXTI2
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
EXTI_InitStruct.EXTI_Line = EXTI_Line2; //中断线2
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling; //下降沿
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI2_IRQn; //中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
void Exti_PE3_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//使能SYSCFG时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//打开GPIOE组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; //引脚3
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE, &GPIO_InitStruct);
//设置IO口与中断线的映射关系。PE3 -- EXTI3
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
EXTI_InitStruct.EXTI_Line = EXTI_Line3; //中断线3
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling; //下降沿
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI3_IRQn; //中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
void Exti_PE4_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
//使能SYSCFG时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//打开GPIOE组时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4; //引脚4
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; //输入模式
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE, &GPIO_InitStruct);
//设置IO口与中断线的映射关系。PE4 -- EXTI4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
EXTI_InitStruct.EXTI_Line = EXTI_Line4; //中断线4
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //中断
EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling; //下降沿
EXTI_InitStruct.EXTI_LineCmd= ENABLE; //中断线使能
//初始化线上中断,设置触发条件等。
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = EXTI4_IRQn; //中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能
//配置中断分组(NVIC),并使能中断。
NVIC_Init(&NVIC_InitStruct);
}
/******************************************
编写中断服务函数
所有的中断服务函数都可在startup_stm32f40_41xxx.s当中查找
中断服务函数只能写一次,且不需要程序员调用此函数,当需要
中断条件时,CPU自动会执行该函数
*****************************************/
//KEY0 -- 正/反转
void EXTI0_IRQHandler(void)
{
//判断中断线标志位是否为1
if(EXTI_GetITStatus(EXTI_Line0) == SET)
{
//变更灯状态
delay(100);
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
{
car_flag = !car_flag; //每次变更状态
//反转
if(car_flag == 0)
{
//反转
TIM_SetCompare3(TIM2, 0); //占空比为0,相当接GND(PA2)
TIM_SetCompare4(TIM2, speed);
}
else
{
//正转
TIM_SetCompare3(TIM2, speed);
TIM_SetCompare4(TIM2, 0); //占空比为0,相当接GND(PA3)
}
}
//如果不清空标志位CPU会不停响应中断
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
//加速
void EXTI2_IRQHandler(void)
{
//判断中断线标志位是否为1
if(EXTI_GetITStatus(EXTI_Line2) == SET)
{
//变更灯状态
delay(100);
if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2) == 0)
{
speed += 20; //一次调节20
if(speed >= 499)
{
speed = 499;
}
//判断正反转
//反转
if(car_flag == 0)
{
//反转
TIM_SetCompare3(TIM2, 0); //占空比为0,相当接GND
TIM_SetCompare4(TIM2, speed);
}
else
{
//正转
TIM_SetCompare3(TIM2, speed);
TIM_SetCompare4(TIM2, 0); //占空比为0,相当接GND
}
}
//如果不清空标志位CPU会不停响应中断
EXTI_ClearITPendingBit(EXTI_Line2);
}
}
//减速
void EXTI3_IRQHandler(void)
{
//判断中断线标志位是否为1
if(EXTI_GetITStatus(EXTI_Line3) == SET)
{
//变更灯状态
delay(100);
if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3) == 0)
{
speed -= 20; //一次调节20
if(speed <= 150)
{
speed = 150; //实际这个150可以是0
}
//判断正反转
//反转
if(car_flag == 0)
{
//反转
TIM_SetCompare3(TIM2, 0); //占空比为0,相当接GND
TIM_SetCompare4(TIM2, speed);
}
else
{
//正转
TIM_SetCompare3(TIM2, speed);
TIM_SetCompare4(TIM2, 0); //占空比为0,相当接GND
}
}
//如果不清空标志位CPU会不停响应中断
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
//暂停与继续
void EXTI4_IRQHandler(void)
{
//判断中断线标志位是否为1
if(EXTI_GetITStatus(EXTI_Line4) == SET)
{
//变更灯状态
delay(100);
if(GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4) == 0)
{
//继续
if(stop_cont_flag == 1)
{
//反转
if(car_flag == 0)
{
//反转
TIM_SetCompare3(TIM2, 0); //占空比为0,相当接GND
TIM_SetCompare4(TIM2, speed);
}
else
{
//正转
TIM_SetCompare3(TIM2, speed);
TIM_SetCompare4(TIM2, 0); //占空比为0,相当接GND
}
stop_cont_flag = 0;
}
else //暂停
{
TIM_SetCompare3(TIM2, 0);
TIM_SetCompare4(TIM2, 0);
stop_cont_flag++;
}
}
//如果不清空标志位CPU会不停响应中断
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
motor.c
#include "motor.h"
/********************************
PA2 -- TIM2_CH3
PA3 -- TIM2_CH4
TIM2(32位定时器) 挂在APB1, 定时器频率:84MHZ
********************************/
void Pwm_PA2_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
//使能定时器2时钟:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//使能GPIOA时钟:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 ; //引脚2
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; //复用模式
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //复用推挽
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHZ
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA, &GPIO_InitStruct);
//GPIOA2复用映射到定时器2
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_TIM2);
TIM_TimeBaseInitStruct.TIM_Prescaler = 84-1; //84分频 84MHZ/84 = 1MHZ
TIM_TimeBaseInitStruct.TIM_Period = 500-1; //计500个数,在1MHZ,用时500us
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInitStruct.TIM_ClockDivision= TIM_CKD_DIV1; //分频因子
//2、初始化定时器,配置ARR,PSC。
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; //PWM1模式
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //极性电平为高,设定的输出电平值
TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable; //输出通道使能
//初始化输出比较参数, OC3 --- 通道3
TIM_OC3Init(TIM2, &TIM_OCInitStruct);
//使能预装载寄存器:
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
//使能自动重装载的预装载寄存器允许位-- ARR
TIM_ARRPreloadConfig(TIM2,ENABLE);
//使能定时器。
TIM_Cmd(TIM2, ENABLE);
}
void Pwm_PA3_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
//使能定时器2时钟:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//使能GPIOA时钟:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 ; //引脚3
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; //复用模式
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //复用推挽
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHZ
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA, &GPIO_InitStruct);
//GPIOA3复用映射到定时器2
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_TIM2);
TIM_TimeBaseInitStruct.TIM_Prescaler = 84-1; //84分频 84MHZ/84 = 1MHZ
TIM_TimeBaseInitStruct.TIM_Period = 500-1; //计500个数,在1MHZ,用时500us
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInitStruct.TIM_ClockDivision= TIM_CKD_DIV1; //分频因子
//2、初始化定时器,配置ARR,PSC。
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; //PWM1模式
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //极性电平为高,设定的输出电平值
TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable; //输出通道使能
//初始化输出比较参数, OC4 --- 通道4
TIM_OC4Init(TIM2, &TIM_OCInitStruct);
//使能预装载寄存器:
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
//使能自动重装载的预装载寄存器允许位-- ARR
TIM_ARRPreloadConfig(TIM2,ENABLE);
//使能定时器。
TIM_Cmd(TIM2, ENABLE);
}