前言:
这辆车是我大一实验室评估的时候做的。内容比较简单,有些代码有冲突(但还是可以跑)。请轻轻喷洒。接下来,我将介绍实现这辆车的每一步。
1:3光电开关,1HC-SR04超声波模块
2:一个stc89c52最小系统板
3:4个TT马达、一个sg90舵机、2个l298n
1.光电开关:
接线:蓝色接线gnd,黑色接你单片机定义的io口,棕色接VCC(5v)
使用方法:检测障碍物时,单片机与黑线连接I/O口被置低电平0,即读取I/O可以知道传感器前面是否有障碍物,
2.超声模块:
接线:Vcc: 5V电源供电Trig:输入触发信号(可触发测距)Echo:发出信号回响(可以发回时差)Gnd:接地
使用方法接给trig高电平,然后读取ECHO引脚是否为高电平,如为高电平,则打开定时器,然后继续检测等待其为低电平时,获得计数器值,然后计算
计算公式:测试距离=(高电平时间*声速(340M/S))/2。
3.舵机pwm波:
接线:舵机上有三条线,分别是GND(棕色线),VCC(红线)和SIG(黄线),即地线、电源线和信号线。VCC接5v,gnd接单片机的gnd,将您定义的引脚连接到信号线。
使用方法:舵机的控制需要20ms时基脉冲,控制高电平时间为0.5ms~2.5ms可以在0的范围内控制舵机 ~ 180°转动。(注:舵机pwm在52上,似乎只能用定时器控制delay控制不准确)。
4.l298n:
注:这里的驱动必须和谐:stc89c52共地!!!!否则,数据无法传输。还有通道A、B把能上的东西拔掉,然后把能上的东西拔掉A、B电机的使能可以通过一条线连接到单片机来控制。
#include <car.h> float S=0; extern bit flag; unsigned int measure_time; char M_sensor; void StartModule() { Trig=1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); Trig=0; } void Conut(void) { measure_time=TH0*256 TL0; TH0=0; TL0=0; S=(measure_time*1.87)/100; if(flag==1||S>20||S<10) { flag=0; LED=1; M_sensor=1; } else { LED=0; M_sensor=0; } }
#define uint8 unsigned char #define uint16 unsigned short int #define uint32 unsigned long #include "reg52.h" #include <intrins.h> sbit D_sensor=P2^2; sbit SERVO0=P1^1; sbit P12=P1^2; sbit P13=P1^3; sbit P23=P2^3; sbit P24=P2^4; sbit LED=P0^0; sbit L_sensor=P2^0; sbit R_sensor=P2^1; //电机L298N void run(void)//前进 { P12=1; P13=0; P23=1; P24=0; } void back(void)//后退 { P12=0; P13=1; P23=0; P24=1; } void left(void)//左转 { P12=1; P13=0; P23=0; P24=0; } void right(void)//右转 { P12=0; P13=0; P23=1; P24=0; } void stop(void)//停止 { P12=0; P13=0; P23=0; P24=0; } uint16 Servo0PwmDuty=1500; //PWM脉冲宽度 void DelayMs(uint16 ms) { uint16 i,j; for(i=0;i<85;i ) //89单片机85,12系列单片机800 for(j=0;j<ms;j ); } void Timer0Init(void) { TMOD&= 0xF0; //设置定时器模式 TMOD|= 0x01; //设置定时器模式 TL0 = 0x00; ///设定时初值 TH0 = 0x00; ///设定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; ///定时器0开始计时 ET0 = 1; //开定时器0中断 } void Timer0Value(uint16 pwm) { uint16 value; value=0xffff-pwm; TR0 = 0; TL0=value; TH0=value>>8; TR0 = 1; } void Timer0_isr(void) interrupt 1 using 1 { static uint16 i = 1; //静态变量:每次调用函数时,保持上次赋予的值, switc(i)
{
case 1:
SERVO0 = 1; //PWM控制脚高电平
Timer0Value(Servo0PwmDuty);
break;
case 2:
SERVO0 = 0; //PWM控制脚低电平
Timer0Value(20000-Servo0PwmDuty);
i = 0;
break;
}
i++;
}
void main()
{
EA=1;
Timer0Init();
LED=0;
while(1)
{
if(D_sensor==0)//检测黑线的光电
{run(); }
else
{ stop();
Servo0PwmDuty = 1500;
DelayMs(500);
Servo0PwmDuty = 500;
DelayMs(500);
}
}
}
有需要全部代码可以私信我(应该也不会有人问吧)