嵌入式小專案練習-光電設計競賽-尋跡小車-03-尋跡演算法分析與原始碼
阿新 • • 發佈:2018-11-17
這裡我用了三個光敏電阻的感測器來進行尋跡:這裡用X1,X2,X3(檢測到了為0)來表示:
演算法思路:
將三個感測器放置如圖: | | |
1)直行:X1=1;X2=0;X3=1;
2)左轉:X1=0;X2=1;X3=1;
3)右轉:X1=1;X2=1;X3=0;
4)直角左轉:X1=0;X2=0;X3=1;
5)直角右轉:X1=1;X2=0;X3=0;
其他情況慢慢後退:這樣提高了小車的容錯性,如果一旦出現尋跡亂碼的情況(這裡指未出現的組合數如:X1=1 X2=0 X3=1)
演算法思路很簡單主要看小車尋跡的賽道,程式碼中的pwm的寬度是隨意設定的,具體什麼樣的彎道角度需要耐心除錯,反覆試驗。
main.c
#include <reg52.h> #include <pwm.h> #define u8 unsigned char #define u16 unsigned int //光學開關模組 sbit LS=P2^3; //接尋跡模組 #define fin_1 P3^6 #define fin_2 P3^7 #define fin_3 P3^5 void main() { P1=0X00; //關電機 TMOD=0X01; TH0= 0XFc; //1ms定時 TL0= 0X18; TR0= 1; ET0= 1; EA = 1; //開總中斷 while(1) { if(LS==1) { if(fin_1==1&&fin_2==0&&fin_3==1) run(); else if(fin_1==1&&fin_2==1&&fin_3==0) right(); else if(fin_1==0&&fin_2==1&&fin_3==1) left(); else if(fin_1==1&&fin_2==0&&fin_3==0) right_90(); else if(fin_1==1&&fin_2==0&&fin_3==0) left_90(); else back(); } else { P0=0X00; //關電機 } } }
pwm.h檔案:
#ifndef _PWM_H #define _PWM_H #include <reg52.h> //定義小車驅動模組輸入IO口 sbit IN1=P1^0; sbit IN2=P1^1; sbit IN3=P1^2; sbit IN4=P1^3; //pwm端使能位: sbit Left_pwm=P1^6; //PWM訊號端 sbit Right_pwm=P1^7; //PWM訊號端 //小車驅動接線定義 void Left_moto_go(); //左電機向前走 void Left_moto_back(); //左邊電機向後轉 //void Left_moto_Stop(); //左邊電機停轉 void Right_moto_go(); //右邊電機向前走 void Right_moto_back(); //右邊電機向後走 //void Right_moto_Stop(); //右邊電機停轉 //左電機調速 調節push_val_left的值改變電機轉速,佔空比 extern void pwm_out_left_moto(void); extern void pwm_out_right_moto(void); //調速模組 extern void run(); extern void left_90(); extern void right_90(); extern void left(); extern void right(); extern void back(); #endif
pwm.c檔案
#include <reg52.h>
#include <pwm.h>
unsigned char pwm_left=0;//變數定義
unsigned char push_left=0;// 左電機佔空比N/100
unsigned char pwm_right=0;
unsigned char push_right=0;// 右電機佔空比N/100
unsigned int time=0;
void Left_moto_go()
{
IN1=1;
IN2=0;
}
void Left_moto_back()
{
IN1=0;
IN2=1;
}
/*
void Left_moto_Stop()
{
IN1=0;
IN2=0;
}
*/
void Right_moto_go()
{
IN3=1;
IN4=0;
}
void Right_moto_back()
{
IN3=0;
IN4=1;
}
/*
void Right_moto_Stop()
{
IN3=0;
IN4=0;
}
*/
//左電機調速 調節push_val_left的值改變電機轉速,佔空比
void pwm_out_left_moto(void)
{
if(pwm_left <= push_left)
{
Left_pwm = 1;
}
else
{
Left_pwm = 0;
}
if(pwm_left>100)
pwm_left=0;
}
//右電機調速
void pwm_out_right_moto(void)
{
if(pwm_right>100)
pwm_right=0;
if(pwm_right<=push_right)
{
Right_pwm = 1;
}
else
{
Right_pwm =0;
}
}
//前進
void run(void)
{
push_right=80;
push_left=80;
Left_moto_go();
Right_moto_go();
}
//左轉直角
void left_90(void)
{
push_right=50;
push_left=80;
Left_moto_go();
Right_moto_back();
}
//右轉直角
void right_90(void)
{
push_right=80;
push_left=50;
Right_moto_go();
Left_moto_back();
}
//左轉微調
void left(void)
{
push_right=80;
push_left=60;
Left_moto_go();
Right_moto_go();
}
//右轉微調
void right(void)
{
push_right=80;
push_left=60;
Right_moto_go();
Left_moto_go();
}
//後退
void back(void)
{
push_right=20;
push_left=20;
Left_moto_back();
Right_moto_back();
}
// TIMER0中斷服務子函式產生PWM訊號
void timer0() interrupt 1 using 2
{
TH0=0XFc; //1Ms定時
TL0=0X18;
time++;
pwm_left++;
pwm_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}