1、目 录 1 设计任务与调研 1 1.1设计目的 1 1.2 设计的思路、方法 1 1.3 调研的目的和总结 2 2 设计过程与说明 4 2.1硬件设计 4 2.2 传感器的模块 9 2.3软件设计 10 3 设计成果简介 12 3.1总电路图 12 3.2 Proteus仿真 12 3.3技术指标 13 3.4作品特点 13 3.5附录:程序 13 4 结束语 28 1 设计任务与调研 自行车是人类发明的最成功的一种人力机械,是由许多简单机械
2、组成的复杂机械。 自行车,具有100多年的历史,由于环保以及交通的问题,是世界各国特别是发达国家居民喜爱的交通、健身工具,世界自行车行业的重心正从传统的代步型交通工具向运动型、山地型、休闲型转变。随着中国居民生活水平的不断提高,自行车不再仅仅是普通的运输、代步的工具,而是成为人们娱乐、休闲、锻炼的首选。因此,人们希望自行车的功用更强大,能给人们带来更多的方便。像是摩托车或是称霸中国的交通工具电动自行车也是有自行车演变而来。而现在的中国因为污染严重雾霾难治理,越来越提倡绿色出行,自行车无疑是最为方便绿色的出行工具,自行车对地形要求较低可以说是有路就能跑,在新中国发展初期甚至作为一种家庭必须品。
3、近两年来市场也出现了共享自行车给居民带来极大出行便利也减少交通压力。 自行车里程表是用于远距离连续测量自行车行驶速度和距离的仪表。它分为传感器、单片机和显示器三部分。目前,里程表普遍使用在汽车和摩托车上, 是一种机械测量装置,测试精度相对低,自行车上使用里程表的还很少见。针对这种情况,研制数字化里程表用于自行车上是非常有必要的用处也是十分广泛。 自行车简易数字里程表作为自行车的一大辅助工具也随着这个需求而面世,其功能也逐渐从单一的里程显示发展到速度、时间显示。然而因为自行车大小重量的局限性自行车的码表并没有汽车、摩托车码表的功能复杂,相对的体积也更加小巧。通过码表的功能我
4、们能像运动员一般能够监测一天的运动量、骑行最快速度。 1.1设计目的 (1) 设计一个可以适用各种自行车的数字里程表 (2) 码表可显示骑行里程。 (3) 码表可显示实时速度。 (4) 里程表带有超速报警功能。 (5)学习、了解自行车数字里程表的基本工作原理。 1.2 设计的思路、方法 本次设计中采用单片机作为处理核心,用霍尔传感器将车轮的转数转换为电脉冲,进行处理后送入单片机。里程及速度的测量,是经过51单片机的定时/计数器测出总的脉冲数和每转一圈的时间,再经过单片机的计算得出,其结果通过LED显示器显示出来。结合高精度的采样电路、控制电路、显示电路,方便地实现了智能化、高
5、精度、高可靠性、高效率的自行车里程表的设计,并且使用方便。 以AT89C51为核心,搭建数据采集模块(霍尔传感器采集数据、键盘矩阵)、控制模块(AT89C51)、显示模块。 数据采集 AT89C51 显示 外部信号 图1-1 系统框图 用单片机设计一个可以适用各种自行车的数字里程,表实现自行车在行驶过程中速度,里程数和时间的显示功能。 通过数据采集,单片机控制系统搭建,液晶显示和键盘输入实现设计目标。 其中数据的采集由霍尔传感器来完成,其中关键的处理由单片机系统来完成,输出的信号由液晶进行显示,显示
6、当前的行驶里程情况。 最后利用Proteus的交互式仿真功能,用户可以清楚的观察电路的工作情况,确认设计方法以及结果无误。 假定轮圈的周长为L,在轮圈上安装a个永久磁铁,则测得的里程值最大误差为L/a。经综合分析,本设计中取a=1。当轮子每转一圈,通过开关型霍尔元件传感器采集到一个脉冲信号,并从引脚P3.2中断0端输入,传感器每获取一个脉冲信号即对系统提供一次计数中断。每次中断代表车轮转动一圈,中断数n与轮圈的周长L的乘积为里程值。计数器T1计算每转一圈所用的时间time,就可以计算出即时速度speed。若自行车超过限定速度,系统发出报警信号,蜂鸣器响。 1.3 调研的目的和总结
7、 60、70年代,自行车已经在人们的生活中占有重要位置,缝纫机、手表、自行车被列为三大件,成为一个家庭是否富裕的象征。据父辈讲,这是女孩子当时找婆家的首要物质条件,是为姑娘出嫁时一份倍有面子的嫁妆。如果有人骑上自行车,后面都会引来一群驻足羡慕的眼神。而且那时凭票购买自行车后需及时向当地派出所登记上牌,另如谁家的自行车丢失了,公安局、派出所也会立刻派人侦破。随着时代的进步、科技的发展,汽车在越来越多的家庭中开始普及,从而导致了环境污染与交通拥堵,所以人们又重新开始重视自行车这种无能源消耗的交通工具,政府也倡导文明绿色的出行方式,所以现在为了能更好的向社会推广这种出行方式,各地也频出奇招,例如市
8、面普及的共享单车,它是无桩借还车模式的智能硬件,人们通过智能手机就能快速租用和归还一辆共享单车,用可负担的价格来完成一次几公里的市内骑行。在现代智能手机虽有计步功能也有gps定位,但是并不精准,在专业的自行车运动员的车上依旧使用的是传统的码表。将来码表里面记录的数据可任意上传至手机发到朋友圈,实现远程尽速,以后可以和全世界的自行车爱好者来一场不同时间不同地方的耐力赛和自己差不多水平的自行车手一起训练。 设计自行车数字里程表,功能包含:数码管显示速度、里程;通过按键设定报警速度;可以通过按钮实现速度的加、减;超过预定速度报警;复位按钮可以实现里程计复位,清“0”按钮实现里程清“0”。
9、 2 设计过程与说明 2.1硬件设计 本设计的任务是:以通用MCS-51单片机为处理核心,用传感器将车轮的转数转换为电脉冲,进行处理后送入单片机。里程及速度的测量,是经过MCS-51的定时/计数器测出总的脉冲数和每转一圈的时间,再经过单片机的计算得出,其结果通过LED显示器显示出来。 2.1.1单片机模块 单片机是指一种集成在电路芯片上的微型计算机,它包括中央处理器CPU、随机存储器RAM、只读存储器ROM、并行I/O口、串行I/O口、中
10、断系统、定时器/计数器、定时电路及元件等部件集成到一块芯片上构成的一个小而完善的计算机系统。 51系列单片机的优点及各种51单片机的简单比较 51系列优点之一是它从内部的硬件到软件有一套完整的按位操作系统,称作位处理器,或布尔处理器。它的处理对象不是字或字节而是位。它不光能对片内某些特殊功能寄存器的某位进行处理,如传送、置位、清零、测试等,还能进行位的逻辑运算,其功能十分完备,使用起来得心应手。虽然其他种类的单片机也具有位处理功能,但能进行位逻辑运算的实属少见。 51系列在片内RAM区间还特别开辟了一个双重功能的地址区间,十六个字节,单元地址20H~2FH,它既可作字节
11、处理,也可作位处理(作位处理时,合128个位,相应位地址为OOH~7FH),使用极为灵活。这一功能无疑给使用者提供了极大的方便,因为一个较复杂的程序在运行过程中会遇到很多分支,因而需建立很多标志位,在运行过程中,需要对有关的标志位进行置位、清零或检测,以确定程序的运行方向。而实施这一处理(包括前面所有的位功能),只需用一条位操作指令即可。对周围的其他位不会产生影响。 有的单片机并不能直接对RAM单元中的位进行操作,如AVR系列单片机中,若想对RAM中的某位置位时,必须通过状态寄存器SREG的T位进行中转。51系列的另一个优点是乘法和除法指令,这给编程也带来了便利。八位除以八位的除法
12、指令,商为八位,精度嫌不够,用得不多。而八位乘八位的乘法指令,其积为十六位,精度还是能满足要求的,用的较多。作乘法时,只需一条指令就行了,即MuL AB(两个乘数分别在累加器A和寄存器B中。积的低位字节在累加器A中,高位字节在寄存器B中)。很多的八位单片机都不具备乘法功能,作乘法时还得编上一段子程序调用,十分不便。 在51系列中,还有一条二进制一十进制调整指令DA,能将二进制变为BCD码,这对于十进制的计量十分方便。而在其他的单片机中,则也需调用专用的子程序才行。 AT89C51单片机的介绍 AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPE
13、ROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。(1).主要特性: 1. 与MCS-51 兼容 2.4K字节可编程闪烁存储器 寿命:1000写/擦循环 数据保留时间:10年 3.全静态工作:0Hz-24Hz 4.三级程序存储器
14、锁定 5.128*8位内部RAM 6.32可编程I/O线 7.两个16位定时器/计数器 8.5个中断源 9.可编程串行通道 10.低功耗的闲置和掉电模式 11.片内振荡器和时钟电路 (2).管脚说明: VCC:供电电压。 GND:接地。 P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双
15、向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据
16、存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。 P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。 P3口也可作为AT89C51的一些特殊功能口,口管脚 备选功能 P3.0 RXD(串行输入口) P3.1 TXD(串行输出口) P3.2 /INT0(外部中断0) P3.3 /INT1(外部中断1) P3.4 T0(记时器0外部输入) P3.5 T1
17、记时器1外部输入) P3.6 /WR(外部数据存储器写选通) P3.7 /RD(外部数据存储器读选通) P3口同时为闪烁编程和编程校验接收一些控制信号。 RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。 ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址
18、上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。 /PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。 /EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。 XTAL1:
19、反向振荡放大器的输入及内部时钟工作电路的输入。XTAL2:来自反向振荡器的输出。 图2-1 单片机 电源电路:20脚是地GND, 40脚是电源VCC,一般我们会选择在电源VCC处,加一个瓷片电容,它的目的是能滤掉电源中的高频杂波,使系统更加安全。需要注意的是51单片机使用的是5伏直流电源。 时钟电路: AT89C51片内有一个用于构成振荡器的反相放大器,该反相放大器的输入为芯片引脚XTAL1(19脚),输出端为引脚XTAL2(18脚),这两个引脚通过连接
20、一个12MHz晶振X1和两个30pF的瓷片电容C1、C2,构成了单片机的时钟电路。振荡器是单片机系统正常工作的保证,如果振荡器不起振,系统将会不能工作;假如振荡器运行不规律,系统执行程序的时候就会出现时间上的误差,这在通信中会体现的很明显:电路将无法通信。晶振是石英晶体振荡器的简称,通常用来构成振荡电路,产生各种频率信号。是一种能够输出稳定的震荡周期的元件,通过晶振输出的时钟脉冲,来安排单片机的工作,这样单片机才能够有了时间的概念。但是晶振并不能够独立的使用,图中的瓷片电容C1和C2起稳定作用,所以晶振必须配合合适的负载电容,否则会产生错误,或者是晶振不能正常的工作。晶振所加电容是匹配电容,主
21、要是根据单片机内部电路和晶振确定的,一般选取30pF左右即可,电容大小对振荡的稳定性有较大影响,对频率有一定的微调,但不明显。晶振和瓷片电容是没有正负的,注意两个瓷片电容相连的那端一定要接地。51单片机最小系统晶振的振荡频率直接影响单片机的处理速度,频率越大处理速度越快。 图2-2 时钟电路 复位电路:AT89C51单片机的复位信号时高电平有效,通过RST/VPD(9脚)连接复位电路,复位电路连接方式有两种。1)上电复位:单片机接通电源时产生复
22、位信号,完成单片机启动,确定单片机起始工作状态。2)手动复位:手动按键产生复位信号,完成单片机启动,确定单片机的初始状态。通常在单片机工作出现混乱或“死机”时,使用手动复位可实现单片机的“重启”。上电复位是每个单片机都必须有的,一般断电以后,再上电就复位了,而手动复位在大型的系统中运用比较多,在一般的小东西里面基本不用,所以本设计采用了上电复位方式。 本设计的复位电路是由一个10uF的电容C3和一个10K的电阻R1组成的。一般单片机复位脚至少需要大约10ms时间的持续高电平脉冲,才能保证有效复位。当上电时,电容充电,类似于短路,复位脚就变成高电平,电容充满电后,复位脚就变成低电平。
23、同时应注意保证加在RST 引脚上的高电平持续两个机器周期,才能使单片机可靠复位。 图2-3 复位电路 复位是使CPU 和系统中其他部件都处于一个确定的初始状态,并从这个状态开始工作。51系列单片机通常采用上电复位、手动复位、上电+手动的混合复位等方式。而本设计采用上电复位方式,其实质是一阶充放电电路,系统上电时该电路将提供有效的复位信号RST(高电平)直至系统电源稳定后撤销复位信号(低电平)。同时应注意保证加在RST 引脚上的高电平持续两个机器周期,才能使单片机可靠复位。 中断系
24、统 中断源:引起中断的根源 中断请求:中断源向CPU提出的处理要求 中断响应过程:CPU中断事件A,转去执行事件B的过程 中断处理:对事件B的整个处理过程 中断返回:CPU处理完事件B返回到原事件A被中断的地方继续执行实现上述中断功能—中断系统。 AT89C51有5个中断源,2个优先级。 显示模块 显示设计采用LM016L液晶模块,该点阵的屏显成本相对较低,适用于各类仪器,小型设备的显示领域。在本设计中用来显示速度、路程。LCD模块引脚及功能如下 图2-4 液晶模块
25、LM016L引脚 VSS:接地 VDD(VCC):电源电路,+5V VEE(VO):液晶驱动电压 RS:寄存器选择(为“1”时,选数据寄存器DR,为“0”时选指令寄存器IR) RW:读写信号 E:使能,片选,下降沿触发 DB0-DB7:数据线 报警设计 报警设计中当即时速度超过固定值时,指示灯D1会发亮,提示需要减速 2.2 传感器的模块 里程测量传感器的选择方案有:使用编码器对自行车车轮的圈数进行测量、可做选择的传感方式有两种 1.使用红外光敏电阻对里程进行测量。 2.利用霍尔传感器对自行车里程进行测量。 在本次毕业设计中我选择了霍尔传感
26、器,因为红外光敏电阻不仅对光敏感,还对环境和天气的要求也高,这些因素都能严重影响测量的效果,如果装在自行车辐条上的红外光敏原件被路面污泥覆盖就会出现测量不出的结果。 而霍尔传感器完全能避免上述的不足之处,由霍尔元件加整形电路构成的霍尔开关系统,不仅安装方便,不受光线和环境的影响,而且具有输出响应快,数字脉冲性能好,既简单又经济适用,所以本设计采用霍尔传感器来对里程进行测量。 霍尔传感器 霍尔传感器是根据霍尔效应制作的一种磁场传感器。霍尔效应是磁电效应的一种,这一现象是霍尔(A.H.Hall,1855-1938)于1879年在研究金属的导电机构时发现的。后来发现半导体、导
27、电流体等也有这种效应,而半导体的霍尔效应比金属强得多,利用这现象制成的各种霍尔元件,广泛地应用于工业自动化技术、检测技术及信息处理等方面。霍尔效应是研究半导体材料性能的基本方法。通过霍尔效应实验测定的霍尔系数,能够判断半导体材料的导电类型、载流子浓度及载流子迁移率等重要参数。 当一块通有电流的金属或半导体薄片垂直地放在磁场中时,薄片的两端就会产生电位差,这种现象就称为霍尔效应。两端具有的电位差值称为霍尔电势U,其表达式为 U=K·I·B/d,其中K为霍尔系数,I为薄片中通过的电流,B为外加磁场的磁感应强度,d是薄片的厚度,由此可见,霍尔效应的灵敏度高低与外加磁场的磁感应强度成正比的关
28、系。而利用霍尔效应制成的元件叫做霍尔元件. 图2-5 霍尔元件接线图 图2-6 霍尔传感器 2.3软件设计 所谓的软件设计就是指把软件需求变换成软件具体设计方案(即模块化结构)的过程。模块化结构设计是指根据要求和硬件设计的结构,将整个系统的功能分成多个小的功能模块,再根据小的功能模块进行程序编写的过程。所以在本设计中的软件设计的思想主要是模块化设计,包括一个主模块和三个子模块(数据采集子模块、控制子模块、LCD显示子模块),对各个子模块进行逐一设计,主模块完成对各个子模块的初始化,调用控制子模块、显示子模块。数据采
29、集子模块采用中断方式工作,同时在编程中采用C语言编写,使用了许多技巧,使运算做到高精度、快速。 开始 初始化液晶模块 中断时间是否到 重新设置中断时间 计算速度和里程 显示内容 N Y Y
30、 图2-7主程序流程图 延时 、 显示内容 设置显示位置 初始化 开始 图2-8 显示流程图 开始 计算速度 是否超速
31、 Y N 显示速度 报警 返回 图2-9速度处理流程图 3 设计成果简介 3.1总电路图 3.2 Proteus仿真 Proteus中的电路仿真是在ISIS 原理图设计模块中延续下来的,利用Proteus的交互式仿真功能,用户可以清楚的观察电路的工作情况。Proteus原理图仿真分析的首要任务是从元件库中选取绘
32、制电路所需元件,查找所需元件,将元件放置在绘图区,同时编辑元件的参数,然后连线。再利用电器规则对设计进行检查直到通过其检查为止。在源代码通过编译无误后就可以进行仿真。 3.3技术指标 IEC国际电工委员会标准IEC60310:2004; GB3797-2005电气控制设备; 维修电工-国家职业技能标准(2009)年修订。 3.4作品特点 本设计的自行车码表具有市面上码表的基础功能,显示实时速度、骑行里程、显示年月日。还新加了超速报警功能,更加广泛适用安全可靠。 操作简单,显示读数清晰明了适合大范围人群。 由于自己的技术水
33、平和时间关系,本次设计并不是十分完美,外观粗糙,只能实现基础功能,希望以后有机会做复杂功能的装备。
3.5附录:程序
#include
34、M1 1100 001R/W ....... RAM30 1111 110R/W ********************/ sbit clk = P1^3; //ds1302时钟线定义 sbit io = P1^4; //数据线 sbit rst = P1^5; //复位线 uchar code write_add[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a}; //写地址 uchar code read_add[] ={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b}; //读地址 uchar
35、code init_ds[] ={0x55,0x17,0x15,0x01,0x01,0x13,0x13}; uchar miao,fen,shi,ri,yue,week,nian; uchar i; uchar t1_num,t2_num; //计时间中断的次数 unsigned long speed1,juli,time2; float f_hz ,speed_km,speed_m; //dlaout time1 ,speed_km,speed_m; uchar TH11,TL11; uchar flag_en; //开始计算速度使能 uchar flag_stop_
36、en; //要确定车子是否停下了 uint juli_s; //每秒走的距离 uint juli_z; //总路程 float zhijing = 0.55; //直径 0.55M bit flag_1s = 1; //1s uchar menu_1; //菜单设置变量 uchar menu_2; //菜单设置变量 long zong_lc; //总量程 uchar flag_200ms; uint shudu; //定义速度的变量 uint bj_shudu = 80; //报警速度
37、 //这三个引脚 sbit rs=P1^0; //寄存器选择信号 H:数据寄存器 L:指令寄存器 sbit rw=P1^1; //寄存器选择信号 H:数据寄存器 L:指令寄存器 sbit e =P1^2; //片选信号 下降沿触发 uchar code table_num[]="0123456789abcdefg"; uchar i; sbit beep = P3^7; //蜂鸣器IO口定义 /******************1ms 延时函数*******************/ void delay_1ms(uint q) { uint i,
38、j;
for(i=0;i 39、
byte_write(0x2004, zong_lc / 256 / 256 % 256);
byte_write(0x2055, a_a);
}
/******************把数据从单片机内部eepom中读出来*****************/
void read_eeprom()
{
uint value;
bj_shudu = byte_read(0x2001);
bj_shudu <<= 8;
bj_shudu |= byte_read(0x2000);
zong_lc = byte_read(0x2004);
zong_lc <<= 16 40、
value = byte_read(0x2003);
zong_lc |= (value << 8);
zong_lc |= byte_read(0x2002);
a_a = byte_read(0x2055);
}
/**************开机初始化保存的数据*****************/
void init_eeprom() //开机初始化保存的数据*
{
read_eeprom(); //先读
if(a_a != 1) //新的单片机初始单片机内问eeprom
{
bj_shudu = 50;
a_a = 1;
write_e 41、eprom(); //保存数据
}
/********************************************************************
* 名称 : delay_uint()
* 功能 : 小延时。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay_uint(uint q)
{
while(q--);
}
/********************************* 42、
* 名称 : write_data(uchar dat)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void write_data(uchar dat)
{
i =0;
e=0;
rs=1;
rw=0;
P0=dat;
delay_uint(3);
e=1;
delay_uint(25);
e=0;
43、
}
/********************************************************************
* 名称 : write_sfm4(uchar hang,uchar add,uchar date)
* 功能 : 显示2位十进制数,如果要让第一行,第五个字符开始显示"23" ,调用该函数如下
write_sfm1(1,5,23)
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
*********************************************************************** 44、/
void write_sfm4(uchar hang,uchar add,uint date)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
write_data(0x30+date/10000%10);
write_data(0x30+date/1000%10);
write_data('.');
write_data(0x30+date/100%10);
write_data(0x30+date/10%10);
write_data(0x30+date%10);
write_ 45、data('k');
write_data('m');
}
void write_sfm7(uchar hang,uchar add,uint date)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
write_data(0x30+date/100000%10);
write_data(0x30+date/100000%10);
write_data(0x30+date/10000%10);
write_data(0x30+date/1000%10);
write_data(' 46、');
write_data(0x30+date/100%10);
write_data(0x30+date/10%10);
write_data('k');
write_data('m');
}
/***********************lcd1602上显示两位十进制数************************/
void write_sfm2_ds1302(uchar hang,uchar add,uchar date)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
47、
write_data(table_num[date / 16]);
write_data(table_num[date % 16]);
}
/*****************控制光标函数********************/
void write_guanbiao(uchar hang,uchar add,uchar date)
{
if(hang==1)
write_com(0x80+add);
else
write_com(0x80+0x40+add);
if(date == 1)
write_com(0x0f); //显示光标并且闪烁
else
48、write_com(0x0c); //关闭光标
}
/********************************************************************
* 名称 : init_1602()
* 功能 : 初始化1602液晶
* 输入 : 无
* 输出 : 无
***********************************************************************/
void init_1602() //1602初始化
{
write_com(0x38);
write_com(0x0 49、c);
write_com(0x06);
delay_uint(1000);
write_string(1,0,"sd:00km/h 00:00");
write_string(2,0,"lc:00.00km ");
}
// E309R
/*************写一个数据到对应的地址里***************/
void write_ds1302(uchar add,uchar dat)
{
rst = 1; //把复位线拿高
for(i=0;i<8;i++)
{ //低位在前
clk = 0; //时钟线拿低开始写 50、数据
io = add & 0x01;
add >>= 1; //把地址右移一位
clk = 1; //时钟线拿高
}
for(i=0;i<8;i++)
{
clk = 0; //时钟线拿低开始写数据
io = dat & 0x01;
dat >>= 1; //把数据右移一位
clk = 1; //时钟线拿高
}rst = 0; //复位线合低
clk = 0;
io = 0;
}
/*************从对应的地址读一个数据出来***************/
uchar read_ds1302(uchar add)
{
u






