1234 | void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); |
配置输出比较模块,OC意为Output Compare。
有四个输出比较单元,对应四个函数。
1 | void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); |
用来给输出比较结构体赋默认值。可以不用手动设置所有的TIM结构体参数。
1 | void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); |
使用高级定时器输出PWM时,需要使能主输出,否则PWM将不能正常输出(仅高级定时器)
1234 | void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction); |
配置强制输出模式,暂停输出波形并且强制输出高电平或者低电平。
1234 | void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); |
配置CCR寄存器的预装功能(影子寄存器),即写入的值不会立即生效,而是在更新事件后生效。
1234 | void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast); |
配置快速使能。
1234 | void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear); |
外部事件时清除REF信号。
12345678910 | void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); |
单独设置输出比较极性,NPolarity是高级定时器里互补通道的配置。OC4没有互补通道,所以没有OC4N的函数
12 | void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN); |
单独修改输出使能的。
1 | void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); |
选择输出比较模式,单独修改输出比较模式。
1234 | void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4); |
单独更改CCR寄存器值,在运行时修改占空比需要用到。
PWM驱动LED呼吸灯
PWM.C
123456789101112131415161718192021222324252627282930313233343536373839404142434445 | void PWM_Init(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使用引脚重映射,需要先使能AFIO// GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//引脚重映射,把PA0映射到PA15// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//使用复用开漏/推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;//ARR TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;//PSC TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure); //输出比较 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure);//用来给输出比较结构体赋默认值。 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//设置OC比较的模式 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能 TIM_OCInitStructure.TIM_Pulse = 0;//设置CCR TIM_OC1Init(TIM2,&TIM_OCInitStructure); TIM_Cmd(TIM2,ENABLE); } void PWM_SetCompare1(uint16_t Compare)//运行时修改CCR的值{ TIM_SetCompare1(TIM2,Compare);} |
main.c
1234567891011121314151617181920212223 | uint8_t i;int main(void){ OLED_Init(); PWM_Init();//PWM初始化 while (1) { for(i = 1 ;i <= 100 ; i++)//CCR的值从1到100变化,再从100到1,LED的占空比不断变化,亮度也不断变化。 { PWM_SetCompare1(i); Delay_ms(20); } for(i = 1 ;i <= 100 ; i++) { PWM_SetCompare1(100 - i); Delay_ms(20); } }} |
PWM驱动舵机
PWM.C
123456789101112131415161718192021222324252627282930313233343536373839 | void PWM_Init(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//使用复用开漏/推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;//ARR TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//PSC TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//设置OC比较的模式 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能 TIM_OCInitStructure.TIM_Pulse = 0;//设置CCR,默认先设置成0,之后再改 TIM_OC2Init(TIM2,&TIM_OCInitStructure); TIM_Cmd(TIM2,ENABLE); } void PWM_SetCompare2(uint16_t Compare){ TIM_SetCompare2(TIM2,Compare);} |
Servo.c
1234567891011121314 | void Servo_init(void){ PWM_Init(); } void Servo_SetAngle(float Angle){ PWM_SetCompare2(Angle / 180 * 2000 + 500);} |
Main.c
123456789101112131415161718192021222324252627282930 | uint8_t KeyNum;float Angle;int main(void){ OLED_Init(); Servo_init(); KEY_Init(); OLED_ShowString(1,1,"Angle:"); while(1) { KeyNum = Key_GetNum(); if(KeyNum == 1) { Angle += 30; if(Angle > 180) { Angle = 0; } } Servo_SetAngle(Angle); OLED_ShowNum(1,7,Angle,3); }} |
PWM驱动直流电机
Motor.c
1234567891011121314151617181920212223242526272829303132 | void Motor_Init(void)//初始化直流电机{ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); PWM_Init(); } void Motor_SetSpeed(int8_t Speed){ if(Speed >= 0)//输入的Speed>=0 { GPIO_SetBits(GPIOA,GPIO_Pin_4);//置位PA4,方向 GPIO_ResetBits(GPIOA,GPIO_Pin_5);//复位PA5,对应方向 PWM_SetCompare3(Speed);//修改CCR } else//Speed<0 { GPIO_SetBits(GPIOA,GPIO_Pin_5); GPIO_ResetBits(GPIOA,GPIO_Pin_4); PWM_SetCompare3(-Speed);//Speed为负数,取反 }} |
PWM.c
12345678910111213141516171819202122232425262728293031323334353637383940 | void PWM_Init(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;//ARR TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;//PSC TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC3Init(TIM2,&TIM_OCInitStructure); TIM_Cmd(TIM2,ENABLE); } void PWM_SetCompare3(uint16_t Compare){ TIM_SetCompare3(TIM2,Compare);} |
main.c
123456789101112131415161718192021222324252627282930 | uint8_t KeyNum;int8_t Speed;int main(void){ OLED_Init(); Motor_Init(); OLED_ShowString(1,1,"Speed:"); while (1) { KeyNum = Key_GetNum(); if(KeyNum == 1) { Speed += 20; if(Speed > 100) { Speed = -100; } Motor_SetSpeed(Speed); OLED_ShowSignedNum(1,7,Speed,3); } }} |