STM32mini板 红外遥感控制 舵机小车 初学者适用

1.小车及单片机

小车用的是平衡小车之家的,单片机用的是正点原子的STM32mini板。

2.舵机的控制原理

舵机工作原理简单来说就是接收1个控制脉冲并驱动电机转动来控制方向,该脉冲的宽度决定舵机转动的角度。一般采用单片机来产生PWM信号来控制舵机,PWM波的周期为20ms,通过改变其占空比来改变其转动方向,具体如下图所示。我是采用PA8端口的PWM波来控制舵机的,PWM波初始化代码如下:

在这里插入图片描述

控制舵机的PWM波初始化

void TIM1_PWM_Init(u16 arr,u16 psc)
{  
	 GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);// 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);  //使能GPIO外设时钟使能
	                                                                     	

   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn ;  //TIM5中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
	
	
	
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 80K
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM1, &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(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

  TIM_CtrlPWMOutputs(TIM1,ENABLE);	//MOE 主输出使能	

	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //CH1预装载使能	 
	
	TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
	
	TIM_Cmd(TIM1, ENABLE);  //使能TIM1
 
   
}

再main函数中用TIM8_PWM_Init(199,7199);来产生周期20ms的PWM波,采用的PWM波为模式2且高电平为有效电平,所以舵机从-90°到90°转动时对应的CRR为175到195。

3.驱动模块的使用

驱动模块使用的是A4950,其工作电压范围在7.6V到30V间。
在这里插入图片描述
其中VM为驱动模块的电源,接7.6V到40V,VCC接5V,GND接地。
其余引脚接法如下,PA8接舵机,PC6,7,8,9接AIN1,BIN1,BIN2,AIN2,BOUT1接电机线1+,BOUT2接电机线1-,AOUT1接电机线2+,AOUT2接电机线2-
控制原理就是AIN1和AIN2信号的压差来控制电机的转动速度与正转反转。例如AIN1接低电平(占空比为0,)AIN2接50%占空比的PWM波,电机以50%的速度转动。压差越大转速越快,压差相等则停转。
初始化代码如下

