基于单片机的计步器设计.docx

上传人:b****6 文档编号:7529563 上传时间:2023-01-24 格式:DOCX 页数:19 大小:701.69KB
下载 相关 举报
基于单片机的计步器设计.docx_第1页
第1页 / 共19页
基于单片机的计步器设计.docx_第2页
第2页 / 共19页
基于单片机的计步器设计.docx_第3页
第3页 / 共19页
基于单片机的计步器设计.docx_第4页
第4页 / 共19页
基于单片机的计步器设计.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

基于单片机的计步器设计.docx

《基于单片机的计步器设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的计步器设计.docx(19页珍藏版)》请在冰豆网上搜索。

基于单片机的计步器设计.docx

基于单片机的计步器设计

 

班级:

电信12-2

姓名:

李猛

学号:

1206110207

成绩:

电子与信息工程学院

信息与通信工程系

 

基于单片机的计步器设计

摘要

随着社会的发展,生活方式的改变,现代人的生活越来越远离运动,都市的白领们在享受着汽车、互联网等科学技术为生活带来便利的同时,身体的活动机会也在不断的减少。

高强度的脑力劳动,长时间的办公室作业,让许多人的身体处于亚健康状态,更有不少人患上了肥胖、失眠等疾病。

本文基于IAP15F2K61S2单片机,利用常开型振动传感器模块检测人体行走的步数,通过数码管显示出来。

并具有清零、存储记录和查看历史记录的功能。

使人们时刻掌握着自己的健身强度和运动水平。

关键词:

IAP15F2K61S2、常开型振动传感器模块、计步器

1设计任务

计步器主要由振动传感器和电子计数器组成。

人在步行时重心都要有一点上下移动。

以腰部的上下位移最为明显,所以计步器挂在腰带上最为适宜。

计步器的工作核心就是振动传感器,通过振动传感器对日常锻炼进度监控器,可以计算人们行走的步数,估计行走距离、消耗的卡路里,方便人们随时监控自己的健身强度和运动水平。

通过设计实现的功能有:

1)利用振动传感器来实现对计步器功能的模拟;

2)可以记录行走的步数,可以显示记录的步数;

3)通过按键实现归零功能,可以存储历史记录,并断电不丢失;

4)通过按键实现了历史记录的查看。

2设计思路

计步器由振荡电路、复位电路、数码管显示模块以及按键模块和传感器模块等几个部分组成(如图2-1)。

振荡电路是给单片机提供外部时钟信号,使单片机工作。

复位电路是使单片机恢复初始状态。

数码管显示模块是受单片机控制显示步数。

按键模块是通过相应的按键控制单片机实现相应的功能。

传感器模块是检测人体行走时的振动,若检测到振动则传感器给出低电平,来告诉单片机记录步数。

图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位共阳数码管

1块

4

晶振11.0592

1块

5

三极管NPN

4个

6

四角开关

4个

7

电阻10K

5个

8

电阻470R

9个

9

电阻300R

4个

10

电解电容10uF

1个

11

电容47pF

2个

12

发光二极管红色

1个

13

开关

1个

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);

sel1=0;sel2=0;sel3=1;sel4=0;

seg(bai);delay

(1);

sel1=0;sel2=1;sel3=0;sel4=0;

seg(shi);delay

(1);

sel1=1;sel2=0;sel3=0;sel4=0;

seg(ge);delay

(1);

}

voidseg(uintn)

{

switch(n)

{

case0:

P0=0xC0;break;

case1:

P0=0xF9;break;

case2:

P0=0xA4;break;

case3:

P0=0xB0;break;

case4:

P0=0x99;break;

case5:

P0=0x92;break;

case6:

P0=0x82;break;

case7:

P0=0xF8;break;

case8:

P0=0x80;break;

case9:

P0=0x90;break;

default:

P0=0xC0;break;

}

}

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_contr=eniap;

iap_cmd=0x03;

iap_addrl=addr;

iap_addrh=addr>>8;

iap_trig=0x5A;

iap_trig=0xA5;

_nop_();

uniap();

}

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

#include

#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;bai=(num/100)%10;shi=(num/10)%10;ge=num%10;

sel1=0;sel2=0;sel3=0;sel4=1;

seg(qian);delay

(1);

sel1=0;sel2=0;sel3=1;sel4=0;

seg(bai);delay

(1);

sel1=0;sel2=1;sel3=0;sel4=0;

seg(shi);delay

(1);

sel1=1;sel2=0;sel3=0;sel4=0;

seg(ge);delay

(1);

if(num==9999)//计数等于9999灯闪烁两下

{

sel1=1;sel2=1;sel3=1;sel4=1;

led=0;

delay(50);

led=1;

delay(50);

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);break;

case1:

write(n,bai);break;

case2:

write(n,shi);break;

case3:

write(n,ge);break;

}

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;sel2=1;sel3=1;sel4=1;

m=iapaddr;

led=0;

delay(36);

led=1;

}

for(i=0;i<200;i++)

{

sel1=0;sel2=0;sel3=0;sel4=1;

seg(read(m));delay

(1);

sel1=0;sel2=0;sel3=1;sel4=0;

seg(read(m+1));delay

(1);

sel1=0;sel2=1;sel3=0;sel4=0;

seg(read(m+2));delay

(1);

sel1=1;sel2=0;sel3=0;sel4=0;

seg(read(m+3));delay

(1);

}

}

if(key3==0)//按键按下显示上一条记录

{

m=m-4;

if(m

{

sel1=1;sel2=1;sel3=1;sel4=1;

m=((read((uint)endaddr)<<8)+read((uint)endaddr+1))-4;

led=0;

delay(36);

led=1;

}

for(i=0;i<200;i++)

{

sel1=0;sel2=0;sel3=0;sel4=1;

seg(read(m));delay

(1);

sel1=0;sel2=0;sel3=1;sel4=0;

seg(read(m+1));delay

(1);

sel1=0;sel2=1;sel3=0;sel4=0;

seg(read(m+2));delay

(1);

sel1=1;sel2=0;sel3=0;sel4=0;

seg(read(m+3));delay

(1);

}

}

if(key0==0)

num++;

}

}

//===============延时程序===============

voiddelay(uintz)

{

uinti,j;

for(i=z;i>0;i--)

for(j=1300;j>0;j--);

}

//===============数码管段显示===============

voidseg(uintn)

{

switch(n)

{

case0:

P0=0xC0;break;

case1:

P0=0xF9;break;

case2:

P0=0xA4;break;

case3:

P0=0xB0;break;

case4:

P0=0x99;break;

case5:

P0=0x92;break;

case6:

P0=0x82;break;

case7:

P0=0xF8;break;

case8:

P0=0x80;break;

case9:

P0=0x90;break;

default:

P0=0xC0;break;

}

}

//===============关闭IAP功能===============

voiduniap(void)

{

iap_contr=0;

iap_cmd=0;

iap_trig=0;

iap_addrh=0x80;

iap_addrl=0;

}

//===============读字节数据===============

uintread(uintaddr)

{

uintdat;

iap_contr=eniap;

iap_cmd=0x01;

iap_addrl=addr;

iap_addrh=addr>>8;

iap_trig=0x5A;

iap_trig=0xA5;

_nop_();

dat=iap_data;

uniap();

returndat;

}

//===============写字节数据===============

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_contr=eniap;

iap_cmd=0x03;

iap_addrl=addr;

iap_addrh=addr>>8;

iap_trig=0x5A;

iap_trig=0xA5;

_nop_();

uniap();

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1