STM32循跡小車/Android藍牙控制小車(一)

STM32循跡小車

第一天:硬件平臺介紹
硬件平臺:

控制模塊:正點原子STM32精英開發板
驅動模塊:L298N兩路電機驅動模塊,兩路pwm控制,正反轉控制
轉向控制:S3010舵機,由20ms脈寬pwm信號控制轉向
循跡模塊:5路光電對管循跡模塊RS016
藍牙模塊:待定
小車平臺:10年前飛思卡爾比賽車模

軟件設計平臺:

STM32程序開發:MDK5 Keil uVision5
Android APP開發:AndroidStudio2.2.2

預計實現功能:

1、遙控模式,通過紅外遙控控制前進後退停止轉向,連續調速
2、自動模式,通過循跡模塊自動檢測黑線並跟蹤行駛
3、手機控制,通過Android定製APP控制小車前進後退停止轉向,連續調速

已經實現功能:遙控模式,下附主要源代碼:

#define MIN_zou 1000 //向左
#define Z_qian 1200  //向前
#define MAX_you 1400 //向右
/*
	循跡車引腳接線:
	PG13/PG14引腳控制車前進(1,0)/倒退(0,1),接L298控制引腳IN4/IN3
	定時器3通道2對應引腳PB5控制舵機轉向,由20ms脈寬920-2120高電平控制。黑線(接地),紅線(電源線),白色(控制線)
	定時器3通道4對應引腳PB1控制車驅動電機轉速
*/

//pwm波輸出 開發板驗證
void TIM3_PWM_Init(u16 arr,u16 psc)
	{
		GPIO_InitTypeDef GPIO_InitStrcut;
		TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrcut;
		TIM_OCInitTypeDef TIM_OCInitStrcut;	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//複用端口需要使能AFIO時鐘
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);	//使能TIM3時鐘	
		GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);	//端口部分重映射	
		//設置該引腳爲複用輸出功能,輸出 TIM3 CH2 的 PWM 脈衝波形 GPIOB.5
		GPIO_InitStrcut.GPIO_Mode = GPIO_Mode_AF_PP;				//複用推輓輸出							
		GPIO_InitStrcut.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_1;						//
		GPIO_InitStrcut.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_Init(GPIOB,&GPIO_InitStrcut);
		//定時器初始化
		TIM_TimeBaseInitStrcut.TIM_CounterMode=TIM_CounterMode_Up;//計數模式
		TIM_TimeBaseInitStrcut.TIM_Period=arr;						//重裝值
		TIM_TimeBaseInitStrcut.TIM_Prescaler=psc;					//分頻值
		TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStrcut);	
		//PWM相關寄存器初始化
		TIM_OCInitStrcut.TIM_OCMode = TIM_OCMode_PWM2; //選擇 PWM 模式 2
		TIM_OCInitStrcut.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
		TIM_OCInitStrcut.TIM_OCPolarity = TIM_OCPolarity_Low; //輸出極性高
		TIM_OC2Init(TIM3, &TIM_OCInitStrcut); //初始化外設 TIM3 OC2通道2
		TIM_OC4Init(TIM3, &TIM_OCInitStrcut); //初始化外設 TIM3 OC2通道4
		TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);	//裝載預裝值
		TIM_Cmd(TIM3,ENABLE);		//使能定時器3
	}

