基于单片机的计步器设计Word文档下载推荐.docx
《基于单片机的计步器设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于单片机的计步器设计Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。
![基于单片机的计步器设计Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2023-1/24/ace03064-c766-4c50-b90d-55469043dccf/ace03064-c766-4c50-b90d-55469043dccf1.gif)
传感器模块是检测人体行走时的振动,若检测到振动则传感器给出低电平,来告诉单片机记录步数。
图2-1计步器系统框图
3电路原理图
图3-1计步器电路原理图
4硬件设计及器件清单
4.1振荡电路
单片机内设有一个由反向放大器所构成的振荡电路,振荡电路是单片机系统正常工作的保证,如果振荡器不起振,系统将会不能工作。
假如振荡器运行不规律,系统执行程序的时候就会出现时间上的误差。
单片机内部时钟不精确,尤其是在高频时,添加外部振荡电路[3],时钟电路中的两个电容用作抗干扰,使得晶振频率更加稳定(如图4-1)。
图4-1时钟振荡电路
4.2复位电路
为确保单片机电路稳定可靠工作,复位电路是必不可少的一部分,复位电路的第一功能是上电复位[3]。
按键放开时,电容充满电后相当于断路,RST通过电阻接地为低电平。
按键按下时,RST通过电阻链接到VCC为高电平,按键松开后,电容充电保持一定时间高电平,系统复位(如图4-2)。
图4-2系统复位电路
4.3显示电路
计步器设计采用4位LED共阳极数码管显示做为系统的显示界面(如图4-3)。
常用的LED数码管为8段或7段(8段比7段多了一个小数点“dp”段)。
每一个段对应一个发光二极管,数码管有共阳极和共阴极两种。
共阳极LED数码管的发光二极管的阳极连接在一起,通常是共阳极接VCC。
为了使LED数码管显示不同的符号和数字,就要把不同段的发光二极管点亮,这样就要为LED数码管提供代码,因为这些代码可使LED相应的段发光,从而显示不同字型,该代码称之为段码。
当某些发光二极管的阴极为低电平时,发光二极管点亮,相应的段被显示,这些段组合成字型[2]。
图4-3数码管显示电路
4.4按键电路
本次设计通过按键的按下来实现步数的存储、步数的清零、查看存储的上一条记录和查看下一条记录(如图4-4)。
图4-4系统按键电路
4.5传感器模块
振动传感器的基本工作原理是当检测到机械振动信号后,它在电路的配合下,将机械振动信号转换为电信号输出[1]。
模块使用说明
1)用于各种振动触发作用,报盗报警,智能小车,电子积木等;
2)模块在感应到小的振动时触发时间会很短,不够驱动继电器,有些人的资料显示可以直接和继电器模块相连,实际运用效果不佳;
3)产品不振动时,振动开关呈断开状态,输出端输出高电平,黄色指示灯不亮;
4)产品振动时,振动开关瞬间导通,输出端输出低电平,黄色指示灯亮;
5)输出端可以与单片机直接相连,通过单片机来检测高低电平,由此来检测环境是否有振动,起到报警作用。
4.6器件清单
表4-1计步器元器件列表
序号
器件
数量
1
IAP15F2K61S2单片机
1片
2
常开型振动传感器模块
1块
3
4位共阳数码管
4
晶振11.0592
5
三极管NPN
4个
6
四角开关
7
电阻10K
5个
8
电阻470R
9个
9
电阻300R
10
电解电容10uF
1个
11
电容47pF
2个
12
发光二极管红色
13
开关
14
排针、导线
若干
5PCB图
5.1计步器PCB正面图
图5-1计步器PCB正面图
5.2计步器PCB背面图
图5-2计步器PCB背面图
6程序流程图
7部分程序代码
7.1数码管显示程序
循环语句实现数码管的动态扫描,显示对应的位,利用人眼的视觉惰性实现显示。
主程序调用数码管段显示子程序,显示字型[4]。
while
(1)
{
qian=num/1000;
bai=(num/100)%10;
shi=(num/10)%10;
ge=num%10;
sel1=0;
sel2=0;
sel3=0;
sel4=1;
seg(qian);
delay
(1);
sel3=1;
sel4=0;
seg(bai);
sel2=1;
seg(shi);
sel1=1;
seg(ge);
}
voidseg(uintn)
switch(n)
{
case0:
P0=0xC0;
break;
case1:
P0=0xF9;
case2:
P0=0xA4;
case3:
P0=0xB0;
case4:
P0=0x99;
case5:
P0=0x92;
case6:
P0=0x82;
case7:
P0=0xF8;
case8:
P0=0x80;
case9:
P0=0x90;
default:
}
7.2记录存储程序
存储记录要先擦除扇区,在写入数据,写入数据前要对命令触发寄存器写入0x5A,再写入0xA5,才能写如数据。
//===============写字节数据===============
voidwrite(uintaddr,uchardat)
iap_contr=eniap;
iap_cmd=0x02;
iap_addrl=addr;
iap_addrh=addr>
>
8;
iap_data=dat;
iap_trig=0x5A;
iap_trig=0xA5;
_nop_();
uniap();
//===============擦除扇区===============
voiderase(uintaddr)
iap_cmd=0x03;
8设计总结及学习FPGA感想
为期两周的生产实习渐渐的结束了,在这次实习过程中,我选择了计步器设计。
在实习过程中,我先是对硬件电路进行了设计,之后要进行焊接操作,由于之前很少使用电烙铁进行焊接,所以导致刚开始焊接时对焊点焊的不够饱满,有时甚至出现了虚焊的情况,但慢慢地熟悉了之后,焊接起来也就快了不少。
而在后面的程序设计的阶段,我选择的C语言进行设计,在经过数百次的修改和调试之后,最终顺利完成了设计。
同时,这次生产实习是一次很好的把理论应用到实践中去的锻炼,通过实习,我更加认识到了理论知识的重要性,也对自己所学知识的长处与不足有了一定的认识,锻炼了动手能力。
最后看着自己努力设计出来的成果,心里有了一丝的成就感。
感谢至芯科技,无私地给我们带来一个星期的FPGA培训。
经过一周的培训,我收获颇丰。
有技能的提高,思维的扩展还有生活的充实。
技能的提升对我来说非常明显。
培训一开始,老师教我们用熟这些软件,这些软件的熟练掌握,加速了进一步设计电路的速度。
老师根据我们薄弱的底子和对VerilogHDL的一无所知的基本情况,从简单的显数、计数,再到RAM、ROM、串行通信的设计,逐步深入,设计合适的万用框架体系让我们更容易上手,化繁为简,局部分模块化逐步设计到后来顶层文件做关联形成一个看起来功能很复杂的程序体系。
最后能够轻松完成一个复杂功能的电路。
体现了硬件描述语言能够模块化设计关联的强大特性。
也使我们对VerilogHDL编程有了浓厚的兴趣。
学习的一周过的十分充实,坐在实验室里写程序看似单调,但有条不紊,忙忙碌碌,脑子里是如何用语言描述一个功能,如何处理时序还有各个功能块之间的关系。
现在我能能感觉到自己的提高,自然会感觉无限充实。
经过培训和实习,大大增强了我的自学能力和独立能力。
更重要的是,我拓展了思路,开阔了视野,活跃了思想,对以后的学习工作起到了很大的帮助作用。
参考文献
[1]胡向东.传感器与检测技术.机械工业出版社.2015,01
(2):
303~314.
[2]童诗白,华成英.模拟电子技术基础.高等教育出版社.2013,12(19):
74~115.
[3]姜志海,黄玉清,刘连鑫.单片机原理与应用.电子工业出版.2014,07
(2):
27~32.
[4]谭浩强.C程序设计(第四版).清华大学出版社.2012,10(10):
37~140.
附录
计步器完整程序:
#include<
reg51.h>
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineiapaddr0x4A00
#defineendaddr0x4800
#defineeniap0x82
sfriap_data=0xC2;
//iap数据寄存器
sfriap_addrh=0xC3;
//iap地址寄存器高字节
sfriap_addrl=0xC4;
//iap地址寄存器低字节
sfriap_cmd=0xC5;
//iap命令寄存器
sfriap_trig=0xC6;
//iap命令触发寄存器
sfriap_contr=0xC7;
//iap控制寄存器
sbitled=P2^7;
sbitkey0=P2^0;
sbitkey1=P2^6;
sbitkey2=P2^5;
sbitkey3=P2^4;
sbitsel1=P1^0;
sbitsel2=P1^1;
sbitsel3=P1^2;
sbitsel4=P1^3;
voiddelay(uintz);
//延时程序
voidseg(uintn);
//数码管段显示
voiduniap(void);
//关闭IAP功能
uintread(uintaddr);
//读字节数据
voidwrite(uintaddr,uchardat);
//写字节数据
voiderase(uintaddr);
//擦除扇区
//===============主程序===============
voidmain(void)
{
uintnum=0,n,m,i;
ucharqian,bai,shi,ge;
n=iapaddr;
m=iapaddr-4;
led=1;
while
(1)
{
qian=num/1000;
sel1=0;
seg(qian);
seg(bai);
seg(shi);
sel1=1;
seg(ge);
if(num==9999)//计数等于9999灯闪烁两下
{
sel1=1;
led=0;
delay(50);
led=1;
}
if((key1==0)||(num==9999))//按键按下存储数据并归零
{
if(num!
=0)
{
erase(endaddr);
if(!
(n%512))
erase(n);
for(i=0;
i<
4;
i++)
{
switch(i)
{
case0:
write(n,qian);
case1:
write(n,bai);
case2:
write(n,shi);
case3:
write(n,ge);
}
n++;
}
m=n;
if(n==0xFDFF)
n=iapaddr;
write((uint)endaddr,(uchar)(n>
8));
write((uint)endaddr+1,(uchar)n);
}
num=0;
if(key2==0)//按键按下显示下一条记录
m=m+4;
if(m>
=((read((uint)endaddr)<
<
8)+read((uint)endaddr+1))||m==iapaddr)
{
sel1=1;
m=iapaddr;
led=0;
delay(36);
led=1;
for(i=0;
200;
sel1=0;
seg(read(m));
seg(read(m+1));
seg(read(m+2));
seg(read(m+3));
}
if(key3==0)//按键按下显示上一条记录
m=m-4;
if(m<
iapaddr)
m=((read((uint)endaddr)<
8)+read((uint)endaddr+1))-4;
if(key0==0)
num++;
//===============延时程序===============
voiddelay(uintz)
uinti,j;
for(i=z;
i>
0;
i--)
for(j=1300;
j>
j--);
//===============数码管段显示===============
//===============关闭IAP功能===============
voiduniap(void)
iap_contr=0;
iap_cmd=0;
iap_trig=0;
iap_addrh=0x80;
iap_addrl=0;
//===============读字节数据===============
uintread(uintaddr)
uintdat;
iap_cmd=0x01;
dat=iap_data;
returndat;