基于单片机的自行车里程表设计

摘要

针对自行车码表在国内外发展趋势快速,可以有效处理速度和千米数,让选手恰当健身运动,做到运动康和走动的最好实际效果的背景。本文采用了AT89C52单片机系统,硬件部分由AT89C52单片机设计系统软件最小模块、控制模块、检测模块、计时模块和显示显示模块,报警模块,按键模块构成。软件的是用C语言、proteus、keil编程的,采用模块化设计思想。采用AT89C52单片机作为关键芯片,通过按键来控制功能显示,系统可以实现准确的测量行驶里程,实时的时间,骑行的速度,具有对骑行爱好者能随时获取自己状态信息有很大的意义。

引言

智能化时速表可以测量电机的转速比,运作时必须操纵电机的线性度。立即测量转速比可以合理地体现电机的情况。该体系主要是由感应器和AT89C51单片机设计构成,可以测量宽范畴和高速运行,并且能够与PC机通讯完成电机转速比的测量。MCU的英文名称是microcontrollerunit,简称为MCU。还有一个微控制器,是面对操纵的电子器件列阵关键。它多功能性强、体型小、稳定性高、便于运用,因而运用覆盖面广,能推动各领域的工艺进步和智能化[1]。这篇论文详细介绍了该体系的作用、性能指标和基本前提。详细介绍了总体方案设计全过程,明确了性能指标和零部件型号选择。总部主要详细介绍叙述了操作系统的硬件电路原理,硬件设计方案电源电路及其常用元件的差异作用和特点。

第一章设计分析

1.1整体设计分析
  以通用性的ST89C52单片机为关键核心,根据感应器将车论的转速比转化成脉冲电流,经加工处理后送进单片机。里程和速率的精确测量是由记时器/计数测到的总脉冲数和每转的畤间,随后由单片机推算出来,结果由LED显示器表明。假定轮圈直径为L,轮圈上安装m块永磁材料,测出的里程值较大偏差为L/m[2]。经综合分析,本设计中取m=1。当轮子每转一圈,通过开关型霍尔元件传感器采集到一个脉冲信号,并从引脚P3.2中断0端输入,传感器每获取一个脉冲信号即对系统提供一次计数中断。每次中断代表车轮转动一圈,中断数n轮圈的周长为L的乘积为里程值。计数器T1计算每转一圈所用的时间t,就可以计算出即时速度v。按住速率键时,速度显示灯闪烁,LED转换表明现阶段速率。假如单车超速行驶,系统软件会产生报警系统,显示灯会闪动。
所需标准和完成方式如下所示:
1.运用霍尔传感器造成里程差分脉冲信号。
2.对脉冲开展记数。
实现:根据单片机的计数T1对霍尔传感器的脉冲开展记数。
3.为了更好地解决数据信息,必须用LED表明总里程和当时速度。
实现:运用软件编程,对数据资料完成解决,获得需要的标值。最终实现目的单车的车速表具备里程和即时速度表明作用,由单片机操纵,表明电源电路可以表明里程和速度。
1.2硬件电路设计思路
硬件是由测量模块、按键模块、显示模块、控制模块组成的。里程测量传感器的选择方案:1.用光敏二极管精确测量里程:光敏二极管对光线比较敏感。大白天行车时,外界灯源会使光敏二极管传出异常数据信号;光敏二极管对自然环境的标准很高。假如光敏二极管或LED被碎石子或尘土遮盖,光敏二极管将没法精准测量;2.霍尔传感器精确测量里程:霍尔元件或簧片电源开关不但不会受到气候危害,即使被土壤或尘土遮盖也不会得到危害,安装便捷。因而,本设计选用霍尔元件精确测量里程和速度,简便易行,经济发展适用[3]。
设计方案采用ST89C52单片机。硬件配置构造方框图如图1.1所示。在这里插入图片描述

图1.1系统结构框图
1.3软件设计思路
软件开发包含子程序、里程和速度测算程序段、延迟程序段、终断服务项目程序段、表明程序段等。中断程序段是将感应器造成的数据信号连接外部中断0,将74LS74分频后的数据信号连接外部中断1,运用中断和计时器各自总计里程和精确测量每周转的畤间[4]。数据处理方法程序段是依据进到单片机的差分脉冲信号与要表明的真实值中间的某类对应关系,根据软件编程表明所需值。显示程序段是将数据处理方法的结果送至显示屏开展表明。系统软件总体流程图如图1.2所示。
图1.2软件总体流程图在这里插入图片描述

第二章硬件电路设计

2.1控制模块
2.1.1单片机
STC89C52RC单片机是传统式的8051单片机,命令编码彻底兼容。可以随意挑选12个时钟/振荡周期和6个时钟/机器周
期。特点如表1.1所示。
表1.1ST89C52单片机特点
  
