网上购物网站开发开题报告,网络推广费用大概价格,校园网站建设教程,淘宝运营培训课程有用吗目录 一、输出比较简介
二、PWM简介
三、输出比较模式实现
1.输出比较框图(以通用定时器为例)
2.PWM基本结构
四、固件库实现
1.程序1#xff1a;PWM呼吸灯 2.程序2#xff1a;PWM驱动直流电机
3.程序3#xff1a;控制舵机 一、输出比较简介 死区生成和互补输出一般…目录 一、输出比较简介
二、PWM简介
三、输出比较模式实现
1.输出比较框图(以通用定时器为例)
2.PWM基本结构
四、固件库实现
1.程序1PWM呼吸灯 2.程序2PWM驱动直流电机
3.程序3控制舵机 一、输出比较简介 死区生成和互补输出一般用于对电机的控制 二、PWM简介 惯性系统即要能使人眼产生视觉停留的系统 三、输出比较模式实现 1.输出比较框图(以通用定时器为例) 高级定时器比通用定时器多了个互补输出和死区生成 如右图两个mos管构成了推挽电路上管导通下管关闭输出高电平下管导通上管关闭输出低电平两管都关闭为高阻态两管都导通为短路会对元器件造成损伤所以两管不能同时导通 互补输出当单片机要控制这个电路时就需要两个输出端口且二者电平要相反即互补而这里OC1和OC1N就是互补的两个端口即互补输出 死区发生器但是若在上管关闭的瞬间下管就导通很可能由于器件的不理想而出现上下管都导通的情况为了避免这种情况发生于是又是死区发生器即他可以在上管关闭后延迟一段时间再导通下管避免同时导通 2.PWM基本结构 四、固件库实现
1.程序1PWM呼吸灯 1.我使用的是TIM3的CH2的重定义引脚PB5所以要打开AFIO时钟 2.开启TIM3和GPIO的时钟 3.初始化GPIO结构体。注意要记得使用库函数进行重定义 4.选择TIM3的时钟输入可以为内部时钟外部时钟模式1和2 外部时钟模式1来源可以是ITR(其他定时器,多用于定时器级联)可以是ETR外部时 钟可以是CH1引脚的边沿CH1引脚和CH2引脚多用于输入捕获测频率 外部时钟模式2ETR的触发控制模式 5.初始化TIM3结构体--配置PSCARR计数模式等等 6.初始化OC结构体--PWM模式选择CCR输出ref的有效电平 7.定时器使能 //使用TIM3的通道2的重定义引脚PB5-指南者上面是红灯
//我们配置
void PWM_Config()
{//首先开启GPIO时钟//开启AFIO时钟因为用到了重定义RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);//开启定时器的时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//重定义引脚//选择部分重定义GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//初始化GPIO结构体-PB5-输出比较GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽手册可看GPIO_InitStruct.GPIO_Pin GPIO_Pin_5;GPIO_Init(GPIOB,GPIO_InitStruct);//选择TIM3的时钟输入TIM_InternalClockConfig(TIM3);//我们直接使用内部时钟//配置TIM结构体TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_Prescaler 72-1;//PSCTIM_TimeBaseInitStruct.TIM_CounterMode TIM_CounterMode_Up;//计数模式TIM_TimeBaseInitStruct.TIM_Period 100-1;//ARRTIM_TimeBaseInitStruct.TIM_ClockDivision TIM_CKD_DIV1;//输入滤波器的分频TIM_TimeBaseInitStruct.TIM_RepetitionCounter 0;//重复计数器,只有高级定时器才有TIM_TimeBaseInit(TIM3,TIM_TimeBaseInitStruct);//初始化OC结构体TIM_OCInitTypeDef TIM_OCInitStruct;TIM_OCStructInit(TIM_OCInitStruct);//先赋初值因为我们没有把结构体配置完全TIM_OCInitStruct.TIM_OCMode TIM_OCMode_PWM1;//模式选择-PWM1TIM_OCInitStruct.TIM_OutputState TIM_OutputState_Enable;//输出使能TIM_OCInitStruct.TIM_Pulse 0;//CCR这里我们不配置CCR的值后面用一个库函数直接在主函数 里面配置实现呼吸灯TIM_OCInitStruct.TIM_OCPolarity TIM_OCPolarity_High;//输出ref极性,选择有效电平即ref有效时输出高电平//TIM_OCInitStruct.TIM_OCNPolarity ;//TIM_OCInitStruct.TIM_OCIdleState ;//TIM_OCInitStruct.TIM_OCNIdleState ;//TIM_OCInitStruct.TIM_OutputNState ;TIM_OC2Init(TIM3,TIM_OCInitStruct);//启动定时器TIM_Cmd(TIM3,ENABLE);}void PWM_SetCompare2(uint16_t Compare)
{TIM_SetCompare2(TIM3,Compare);
}main.c#include stm32f10x.h // Device header
#include bsp_led.h
#include .\tim\bsp_tim.hextern uint16_t Num;//定时器都是16位的int i;
void Delay(u32 i)
{u32 temp;SysTick-LOAD9000*i; //设置重装数值, 72MHZ时SysTick-CTRL0X01; //使能减到零是无动作采用外部时钟源SysTick-VAL0; //清零计数器do{tempSysTick-CTRL; //读取当前倒计数值}while((temp0x01)(!(temp(116)))); //等待时间到达SysTick-CTRL0; //关闭计数器SysTick-VAL0; //清空计数器
}//ARR99--PWM一个周期是100那么分辨率为1%
//占空比 CCR/(ARR1)
//频率 计数器溢出频率 CK_PSC/(PSC1)/(ARR1) 72M/720/100 1000HZ -1ms
int main()
{LED_GPIO_Config();PWM_Config();while(1){for(i0;i100;i){PWM_SetCompare2(i);Delay(10);}for(i100;i0;i--){PWM_SetCompare2(i);Delay(10);}}
} 2.程序2PWM驱动直流电机 具体TIM的配置过程同呼吸灯一样同样是输出不同的PWM占空比来实现电机的不同速度 我们需要三个引脚一个输出PWM给电机两个接电机的控制引脚 使用PA2输出PWMAIN1/2接到PA4/5频率设置为1KHZ可以自己随便设置定义一个八位有符号的变量Speed正转 -反转使用GPIO_SetBits/ResetBits();来设置AIN1/2的电平高低 使用按键来改变转速 void PWM_Config()
{//开启时钟//使用TIM2的CH3的PA2RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启PWM引脚//初始化GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽手册可看GPIO_InitStruct.GPIO_Pin GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5 ;GPIO_Init(GPIOA,GPIO_InitStruct);//选择时基单元的时钟-为内部时钟--定时器上电后默认是内部时钟故不写这一个也行TIM_InternalClockConfig(TIM2);//初始化时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;//配置1KHZ的PWMTIM_TimeBaseInitStruct.TIM_Prescaler 720-1;//PSC-预分频器TIM_TimeBaseInitStruct.TIM_CounterMode TIM_CounterMode_Up;//向上计数 TIM_TimeBaseInitStruct.TIM_Period 100-1;//ARR寄存器-重装载寄存器TIM_TimeBaseInitStruct.TIM_ClockDivision TIM_CKD_DIV1;/*不分频----滤波器的采样频率可以由内部时钟直接提供也可以由内部时钟加一个时钟分频而来分频系数就是由TIM_ClockDivision决定*/TIM_TimeBaseInitStruct.TIM_RepetitionCounter 0;//重复计数器只有高级定时器才有TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStruct);//初始化OC-输出比较结构体TIM_OCInitTypeDef TIM_OCInitStruct;TIM_OCStructInit(TIM_OCInitStruct);//因为结构体里面的成员有些是高级定时器采用得到所以这里就先全部初始化一遍然后再配置具体的值TIM_OCInitStruct.TIM_OCMode TIM_OCMode_PWM1;//输出比较模式TIM_OCInitStruct.TIM_OutputState TIM_OutputState_Enable;//TIM_OCInitStruct.TIM_Pulse 50;//CRR TIM_OCInitStruct.TIM_Pulse 0;//输出要求波型这里的CRR就不需要了用固件库的一个函数 TIM_SetCompare3 直接配置CRRTIM_OCInitStruct.TIM_OCPolarity TIM_OCPolarity_High;//输出比较极性TIM_OC3Init(TIM2,TIM_OCInitStruct);//CH3通道//启动定时器TIM_Cmd(TIM2,ENABLE);}
//电机控制函数void Motor_SetSpeed(int8_t Speed)//正转 -反转
{if(Speed 0){GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_ResetBits(GPIOA,GPIO_Pin_5);TIM_SetCompare3(TIM3,Speed);}else {GPIO_ResetBits(GPIOA,GPIO_Pin_4);GPIO_SetBits(GPIOA,GPIO_Pin_5);TIM_SetCompare3(TIM3,-Speed);}
}
//主函数#include stm32f10x.h // Device header
#include .\tim\bsp_tim.h
#include .\KEY\bsp_key.huint8_t KeyNum;
int8_t Speed;int main()
{KEY_GPIO_Config();PWM_Config();while(1){KeyNum Key_Scan();if(KeyNum 0){Speed 20;if(Speed 100){Speed -100;}}else if(KeyNum 1){Speed - 20;if(Speed -100){Speed 100;}}Motor_SetSpeed(Speed);}
}3.程序3控制舵机 -TB6612驱动板 VM-STLINK的5v VCC-面包板3.3v GND-面包板负极 AO1 AO2 接电机 STBY-待机控制引脚这里不需要待机接面包3.3v AIN1/2- 任意接两个引脚 PWMA-PWM输出控制引脚 驱动VM放在左下角使用PA2输出PWMAIN1/2接到PA4/5 要点输出如上图右侧所示的PWM波型指南者的PA0引脚为按键1所以使用TIM2的CH3通道的PA2PWM要求频率为50HZ即总时间20ms高电平占0.5~2.5ms这里我们可以给ARR配置20000-1PSC配置72-1封装Angle转换函数0-50 180-2500 --yAngle/180*250050, Angle使用浮点型利于计算使用按键来改变角度 #include bsp_tim.hvoid PWM_Config()
{//开启时钟//使用TIM2的CH3的PA2RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启PWM引脚//初始化GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽手册可看GPIO_InitStruct.GPIO_Pin GPIO_Pin_2;GPIO_Init(GPIOA,GPIO_InitStruct);//选择时基单元的时钟-为内部时钟--定时器上电后默认是内部时钟故不写这一个也行TIM_InternalClockConfig(TIM2);//初始化时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_Prescaler 72-1;//PSC-预分频器TIM_TimeBaseInitStruct.TIM_CounterMode TIM_CounterMode_Up;//向上计数 TIM_TimeBaseInitStruct.TIM_Period 20000-1;//ARR寄存器-重装载寄存器TIM_TimeBaseInitStruct.TIM_ClockDivision TIM_CKD_DIV1;/*不分频----滤波器的采样频率可以由内部时钟直接提供也可以由内部时钟加一个时钟分频而来分频系数就是由TIM_ClockDivision决定*/TIM_TimeBaseInitStruct.TIM_RepetitionCounter 0;//重复计数器只有高级定时器才有TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStruct);//初始化OC-输出比较结构体TIM_OCInitTypeDef TIM_OCInitStruct;TIM_OCStructInit(TIM_OCInitStruct);//因为结构体里面的成员有些是高级定时器采用得到所以这里就先全部初始化一遍然后再配置具体的值TIM_OCInitStruct.TIM_OCMode TIM_OCMode_PWM1;//输出比较模式TIM_OCInitStruct.TIM_OutputState TIM_OutputState_Enable;//TIM_OCInitStruct.TIM_Pulse 50;//CRR --舵机要求设置频率50HZ-即总时间20ms高电平时间在0.5~2.5ms之间的PWM波型即CCR-500~2500TIM_OCInitStruct.TIM_Pulse 0;//输出要求波型这里的CRR就不需要了用固件库的一个函数 TIM_SetCompare3 直接配置CRRTIM_OCInitStruct.TIM_OCPolarity TIM_OCPolarity_High;//输出比较极性TIM_OC3Init(TIM2,TIM_OCInitStruct);//CH3通道//启动定时器TIM_Cmd(TIM2,ENABLE);
}
//0.5ms-0度 2.5ms-180度
//0度 CCR500
//180度 CCR2500
//舵机设置角度范围0~180
void Servo_SetAngle(float Angle)
{TIM_SetCompare3(TIM2,Angle*2000/180500);
}void PWM_SetCompare3(uint16_t Compare)//设置CRR
{TIM_SetCompare3(TIM2,Compare);
}#include stm32f10x.h // Device header
#include .\tim\bsp_tim.h
#include .\KEY\bsp_key.h
uint8_t KeyNum;
float Angle;int main()
{KEY_GPIO_Config();LED_GPIO_Config();PWM_Config();while(1){KeyNum Key_Scan();if(KeyNum 0){Angle30;if(Angle180){Angle 0;}}else if(KeyNum 1){Angle-30;if(Angle0){Angle 180;}}Servo_SetAngle(Angle);}
}