void TIM8_PWM_Init(u16 arr,u16 psc)
{  
	 GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);// 
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);  //使能GPIO外设时钟使能
	                                                                     	

   //设置该引脚为复用输出功能,输出TIM8 CH1的PWM脉冲波形
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9; //TIM_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	
    NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_IRQn ;  //TIM5中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
	
	
	
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 80K
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM8, &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(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设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_OC2Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设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_OC3Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设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_OC4Init(TIM8, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
	
	
  TIM_CtrlPWMOutputs(TIM8,ENABLE);	//MOE 主输出使能	

	TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH1预装载使能	 
	
	TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器
	
	TIM_Cmd(TIM8, ENABLE);  //使能TIM8
}

4.稳压模块的使用

在这里插入图片描述
使用较为简单,IN+和IN-接2s航模电池,然后其可以输出5V,3.3V电压,以及航模电池本身电压。

5.单片机控制

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "pwm.h"
#include "remote.h" 
#include "usart.h"	
int main(void)
 { u8 sign=1;
	u8 key;
	u8 t=0;	
	u16 pwm1=185;
	delay_init();	    	 //延时函数初始?
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2	  
	uart_init(9600);	 	//串口初始化为9600
	LED_Init();		  		//初始化与LED连接的硬件接口
	TIM8_PWM_Init(199,7199);
	TIM1_PWM_Init(199,7199);
	Remote_Init();			//红外接收初始化	  	  
    
	TIM_SetCompare2(TIM8,1);//1
	TIM_SetCompare3(TIM8,1);
	TIM_SetCompare1(TIM8,1);
	TIM_SetCompare4(TIM8,1);
	TIM_SetCompare1(TIM1,185);

		
	while(1)
	{
		key=Remote_Scan();	
		if(key)
		{	 	  
			switch(key)
			{			    
				/*case 104:TIM_SetCompare1(TIM8,195);delay_ms(500);break;		 //1 
				case 152:TIM_SetCompare1(TIM1,175);break;	   //2*/
				/*case 0:str="ERROR";break;			   
				case 162:str="POWER";break;	    
				case 98:str="UP";break;	    
				case 2:str="PLAY";break;		 
				case 226:str="ALIENTEK";break;		  
				case 194:str="RIGHT";break;	   
				case 34:str="LEFT";break;		  
				case 224:str="VOL-";break;		  
				case 168:str="DOWN";break;		   
				case 144:str="VOL+";break;	*/
				case 0:;break;	
				case 98:TIM_SetCompare1(TIM1,185);break;//up
				case 194:TIM_SetCompare1(TIM1,175);break;	//right
				
				case 34: 
						TIM_SetCompare1(TIM1,195);break;//left
				
				case 168:TIM_SetCompare2(TIM8,195);
						 TIM_SetCompare3(TIM8,175);
						 TIM_SetCompare1(TIM8,175);
					     TIM_SetCompare4(TIM8,195);
						 break;	//down		
				
				case 2:TIM_SetCompare2(TIM8,1);//play
					   TIM_SetCompare3(TIM8,1);
					   TIM_SetCompare1(TIM8,1);
					   TIM_SetCompare4(TIM8,1);
					    break;
				case 104:TIM_SetCompare2(TIM8,175);//1蜗牛模式
						 TIM_SetCompare3(TIM8,195);
						 TIM_SetCompare1(TIM8,195);
					     TIM_SetCompare4(TIM8,175);
						 delay_ms(500);
				         break;		  
						 
				case 152:TIM_SetCompare2(TIM8,125);//2正常模式
						 TIM_SetCompare3(TIM8,175);
						 TIM_SetCompare1(TIM8,175);
					     TIM_SetCompare4(TIM8,125);
						 break;	
						 
				case 176:TIM_SetCompare2(TIM8,95);//3,究极超高速模式
						 TIM_SetCompare3(TIM8,195);
						 TIM_SetCompare1(TIM8,195);
					     TIM_SetCompare4(TIM8,95);
						 break;
						 
				/*case 152:str="2";break;	   
				case 176:str="3";break;	    
				case 48:str="4";break;		    
				case 24:str="5";break;		    
				case 122:str="6";break;		  
				case 16:str="7";break;			   					
				case 56:str="8";break;	 
				case 90:str="9";break;
				case 66:str="0";break;
				case 82:str="DELETE";break;	*/
				
			}
		}else delay_ms(10);	  
		t++;
		if(t==20)
		{
			t=0;
			LED1=!LED1;
		}
	}
}

在这里插入图片描述
红外遥控的初始化代码参考正点原子,遥控器也是正点原子的,按键功能如下:play为暂停按键,down为后退,up为调正舵机角度,right为右转,left为左转,1为蜗牛向前,2为正常模式,3为究极高速模式。

附:

当时脑子一热花300大洋买了小车组件,在学校一直没时间装,寒假有空花了2天时间搞了起来,还烧坏了一个mini板…不懂为啥我的稳压模块5V输出似乎有些不灵,第一天搞了半天舵机用稳压模块的5V不得转,用板子上5V输出就能转,后来干脆直接用稳压模块的7.6V的电压来控制舵机(做成之后没过多久舵机就烧坏了…,但好歹也做起来了)这是我第一次尝试用单片机做一个具体的东西,而不是就烧烧例程,讲真的花了挺久的,但起码还算是做成了…。还买了蓝牙模块和编码器…但给的上位机软件是安卓的,手机没法装,就暂时没整这些,等以后如果从事自控方向的话再说吧。(原本寒假要留校参加电赛冬令营的,没想到整这么一出,而且我选的是模拟方向,寒假头几天看完了你好放大器,看了会儿模电,线上冬令营极其不靠谱,队友也是别的班人找我的,没啥交流…感觉巨无聊,毕竟在家又没示波器等等工具…光看这些虚的不用很快就会忘了,不如亲手做个小车玩玩),哦,对了记得要所有模块都要共地呀。
附上演示视频:
32单片机控制的舵机小车的演示视频,点击文字即可查看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值