ST89C52单
片机特点
增强型8051单片机,6时钟/机器周期 和12时钟/机器周期可以任意选择,指 令代码完全兼容传统
8051。工作电压:5.5V3.3V( 5V单片机)
  /3.8V2.0V (3V 单片机)。
工作频率范围:040MHz,相当于普通 8051的080MHz,实际工作频率可达 48MHz。片上集成512字节RAM。
用户应用程序空间为8K字节。
通用I/O 口 ( 32个),复位后为: P1/P2/P3/P4是准双向口/弱上拉,P0 口是漏极开路输出,作为总线扩展用时, 不用加上拉电阻,作为I/O 口用时,需加上拉电阻。
具有EEPROM功能。
共3个16位定时器/计数器。即定时器
  T0、 T1、 T2。
通用异步串行口(UART),还可用定时 器软件实现多个UART。
工作温度范围:-40+85°C(工业级)/075°C(商业级)。
  STC89C52RC单片机是宏景高新科技发布的新一代快速/功耗低/极强抗干扰性单片机。如图1.3所示。
U1
PIO VCC
Pll P00 -4^
2— P12 P01 -4^
-——7— P13 P02
P14 P03 书-
?i5 P04
-——i— P16 P05 -^7-
P17 P06 -4^
RESET P07_
—广 P30/RXD EA『T
—F31/TXD ALE 号-
p— P32HNT0 PSEN
莅一 P33HNTT P27
p— P34/T0 P26 -4^
―括一P35m P25
—丹一 F36/W P24 -4^
—椅一 P37/RD P23 淄-
需一 KTAL2 P22
升L XTAL1 P21
I―尖一GND P20
GMD
  P0端口(P0.0P0.7,3932引脚):P0端口是开漏8位双边I/O端口。做为输出端口,每一个管脚可以推动8个TTL负荷。将“1”载入端口P0时,它可以用于高抗阻键入。
  P1端口(P1.0P1.7,18引脚):P1端口是一个8位双边I/O端口,内嵌上拉电阻。P1的输出油压缓冲器可以推动消化吸收或输出电流量)四个TTL键入。
  除此之外,P1.0和P1.1也可作为计时器/计数2的外界技术性键入(P1.0/T2)和开启键入(P1.1/T2EX)。当程序编写和认证闪存芯片ROM肘,P1接受低8位详细地址。详见下表1.2:
表1.3 P3口引脚复用功能
  
引脚号 复用功能
P3.0 RXD (串行输入口)
P3.1 TXD (串行输出口)
P3.2 (外部中断0)
P3.3 (外部中断1)
P3.4 T0 (定时器0的外部输入)
P3.5 T1 (定时器1的外部输入)
P3.6 (外部数据存储器写选通)
P3.7 (外部数据存储器读选通)
  RST(9引脚):复位输入。当输入连续两个机器周期以上高电平时为有效,用来完成单片机单片机的复位初始化操作。
ALE/(30引脚):地址锁存控制信号(ALE)是浏览外界程序存储器时,锁存低8位地址的输出脉冲。
/PSEN(29引脚):是外部程序存储器选通信号。
  /VPP(31引脚):浏览外界程序存储器操纵数据信号。要从外界程序存储器0000H至FFFFH载入命令,务必联接GND。留意数据加密方式1时,重设内部结构锁住位。
XTAL1(19引脚):震荡器反相放大器和内部结构时钟造成电源电路的键入。
XTAL2(18引脚):震荡器反相放大器键入。
2.1.2单片机的时钟电路
  时钟是电子计算机的关键构成部分,操纵着电脑的运行节奏感。MCS-51单片机设计容许的时钟原率因型号规格不一样而异,典型值为12MHz。
  一个CMOS单片机设计(如AT89C51)内部结构可控性负反馈反相放大器,振荡器由外面的结晶振荡器(或瓷器谐振器)和电容器构成。图1.4是用CMOS单片机设计方案的时钟开关电源的电源电路框架图[5]。振荡器的实际操作由end/PD操纵。根据设定“1”PD(即独特PCON函数公式纪录1)让/PD“0”,振荡器停止工作,从而全部单片机设计停止工作,可以实现节能环保的目地。消除PD"0”使震荡器工作中并造成时钟,单片机设计正常的工作中[6]。振荡器造成的时钟频率关键由sys主要参数(晶振电路中标示的频率)决策。电力电容器C1和C2有相对的功效:一是使振荡器震动;第二,调整振荡器的频率f(C1和C2大,f小),
