基于STM32的蓝牙小车

目录

tb6612

520编码电机

PI闭环

蓝牙


tb6612

TB6612是双驱动,也就是可以驱动两个电机

下面分别是控制两个电机的IO口

STBY接低电平处于待机模式,接高电平开始工作置1通过AIN1 AIN2,BIN1,BIN2 来控制正反转

VM接12V以内电源

VCC接5V电源

GND 接电源负极

520编码电机

time.h配置定时器PWM模式和定时器编码模式

void encoder_PWM_Init(u16 arr,u16 psc);//TIM1的CH1和CH3作为A通道和B通道的PWM输出
void Encoder_Init_TIM2(void);//TIM2读取右轮的编码器值
void Encoder_Init_TIM3(void);//TIM3读取左轮的编码器值
int Read_Encoder(u8 TIMX);//编码器读取函数
void Encoder_Init(void);//与tb6612的AIN1 AIN2 BIN1 BIN2连接引脚的初始化

wheel.c将小车的前进、停止、左拐、右拐、掉头函数进行封装

extern int dianji_sudu_zuo,dianji_sudu_you;
extern int pwm_dianji_zuo,pwm_dianji_you;

void you_h(int sudu)
{
	dianji_sudu_you=sudu;
	GPIO_SetBits(GPIOB,GPIO_Pin_13);
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);
	TIM_SetCompare1(TIM1,sudu*1.4+pwm_dianji_you);		
}


void you_q(int sudu)
{
	dianji_sudu_you=sudu;
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
	GPIO_ResetBits(GPIOB,GPIO_Pin_13);
	TIM_SetCompare1(TIM1,sudu*1.4+pwm_dianji_you);		
}


void zuo_q(int sudu)
{
	  dianji_sudu_zuo=sudu;
		GPIO_SetBits(GPIOB,GPIO_Pin_1);
		GPIO_ResetBits(GPIOB,GPIO_Pin_0);
		TIM_SetCompare3(TIM1,sudu*1.4+pwm_dianji_zuo);			
}


void zuo_h(int sudu)
{
	  dianji_sudu_zuo=sudu;
		GPIO_SetBits(GPIOB,GPIO_Pin_0);
		GPIO_ResetBits(GPIOB,GPIO_Pin_1);
		TIM_SetCompare3(TIM1,sudu*1.4+pwm_dianji_zuo);			
}

void zuoguai(int sudu_zuo,int sudu_you,int shijian)
{
   zuo_h(sudu_zuo);
	 you_q(sudu_you);
	 delay_ms(shijian);
}                                             //×ó¹Õ

void qianjin(int sudu_zuo,int sudu_you,int shijian)
{
   zuo_q(sudu_zuo);
	 you_q(sudu_you);
	 delay_ms(shijian);
}         
void stop(int time)
{
	zuo_q(0);
	you_q(0);
//	GPIO_ResetBits(GPIOB,GPIO_Pin_11);
//	GPIO_ResetBits(GPIOB,GPIO_Pin_12);
//	GPIO_ResetBits(GPIOB,GPIO_Pin_0);
//	GPIO_ResetBits(GPIOB,GPIO_Pin_1);
	delay_ms(time);


}


void youguai(int sudu_zuo,int sudu_you,int shijian)
{
   zuo_q(sudu_zuo);
	 you_h(sudu_you);
	 delay_ms(shijian);
}                                                 //ÓÒ¹Õ

void diaotou(int sudu,int shijian)
{
   zuo_h(sudu);
	 you_q(sudu);
	 delay_ms(shijian);
}                                             //µôÍ·

PI闭环

pid.c

#include "pid.h"

void pid_init(pid_t *pid,u32 max_out,u32 integral_limit,float kp,float ki,float kd)
{
	pid->integral_limit=integral_limit;
	pid->max_output=max_out;
	pid->p=kp;
	pid->i=ki;
	pid->d=kd;
}                                                                    //pidµÄ³õʼ»¯

static void abs_limit(float *a,float ABS_MAX)
{
	if(*a>ABS_MAX)*a=ABS_MAX;
	if(*a<-ABS_MAX)*a=-ABS_MAX;
}


//µç»ú±Õ»· PI
int pid_speed(pid_t *pid,int get,int set)
{
	pid->get=get;//»ñÈ¡µ±Ç°Öµ
	pid->set=set;//»ñÈ¡Ä¿±êÖµ
	pid->err[NOW]=set-get;
	
	pid->pout=pid->p*pid->err[NOW];//pÊä³ö¼ÆËã
	pid->iout+=pid->i*pid->err[NOW];//iÊä³ö¼ÆËã
	
	abs_limit(&(pid->iout),pid->integral_limit);//iÏÞ·ù
	pid->out=pid->pout+pid->iout;//p+i
	
	abs_limit(&(pid->out),pid->max_output);//p+iÏÞ·ù
	pid->err[LAST]=pid->err[NOW];//µü´úÎó²î
	return pid->out;
}

在main.c中使用TIM4中断周期性进行PID的运算,并将结果反馈到TIM_SetCompare()函数中,更新PWM的比较值。

void TIM4_IRQHandler(void)   //TIM3??
{	 		
	if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
	{
	 TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	 dianji_zuo_duqu=Read_Encoder(3);
	 dianji_you_duqu=Read_Encoder(2);
	 pwm_dianji_zuo=pid_speed(&speed_pid_zuo,abs(dianji_zuo_duqu),dianji_sudu_zuo);
	 pwm_dianji_you=pid_speed(&speed_pid_you,abs(dianji_you_duqu),dianji_sudu_you);
	}
}

蓝牙

手机端发送"A""B"等字符,单片机串口2接收后将标志量更新

void USART2_IRQHandler(void)  
{  

     if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)  
  {  
     R_Data = USART_ReceiveData(USART3);//ÕâÐбíʾÊÕµ½µÄÊý¾Ý
		
		if(R_Data=='A') USART3_Flag=1;
		if(R_Data=='B') USART3_Flag=2;
		if(R_Data=='C') USART3_Flag=3;
		if(R_Data=='D') USART3_Flag=4;
		if(R_Data=='E') USART3_Flag=5;
		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
  }  
}  

main.c中根据不同的标志量控制小车进行不同操作

while(1)
	{
		delay_ms(10);	 
		
		 if (USART3_Flag == 1)
		{
			USART3_Flag =0;
			qianjin(120,120,160);
			delay_ms(2000);
				stop(3000);
		}
				 if (USART3_Flag == 2)
		{
			USART3_Flag =0;
			diaotou(120,740);
			delay_ms(2000);
			stop(3000);
		}
				 if (USART3_Flag == 3)
		{
			USART3_Flag =0;
			zuoguai(120,120,420);
			delay_ms(2000);
			stop(3000);
		}
				 if (USART3_Flag == 4)
		{
			USART3_Flag =0;
			youguai(120,120,410);
			delay_ms(2000);
			stop(3000);
		}
	}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值