[mw_shl_code=c,true]#include "pwm.h"
//////////////////////////////////////////////////////////
//arr:自动重装值
//psc:时钟预分频数
//左电机:PA6(TIM3_CH1) 右电机

A7(TIM3_CH2)
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM3 CH1的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //TIM3_CH1(PA6)
TIM3_CH2(PA7) [/mw_shl_code]
[mw_shl_code=c,true] GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //TIM3_CH1预装载使能
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //TIM3_CH2预装载使能
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
}
//////////////////////////////////////////////////////////
//左电机:设置PA4,PA5引脚为推挽输出,PA4连接驱动器IN1,PA5连接驱动器IN2
//右电机:设置PA2,PA3引脚为推挽输出,PA2连接驱动器IN1,PA3连接驱动器IN2
void IN1_IN2_GPIO_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_2);
GPIO_ResetBits(GPIOA,GPIO_Pin_3);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);
GPIO_ResetBits(GPIOA,GPIO_Pin_5);
}
[mw_shl_code=c,true]#include "speedControl.h"
#include "pwm.h"
#define PARAM1 0.009751503597 //speed=PARAM1*pulses pulses:5ms内测得的脉冲个数 轮径:194mm 电机减速比:12.5:1 500线编码器
extern float setSpeed;
struct _myStruct myStructL;
struct _myStruct myStructR;
int L_pwmval=700;
int R_pwmval=700;
/////////////////////////////////////////////////
//速度控制周期 10ms
void TIM6_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 , ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
}
/////////////////////////////////////////////////
//速度控制周期 10ms,中断执行程序
void TIM6_IRQHandler(void)
{
u32 L_pulses=0;
u32 R_pulses=0;
if(TIM_GetITStatus(TIM6,TIM_IT_Update)!=RESET) //TIM6更新中断发生与否
{
L_pulses=TIM5->CNT;
R_pulses=TIM4->CNT;
TIM4->CR1&=0XFFFE; // 停止计数器
TIM5->CR1&=0XFFFE; // 停止计数器
TIM6->CR1&=0XFFFE; // 停止定时器
myStructL.actualSpeed=L_pulses*PARAM1;
myStructR.actualSpeed=R_pulses*PARAM1;
printf("%f ",myStructL.actualSpeed);
printf(" %f\n ",myStructR.actualSpeed);[/mw_shl_code]
[mw_shl_code=c,true] myControl();
TIM_ClearITPendingBit(TIM6,TIM_IT_Update);
TIM5->CNT=0;
TIM4->CNT=0;
TIM6->CR1|=1<<0; // 启动定时器
TIM5->CR1|=1<<0; // 启动计数器
TIM4->CR1|=1<<0; // 启动计数器
}
}
///////////////////////////////////////////////////////////////////////
//左电机测速设置
//TIM5_CH1外部时钟源模式1
void TIM5_CH1_Excnt_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<3; // TIM5时钟使能
RCC->APB2ENR|=1<<2; // 使能PORTA时钟
GPIOA->CRL&=0XFFFFFFF0; // PA0清除之前设置
GPIOA->CRL|=0X00000004; //PA0输入
GPIOA->ODR|=0<<0; // PA0下拉
TIM5->ARR=arr; //
TIM5->

SC=psc; //
TIM5->CCMR1|=1<<0; // 选择输入端IC1映射到TI1
TIM5->CCMR1&=0XFF0F; // IC1F=0000 配置输入滤波器不滤波
TIM5->CCER|=1<<0; // CC1P=0 上升沿计数
TIM5->SMCR|=5<<4; // 触发选择:滤波后的定时器输入1(TI1FP1)
TIM5->SMCR|=7<<0; // 外部时钟模式1
}
///////////////////////////////////////////////////////////////////////
//右电机测速设置
//TIM4_CH1(PB6)外部时钟源模式1 APB1
void TIM4_CH1_Excnt_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<2; // TIM4时钟使能
RCC->APB2ENR|=1<<3; // 使能PORTB时钟
GPIOB->CRL&=0XF0FFFFFF; // PB6清除之前设置
GPIOB->CRL|=0X04000000; //PB6输入
GPIOB->ODR|=0<<6; // PB6下拉
TIM4->ARR=arr; //
TIM4->

SC=psc; //
TIM4->CCMR1|=1<<0; // 选择输入端IC1映射到TI1
TIM4->CCMR1&=0XFF0F; // IC1F=0000 配置输入滤波器不滤波
TIM4->CCER|=1<<0; // CC1P=0 上升沿计数
TIM4->SMCR|=5<<4; // 触发选择:滤波后的定时器输入1(TI1FP1)
TIM4->SMCR|=7<<0; // 外部时钟模式1
}
//车轮速度控制(PID没调出来,用此代替(实测反应,误差都还好。))
void myControl(void)
{
//左电机
myStructL.speedError=myStructL.setSpeed-myStructL.actualSpeed;
if(myStructL.speedError<-0.05) L_pwmval+=5 ;
if(myStructL.speedError>-0.05 && myStructL.speedError<0 )
L_pwmval+=1;
if(myStructL.speedError<0.05 && myStructL.speedError>0)
L_pwmval-=1;
if(myStructL.speedError>0.05) L_pwmval-=5 ;
if(L_pwmval<0) L_pwmval=0;
if(L_pwmval>900) L_pwmval=900;
//右电机
myStructR.speedError=myStructR.setSpeed-myStructR.actualSpeed;
if(myStructR.speedError<-0.05) R_pwmval+=5 ;
if(myStructR.speedError>=-0.05 && myStructR.speedError<0 )
R_pwmval+=1;
if(myStructR.speedError<=0.05 && myStructR.speedError>0)
R_pwmval-=1;
if(myStructR.speedError>0.05) R_pwmval-=5 ;
if(R_pwmval<0) R_pwmval=0;
if(R_pwmval>900) R_pwmval=900;
[/mw_shl_code]
[mw_shl_code=c,true] TIM_SetCompare1(TIM3, L_pwmval); //左电机PWM
TIM_SetCompare2(TIM3, R_pwmval); //右电机PWM
}
[/mw_shl_code]
[mw_shl_code=c,true]
[/mw_shl_code]
[mw_shl_code=c,true]
[/mw_shl_code]
[/mw_shl_code]