2.1.3单片机的复位电路
  当电子计算机运行时,务必开展修复,使CPU等系统软件构件处在某类初始值,并依照这类情况开始工作。MCS-51微处理器有一个RST管脚,它是施密特触发器的重要部位(针对CHMOS微处理器,第一个管脚有一个下拉电阻)。当振荡器逐渐震动时,超出2个振荡周期(即24个时钟周期时间)发生在引脚,以校准器件。只需RST维持在低位,MCS-51就可以修复。RST变成低电频后,校准撤出,CPU逐渐从初始值运[7]。
  MCU的校准方式是全自动校准方式。针对片式MOS微(AT89C51),只需将电容器联接到VCC(见图2.6)。打火时,电容器根据电阻器电池充电,一定时间段内第一端发生高电平。只需高层住宅畤间非常长,MCS-51是可以有效的修复的。RST接线端子在打火期内应维持高电平,包含VCC增益值和振荡器开机时间⑻。假定VSS的增益值为10ms,证实了振荡器的开机时间与原率相关[8]。为了更好地维持10MHz以上的输出功率脉冲信号大概1ms,第一个应当维持高电平大概1ms。RC稳态值越高,rst端开关电源维持高电平的时间段越长。假如延时电路无效,CPU通电后逐渐任意运作,系统软件不能正常的工作。
2.2检测模块
2.2.1霍尔器件概述
  霍尔元件是一种根据霍尔效应的电滑环。已发展变成各种各样磁感应器商品,并获得广泛运用。霍尔元件是一种电滑环,在各类与电磁场相关的场所,它都应当能监测到电磁场以及转变。霍尔效应是霍尔元件的工作中。
  霍尔元件具备构造坚固、体型小、重量轻巧、工作寿命长、安装便捷、功能损耗低、频率高(可达1MHz)、抗震动、不害怕尘土、水蒸气和粉尘环境污染或锈蚀等许多优势[9]。
  霍尔元件线形器件高精度,线性好霍尔元件器件无触点开关、无损坏、输出波型清楚、无颤动、无调整、部位反复高精度(可达um级)。各种各样赔偿方法的霍尔元件操作温度范畴宽,可达55~150度。霍尔元件按其作用可分成霍尔元件线形器件和霍尔元件器件。前面一种输出plc,后面一种输出数据量。
  集成化霍尔传感器的输出是通过加工处理的霍尔元件输出数据信号。依据输出数据信号的方法,可分成输出功率电源开关集成化霍尔传感器和线形集成化霍尔传感器。[10]。
  电源开关型集成化霍尔传感器设计方案成在求得霍尔元件输出后输出差分信号或低频率脉冲信号。霍尔元件电路又被称为霍尔元件数字电路设计,由可调稳压电源、霍尔元件处理芯片、差分放大器、定位触发器和输出级构成。
2.2.2霍尔传感器的应用
  用霍尔元件机器设备精确测量电磁场的方式简易。霍尔元件元器件做成多种类型的摄像头,放置被测电磁场中。霍尔元件机器设备只对三等分点霍尔元件表面的磁感应强度比较敏感,因此感应线圈线应垂直平分机器设备表面。插上去开关电源后,就可以获得输出工作电压测出的电磁场的磁感应强度[11]。非竖直时,为了更好地测算测量磁场的磁场强度值,务必求出竖直份量。此外,因为霍尔元件的大小十分小,因而可以检验多一点、电子计算机解决数据、场的分散情况、双缝、小圆孔的磁场。假如将磁场作为被磁感应物体的运动和位置信息媒介,则通常应用永磁材料来造成工作中磁场。
2.2.3AH41霍尔开关
  AH41霍尔元件电源电路用以转变梯度方向最合适险峻磁场且磁相对密度较差的状况,由反方向工作电压保护装置、电压调节器、霍尔电压产生器、信号增强器、SMIT触发器、集电极引路输出水准构成[12]。操作温度范畴为-40~150度(储存温度为150度),适用各种各样机械设备和机电一体化行业。
2.3计时模块
2.3.1DS1302主要的性能指标和特点
1.即时时钟可以测算秒、天、周、月、年。
2.31*8位演出舞台数据储存RAM。
3.串行通信I/O端口号方式可最大限度地降低针角数。
4.大范畴工作标准电压。
5.工作中电流量在2.0V时低于300mA。
6.读写能力时钟或RAM数据信息时,有单字节传送和多字节数传送标志符组。
7.8针DIP封装形式或供选择的8针SOIC封装是依据表层拼装的。
8.简易的三线插口。
9.合乎TTL规范的VCC=5V。
10.可选择性工业生产温度范围-40~85度。
11.与 DS1202 兼容。
12.DS1202中增加的作用。
13.Vcc1的可选择性原料油电池充电作用。
14.用以主、后备电源的双电源开关管。
15,后备电源针角可以用充电电池或大空间电容器键入。
2.4显示模块
2.4.1 LCD1602
LCD1602标识符液晶显示屏是专业用来表明英文字母、数据、标记等的点阵式液晶显示模块。如下图1.5所显示。标识符LCD可以与此同时表明32字符。LCD 1602
2.5报警模块
  运用I/O口按时旋转脉冲信号设定无源蜂鸣器相对性简易,只必须剖析波型就可以。由于驱动的信号刚好为周期为500us,占空比为1/2duty的方波,因此推动无源蜂鸣器的波形数据信号只有每过250us根据脉冲信号反转来得到。
