库函数
int cnt;
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
TIM3_PWM_Init(7199,0);//电机
TIM4_PWM_init(199,719);//舵机
hcsro4_init();
encoder_init();
uart_init(115200);
tongxing_init();
TIM2_Int_Init(99,7199);
cnt=read_encodera();
while(1)
{
send_data(cnt);
}
}
```c
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);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
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_0);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
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_1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
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_4);
GPIO_InitStructure.GPIO_Pin = 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_5);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_Cmd(TIM3, ENABLE);
}
void qianhou(float distance)
{
if(distance>0){
Ina=1;
Inb=0;
Inc=1;
Ind=0;
TIM_SetCompare1(TIM3,distance);
TIM_SetCompare2(TIM3,distance);
}
if(distance<0)
{
Ina=0;
Inb=1;
Inc=0;
Ind=1;
TIM_SetCompare1(TIM3,-distance);
TIM_SetCompare2(TIM3,-distance);
}
}
```c
int pwm_turn(int a)
{
int temp;
if(a<0)temp=-a;
else temp=a;
return temp;
}
float v_real=0;
float kp=5;
float ki=0.0;
float kd=0.5;
int err_now=0;//现在误差
int err_last=0;
int err_last_last=0;
int spd_now=0;//速度
int err_i=0;//误差积分值
int jiaua =0;//
int out=0;
int16_t PID(float val,int target)
{
//位置
spd_now=pwm_turn(val);
err_now=target-spd_now;
err_i+=err_now;
if (err_i>90) err_i=90;//限幅
out=kp*err_now+ki*err_i+kd*(err_now-err_last);
if(out>199) out=199;//pwm最大值不能超过
if(out<-199) out=-199;
err_last=err_now;
//增量式
// spd_now=cnt;
// err_now=target-spd_now;
// jiaua=kp*(err_now-err_last)+ki*err_now+kd*(err_now+err_last_last-2*err_last);
// out+=jiaua;
// if(out>900) out=900;
// TIM_SetCompare1(TIM3,out);
// err_last_last=err_last;
// err_last=err_now;
return out;
}
```c
void encoder_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICINITStructInit;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD;
TIM_TimeBaseStructure.TIM_Prescaler =ENCODER_TIM_PSC;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_ICStructInit(&TIM_ICINITStructInit);
TIM_ICINITStructInit.TIM_ICFilter=0xF;
TIM_ICINITStructInit.TIM_Channel=TIM_Channel_1;
TIM_ICInit(TIM4,&TIM_ICINITStructInit);
TIM_ICINITStructInit.TIM_ICFilter=0xF;
TIM_ICINITStructInit.TIM_Channel=TIM_Channel_2;
TIM_ICInit(TIM4,&TIM_ICINITStructInit);
TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_SetCounter(TIM4,0);
TIM_Cmd(TIM4, ENABLE);
}
void TIM4_IRQHandler(void)
{
if(TIM_GetFlagStatus(TIM4,TIM_FLAG_Update)==SET)//溢出中断
{
TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
}
}
int16_t read_encodera(void)
{
uint32_t encoderNum = 0;
encoderNum = TIM_GetCounter(TIM4);
//encoderNum=(encoderNum/4)/1320/0.1;//单位转每秒
return encoderNum;
}
void TIM2_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_TimeBaseInitStruct.TIM_Period = arr; //重装载值
TIM_TimeBaseInitStruct.TIM_Prescaler = psc; //预分频系数
TIM_TimeBaseInitStruct.TIM_ClockDivision =0; //时钟分割
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能定时器中断
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; //使能外部中断通道
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; //响应优先级3
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM2,ENABLE);
}
void TIM2_TRQHANDLER(void)
{
if (TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
int cnt=read_encodera();
int target=1000;
int out=PID(cnt,target);
qianhou(out);
}
}
```