代码实现:
1.
main.c
#include "reg52.h" #include "hc04.h" #include "sg90.h" #include "delay.h" #include "motor.h" #define MIDDLE 0 #define LEFT 1 #define RIGHT 2 void main() { char dir; double dismiddle; double disleft; double disright; time0init(); time1init(); sgmiddle();//置于中间位置 dir=MIDDLE; Delay300ms(); Delay300ms(); while(1){ dismiddle=getdistance(); if(dismiddle>25){ //前进 goforward(); }else if(dismiddle<10){ goback(); Delay200ms(); stop(); } else{ stop(); //摇头测距+转弯 sgleft(); dir=LEFT; Delay300ms(); disleft=getdistance(); sgmiddle(); sgright(); dir=RIGHT; Delay300ms(); disright=getdistance(); if(disleft>disright){ goleft(); Delay300ms(); stop(); } if(disleft<disright){ goright(); Delay300ms(); stop(); } } if(dir!=MIDDLE){//解决舵机本来就在中间,还要回到中间位置,抽搐问题 sgmiddle(); dir=MIDDLE; Delay300ms(); } } }
2.
motor.c
#include "reg52.h" sbit right1=P3^2; sbit right2=P3^3; sbit left1=P3^4; sbit left2=P3^5; void goforwardleft() { left1=0; left2=1; } void goforwardright() { right1=0; right2=1; } void goforward() { left1=0; left2=1; right1=0; right2=1; } void goback() { left1=1; left2=0; right1=1; right2=0; } void goleft() { left1=1; left2=0; right1=0; right2=1; } void goright() { left1=0; left2=1; right1=1; right2=0; } void stop() { left1=0; left2=0; right1=0; right2=0; } void stopleft() { left1=0; left2=0; ; } void stopright() { right1=0; right2=0; }
motor.h
void goback(); void goforward(); void goleft(); void goright(); void stop(); void goforwardleft(); void goforwardright(); void stopleft(); void stopright();
3.舵机
sg90.c
#include "reg52.h" #include "delay.h" sbit sg90=P1^1; sbit D5=P3^7; sbit D6=P3^6; int jd; int t=0; void time0init() { TMOD &= 0xF0; TMOD |= 0x01; TL0=0x33; TH0=0xFE; TR0 = 1; TF0 = 0; ET0 = 1; EA = 1; D5=0; } void sgleft() { jd = 5; t = 0; Delay450ms(); } void sgmiddle() { jd = 3; t = 0; Delay450ms(); } void sgright() { jd = 1; t = 0; Delay450ms(); } void time0hander() interrupt 1//定时器寄存器溢出,此时TF0=1,中断发生,TF0置0,重新循环 { t++; TL0=0x33; TH0=0xFE; if(t < jd){ sg90 = 1; }else{ sg90 = 0; } if(t == 40){ t = 0; sg90 = 1; } }
sg90.h
void time0init(); void initsg90(); void sgleft(); void sgmiddle(); void sgright();
4.超声波
hc04.c
#include "reg52.h" #include "delay.h" sbit trig=P2^3; sbit echo=P2^2; void time1init() { TMOD &= 0x0F;//低四位不变,高四位清0 //定时器1模式 TMOD |= 0x10;//高四位置1,低四位不变 TL1 = 0x00; TH1 = 0x00; } void startHC() { trig=0; trig=1; Delay10us(); trig=0; } double getdistance() { double distance; double time; time1init();//开始计时,初始化为0 startHC();//超声波模块发波,需要给trig10us的高电平 while(echo==0);//发波之前都维持低电平,当不是低电平就往下进行 TR1=1;//定时器开始计时 while(echo==1);//返回波之前都是高电平,当不是高电平不满足echo==1,向下进行 TR1=0;//定时器结束计时 time=(TH1*256+TL1)*1.085;//计算计数所对应的时间 distance=time*0.034/2;//340m/s=0.034cm/us return distance; }
hc04.h
void time1init(); double getdistance();
5.延时
delay.c
#include "intrins.h" void Delay10us() //@11.0592MHz { unsigned char i; i = 2; while (--i); } void Delay2000ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 15; j = 2; k = 235; do { do { while (--k); } while (--j); } while (--i); } void Delay450ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 4; j = 39; k = 209; do { do { while (--k); } while (--j); } while (--i); } void Delay300ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 3; j = 26; k = 223; do { do { while (--k); } while (--j); } while (--i); } void Delay200ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 2; j = 103; k = 147; do { do { while (--k); } while (--j); } while (--i); }
delay.h
void Delay10us(); //@11.0592MHz void Delay2000ms(); //@11.0592MHz void Delay450ms(); void Delay300ms(); void Delay200ms(); //@11.0592MHz