2.6按键模块
采用四位独立按键开关,常闭点和常闭触点的组成。常闭点的功能是当工作压力增加在常闭点处时,电源电路接入当工作压力终止时,原先的常闭点修复,即断掉;工作压力是拿手按住按键开关。

第三章软件设计

3.1自行车码表程序设计思路及过程
  自行车码表程序流程分成很多个控制模块,子程序启用每一个控制模块。按下开关会显示初始状态,通过启动马达来启动车轮转动,显示出的速度随转速变化而变化,启动后随时显示当时的时间,行驶的里程。流程如下图2.8所显示。在这里插入图片描述

图2.8总体设计流程图
3.2速度程序设计思路
频率测量方式“m”法
P轴转动一周脉冲产生器造成的脉冲数;
n-速度单位:转动/分钟;T-记时时间单位:秒。
在这些方式中,存有测量精密度无法确保严苛同步的畤间T和脉冲的状况,大概会发生一个脉冲的定量分析偏差。因而,要测量测量的精确度,T务必有充足的畤间。侧周期时间法“T”法
  转速可以根据2个脉冲造成的间距总宽TP来明确。搜集数据的码盘、双孔或多孔结构都能够挑选,依据双孔码盘测量2个脉冲中间的时间段可以测量数据,时钟脉冲数可以表明TP。针对多孔结构硬盘,测量畤间为每转1/n,n是硬盘孔眼。如(1.3)“T”法脉冲宽度测量中所显示,TP是根据记时器测量的。,计时器畤间标准脉冲(频率兀)测算记时,假如TP内的计标值为m2,则公式计算为60fcP~m2
(1.4)九-为硬件配置形成的标准时钟脉冲;频率:Hz;n-速度单位:转动/分钟;m2-根据时间段的脉冲。
  从“T”法脉冲宽度测量可以看得出,“T”法测量精密度的偏差关键有两个层面,一是因为2个脉冲的上升沿开启畤间不一致导致的。第二,记数和记时开始与结束不一致而产生。关键测量方式在转速较低时精密度较高,但转速提升时精密度会下降,偏差低于一个脉冲[13]。
3.3行程程序设计思路
行程安排可以根据外界脉冲数据信号积累,因而可以利用stm32的外部中断来完成。根据数码显示管表明。
3.4日历程序设计
DS1302根据简洁的串行通信页面与单独控制板通讯,可以自行调节秒、日、月、年、月、日、平年等。依据AM/PM的标示,可以明确12钟头或4小畤的文件格式。数据和时钟信息内容都需要保证在1mW下列[14]。
  读写能力记时表明:DS1302是一种SPI系统总线推动方式。除开在存储器中载入控制板外,还务必载入该存储器
中的数据。要与DS1302通讯,最先需要掌握DS1302的操纵者。控制板的最大合理位(位7)务必是逻辑性1。假如为操纵词一直从较低位逐渐输出。操纵字指令键入后,下一个SCLK时钟上升,数据将载入DS1302,数据键入以最少位(0位)逐渐[15]。一样,紧接在8位操纵者指令以后的下一个SCLK脉冲的降低边沿载入DS1302的数据,读取的数据也从较低位载入到最大位。

