|
多功能自行车测速仪
参赛作品名称:多功能自行车测速仪 参赛作者单位:北京大学 参赛作者:
崔健 邮编:
100871 非常抱歉!由于本文图片较多,word和htm格式有所区别, 转换的时候容易出现问题,为此图片有些丢失,为此请在这里下载本文完整的word文档!
目录 一、作品设计背景……………………………………2 二、作品功能简介……………………………………2 三、系统硬件设计……………………………………3 四、MCU软件设计……………………………………8 五、上位机软件bike
V1.0设计……………………8 六、作品实物及测试…………………………………10 6.1<测速模式>……………………………………13 6.2<数据传输>……………………………………14 6.3<其它功能>……………………………………15 6.4<退出系统>……………………………………16 七、结语………………………………………………16 附录1
电路图…………………………………………17 附录2
源程序…………………………………………18
多功能自行车测速仪使用说明书 一、产品设计背景 随着人们生活水平的逐渐提高,人们对于生活质量的要求也日益增加,尤其是对健身的要求。自行车在中国普遍作为代步工具。而在国外,自行车却是一项十分受欢迎的健身运动。因为它无污染,价位低廉,老少皆宜。而且在运动过程中可以充分享受到大自然,对于忙碌的现代人来说,无疑是一种较好的放松方法。在中国这种情况也在慢慢发生变化。因此爱好自行车运动的人十分学要一款能测速的装置,以知道自己的运动情况。并根据外界条件,如温度,风速等进行适当的调节,已达到最佳运动的效果。
而对于自行车运动员来说,最为关心的莫过于一段时间内的训练效果。因为教练要根据一段时间内运动员的训练效果进行评估,从而进行适当的调整已使运动员达到最佳的状态。因此需要一种装置进行对训练中各种参数的测定记录。本作品就是针对此而设计的。 二、产品功能简介
并会逐渐对该软件加以升级,使其功能更加完善,以满足广大使用者的需求。
三、系统硬件设计 系统框图
通过传感器对外部物理量进行测量,再将物理信号转换为电信号,输入单片机,单片机对所输入的电信号进行处理,最后输出显示,并可以通过与上位机通讯将数据采集到电脑中。 本设计中用到的主要部件包括单片机AT89C52、DS12887时钟芯片、DS18B20温度传感器、欧姆龙公司的EE-SX671型光电传感器、MAX232通信芯片以及液晶显示器。
1、
时钟芯片DS12887 DS12887是美国达拉斯半导体公司最新推出的时钟芯片,采用CMOS技术制成,把时钟芯片所需的晶振和外部锂电池相关电路集于芯片内部。采用DS12887芯片设计的时钟电路勿需任何外围电路并具有良好的微机接口。DS12887芯片具有微功耗、外围接口简单、精度高、工作稳定可靠等优点,可广泛用于各种需要较高精度的实时时钟场合中。
这里我们将DS12887的数据线与单片机的P0口相连,将其片选线与P2.0相连,这样便可通过R0或R1寄存器实现时钟芯片与单片机的数据传输。注意在DS12887的RESET端应连接上电复位电路,因为只有当该脚保持低电平时间大于200ms,DS12887才能有效工作。DS12887的IRQ端脚为其中断信号输出口,低电平有效,可作微处理的中断输入。没有中断条件满足时,IRQ处于高阻态。IRQ线是漏极开路输入,要求外接上接电阻。时钟芯片的有多种中断处理方式,例如周期中断,闹钟中断,更新中断等,这里我们利用它的更新中断,即时间每过1秒中,DS12887的更新中断便会从IRQ端输出,而IRQ引脚则与单片机的INT1中断相连,这样每当DS12887发出时间上的中断请求单片机便可从它的INT1中断得知,随之立刻进入中断子程序,在这个中断程序中对光电传感器所发出的脉冲信号进行计数处理,这样就可以得到速度以及里程等所要测量的量。
由于在测速系统中时间的测定非常重要,因此DS12887可以说是本设计的核心部件,它的使用好坏直接影响着最终测量的精确度,所以在调试时务必细心,尽量在熟悉DS12887的各种功能后在开始编程。 2、
温度传感器DS1820
由于DS1820采用单总线结构因此外围电路非常简单,通过一上拉电阻R5即可与单片机相连。这里我们将DS1820的数据引脚DQ与单片机的T0口(即P3.4)相连,通过这条数据线接收温度测量值。 虽然DS1820的外围电路十分简单,但是凡事哪能完美,可以说这是以繁杂的编程换来的。DS1820以其严格而繁难的时序要求著称。因为它只有一根数据线,即数据与命令字都要在同一条线上传输,所以DS1820制定了严格的时序,大家在使用时务必严格按照说明书上的要求对其进行操作,否则时序要是不正确,DS1820就罢工。笔者在调试的时候大部分时间都花在了调试DS1820上。通过切身的体会,我觉的最好变一到两个通用的延时子程序,在DS1820的编程中就可以直接调用延时程序,以保证时序的准确。 3、EE-SX671型光电传感器
由电路图可知,将传感器的输出信号经过光耦接到单片机的T1口,再设定T1为计数器工作方式,这样就可以对所接收到的脉冲进行计数,进而计算出速度里程等。注意一定要将光电传感器的输出信号调好,使其成为标准的脉冲信号,这样T1计数器才能正常的工作。再调试的时候可先不接入EE-SX671,可先用信号发生器产生所需要的脉冲信号来进行模拟,待全部调试好后再接入EE-SX671。在使用EE-SX671之前最好用示波器看一下输出波形是否规整达到要求。一般情况下,输出的就是标准的脉冲信号,如果发现有点偏差可通过外连调理电路将其整理一番。而且最好用电压表的交流档打一下,看一下峰值,是否达到T1口的电平识别范围。
EE-SX671最后要安装到车上,所以事先最好准备一个易弯曲的铁片用螺母将其与EE-SX671连接然后在固定于车上,这样可以保证在车子行驶过程中不发生晃动。 4、
液晶显示 由于现在的液晶模块应用已经十分广泛,其使用方法大同小异,所以笔者不准备祥加介绍。大家可根据自己的熟悉程度自行选择显示器件。如果对于液晶不熟悉,完全可以使用数码管作为显示媒介。这里我把自己的液晶显示界面给大家看
开机画面 5、
电源 这里我们采用9V的电池供电,用LM7805进行稳压处理,将9V稳降到5V以供单片机以及各芯片使用。有条件的可以购买电源模块为系统供电。经测试9V电池完全可以满足实际需要。 6、与微机通信 笔者在设计该仪器时,想将所测得的数据传送到电脑中,再用高级语言对数据进行处理,比如速度,在绘制出速度曲线,这样对于教练或是广大自行车爱好者来说,就可以很清晰地看到自己在训练过程中的情况。
这里笔者采用大家熟知的串口通讯方式,采用MAX232作为电平转换芯片。相信大家已经很熟悉了,笔者就不赘述了。 四、MCU软件设计 这里采用汇编语言进行编程,软件的任务量比较大,涉及到计速算法,具体会在附录的源程序中详细说明,这里不多述了。 五、上位机软件bike
V1.0设计
在用高级语言处理上,笔者采用VB捆绑数据库将采集得数据转存入数据库中,这样就可以保存每一次的训练数据,以备日后查用。后来索性就编了一个小软件,除了上述功能外,还增加了一些对于自行车运动的常识和知识。 用串口线将测速仪与电脑连接后,即可进行数据的传输。在PC机上即可进行数据的接收处理,并可以转存入数据库。
本作品采用9V电池供电,使用时务必保证电池电量充足,将电池按要求接到系统电源接口处。
拨动开关,使系统工作,将出现如下开机画面:
开机画面 待系统自检4秒后便进入系统主菜单,如前图所示。共有四大功能模块: 1.
测速模式:系统的主工作界面,进行速度及相关量的检测 2.
数据传输:将所记录的数据传入PC机,再由配套软件 bike
v1.0进行处理,包括绘制曲线及转存入数据库 3.
其它功能:可以进行时间设定及查看版本信息 4. 退出系统:使系统进入节能休眠模式 各功能模块详细测试说明 【注】为方便叙述,将产品的功能按键从左自右依次定义为①号键、②号键、③号键、④号键。 (一)在主菜单下按①号键(SET)即进入<测速模式>,出现如下子菜单:
车型选择
在此子菜单下先进行车型的选择,您可以选择26型和275型两钟目前最常见的车型进行测量
按③号键可以返回主菜单 如按②号键即选择275型,系统会根据您的不同选择为您准确选定参数进行测量。紧接着会出现如下菜单: 采样频率设定 在本菜单中,询问您希望设定的采样频率,这样系统便会按照您的设定时间,每隔固定的时间便向系统内部的RAM中自动写入当前的速度值。在选定采样时间后系统便会进入主测量界面: 主测量界面 【注】此时确保您正确接入传感器,否则速度,里程便显示零
在此界面处,随时按下④号键(EXIT),系统便会返回主界面。 在采样时间设定处,当设定好时间后,系统会自动将内部存储单元清零。 (二)在主菜单下按②号键即进入<数据传输>,出现如下子菜单:
数据传输菜单 按①号键即进入数据传输模式,在您将测速仪与电脑连接后系统会自动将您刚才运动过程中存储在系统中的速度值传到电脑中以供处理。 按②号键,返回主菜单。 当画面显示【数据传输完毕!】时,表示数据已传输完毕,系统会自动返回主菜单。 【注】在进行数据传输时,为保证正确传输,请务必用串口线将测速仪与电脑连接牢靠。 (三)在主菜单下按③号键即进入<其它功能>,出现如下子菜单:
其它功能菜单 按①号键即进入<时间设定>,出现如下设定画面:
时间设定画面 此时按①号键可以选择修改单元,按②号键(UP),加值;按③号键(DOWN),减值。修改完毕后,按④号键确定,OK处光标闪烁反显,后返回上一级菜单。 (四)在主菜单下按④号键即进入<退出系统>,系统即进入节能休眠模式,系统出现如下画面 结束画面 在休眠模式下,按⑤号键(WAKE)即可激活唤醒系统。 六、结语 以上是对本产品的功能及使用说明。诚然,本次开发的这款产品还有许多亟待改进的地方。包括功能上及软件的设计上。 这是本人大三的时候开发的一个基于51单片机的作品,现在看来可以改进的地方很多,比如在体积上,可一选用更小封装的单片机,而且对于手持设备应该低功耗,比如可采用TI的430系列的单片机,这样就可以用钮扣电池供电,使用时间可以更长。 最后非常感谢本网站能举办这样的活动,这对于普及单片机技术以及提高广大爱好者的动手能力都非常有益! 附录1 电路
附录2
源程序 ;*******总程序******************* ;Controller:ST7920
;MCU:AT89C52
,晶体频率:11.0592MHz ;LCM:128*64 ;LCM型号:带中文字库的128X64-5ZK ;LCM
接口:1:GND 2:VCC 3:V0 4.RS 5:RW 6:E 7--14:DB0-DB7 15:PSB 16:NC 17:RST 18:Vout ;****************************************************** ;***********功能引脚命名******************************** D_PORT
EQU P1
;数据口 RS
EQU P2.1
;液晶指令与数据寄存器设置位 RW
EQU P2.2
;液晶读写控制位 E
EQU P2.3
;液晶使能端 COM
EQU 20H
;指令寄存器 DAT
EQU 21H
;数据寄存器 TD
EQU P3.4
;DS1820数据引脚 WAKE
EQU PSW.5
;液晶复位标志 FX_KEY
EQU PSW.1 ;液晶光标反显开关,FX_KEY=1一直反显;FX_KEY=0反显一次后关闭 ;******************相关使用单元说明***** ;25H光标移动计数器 ;2EH用来保护读时钟芯片的R0 ;22h用来存放时钟的BCD码 ;2DH用来存放修改时间时的汉字查询标志位 ;2FH存放温度十位 ;30H存放温度各位 ;85H用做判断使用内部RAM还是时钟RAM的标志位,0为内部,1为时钟 ;37H用做保存时钟芯片的RAM地址 ;84H用做保存内部RAM的地址 ;******************************************************
;****************里程和速度的基本命名****** TAB2
EQU 08H ;30H用来查汉字时钟表时使用 LUNZ_Z
EQU 09H ;31H中存轮周长整数部分 LUNZ_X
EQU 0AH ;32H中存小数部分 SPD_Z
EQU 0BH ;33H中存速度的整数部分 SPD_X
EQU 0CH ;34H中存小数部分 LC_Z
EQU 0DH ;35h中存里程的整数部分 LC_X
EQU 0EH ;36h中存小数部分 LC_JW
EQU 0FH ;37H中存里程计算时的一个小数向整数部分进位的标志位 SPD_SUM
EQU 10H ;38H中存速度的和(三妙内的) SPD_PDW
EQU 11H ;39H中存速度平均值的判断位(三次) LC_XZB
EQU 12H ;41H中存里程显示部分的整数的百位 LC_XZS
EQU 13H ;42H中存里程显示部分的整数的十位 LC_XZG
EQU 14H ;43H中存里程显示部分的整数的个位 LC_XSF
EQU 15H ;44H中存里程显示部分的小数的十分位 SPD_XZS
EQU 16H ;45H中存速度显示部分的整数的十位 SPD_XZG
EQ17H ;46H中存速度显示部分的整数的个位 SPD_XSF
EQU 18H ;47H中存速度显示部分的小数的十分位 KM_JW
EQU 19H ;48H中存里程向千米进位时的标志位 KM
EQU 1AH
;49H中存里程的公里数 CAI
EQU 1BH
;50H中是存采样频率的数值 QIAN_Z
EQU 1CH ;51H中存前一秒时的里程整数。(用于计算速度) HOU_Z
EQU 1DH ;52H中存现在时刻的里程的整数
(用于计算速度) QIAN_X
EQU 1EH ;53H中存前一秒时的里程小数;54H中存现在时刻的里程的小数。 HOU_X
EQU 1FH ;54H中存现在时刻的里程的小数。 QBZW_Z
EQU 23H ;55H中存里程整数部分前一秒时的进位标志位 HBZW_Z
EQU 24H ;56H存整数部分后一秒的进位标志位 QBZW_X
EQU 26H ;57H中存里程小数部分前一秒的进位标志位 HBZW_X
EQU 27H ;58H中存小数部分后一秒的进位标志位 SPD_SUMX
EQU 28H ;59H中存速度的平均值的小数部分 SDJS
EQU 29H ;61H中存:轮周长÷每周脉冲数 SD
EQU 2AH ;62H中存脉冲数和61h中相乘后的高八位 TEP
EQU 2BH
;63h中存的是主程序中判断是否到一分钟的标志位,用于读温度传感器 CUN
EQU 2CH
;64H中每到一秒加一,当和cai里的数相等时遍向ram中保存一个速度值 ;*****************程序地址编排****************
ORG 0000H
AJMP MAIN
;主程序入口
ORG 0003H
LJMP WAKE_UP
;INT0中断入口
ORG 0013H
LJMP SUDU
;INT1中断入口
ORG 001BH
LJMP JISUAN
;T1中断入口
;*********************主程序入口地址
ORG 0040H MAIN:
MOV
SP,#60H
MOV DPTR,#START
LCALL PIC_SHOW
;显示开始画面
LCALL TEMPER ;测试温度
MOV SPD_Z,#00H
MOV SPD_X,#00H
MOV LC_Z,#00H
MOV LC_X,#00H
MOV LC_JW,#00H
MOV
SPD_SUM,#00H
MOV SPD_PDW,#00H
MOV LC_XZB,#00H
MOV LC_XZS,#00H
MOV LC_XZG,#00H
MOV LC_XSF,#00H
MOV SPD_XZS,#00H
MOV SPD_XZG,#00H
MOV SPD_XSF,#00H
MOV KM_JW,#00H
MOV KM,#00H
MOV QBZW_Z,#00H
MOV HBZW_Z,#00H
MOV QBZW_X,#00H
MOV HBZW_X,#00H
MOV QIAN_Z,#00H
MOV HOU_Z,#00H
MOV QIAN_X,#00H
MOV HOU_X,#00H
MOV SPD_SUMX,#00H
MOV SD,#00H
MOV TEP,#00H
MOV TAB2,#00H ;相关单元的初始化
MOV CUN,#00H
MOV 2FH,#02H
MOV 30H,#09H
MOV R1,#85H
MOV @R1,#0
MOV 37H,#0EH
MOV R1,#84H
MOV @R1,#38H TIME:
CLR P2.0
;时钟芯片的初始化
MOV R0,#0AH
MOV A,#70H
MOVX @R0,A
MOV R0,#0BH
MOV A,#96H
MOVX @R0,A
MOV R0,#0CH
MOVX A,@R0
;基本寄存器的初始化
MOV R0,#00H
MOV A,#00H
MOVX @R0,A
;秒单元的初始化
MOV R0,#02H
MOV A,#00H
MOVX @R0,A
;分单元的初始化
MOV R0,#04H
MOV A,#00H
MOVX @R0,A
;时单元的初始化
MOV R0,#06H
MOV A,#05H
MOVX @R0,A
;星期单元的初始化
MOV R0,#07H
MOV A,#05h
MOVX @R0,A
;日单元的初始化
MOV R0,#08H
MOV A,#05H
MOVX @R0,A
;月单元的初始化
MOV R0,#09H
MOV A,#05H
MOVX @R0,A
;年单元的初始化
MOV R0,#0AH
MOV A,#20H
MOVX @R0,A
MOV R0,#0BH
MOV
A,#16H
MOVX @R0,A
;启动时钟芯片
;*****************以上是时钟芯片的初始化 ;***********主菜单显示模块**************ZHU_MENU:
LCALL INIT_LCM
MOV COM,#80H
MOV
DPTR,#STRING_ZHU
LCALL
PUT_STRING
CLR FX_KEY
;FX_KEY=0反显一次后关闭
clr EA
;关中断
SETB P2.4
SETB P2.5
SETB
P2.6
SETB P2.7 CHOICE_ZHU:
JNB P2.4,CESU_JUMP
JNB
P2.5,CHUANSHU_JUMP
JNB P2.6,FUNCTION_JUMP
JNB P2.7,EXIT_JUMP
AJMP CHOICE_ZHU CESU_JUMP:
LJMP CESU_MENU
;进入【测速功能】模块 CHUANSHU_JUMP:
LJMP CHUANSHU_MENU ;进入【数据传输】模块 FUNCTION_JUMP:
LJMP FUNCTION_MENU
;进入【其它功能】模块 EXIT_JUMP:
LJMP EXIT_MENU
; 【退出系统】 ;****************************************************** ;********************测速菜单 CESU_MENU:
MOV R4,#30
;反显第一行 LCALL
FANXIAN
;反显示主菜单中的【测速模式】项
LJMP
CESU ;******************************************************
CESU:
LCALL INIT_LCM
MOV COM,#80H
MOV DPTR,#STRING_CESU
LCALL PUT_STRING ;显示测速界面
MOV TMOD,#01100000B
;设定为方式2
MOV TH1,#224
MOV TL1,#224 ;装初值
CLR EA ;**********************以上是历程和速度的初始化
SETB P2.4
SETB P2.5
SETB P2.6
;准备读管脚
JUDGE:
JNB P2.4,LZC26
JNB P2.5,LZC275
JNB P2.6,RETURN1
AJMP JUDGE ;***********************以上是判断按键 LZC26:
MOV R4,#13
;反显第二行
LCALL FANXIAN
;反显示测速菜单中的【26型】项
MOV
LUNZ_Z,#2
MOV LUNZ_X,#73
MOV SDJS,#65
LJMP
SAMPLE_MENU LZC275:
MOV R4,#21
;反显第三行
LCALL
FANXIAN
;反显示测速菜单中的【275型】项
MOV LUNZ_Z,#02H
MOV LUNZ_X,#193
MOV SDJS,#68
LJMP SAMPLE_MENU RETURN1:
MOV R4,#05
;反显第四行
LCALL FANXIAN
;反显示测速菜单中的【退出】项
LJMP ZHU_MENU
;退出本级菜单,返回主菜单 ;************************测速菜单结束 ;*********************数据传输菜单 CHUANSHU_MENU: MOV
R4,#14
;反显第二行 LCALL FANXIAN
;反显示主菜单中的【数据传输】项
LCALL INIT_LCM
;重新初始化,显示【数据传输】菜单项 MOV
COM,#80H MOV
DPTR,#STRING_CHUANSHU LCALL
PUT_STRING
SETB
P2.4
SETB
P2.5
CHOICE_CHUANSHU:
JNB
P2.4,BEGIN_CHUAN JNB
P2.5,RETURN2 AJMP
CHOICE_CHUANSHU RETURN2:
MOV R4,#14
;反显第三行 LCALL
FANXIAN
;反显示数据传输菜单中的【退出】项
AJMP
ZHU_MENU BEGIN_CHUAN: MOV
R4,#06H
;反显第二行 LCALL FANXIAN
;反显示数据传输菜单中的【开始传输】项
LCALL INIT_LCM
;重新初始化,显示【正在传输....】 MOV COM,#91H MOV
DPTR,#START_CHUAN LCALL
PUT_STRING LCALL
delay1 LCALL
delay1 ;*******************通信传送模块
MOV
SCON,#40H
;方式1传输 MOV TMOD,#20H MOV
TL1,#0F4H
;设置2.4k波特率 MOV TH1,#0F4H MOV
PCON,#00H
;SMOD=0,波特率不加倍 CLR
TI CLR
P2.0 SETB
TR1
;T1开始计时 MOV
R2,#57
;传送57次 MOV
R0,#0EH
;时钟芯片的内部RAM起始单元 DO1: MOV
SBUF,2FH
;传送温度的高位 acall
delay10 CLR
TI MOV
SBUF,30H
;传送温度的低位 acall
delay10 CLR
TI MOVX
A,@R0
;传送速度的整数部分
MOV
SBUF,A
acall delay10
CLR
TI
INC R0
MOVX A,@R0
;传送速度的小数部分
MOV SBUF,A
acall delay10
CLR TI
INC R0
DJNZ R2,DO1
MOV R0,#38H
;单片机的内部RAM起始单元
MOV R2,#20
;传送20次
DO:
MOV SBUF,2FH
;传送温度的高位
acall delay10
CLR TI
MOV SBUF,30H
;传送温度的低位
acall delay10
CLR TI
MOV SBUF,@R0
;传送速度的整数部分
acall delay10
CLR TI
INC R0
MOV
SBUF,@R0 ;传送速度的小数部分
acall delay10
CLR TI
INC R0
DJNZ R2,DO
LCALL INIT_LCM
;重新初始化,显示【数据传输完毕!】
MOV COM,#91H
MOV DPTR,#FINISH_CHUAN
LCALL PUT_STRING
LCALL delay1
LCALL delay1
LJMP ZHU_MENU
DELAY10:
MOV R4,#20H D22:
MOV R5,#248
DJNZ R5,$
DJNZ R4,D22
RET
;************************数据传输菜单结束*********** ;***************************退出菜单
EXIT_MENU:
MOV R4,#06
;反显第四行 LCALL
FANXIAN
;反显示主菜单中的“退出系统”项
LCALL INIT_LCM
;重新初始化,显示关机画面 MOV
DPTR,#FINISH
LCALL PIC_SHOW
;显示关机画面
LCALL DELAY1
CLR WAKE MOV
COM,#34H
;功能设置--8BIT控制界面,扩充指令集
LCALL WRITE_COMMAND
LCALL DELAY
LCALL DELAY
MOV COM,#08H
;进入液晶休眠模式
LCALL WRITE_COMMAND
LCALL DELAY
LCALL DELAY
MOV IE,#81H
SETB IT0 JNB
WAKE,$
;等待INT0中断,判断液晶复位标志wAkE,wAkE=1,继续执行,wAkE=0,原地执行
AJMP ZHU_MENU
;返回主菜单显示 ;*************************退出菜单结束 ;************************采样菜单 SAMPLE_MENU:
LCALL INIT_LCM
;重新初始化,显示【数据传输】菜单项
MOV COM,#80H
MOV DPTR,#STRING_SAMPLE
LCALL PUT_STRING
SETB
P2.4
SETB P2.5
SETB P2.6 CHAXUN:
JNB P2.4,LIANG_MIAO
JNB P2.5,SANSHI_MIAO
JNB P2.6,LIUSHI_MIAO
AJMP CHAXUN LIANG_MIAO:
MOV R4,#11
LCALL FANXIAN
MOV CAI,#2
LJMP CLEAR1 SANSHI_MIAO:
MOV R4,#19
LCALL FANXIAN
MOV CAI,#30
LJMP CLEAR1 LIUSHI_MIAO:
MOV R4,#3
LCALL FANXIAN
MOV CAI,#60
LJMP CLEAR1 ;************************给所有单元清零
CLEAR1:
MOV SPD_Z,#0
MOV SPD_X,#0
CLR P2.0
MOV R1,#85H
MOV @R1,#0
MOV
37H,#0EH
MOV R1,#84H
MOV @R1,#38H ;清零的时候重新赋初值
CLEAR:
MOV R1,#85H
MOV A,@R1 ;85H用做判断使用内部RAM还是时钟RAM的标志位,0为内部,1为时钟
CJNE A,#1,NEIBURAM2
MOV R0,37H
;37H用做保存时钟芯片的RAM地址
CJNE R0,#128,TIMERAM2
MOV R1,#85H
MOV @R1,#0
MOV 37H,#0EH
MOV R1,#84H
MOV @R1,#38H ;清零完成后重新赋初值
LJMP
GZXIANS TIMERAM2:
MOV A,SPD_Z
MOVX @R0,A
INC R0
MOV A,SPD_X
MOVX @R0,A
INC R0
MOV 37H,R0
LJMP BUCUN1 NEIBURAM2:
MOV R1,#84H
;84H用做保存内部RAM的地址
MOV A,@R1
MOV
R0,A
CJNE R0,#60H,NEIBURAM11
MOV R1,#85H
MOV @R1,#1
LJMP BUCUN1 NEIBURAM11:
MOV @R0,SPD_Z
INC R0
MOV @R0,SPD_X
INC R0
MOV R1,#84H
MOV A,R0
MOV @R1,A
LJMP BUCUN1 BUCUN1:
LJMP
CLEAR ;**************************清零完毕 ;***************************采样菜单结束 ;******************************其它功能菜单
FUNCTION_MENU:
MOV R4,#22
;反显第三行
LCALL FANXIAN
;反显示主菜单中的【其它功能】项
FUNC_DOT:
LCALL INIT_LCM
;重新初始化,显示【其它功能】中的内容
MOV COM,#80H
MOV DPTR,#STRING_FUNCTION
LCALL PUT_STRING
SETB P2.4
SETB P2.5
SETB P2.6 CHOICE_FUNCTION:
JNB
P2.4,TIME_SET
;进入【时间设定】功能模块 JNB
P2.5,VERSION_MENU
;进入【产品信息】模块 JNB
P2.6,RETURN3 ;退出本级菜单 AJMP
CHOICE_FUNCTION RETURN3: MOV
R4,#03
;反显第四行
LCALL
FANXIAN ;反显示其它功能菜单中的【退出】项 AJMP
ZHU_MENU ;退出本级菜单,返回主菜单 VERSION_MENU: MOV
R4,#19
;反显第三行 LCALL FANXIAN
;反显示其它功能菜单中的【产品信息】项 MOV
COM,#80H MOV
DPTR,#STRING_VERSION LCALL
PUT_STRING
LCALL
DELAY1
LCALL
DELAY1 LCALL
DELAY1 LCALL
DELAY1 AJMP
FUNC_DOT
;4秒后自动其它功能菜单 ;******************************其它功能菜单结束 ;*******************************时间设定界面 TIME_SET:
MOV R4,#11
;反显第二行
LCALL FANXIAN
;反显[时间设定]项
SETB FX_KEY
CLR P2.0
MOV
R0,#0AH
;向A寄存器送命令
MOV A,#70H
MOVX @R0,A
MOV R0,#0BH
;向B寄存器送命令
MOV A,#86H
;禁止芯片工作,设定为二进制码格式,24小时模式
MOVX @R0,A
MOV R0,#0CH
;指向C寄存器
MOVX
A,@R0
;读C寄存器
LCALL INIT_LCM
;重新初始化,显示【时间设定】 MOV
COM,#80H
MOV DPTR,#STRING_TIME
LCALL PUT_STRING
TIME_DISP:
MOV TAB2,#00H
MOV COM,#90H
LCALL WRITE_COMMAND
MOV R0,#09H
LCALL BIN_BCD
LCALL TDISP
LCALL HANZI
MOV R0,#08H
LCALL BIN_BCD
LCALL TDISP
LCALL HANZI
MOV R0,#07H
LCALL BIN_BCD
LCALL TDISP
LCALL HANZI
MOV R0,#06H
LCALL BIN_BCD
LCALL TDISP
LCALL HANZI
MOV R0,#04H
LCALL BIN_BCD
LCALL TDISP
LCALL HANZI
MOV R0,#02H
LCALL BIN_BCD
LCALL TDISP
LCALL HANZI
MOV R0,#00H
LCALL BIN_BCD
LCALL TDISP
LCALL HANZI
MOV COM,#9FH
MOV DPTR,#STRING_OK
LCALL PUT_STRING ;******************以上界面显示********************** MOV
R4, #04 MOV
25H,#07 ;光标移动计数器,当为0时,要重新复位 SETB
P2.4
SETB P2.5 SETB
P2.6 SETB
P2.7
LCALL
FANXIAN FAN:
JNB
P2.4,xiaodou1 ajmp
j2 xiaodou1:mov
r0,#12 xiaodou11:
lcall
delay
djnz r0,xiaodou11 JNB
P2.4,gb_shift
j2:
JNB P2.5,xiaodou2
ajmp j3
xiaodou2:mov
r0,#10 xiaodou22:
lcall
delay
djnz r0,xiaodou22
JNB P2.5,time_add
j3:
JNB P2.6,
xiaodou3
ajmp j4 xiaodou3:mov
r0,#10 xiaodou33:
lcall
delay
djnz r0,xiaodou33
JNB P2.6,time_minus j4: JNB
P2.7,TIME_OVER AJMP
FAN
;*****************光标移动
GB_SHIFT: DJNZ
25H,LEFT_SHIFT MOV
25H,#07
MOV
R4,#12 GB_FUWEI:
MOV COM,#14H
;设定液晶的光标向右移动 LCALL
WRITE_COMMAND LCALL
DELAY LCALL
DELAY DJNZ
R4,GB_FUWEI
;R4为光标移动位数 AJMP
FAN LEFT_SHIFT: MOV
R4,#02 LCALL
FANXIAN
AJMP
FAN ;****************************************************** TIME_ADD:
MOV R2,#01H
ACALL UPDATE TIME_MINUS:
MOV R2,#00H
ACALL UPDATE TIME_OVER:
CLR
P2.0
MOV R0,#0AH
MOV A,#20H
MOVX @R0,A
MOV R0,#0BH
MOV
A,#16H
MOVX @R0,A
;启动时钟芯片
CLR FX_KEY
MOV COM,#02H
;光标重新回到原点
LCALL WRITE_COMMAND
LCALL DELAY
LCALL DELAY
MOV R4,#32
;设定光标向又移动32次 TIME_OVER1:
MOV COM,#14H
;设定液晶的光标向右移动
LCALL WRITE_COMMAND
LCALL DELAY
LCALL DELAY
DJNZ R4,TIME_OVER1
;R4为光标移动位数
mov r4,#01
lcall fanxian
AJMP ZHU_MENU
UPDATE:
MOV
R1,25H
CJNE R1,#07,MINUTE
LCALL BUSY
MOV R0,#00H
MOVX A,@R0
mov r6,#9ch
CJNE R2,#01H,DEC1
cjne a,#59,inc1
mov a,#00
ajmp
update1 inc1:
INC A
ajmp update1 DEC1:
cjne a,#00,d1
mov a,#59
ajmp update1 d1:
DEC A
ajmp update1
MINUTE:
CJNE R1,#06H,HOUR
LCALL BUSY
MOV
R0,#02H
MOVX A,@R0
mov r6,#9ah
CJNE R2,#01H,DEC2
cjne
a,#59,inc2
mov a,#00
ajmp update1 inc2:
INC A
ajmp update1 DEC2:
cjne a,#00,d2
mov a,#59
ajmp update1 d2:
DEC A
ajmp update1
HOUR:
CJNE R1,#05H,WEEK
LCALL BUSY
MOV
R0,#04H
MOVX A,@R0
mov r6,#98h
CJNE R2,#01H,DEC3
cjne
a,#23,inc3
mov a,#00
ajmp update1 inc3:
INC A
ajmp update1 DEC3:
cjne a,#00,d3
mov a,#23
ajmp update1 d3:
DEC A
ajmp update1
WEEK:
CJNE R1,#04H,DAY
LCALL BUSY
MOV
R0,#06H
MOVX
A,@R0
mov r6,#96h
CJNE R2,#01H,DEC4
cjne
a,#7,inc4
mov a,#01
ajmp
update1 inc4:
INC A
ajmp update1 DEC4:
cjne a,#01,d4
mov a,#07
ajmp update1 d4:
DEC A
ajmp update1
DAY:
CJNE R1,#03H,MONTH
LCALL BUSY
MOV
R0,#07H
MOVX
A,@R0
mov r6,#94h
CJNE R2,#01H,DEC5
cjne
a,#31,inc5
mov a,#01
ajmp update1 inc5:
INC A
ajmp update1 DEC5:
cjne a,#01,d5
mov a,#31
ajmp update1 d5:
DEC A
ajmp update1 MONTH:
CJNE R1,#02H,YEAR
LCALL BUSY
MOV R0,#08H
MOVX A,@R0
mov r6,#92h
CJNE R2,#01H,DEC6
cjne
a,#12,inc6
mov a,#01
ajmp update1 inc6:
INC A
ajmp update1 DEC6:
cjne a,#01,d6
mov a,#12
ajmp
update1 d6:
DEC A
ajmp update1
YEAR:
LCALL BUSY
MOV R0,#09H
MOVX A,@R0
mov r6,#90h
CJNE
R2,#01H,DEC7
INC A
ajmp
update1 DEC7:
cjne a,#00,d7
mov a,#00
ajmp update1 d7:
DEC A
ajmp update1
update1:
MOVX @R0,A
MOV COM,r6
LCALL WRITE_COMMAND
LCALL BIN_BCD
LCALL TDISP
MOV R4,#01
LCALL FANXIAN
AJMP FAN ;******************************时间设定界面结束 ;****************************工作显示界面 GZXIANS:
LCALL INIT_LCM
SETB IT1
SETB EA
SETB ET1
SETB TR1
;开T1中断,并开始计数
SETB EX1
SETB PX1
;开INT1中断 GZXIANS0:
MOV A,TEP
;TEP中存一个是否到一分中的标志
CJNE A,#30,GZXIANS1
MOV TEP,#00H
;到一分钟后就读温度传感器
LCALL TEMPER
GZXIANS1: ;************************第一行
MOV COM,#80H
MOV DPTR,#HANG1
LCALL PUT_STRING
;显示“$速度:”
MOV A,SPD_XZS
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示速度十位
MOV A,SPD_XZG
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示速度个位
MOV A,#10
;显示小数点
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
MOV A,SPD_XSF
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示速度的十分位
MOV A,#11
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示m
MOV A,#12
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示/
MOV A,#13
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示s ;************************第三行
MOV DPTR,#HANG3
LCALL DISP_STR_LOOP
;显示“(温度):”
MOV
R0,#09H
LCALL BIN_BCD
LCALL TDISP ;显示年里的数
MOV A,#10
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA ;显示.
MOV R0,#08H
LCALL BIN_BCD
LCALL TDISP ;显示月里的数
MOV A,#10
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA ;显示.
MOV R0,#07H
LCALL BIN_BCD
LCALL TDISP ;显示日里的数
;************************第二行
MOV DPTR,#HANG2
LCALL DISP_STR_LOOP ;显示“$里程:”
MOV A,LC_XZB
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA ;显示里程的百位
MOV A,LC_XZS
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA ;显示里程的十位
MOV A,LC_XZG
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA ;显示里程的个位
MOV A,#10 ;显示小数点
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV
DAT,A
LCALL WRITE_DATA
MOV A,LC_XSF
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示里程的十分位
MOV A,#14
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示K
MOV A,#15
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示M
;************************第四行
MOV DPTR,#HANG4
LCALL DISP_STR_LOOP
MOV A,2FH
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
MOV A,30H
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示温度的数值
MOV DPTR,#HANG5
LCALL DISP_STR_LOOP
MOV R0,#04H
LCALL BIN_BCD
LCALL TDISP
;显示时里的数
MOV A,#16
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示:
MOV R0,#02H
LCALL BIN_BCD
LCALL TDISP
;显示分里的数
MOV A,#16
MOV DPTR,#SHU
MOVC A,@A+DPTR
MOV DAT,A
LCALL WRITE_DATA
;显示:
MOV R0,#00H
LCALL BIN_BCD
LCALL TDISP
;显示秒里的数
SETB P2.7 ;**********;查询按键。若有则返回主菜单
JNB
P2.7,xiao4
LJMP GZXIANS0 xiao4:
mov
r0,#10 xiao44:
lcall delay
djnz
r0,xiao44
JNB
P2.7,TIAO ;*************;查询按键。若有则返回主菜单
LJMP
GZXIANS0 TIAO:
mov r0,#100 xiao55:
lcall delay
jnz
r0,xiao55
LJMP ZHU_MENU ;***************************工作显示界面结束 ;***************************【里程中断程序】
JISUAN:
MOV A,LUNZ_Z YICHU1:
CLR C
ADD A,LC_Z
MOV LC_Z,A
;计算里程的整数部分
JC KM_CHULI
AJMP NOJINW1 KM_CHULI:
INC KM_JW
INC HBZW_Z
;增加HBZW_Z中的数,以后计算速度时用
MOV A,HBZW_Z
CJNE A,#255,KM_CHULI1
MOV A,#255
CLR C
SUBB A,QBZW_Z
MOV HBZW_Z,A
MOV QBZW_Z,#0 ;标志位溢出时的处理
KM_CHULI1:
MOV A,KM_JW
CJNE A,#04H,NOJINW1
;判断是否该向公里处进1
MOV KM_JW,#00H
INC KM
MOV A,#24
AJMP YICHU1
NOJINW1:
MOV A,LUNZ_X YICHU2:
CLR C
ADD A,LC_X
;计算里程的小数部分
MOV LC_X,A
JC LC_CHULI ;看是否有溢出
AJMP NOJINW2 LC_CHULI:
INC LC_JW
INC HBZW_X
;增加HBZW_X中的数,计算速度时用
MOV A,HBZW_X
CJNE A,#255,LC_CHULI1
MOV A,#255
CLR C
SUBB A,QBZW_X
MOV HBZW_X,A
MOV QBZW_X,#0 ;标志位溢出时的处理 LC_CHULI1:
MOV A,LC_JW
CJNE A,#04H,HUIJIA
;判断小数部分是否进四次位,是否应该向整数部分进1
MOV LC_JW,#00H
MOV A,LC_Z
CLR C
ADD A,#01H
;加一以后再判断整数部分是否有溢出
MOV LC_Z,A
JNC HUIJIA PANDUAN:
INC KM_JW
INC HBZW_Z
;增加HBZW_Z中的数,以后计算速度时用
MOV A,KM_JW
CJNE A,#04H,HUIJIA
;判断是否该向公里处进1
MOV KM_JW,#00H
INC KM
MOV A,#24
CLR C
ADD A,LC_Z
MOV LC_Z,A
JC PANDUAN HUIJIA:
MOV A,#24
;每四次进位,256×4=1024,除去1000,还有24
AJMP YICHU2
;返回判断是否小数部分有溢出 NOJINW2:
MOV A,KM
MOV B,#100
DIV AB
MOV LC_XZB,A
MOV A,B
MOV B,#10
DIV AB
MOV LC_XZS,A
MOV A,B
MOV LC_XZG,A
;将公里单元里的整数分成三个BCD码
MOV A,LC_Z
MOV B,#10
DIV AB
MOV LC_XSF,A
MOV A,KM_JW
MOV B,#25
MUL AB
ADD A,LC_XSF
MOV B,#10
DIV AB
MOV LC_XSF,A
RETI ;***************************里程中断程序结束 ;***************************时钟中断程序(计算速度) SUDU:
MOV R0,#0CH
MOVX A,@R0
;消去相应的时钟标志位
INC TEP
;增加温度标志位中的数,为读温度传感器做标志 ;*****************
INC CUN
MOV A,CUN
CJNE A,CAI,BUCUN
MOV CUN,#00H
CLR P2.0
MOV R1,#85H
MOV A,@R1 ;85H用做判断使用内部RAM还是时钟RAM的标志位,0为内部,1为时钟
CJNE A,#1,NEIBURAM
MOV R0,37H
;37H用做保存时钟芯片的RAM地址
CJNE R0,#128,TIMERAM
LJMP BUCUN TIMERAM:
MOV A,SPD_Z
MOVX @R0,A
INC R0
MOV A,SPD_X
MOVX @R0,A
INC R0
MOV 37H,R0
LJMP BUCUN NEIBURAM:
MOV R1,#84H
;84H用做保存内部RAM的地址
MOV A,@R1
MOV R0,A
CJNE R0,#60H,NEIBURAM1
MOV R1,#85H
MOV @R1,#1
LJMP BUCUN NEIBURAM1:
MOV @R0,SPD_Z
INC R0
MOV @R0,SPD_X
INC R0
MOV R1,#84H
MOV A,R0
MOV @R1,A
LJMP BUCUN
;****************** BUCUN:
MOV A,TL1
;读出现在时刻的脉冲数,计算出相应的路程使得速度精确
MOV TL1,#224
;同时重装初值,以免里程多计算
CLR C
SUBB A,#224
MOV B,SDJS
MUL AB
MOV SD,B
CLR C
ADD A,LC_X
;将相乘后的低八位加到小数部分
MOV LC_X,A
JNC NOJINW3
;判断是否溢出,无就直接处理相乘后的高八位
AJMP YICHU4
;有溢出就到YICHU4 NOJINW3:
;处理相乘后的高八位
MOV A,SD
CJNE A,#00H,YUNSUAN
;高八位表示相乘后有多少个256,每四个就应该向整数进一
AJMP
TIAOCHU YUNSUAN:
DEC SD
YICHU4:
INC LC_JW
INC HBZW_X
MOV
A,LC_JW |