void Init_GPIO1(void)
{	
	 GPIO_InitTypeDef  GPIO_InitStructure;
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);	 //使能PB,PE端口時鐘	
	 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;				 //LED0-->PB.5 端口配置
	 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推輓輸出
	 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度爲50MHz
	 GPIO_Init(GPIOG, &GPIO_InitStructure);					 //根據設定參數初始化GPIOB.5	
}

 int main(void)
 {	 
	u8 key;				//鍵值
	u16 led0pwmval=Z_qian,pwm_sudu=0;
	u8 *str=0;	 
	delay_init();	    	 //延時函數初始化	  
	Init_GPIO1();
	LCD_Init();			   		//初始化LCD   
	W25QXX_Init();				//初始化W25Q128
	Remote_Init();
	TIM3_PWM_Init(14399,99);
	TIM_SetCompare2(TIM3,led0pwmval);
	TIM_SetCompare4(TIM3,pwm_sudu);	
	POINT_COLOR=RED;
	while(font_init()) 		//檢查字庫
	{	    
		LCD_ShowString(30,50,16,"Font Error!",0);
		delay_ms(200);				  
		LCD_Fill(30,50,240,66,WHITE);//清除顯示	     
		delay_ms(200);				  
	} 
	Show_Str(30,30,200,16,"循跡小車調試界面",16,0);
	Show_Str(30,70,200,16,"PWM捕獲寄存器值:",16,0);	
	Show_Str(30,100,200,16,"遙控接收值:",16,0);	
	Show_Str(30,130,200,16,"按鍵連按次數:",16,0);
	Show_Str(30,160,200,16,"按鍵鍵值:",16,0);
	Show_Str(30,190,200,16,"速度PWM值:",16,0);	
	POINT_COLOR=BLUE;
	Show_Str(30,210,200,64,"|<< :向左  2 :前進",16,0);	
	Show_Str(30,230,200,64,">>| :向右  8 :倒退",16,0);	
	Show_Str(30,250,200,64,">|| :向前  5 :停止",16,0);	
	Show_Str(30,270,200,64,"VOL+/- :快/慢",16,0);
	Show_Str(30,300,200,64,"上/下  :左/右",16,0);	
//	Show_Str(30,350,200,64,"2 :前進",16,0);	
//	Show_Str(30,370,200,64,"8 :倒退",16,0);	
//	Show_Str(30,390,200,64,"5 :停止",16,0);	
	
	while(1)
	{	
		key=Remote_Scan();	
		if(key)
		{		
			switch(key)
			{
				case 98:
				{
					str="UP";
					led0pwmval += 20;
					if(led0pwmval >= MAX_you)led0pwmval=MAX_you;
					TIM_SetCompare2(TIM3,led0pwmval);
				}break;	    
				case 194:
				{
					str="RIGHT";
					led0pwmval = MIN_zou;
					TIM_SetCompare2(TIM3,led0pwmval);
				}break;	   
				case 34:
				{
					str="LEFT";
					led0pwmval = MAX_you;
					TIM_SetCompare2(TIM3,led0pwmval);
				}break;		  
				case 168:
				{
					str="DOWN";
					if(led0pwmval >= (MIN_zou+20))led0pwmval -= 20;
					else led0pwmval = MIN_zou;
					TIM_SetCompare2(TIM3,led0pwmval);
				}break;			
				case 2:
				{
					str="PLAY";
					led0pwmval=Z_qian;
					TIM_SetCompare2(TIM3,led0pwmval);
				}break;	
				case 224:
				{
					str="VOL-";
					if(pwm_sudu >=100)pwm_sudu-=100;
					else pwm_sudu=0;
					TIM_SetCompare4(TIM3,pwm_sudu);
				}break;		  		   
				case 144:
				{
					str="VOL+";
					if(pwm_sudu <= 8000)pwm_sudu+=100;
					else pwm_sudu=8000;	
					TIM_SetCompare4(TIM3,pwm_sudu);					
				}break;	
				case 56:
				{
					str="8";
					TIM_SetCompare4(TIM3,pwm_sudu);
					delay_ms(100);
					PGout(13) = 0;
					PGout(14) = 1;
				}break;	
				case 152:
				{
					str="2";
					TIM_SetCompare4(TIM3,pwm_sudu);
					delay_ms(100);
					PGout(13) = 1;
					PGout(14) = 0;
				}break;	
				case 24:
				{
					str="5";
					if(pwm_sudu>=3000){
						TIM_SetCompare4(TIM3,pwm_sudu/2);
						delay_ms(200);
					}	
					PGout(13) = 0;
					PGout(14) = 0;
					delay_ms(20);
				}break;					
			}
			LCD_ShowNum(30+8*16,70,led0pwmval,5,16);	
			LCD_ShowNum(30+8*10,100,key,4,16);		
			LCD_ShowNum(30+8*14,130,RmtCnt,3,16);	
			LCD_ShowString(30+8*10,160,16,"      ",0);	
			LCD_ShowString(30+8*10,160,16,str,0);		
			LCD_ShowNum(30+8*14,190,pwm_sudu,5,16);			
		}
		delay_ms(150);
	}
}

後續功能開發待續,不定時更新,業餘作品,預計一個月左右更新完成。
源碼開發過程中隨時會修正更改,暫時不提供完整代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章