附录C程序
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#include "Data.h”
#include 〃DS1302.h〃
#include 〃AT24C02.h〃
sbit COUNT_IN=P3"2;
//定义1602相关管脚
sbit rs=P1"0;
sbit en=P「4;
//键盘定义
sbitK1=P3"4;//设置时间
sbit K3=P3"6; //减按键
21
sbit K2=P3"5; //加按键
sbitK4=P3"7;//设置半径安全距离
sbit BEEP=P3"0;
uint count;
unsigned long Velocity,Mileage;
  uchar code tab1[] = {" / / : ""}; //14/09/10 16:34 3
uchar code tab2[]={" 0.000km 00km/h"}; //000.000km 00km/h
uchar code tab3[]={"Wheel Radius cm");
uchar code tab4[]={"Safe Speed km/h");
uchar code tab5[]={"Sec"};
uchar Mode=0;
uchar bike_set=0;
uchar a;
char RADIUS,SAFE_SPEED;
bit LED_SEC;
uchar before_sec;
〃自定义字符
uchar code num[] = {
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//1
0x1f,0x01,0x01,0x1f,0x10,0x10,0x1f,0x00,//2
0x1f,0x01,0x01,0x1f,0x01,0x01,0x1f,0x00,//3
0x11,0x11,0x11,0x1f,0x01,0x01,0x01,0x00,//4
0x1f,0x10,0x10,0x1f,0x01,0x01,0x1f,0x00,//5
0x1f,0x10,0x10,0x1f,0x11,0x11,0x1f,0x00,//6
0x1f,0x01,0x01,0x01,0x01,0x01,0x01,0x00,//7 };
void READS();
void SETS();
void delay(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<110;j++);
}
void init()
{
IT0=1;//INT0负跳变触发
TMOD=0x01;//定时器工作于方式1
TH0=0x3c; //50ms
TL0=0xb0;
EA=1;//CPU开中断总允许
ET0=1;//开定时中断
EX0=1;//开外部INTO中断
TR0=1;//启动定时
}
/********液晶写入指令函数与写入数据函数,以后可调用**************/
void write_1602com(uchar com)//**** 液晶写入指令函数 ****
{
22
rs=0;//数据/指令选择置为指令
P0=com;//送入数据
delay(1);
en=1;//拉高使能端,为制造有效的下降沿做准备
delay(1);
en=0;//en由高变低,产生下降沿,液晶执行命令
} void write_1602dat(uchar dat)//*** 液晶写入数据函数 ****
{
rs=1;//数据/指令选择置为数据
P0=dat;//送入数据
delay(1);
en=1;//en置高电平,为制造下降沿做准备
delay(1);
en=0;//en由高变低,产生下降沿,液晶执行命令
}
//自定义字符集
void Lcd_ram()
{
uint i,j,k=0,temp=0x40;
for(i=0;i<7;i++)
{
for(j=0;j<8;j++)
{
write_1602com(temp+j);
write_1602dat(num[k]);
k++;
}
temp=temp+8;
}
}
voidlcd_init()//***液晶初始化函数****
{
Lcd_ram();
write_1602com(0x38);//设置液晶工作模式,意思16*2行显示,5*7点阵,
8位数据
write_1602com(0x0c);//开显示不显示光标
write_1602com(0x06);//整屏不移动,光标自动右移
write_1602com(0x01);//清显示
write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]);//向液晶屏写固定符号部分
}
write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab2[a]);//写显示固定符号
23
}
}
void display()
{
// 1km/h=100m/0.1h 360s
// 10km/h=100m/0.01h 36s
// 100km/h=100m/0.001h 3.6s
if(Mode==0&&bike_set==0)
{
//读时间
Ds1302_Read_Time();
//显示时间
write_1602com(0x80);
write_1602dat(0x30+time_buf1[1]/10);
write_1602dat(0x30+time_buf1[1]%10);
write_1602com(0x80+3);
write_1602dat(0x30+time_buf1[2]/10);
write_1602dat(0x30+time_buf1[2]%10);
write_1602com(0x80+6);
write_1602dat(0x30+time_buf1[3]/10);
write_1602dat(0x30+time_buf1[3]%10);
write_1602com(0x80+9);
write_1602dat(0x30+time_buf1[4]/10);
write_1602dat(0x30+time_buf1[4]%10);
write_1602com(0x80+12);
write_1602dat(0x30+time_buf1[5]/10);
write_1602dat(0x30+time_buf1[5]%10);
write_1602com(0x80+15);
write_1602dat(time_buf1[7]-1);
if(before_sec!二time_buf1[6])
{
before_sec=time_buf1[6];
write_1602com(0x80+11);
write_1602dat(':');
LED_SEC=1;
}
if(LED_SEC==0)
{
write_1602com(0x80+11);
write_1602dat('');
}
write_1602com(0x80+0x40);
if(Mileage/1000000==0)
write_1602dat('');
else
  write_1602dat(0x30+Mileage/1000000);//数字 +0x30 得到该数字 的LCD1602显示码
if(Mileage%1000000/100000==0)
24
write_1602dat('');
else
  write_1602dat(0x30+Mileage%1000000/100000);//数字+0x30 得到 该数字的LCD1602显示码
  write_1602dat(0x30+Mileage%1000000%100000/10000);// 数字 +0x30得到该数字的LCD1602显示码
write_1602com(0x80+0x40+4);
  write_1602dat(0x30+Mileage%1000000%100000%10000/1000);// 数 字+30得到该数字的LCD1602显示码
  write_1602dat(0x30+Mileage%1000000%100000%10000%1000/100);// 数字 +30得到该数字的LCD1602显示码
  write_1602dat(0x30+Mileage%1000000%100000%10000%1000%100/10);// 数 字+30得到该数字的LCD1602显示码
SETS();
write_1602com(0x80+0x40+10);
write_1602dat(0x30+Velocity/10);
write_1602dat(0x30+Velocity%10);// 数字 +30 得到该数字的
LCD1602显示码
}
else if(Mode!=0)
{
switch(Mode)
{
case 1:
write_1602com(0x80+0x40);//显示固定符号写入位置
for(a=0;a<16;a++)
{
write_1602dat(tab5[a]);//写显示固定符号
}
write_1602com(0x80+0x40+14);
write_1602dat(0x30+time_buf1[6]/10);
write_1602dat(0x30+time_buf1[6]%10);
write_1602com(0x0F); //打开闪烁
write_1602com(0x80+1);
break;
case 2:
write_1602com(0x80+4);
break;
case 3:
write_1602com(0x80+7);
break;
case 4:
write_1602com(0x80+10);
break;
case 5:
write_1602com(0x80+13);
break;
case 6:
write_1602com(0x80+0x40+15);
break;
case 7:
write_1602com(0x80+15);
25
break;
case 8:
write_1602com(0x0c);
write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]);//向液晶屏写固定符号部分
}
write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab2[a]);//写显示固定符号
}
break;
}
}
else if(bike_set!=0)
{
switch(bike_set)
{
case 1:
write_1602com(0x80);//显示固定符号写入位置
for(a=0;a<16;a++)
{
write_1602dat(tab3[a]);//写显示固定符号
}
write_1602com(0x80+0x40);//显示固定符号写入位置
for(a=0;a<16;a++)
write_1602dat(tab4[a]);//写显示固定符号 }
write_1602com(0x80+12);
write_1602dat(0x30+RADIUS/10); //车轮半径
write_1602dat(0x30+RADIUS%10);
write_1602com(0x80+0x40+10);
write_1602dat(0x30+SAFE_SPEED/10); //安全速度
write_1602dat(0x30+SAFE_SPEED%10);
  write_1602com(0x0F); //打开闪烁 write_1602com(0x80+13); break;
case 2:
write_1602com(0x80+0x40+11);
break;
case 3:
write_1602com(0x0c);
write_1602com(0x80);//显示固定符号从第一行第1个位置之后开始显示
for(a=0;a<16;a++)
{
write_1602dat(tab1[a]);//向液晶屏写固定符号部分
}
write_1602com(0x80+0x40);//显示固定符号写入位置,从第2个位置后开始显示
26
for(a=0;a<16;a++)
{
write_1602dat(tab2[a]);//写显示固定符号
}
break;
}
}
void KEY()
{
if(bike_set==0&&K1==0)
{
delay(20);
if(bike_set==0&&K1==0)
{
BEEP=0;
delay(50);
BEEP=1;
Mode++;
display();
if(Mode>=8)
{
Mode=0;
Ds1302_Write_Time();
}
}
while(bike_set==0&&K1==0);
}
if(K4==0&&Mode==0)
{
delay(20);
if(K4==0&&Mode==0)
BEEP=0;
delay(50);
BEEP=1;
bike_set++;
display。;
if(bike_set>=3)
{
bike_set=0;
SETS();
}
}
while(Mode==0&&K4==0);
}
//+
if(K2==0&&(Mode!=0||bike_set!=0))
{
27
delay(20);
〃调时
if(K2==0&&(Mode!=0||bike_set!=0))
{
BEEP=0;
delay(50);
BEEP=1;
switch(Mode)
{
case 1:
time_buf1[1]++;
if(time_buf1[1]>=100)
time_buf1[1]=0;
write_1602com(0x80);
write_1602dat(0x30+time_buf1[1]/10);
write_1602dat(0x30+time_buf1[1]%10);
write_1602com(0x80+1);
break;
case 2:
time_buf1[2]++;
if(time_buf1[2]>=13)
time_buf1[2]=1;
write_1602com(0x80+3);
write_1602dat(0x30+time_buf1[2]/10);
write_1602dat(0x30+time_buf1[2]%10);
write_1602com(0x80+4);
break;
case 3:
time_buf1[3]++;
  if(time_buf1[3]>=YDay(time_buf1[1],time_buf1[2])+1)
time_buf1[3]=1;
write_1602com(0x80+6);
write_1602dat(0x30+time_buf1[3]/10);
write_1602dat(0x30+time_buf1[3]%10);
write_1602com(0x80+7);
break;
case 4:
time_buf1[4]++;
if(time_buf1[4]>=24)
time_buf1[4]=0;
write_1602com(0x80+9);
write_1602dat(0x30+time_buf1[4]/10);
write_1602dat(0x30+time_buf1[4]%10);
write_1602com(0x80+10);
break;
case 5:
time_buf1[5]++;
28
if(time_buf1[5]>=60)
time_buf1[5]=0;
write_1602com(0x80+12);
write_1602dat(0x30+time_buf1[5]/10);
write_1602dat(0x30+time_buf1[5]%10);
write_1602com(0x80+13);
break;
case 6:
time_buf1[6]++;
if(time_buf1[6]>=60)
time_buf1[6]=0;
write_1602com(0x80+0x40+14);
write_1602dat(0x30+time_buf1[6]/10);
write_1602dat(0x30+time_buf1[6]%10);
write_1602com(0x80+0x40+15);
break;
case 7:
time_buf1[7]++;
if(time_buf1[7]>=8)
time_buf1[7]=1;
write_1602com(0x80+15);
write_1602dat(time_buf1[7]-1);
write_1602com(0x80+15);
break;
}
switch(bike_set)
{
case 1:
RADIUS++;
if(RADIUS>=71)
RADIUS=0;
write_1602com(0x80+12);
write_1602dat(0x30+RADIUS/10);
write_1602dat(0x30+RADIUS%10);
write_1602com(0x80+13);
break;
case 2:
SAFE_SPEED++;
if(SAFE_SPEED>=100)
SAFE_SPEED=0;
write_1602com(0x80+0x40+10);
write_1602dat(0x30+SAFE_SPEED/10);
write_1602dat(0x30+SAFE_SPEED%10);
write_1602com(0x80+0x40+11);
break;
}
}
29
while(K2==0);
}
//-
if(K3==0&&(Mode!=0||bike_set!=0))
{
delay(20);
//调时
if(K3==0&&(Mode!=0||bike_set!=0))
{
BEEP=0;
delay(50);
BEEP=1;
switch(Mode)
{
case 1:
time_buf1[1]--;
if(time_buf1[1]<0)
time_buf1[1]=99;
write_1602com(0x80);
write_1602dat(0x30+time_buf1[1]/10);
write_1602dat(0x30+time_buf1[1]%10);
write_1602com(0x80+1);
break;
case 2:
time_buf1[2]--;
if(time_buf1[2]<=0)
time_buf1[2]=12;
write_1602com(0x80+3);
write_1602dat(0x30+time_buf1[2]/10);
write_1602dat(0x30+time_buf1[2]%10);
write_1602com(0x80+4);
break;
case 3:
time_buf1[3]--;
if(time_buf1[3]<=0)
time_buf1[3]=YDay(time_buf1[1],time_buf1[2]);
write_1602com(0x80+6);
write_1602dat(0x30+time_buf1[3]/10);
write_1602dat(0x30+time_buf1[3]%10);
write_1602com(0x80+7);
break;
case 4:
time_buf1[4]--;
if(time_buf1[4]<0)
time_buf1[4]=23;
write_1602com(0x80+9);
write_1602dat(0x30+time_buf1[4]/10);
30
write_1602dat(0x30+time_buf1[4]%10);
write_1602com(0x80+10);
break;
case 5:
time_buf1[5]--;
if(time_buf1[5]<0)
time_buf1[5]=59;
write_1602com(0x80+12);
write_1602dat(0x30+time_buf1[5]/10);
write_1602dat(0x30+time_buf1[5]%10);
write_1602com(0x80+13);
break;
case 6:
time_buf1[6]--;
if(time_buf1[6]<0)
time_buf1[6]=59;
write_1602com(0x80+0x40+14);
write_1602dat(0x30+time_buf1[6]/10);
write_1602dat(0x30+time_buf1[6]%10);
write_1602com(0x80+0x40+15);
break;
case 7:
time_buf1[7]--;
if(time_buf1[7]<1)
time_buf1[7]=7;
write_1602com(0x80+15);
write_1602dat(time_buf1[7]-1);
write_1602com(0x80+15);
break;
}
switch(bike_set)
{
case 1:
RADIUS--;
if(RADIUS<0)
RADIUS=70;
write_1602com(0x80+12);
write_1602dat(0x30+RADIUS/10);
write_1602dat(0x30+RADIUS%10);
write_1602com(0x80+13);
break;
case 2:
SAFE_SPEED--;
if(SAFE_SPEED<0)
SAFE_SPEED=99;
write_1602com(0x80+0x40+10);
write_1602dat(0x30+SAFE_SPEED/10);
31
write_1602dat(0x30+SAFE_SPEED%10);
write_1602com(0x80+0x40+11);
break;
}
}
while(K3==0);
}
  if(K2==0&&K3==0&&Mode==0&bike_set==0)
{
BEEP=0;
delay(100);
BEEP=1;
delay(100);
BEEP=0;
delay(100);
BEEP=1;
delay(100);
Mileage=0;
SETS();
while(K2==0&&K3==0);
}
}
void BJ_SAFE()
{
if(Velocity>SAFE_SPEED)
BEEP=0;
}
else
{
BEEP=1;
}
}
void main()
{
//初始化
Ds1302_Init();
lcd_init();
initeeprom();
//读取初始参数
READS();
//定时器初始化
// InitTimer0();
init();
lcd_init();
before_sec=time_buf1[6];
while(1)
{
32
if(Mode==0&&bike_set==0)
{
display();
BJ_SAFE();
}
KEY();
}
void EXINT0() interrupt 0
{
count++;
}
void time0() interrupt 1
{
uchar m,n;
TH0=0x3c;
TL0=0xb0; //50ms
m++;
if(LED_SEC==1)
{
n++;
if(n>=10)
{
n=0;
LED_SEC=0;
}
}
if(m>=10)
{
m=0;
Mileage=Mileage+10*(Velocity/3.6)/2; //里程 m=里程+速度 km/h/3.6/2
  Velocity=count *2*3.14*RADIUS /100000*2*3600 /40;//将 500ms 的 距离经过运算得到km/h,将速度/100,
方便显示
count=0;
}
}
//读初值
void READS()
{
uchar Mileage_H,Mileage_M,Mileage_L;
delay(10);
RADIUS=read_add(0x01);
delay(10);
SAFE_SPEED=read_add(0x02);
delay(10);
Mileage_H=read_add(0x03);
delay(10);
Mileage_M=read_add(0x04);
delay(10);
Mileage_L=read_add(0x05);
  Mileage=Mileage_H*100000+Mileage_M*1000+Mileage_L*10;
}
//写初值
void SETS()
delay(10);
write_add(0x01,RADIUS);
delay(10);
write_add(0x02,SAFE_SPEED);
/* Mileage_H=Mileage/10000; //123.4560
Mileage_M=Mileage%10000/100;
Mileage_L=Mileage%10000%100; */ delay(10);
write_add(0x03,Mileage/100000);
delay(10);
write_add(0x04,Mileage%100000/1000);
delay(10);
write_add(0x05,Mileage%100000%1000/10);
}

