网站的ftp上传地址,wordpress 文章摘要,音乐网站制作视频教学,网站seo优化的目的目录 一、输出比较简介
二、PWM简介
三、输出比较通道#xff08;通用#xff09;
四、输出比较通道#xff08;高级#xff09;
五、输出比较模式
六、PWM基本结构
七、PWM参数计算
八、外设介绍
8.1 舵机
8.2 直流电机及驱动
九、开发步骤
十、输出比较库函数…目录 一、输出比较简介
二、PWM简介
三、输出比较通道通用
四、输出比较通道高级
五、输出比较模式
六、PWM基本结构
七、PWM参数计算
八、外设介绍
8.1 舵机
8.2 直流电机及驱动
九、开发步骤
十、输出比较库函数
十一、实验
9.1 PWM驱动LED呼吸灯
9.2 PWM驱动舵机
9.3 PWM驱动直流电机 一、输出比较简介 OCOutput Compare输出比较 输出比较可以通过比较CNT与CCR捕获/比较寄存器值的关系来对输出电平进行置1、置0或翻转的操作用于输出一定频率和占空比的PWM波形 每个高级定时器和通用定时器都拥有4个输出比较通道 高级定时器的前3个通道额外拥有死区生成和互补输出的功能 二、PWM简介 PWMPulse Width Modulation脉冲宽度调制 在具有惯性的系统中可以通过对一系列脉冲的宽度进行调制来等效地获得所需要的模拟参量常应用于电机控速等领域 PWM参数 频率 1 / Ts 占空比 Ton / Ts 分辨率 占空比变化步距 三、输出比较通道通用 四、输出比较通道高级 五、输出比较模式 六、PWM基本结构 七、PWM参数计算 八、外设介绍
8.1 舵机 8.2 直流电机及驱动 九、开发步骤 ①RCC打开时钟TIM和GPIO外设的时钟打开 ②配置时基单元包括前面的时钟源选择 ③结构体配置输出比较单元CCR输出比较模式极性选择输出使能 ④配置GPIOPWM对应GPIO初始化为复用推挽输出 ⑤运行控制启动计数器 十、输出比较库函数 注标的为重要需掌握 输出比较4模块配置函数 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); 参数①定时器②结构体 void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct); //输出比较结构体赋初值 配置强制输出模式了解即可 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); 配置CCR寄存器的预装功能影子寄存器了解即可 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); 配置快速使能了解即可 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); 外部事件清除REF信号了解即可 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); 单独设置输出比较极性 void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity); void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity); //N高级定时器互补通道的配置 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); 单独修改输出使能参数 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); 单独更改输出比较模式 void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode); 单独更改CCR寄存器值 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); 补充 void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState); //仅高级定时器使用在使用高级定时器输出PWM时需要调用这个函数使能主输出否则PWM将不能正常输出 十一、实验
9.1 PWM驱动LED呼吸灯 PWM.c #include stm32f10x.h // Device header/*PWM初始化*/
void PWM_Init(void)
{/*一、RCC开启时钟TIM与GPIO时钟打开*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);// /*使用重映射(*_*)*/
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
// GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//PA0-PA15部分重映射S
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除JATG调试GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_0;//(*_*)GPIO_Pin_15GPIO_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);/*三、配置输出比较单元CCR的值(捕获/比较器)输出比较模式极性选择输出使能*/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;//设置CCRTIM_OC1Init(TIM2,TIM_OCInitStructure);/*四、配置GPIO复用推挽输出*///一处已操作/*五、运行控制启动计数器CNT*/TIM_Cmd(TIM2,ENABLE);
}/*封装函数-更改CCR值来改变占空比*/
void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2,Compare);
} PWM.h #ifndef __PWM_H
#define __PWM_Hvoid PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);#endifmain.c #include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include PWM.huint8_t i;int main(void)
{OLED_Init();PWM_Init();while (1){//CCR增大逐渐变亮for (i 0; i 100; i){PWM_SetCompare1(i);Delay_ms(10);}//CCR减小逐渐变暗for (i 0; i 100; i){PWM_SetCompare1(100 - i);Delay_ms(10);}}
}9.2 PWM驱动舵机 实验现象按下按键舵机转动固定角度 PWM.c #include stm32f10x.h // Device header/*PWM初始化*/
void PWM_Init(void)
{/*一、RCC开启时钟TIM与GPIO时钟打开*/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);/*三、配置输出比较单元CCR的值(捕获/比较器)输出比较模式极性选择输出使能*/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;//设置CCR500~2500TIM_OC2Init(TIM2,TIM_OCInitStructure);/*四、配置GPIO复用推挽输出*///一处已操作/*五、运行控制启动计数器CNT*/TIM_Cmd(TIM2,ENABLE);
}/*封装函数-更改CCR值来改变占空比*/
void PWM_SetCompare2(uint16_t Compare)
{TIM_SetCompare2(TIM2,Compare);
} PWM.h #ifndef __PWM_H
#define __PWM_Hvoid PWM_Init(void);
void PWM_SetCompare2(uint16_t Compare);#endifServo.c #include stm32f10x.h // Device header
#include PWM.h//舵机初始化PWM初始化
void Servo_Init(void)
{PWM_Init();
}/*
舵机设置角度
角度0-180
CCR500-2500
*/
void Servo_SetAngle(float Angle)
{PWM_SetCompare2(Angle / 180 * 2000 500);
}Servo.h #ifndef __SERVO_H
#define __SERVO_Hvoid Servo_Init(void);
void Servo_SetAngle(float Angle);#endifKey.c #include stm32f10x.h // Device header
#include Delay.h//按键初始化//
void Key_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;//上拉输入GPIO_InitStructure.GPIO_Pin GPIO_Pin_1 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOB,GPIO_InitStructure);
}//获取按键返回码//
uint8_t Key_GetNum(void)
{uint8_t KeyNum 0;if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) 0){Delay_ms(20);//消抖while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) 0);//如果不松手则卡着Delay_ms(20);KeyNum 1;} if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) 0){Delay_ms(20);//消抖while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) 0);Delay_ms(20);KeyNum 2;}return KeyNum;
}key.h #ifndef __KEY_H
#define __KEY_Hvoid Key_Init(void);
uint8_t Key_GetNum(void);#endifmain.c #include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include key.h
#include Servo.huint8_t KeyNum;
float Angle;int main(void)
{OLED_Init();Key_Init();Servo_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);}
}*OLED显示屏代码请参考本专栏文章STM32-OLED显示屏 9.3 PWM驱动直流电机 实验现象 按键按下电机加速达到最大转速时再按一下最大速度反转按下按键电机减速 PWM.c #include stm32f10x.h // Device header/*PWM初始化*/
void PWM_Init(void)
{/*一、RCC开启时钟TIM与GPIO时钟打开*/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);/*三、配置输出比较单元CCR的值(捕获/比较器)输出比较模式极性选择输出使能*/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;//设置CCRTIM_OC3Init(TIM2,TIM_OCInitStructure);/*四、配置GPIO复用推挽输出*///一处已操作/*五、运行控制启动计数器CNT*/TIM_Cmd(TIM2,ENABLE);
}/*封装函数-更改CCR值来改变占空比*/
void PWM_SetCompare3(uint16_t Compare)
{TIM_SetCompare3(TIM2,Compare);
} PWM.h #ifndef __PWM_H
#define __PWM_Hvoid PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare);#endifMotor.c #include stm32f10x.h // Device header
#include PWM.hvoid 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();
}/*设置电机速度-100~100*/
void Motor_SetSpeed(int8_t Speed)
{if(Speed 0){GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_ResetBits(GPIOA,GPIO_Pin_5);PWM_SetCompare3(Speed);}else{GPIO_SetBits(GPIOA,GPIO_Pin_5);GPIO_ResetBits(GPIOA,GPIO_Pin_4);PWM_SetCompare3(-Speed);}
}Motor.h #ifndef __PWM_H
#define __PWM_Hvoid Motor_Init(void);
void Motor_SetSpeed(int8_t Speed);#endif*按键与OLED显示屏的代码参考之前实验代码