超声波接口 电阻 电阻 电阻 电位器 触点按键 自锁按键 电机驱动芯片 电压比较器 循迹头 单片机 比较器 稳压芯片 直流减速电机 超声波模块 1602液晶显示 晶振
P3 R5, R8, R11, R14, R17,R20 R6, R9, R12, R15, R18 R3 RST1 SW1 U1 U2 U3, U4, U5, U6, U8 U7 U9 VR1 Y1 Header 4 10K 200 10k SW-PB sw-灰色 L298 LM339 ST178 STC89c52 lm393 LM7805 HC-SR04 LCD1 12M 1 7 6 5 1 1 1 1 1 5 1 1 1 2 1 1 1 R1, R2, R4, R10 R16,R21,R23 2k 附录3部分源程序
#include
#include
sbit RX = P3^3; //超声波接收 sbit TX = P3^2; //超声波发射 static bit flag = 0;
/********************寻迹模块IO口定义*********************************/ sbit xun_ll = P0^4; //从左到右第1个 sbit xun_l = P0^3; //从左到右第2个
24
sbit xun_z = P0^2; //从左到右第3个 sbit xun_r = P0^1; //从左到右第4个 sbit xun_rr = P0^0; //从左到右第5个
/********************LN298电机驱动IO口定义*********************************/ sbit qu_ll = P2^0; //左边电机控制IN1 sbit qu_zl = P2^1; //左边电机控制IN2 sbit qu_zr = P2^2; //右边电机控制IN1 sbit qu_rr = P2^3; //右边电机控制IN2 #define RS_H RS = 1 #define RS_L RS = 0
#define RW_H RW = 1 #define RW_L RW = 0
#define EN_H EN = 1 #define EN_L EN = 0
#define READ_DATA P1
void DelayMs(unsigned int z) //1ms延时函数 {
unsigned int x; for(;z>0;z--)
for(x=110;x>0;x--); }
void LCDWriteCom(unsigned char com) { RS_L; RW_L; READ_DATA = com; EN_H; DelayMs(5); EN_L; }
void LCDWriteData(unsigned char dat) { RS_H; RW_L; READ_DATA = dat; EN_H; DelayMs(5); EN_L; }
/*******************************************************************************
25
**函数名称:LCD_Write_str()
**函数功能:在LCD上写入一串字符
**输 入 口:hang : 要写入的行,add 要写入列 *s要写入的指针数组 **输 出 口:无 **返 回 值:无
**备 注:strlen()是引用库函数string.h ,可以求出数组的长度 **日 期:2014.2.22
*******************************************************************************/ void LcdWriteStr(unsigned char hang,unsigned char add,char*s) {
unsigned char i;
unsigned char length = 0; if(hang==1) LCDWriteCom(0x80+add); else LCDWriteCom(0x80+0x40+add); length = strlen(s); for(i=0;i LCDWriteData(*s++); //指针送完数据后自加一 } /*void LcdWriteChar(unsigned char hang,unsigned char add,char Ch) { if(hang == 1)LCDWriteCom(0x80+add); else LCDWriteCom(0x80+0x40+add); LCDWriteData(Ch); }*/ //能像printf一样使用 void Lcd1602Printf( unsigned char x, unsigned char y, unsigned char *p,...) { char idata LcdBuf[17]; va_list ap; va_start(ap, p); vsprintf(LcdBuf,p,ap); va_end(ap); LcdWriteStr(x,y,LcdBuf); } void Init_1602(void) { LCDWriteCom(0x38); LCDWriteCom(0x0c); LCDWriteCom(0x06); LCDWriteCom(0x01); 26 DelayMs(2); // Lcd1602Printf(1,0,\ //测试液晶1602显示用 Normal:正常 } //触发一个高电平时间 static void StartModule(void) //启动模块 { TX=1; //启动一次模块 _nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); _nop_();_nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_(); TX=0; } /******************************************************************************* * Function Name : Conut * Description : 取出定时器的值,并通过计算得到距离,返回距离到调用函数 * Input : None * Output : None * Return : 计算得到的距离 * Attention : 当距离大于5m时,返回3个8,表示超出量程 *******************************************************************************/ static int Conut(void) { uint S,time; time=TH0*256+TL0; TH0=0; TL0=0; S=(time*1.7)/100; //算出来是CM if((S>=500)||flag==1) //超出测量范围 , 亲测可以达到6M多一点点,不过 { //跳动的很厉厉害,现改为5M flag = 0; S = 888; } return S; } /******************************************************************************* * Function Name : GetDis * Description : 发出一个10us的高电平脉冲,得到超声波测出的距离 * Input : None * Output : None * Return : S 测得的距离,Uint型变量,比如返回124,则表示为1.24M * Attention : 调用的函数有:StartModule,Conut 27 *******************************************************************************/ int GetDis(void) { StartModule(); //给一个高电平触发脉冲 while(!RX)xunnji(); //当RX为零时等待 TR0=1; //开启计数 while(RX)xunnji(); //当RX为1计数并等待 TR0=0; return Conut(); //计算 } //定时器初始化 static void Timer0Init(void) { TMOD &= 0xf0; TMOD |= 0x01; //设T0为方式1, TH0=0; TL0=0; ET0=1; //允许T0中断 EA=1; //开启总中断 } /******************************************************************************* * Function Name : CsbInit * Description : 超声波初始化函数 * Input : None * Output : None * Return : None * Attention : 调用的函数有:Timer0Init ,只调用了一个定时器初始化 *******************************************************************************/ void CsbInit(void) { Timer0Init(); } /************************** 定时器0中断服务函数 *******************************/ void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围 { flag=1; //中断溢出标志 } /***********************小车前进函数************************/ void go() { qu_ll = 1; 28