第四章实物制作与调试

4.1系统仿真调试
  PROTEUS系统软件模拟仿真服务平台和软件开发平台由美Labcenter企业开发设计,是当前世界最详细的系统开发和模拟仿真服务平台之一。PROTEUS可以完成微控制系统及外接设备的数字电路设计、数字集成电路、混和电控系统的全部作用,系统软件协同模拟仿真,电路原理图制作,PCB设计等。PROTEUS手机软件是一个EDA专用工具,可以即时模拟仿真、调节和检测各种各样CPU。真真正正完成了没有目标原形的系统软件调节和认证。电路原理设计构思好,程序流程编好以后,再开展系统软件模拟仿真。电路原理图的实际设计过程如图2.9所示。
  当制作原理图布线完成后,利用PROTEUSISIS编辑环境所提供的电器规则检查命令对设计进行检查,并根据系统提供的错误检查报告修改原理图。直到通过电器规则检查为止。
  模拟仿真单片机系统软件是PROTEUSVSM的一大特点。与此同时,该模拟仿真系统软件将源码的编写和编译程序集成化到同一个设计方案自然环境中,客户可以在制定中立即编写编码,因而非常容易见到客户改动的危害。源代码通过编译无误后,就可以进行仿真,在仿真过程中不断完善电路和程序的功能最后达到本次设计的目的。仿
