在制作该项目之前首先得准备一些必要的硬件。他们分别是单片机最小系统板,1602液晶,霍尔传感器、磁钢和电池(没有充电电池可以使用电池盒加普通5号电池)。 图2.1 单片机最小系统
图2.2 1602液晶
图2.3 霍尔传感器和磁钢
图2.4 电池
准备好了这些东西之后,就可以非常happy的开始制作了。当然这里的电池,小编使用的是充电电池。因为刚好拆掉一辆遥控小车,所以有了这块充电电池。其实使用电池盒加电池更加便宜和实惠,更加适合入门的人。
下面稍微讲解一下测速与测距的原理。首先是霍尔传感器的原理。如图2.5所示当霍尔传感器没有处于强烈的磁场中的时候,它的信号引脚输出的是高电平,反之,当有强烈的磁场时,它输出的是低电平。
图2.5 霍尔传感器的接线图
图2.6 连接好的霍尔传感器
从图2.5中,大家也看出了霍尔传感器的接法。最左边的引脚为Vcc电源引脚,中间的引脚为GND引脚,最右边的引脚为输出引脚。这里解释一下为什么输出引脚要有一个电阻接到Vcc上面。因为霍尔传感器的输出引脚是漏极输出,所以当需要输出高电平时必须要接上拉电阻到Vcc电源。这里的上拉电阻可以使用1K--10K的电阻。小编使用的是10K的电阻。知道了霍尔传感器的最用之后,具体应该怎么用上去呢?可以这样做,把磁钢(其实就是产生磁场的磁铁)固定在钢圈上面,把霍尔传感器固定在自行车的钢轴上面,如图2.7所示。
图2.7 磁钢的安装和霍尔传感器的安装
那么,当每旋转一圈,当磁钢运动到霍尔传感器附近时,霍尔传感器输出低电平,当磁钢远离霍尔传感器时,霍尔传感器输出高电平。也就是说自行车轮胎每旋转一圈,霍尔传感器就输出一次低电平。那么只要测出两次输出低电平之间的时间间隔,然后再结合自行车轮胎的周长就可以很轻松的求出速度。而对于自行车的行驶里程,只要记录下霍尔传感器输出低电平的次数,再乘以周长就可以求出了。
连接好了霍尔传感器和磁钢,接着把剩下的单片机最小系统板和液晶连接正确。(这里就不详细介绍单片机如何驱动1602液晶的了。有疑问的朋友可以自己百度搜索一下,不难的。)如图2.8,是连接好的单片机系统和液晶。
图2.8 连接好的电池,单片机和液晶
图2.9 已经固定好在自行车上的所有硬件
下面小编讲解一下程序的编写。
这里我把1602的操作封装在Star1602.c源程序中,在主函数中包含Star1602.h即可。(Star1602.h和Star1602.c在本教程的最后给出)
#define CIRCLE 1.8 //宏定义 车轮的周长(这个要根据实际的车轮进行设置)sbit Signal = P1^0; //这里的Signal表示的是霍尔传感器的信号引脚 int m_second=0; //定义变量m_second,用来记录时间(以毫秒为单位)float speed=0.0 ; //定义速度变量 float length=0.0 ;//定义路程变量TMOD = 0x01; //打开定时器0,并设定其工作方式为16位定时模式。TL0=(65536-10000)% 256; //设定定时器的初值,使得没10ms中断一次 while(Signal); //等待霍尔传感器信号线拉低;speed = CIRCLE *1000 / m_second ; //计算速度。length += CIRCLE ; //路程加一个车轮周期lcd_pos(0x0); //设定液晶的写入位置为第一行第一格lcd_wdat( (int)speed%10 ); //显示速度的整数部分lcd_wdat( (int)(speed*10)%10 ); //显示速度的小数第一位lcd_wdat( (int)(speed*100)%10 ); //显示速度的小数第二位lcd_pos(0x80); //设定液晶的写入位置为第二行第一格lcd_wdat(length /10000+0x30); //显示里程的万位;lcd_wdat(length %10000/1000+0x30); //显示里程的千位;lcd_wdat(length %1000/100+0x30); //显示里程的百位;lcd_wdat(length %100/10+0x30); //显示里程的十位;lcd_wdat(length %10+0x30); //显示里程的个位;void timer0_intt() interrupt 1 //TL0=(65536-10000)% 256; //设定定时器的初值,使得没10ms中断一次m_second += 10; //因为中断每10毫秒一次,所以这里每次加10;void lcd_init(); //液晶初始化函数void lcd_pos(unsigned char pos); //设定液晶的显示位置函数void lcd_wdat(unsigned char dat); //液晶写入字符void lcd_write_int(unsigned int x); //液晶显示一个整形变量/**********************************************************************************************************************************************************/static void delay(unsigned char ms)/**********************************************************************************************************************************************************/result = (bit)(P0 & 0x80);/**********************************************************************************************************************************************************/static void lcd_wcmd(unsigned char cmd)while(lcd_bz()); //判断LCD是否忙碌/**********************************************************************************************************************************************************/void lcd_pos(unsigned char pos)/**********************************************************************************************************************************************************/void lcd_wdat(unsigned char dat)while(lcd_bz()); //判断LCD是否忙碌/**********************************************************************************************************************************************************//**********************************************************************************************************************************************************/void lcd_write_int(unsigned int x); unsigned char x1,x2,x3,x4,x5;