欢迎大家来到IT世界,在知识的湖畔探索吧!
最近后台有小伙伴私信我说,我讲得都太基础了,有没有做过单片机霍尔传感器测速度相关的项目,我现在就把以前做的一个单片机霍尔自行车里程测速仪项目分享给大家。
这个也是我以前做过的一个项目,现在拿出来分享给大家,大家不用觉得难,不过就是硬件做基础,然后用软件代码去控制而已,只要按照教程一步步来做你就会发现其实很简单。
好了,针对此项目下面有几点说明
1、单片机是通用的无论51还是52、无论stc还是at都一样,引脚功能都一样。
程序也是一样的。
2、原理图中的.ddb、.Bkp等格式是要用protel打开的,没有软件的不要紧,
3、程序中的.c文件可以用记事本(文本文档)打开,就是程序了。其他的是写程序是自动生成的,没什么用的。
4、可以按照正面布局,不要按照实物的背面焊接,要按照原理图焊接。
数码管脚位排布说明:
正面朝自己,秒点在下,左下为1脚,逆时针排布,左上为最后一个脚!请坛友焊接前弄清脚位排布再焊接!祝你们成功!
废话不多说,直接上实物图:
霍尔自行车测速电路原理图:
元器件列表
单片机霍尔自行车里程测速仪参考源程序:
//说明1:P00—P07:a—–dp P27—P24:com1—–com4 P34切换显示 P32—INT0 一个磁钢
//说明2:此程序针对车轮周长为207cm,其他型号周长,可改变参数就行
//说明3:数码管从左至右 高——低
#include<reg51.h>
#include”juxun001.h”
//主函数=====================
void main()
{
time0_int0_init();//定时器0和外部中断0的初始化
while(!TR0) //上电一直未切割时就显示 0.0.0.0
{
init_display();
}
while(1)
{
if(!change)//按下切换按键显示里程
{
delay1m(5);
if(!change)
{
flag = ~flag;
}
while(!change);
}
}
}
//==定时器0中断函数
void time0_interrupt()interrupt 1
{
TL0 = (65536 – 5000) % 256;// 12M晶振,5ms定时
TH0 = (65536 – 5000) / 256;
display_function();
time_counter++;
time_counter8++;
if(time_counter8 >= 1600)//大于8s没切割,车子视为停下了,速度为:0,但里程还记着
{
time_counter8 = 0;
speed = 0;//速度为 0
point1 = 0;
buf1[3] = speed%10;buf1[2] = speed/10%10;
buf1[1] = speed/100%10;buf1[0] = speed/1000%10;
}
}
//==========外部中断0中断函数=
void int0_interrupt()interrupt 0
{
external_counter++;
if(external_counter ==1 )TR0 = ~TR0;//第一次切割打开定时器0
if(external_counter == 65535)external_counter = 0;
time_counter8 = 0; //只要8秒内有切割,车子就仍在运行
if(external_counter % 2 == 0)//切割2次 更新下速度
{ //*5是因为中断一次是5MS
if(flag10){speed =((ulong)(36000)*zhouchang)/(time_counter * 5);flag1=1;}
else if(flag11){speed =((ulong)(36000)2zhouchang)/(time_counter * 5);}//速度:单位为 m/h ,*1000的目的是不出现浮点数
if((speed >= 100)&&(speed < 1000)) //100 —- 1000 3位整数
{
point1 = 1;buf1[3] = speed%10;buf1[2] = speed/10%10;
buf1[1] = speed/100%10;buf1[0] = 0;}
else if((speed >= 1000)&&(speed < 10000)) //1000 —- 10000 4位整数
{
point1 = 1;speed = (uint)speed;
buf1[3] = speed%10;buf1[2] = speed/10%10;
buf1[1] = speed/100%10;buf1[0] = speed/1000%10;}
else if((speed >= 10000)&&(speed < 100000)) //10000 —– 100000 5位整数
{
point1 = 2;
buf1[3] = speed/10%10;buf1[2] = speed/100%10;
buf1[1] = speed/1000%10;buf1[0] = speed/10000%10;}
else if((speed >= 100000)&&(speed < 1000000)) //100000 —— 1000000 6位整数
{
point1 = 3;
buf1[3] = speed/100%10;buf1[2] = speed/1000%10;
buf1[1] = speed/10000%10;buf1[0] = speed/100000%10;}
time_counter = 0;
}
if(external_counter % 8 == 0)//每切割8次 更新下里程
{
s = (ulong)external_counter * zhouchang; //里程:单位为 cm
if((s >= 1000)&&(s < 10000))
{
point2 = 1; // 0.012 001212
buf2[3] = s/100%10;buf2[2] = s/1000%10;
buf2[1] = 0;buf2[0] = 0;}// 4位整数
else if((s >= 10000)&&(s < 100000))
{
point2 = 1;
buf2[3] = s/100%10;buf2[2] = s/1000%10;
buf2[1] = s/10000%10;buf2[0] = 0;}// 5位整数 0.123 012345
else if((s >= 100000)&&(s < 1000000))
{
point2 = 1;
buf2[3] = s/100%10;buf2[2] = s/1000%10;
buf2[1] = s/10000%10;buf2[0] = s/100000%10;} // 6位整数 1.234 1234 56
else if((s >= 1000000)&&(s < 10000000))
{
point2 = 2;
buf2[3] = s/1000%10;buf2[2] = s/10000%10;
buf2[1] = s/100000%10;buf2[0] = s/1000000%10;}// 7位整数 1234 567
else if((s >= 10000000)&&(s < 100000000))
{
point2 = 3;
buf2[3] = s/10000%10;buf2[2] = s/100000%10;
buf2[1] = s/1000000%10;buf2[0] = s/10000000%10;} // 8位整数 1234 5678
}
}
//==========开电源就显示的数据,初始显示速度
void init_display()
{
uchar i;
for(i = 0;i < 4;i++)
{
wei = bitcode[num – 1];
led = display1[buf1[num–]];
delay1m(4);
if(num == 0)num = 4;
}
}
//==显示函数=
void display_function()
{
if(flag == 0)//显示速度
{
switch(point1)
{
case 0:wei = bitcode[num-1];led = display1[buf1[num-1]];num–;break;//速度显示 0
case 1:if(num == 1){ wei = bitcode[num-1];led = 0x7f&display1[buf1[num-1]];num–;}
else { wei = bitcode[num-1];led = display1[buf1[num-1]];num–;}break;//最高位小数点亮
case 2:if(num == 2){ wei = bitcode[num-1];led = 0x7f&display1[buf1[num-1]];num–;}
else { wei = bitcode[num-1];led = display1[buf1[num-1]];num–;}break;//第二高位小数点亮
case 3:if(num == 3){ wei = bitcode[num-1];led = 0x7f&display1[buf1[num-1]];num–;}
else { wei = bitcode[num-1];led = display1[buf1[num-1]];num–;}break;//第三高位小数点亮
default:break;
}
if(num == 0)num = 4;
}
else if(flag == 1)//显示里程
{
switch(point2)
{
case 0:wei = bitcode[num-1];led = display1[buf2[num-1]];num–;break;//里程显示 0
case 1:if(num == 1){ wei = bitcode[num-1];led = 0x7f&display1[buf2[num-1]];num–;}
else { wei = bitcode[num-1];led = display1[buf2[num-1]];num–;}break;//最高位小数点亮
case 2:if(num == 2){ wei = bitcode[num-1];led = 0x7f&display1[buf2[num-1]];num–;}
else { wei = bitcode[num-1];led = display1[buf2[num-1]];num–;}break;//第二高位小数点亮
case 3:if(num == 3){ wei = bitcode[num-1];led = 0x7f&display1[buf2[num-1]];num–;}
else { wei = bitcode[num-1];led = display1[buf2[num-1]];num–;}break;//第三高位小数点亮
default:break;
}
if(num == 0)num = 4;
}
}
//=================定时器0和外部中断0的初始化函数=
void time0_int0_init()
{
TMOD |= 0x01;
TMOD &= 0xfd;//定时器0工作于方式1
TL0 = (65536 – 5000) % 256;//12M晶振,5ms定时
TH0 = (65536 – 5000) / 256;
IT0 = 1;//外部中断0,负跳变触发方式
TR0 = 0;
ET0 = 1;
EX0 = 1;
EA = 1;
}
//==========ms 级延时函数=
void delay1m(uchar x)
{
uchar i,j;
for(i=0;i<x;i++) //连数x次,约 x ms
for(j=0;j<120;j++); //数120 次,约1 ms
}
好了,以上就是这个项目的全部内容了。
最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,鉴于无法上传附件,如果需要完整代码或设计文件,请留言或私信我,看到后会第一时间回复。
谢谢!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/36384.html