真图如3.0所示。在这里插入图片描述

图2.9 系统设计流程图
图3.0仿真图在这里插入图片描述

4.2实物制作
通过proteus,keil编程,用pcb绘制电路图,将给个元器件对准引脚逐个焊接,在焊接过程中注意单片机的引脚顺序,正负极不能接反,焊接完成后进行调试,最终实现显示时间,速度里程的功能。如图2.9所示。
在这里插入图片描述

图2.9实物焊接图
4.3调试与故障
1.实物调试故障与解决方法
•故障:按住电源总开关没有反映,用手触碰重设引角的时候会表明。
•解决方法:加上开关电源重设电源电路就可表明。
•故障:按住开关电源显有环形一圈的行程。
•解决方法复位程序流程后加上正确引导程序流程解决了启动的显示行程问题。
2.软件仿真调试故障与解决方法
•故障:数码管不显示。
•解决方法本次设计的电源电路的数码显示管选用共负极联接,进行仿真过程中错用共阳极数码管,造成数码管不会显示。
•故障:P0口显示高阻态。
•解决方法:端口P0的输出应当在高(鲜红色)和低(深蓝色)中间转换,但事实上,端口P0发生高阻态(深灰色)。接收数据后,发觉端口P0应联接到I/O端口的上拉电阻。提升上拉电阻后,端口P0的输出正常的。

结论

单车的功能性选用了许多当代智能技术性,根据这种智能产品的运用,可以在现实生活中完成单车的智能化系统作用,单车愈来愈融入当代工艺的发展趋势,有利于单车的将来获得极大优点。单片机设计的智能自行车里程数的设计得到了很大程度的完善和更新,是单车开发设计流程中的关键里程碑式。根据系统对开展特殊调节并模拟仿真备吉果,愈来愈贴近期望的试验实际效果,偏差操纵起着关键功效,可以合理地提升智能自行车的转速。文中设计了根据51单片机设计的简易自行车码表,制做简易便捷。针对喜爱骑单车的学生而言,只需花极少的钱,就可以自己做那样的码表。尤其是针对机械专业、电气类、电子信息工程技术专业的同学而言,自己制作编码表不但可以感受自身的专业技能,还能够感受骑着马的快乐,这对健身运动和学习培训有不错的协助,具备一定的实际意义。现阶段许多里程数转速计的设计全是脚踏式或仿真模拟数字电路设计,这类里程计的不足之处是体型小、精密度低、不形象化、功能损耗大、作用少。反过来,单片机设计有着体型小、控制力强等优势,因而由单片机的里程数具备多功能性、功能损耗、携带式等特性,里程数可以精确、即时地表明现在时间、总里程数、里程、加速度、平均速率等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值