51单片机汇编秒表程序
- 格式:docx
- 大小:14.74 KB
- 文档页数:5
学号:1108421065课程设计报告基于AT89C51单片机的秒表设计院系电子信息工程学院专业电子信息工程班级 1姓名张远远摘要本设计是设计一个单片机控制的多功能秒表系统。
近年来随着科技的飞速发展,单片机的应用正在不断地走向深入,同时带动着传统控制检测日新月异的更新。
在实时检测和自动控制的单片机应用系统中,单片机往往是作为一个核心部件来使用,仅单片机方面的知识是不够的,还要根据具体的硬件结构,以及针对具体的应用对象的软件结合,加以完善。
秒表的出现,解决了传统的由于人为因素造成的误差和不公平性。
本设计的秒表系统采用AT89C51单片机为中心器件,利用其定时器/计数器定时和记数的原理,结合显示电路、电源电路、LED数码管以及按键电路来设计计时器。
将软、硬件有机地结合起来,使得系统能够正确地进行计数,并且结合相应的显示驱动程序,使数码管能够正确地显示时间,暂停和中断。
可谓功能强大。
其中软件系统采用c语言编写程序,包括显示程序,计数程序,中断,延时程序,按键消抖程序等,硬件系统利用PROTEUS强大的功能来实现,简单且易于观察,在仿真中就可以观察到实际的工作状态。
关键字:单片机秒表目录摘要 (I)目录 (II)引言 (III)1.课程设计目的 (1)2.课程设计题目描述和要求 (1)3.课程设计报告内容 (1)3.1设计思路(方案) (1)3.2系统总体方案及硬件设计(方案论证、设计、调试) (1)3.2.1系统总体方案 (1)3.2.2硬件电路设计 (2)3.3 软件设计 (5)3.3.1软件设计概述 (5)3.3.2程序流程图 (5)3.3.3子程序模块设计 (6)4.Protues软件仿真 (7)5.秒表c语言程序 (9)6.焊接实物图 (11)7.总结(设计后的体会和建议) (11)8.参考文献: (12)引言中国使用单片机的历史只有短短的30年,在初始的短短五年时间里发展极为迅速。
纵观我们现在生活的各个领域,从导弹的导航装置,到飞机上各种仪表的控制,从计算机的网络通讯与数据传输,到工业自动化过程的实时控制和数据处理,以及我们生活中广泛使用的各种智能IC卡、电子宠物等,这些都离不开单片机。
SEC EQU 32H ;秒即时时间\伪指令MIN EQU 31H ;分HOUR EQU 30H ;时DAY EQU 35H ;日MON EQU 34H ;月YEAR EQU 33H ;年MIN_1 EQU 41H ;分定时器1路、开存储单元HOUR_1 E QU 42H ;时DAY_1 EQU 43H ;MON_1 EQU 44H ;YEAR_1 EQU 45H ;MIN_11 EQU 40H ;分定时器1路、关存储单元HOUR_11 EQU 46H ;时DAY_11 EQU 47H ;日MON_11 EQU 48H ;月YEAR_11 EQU 49H ;年ORG 0000HLJMP MAINORG 0003H ;中断转换显示年月日、INT0(SB4键)LJMP WB0ORG 000BH ;计数中断T0、方式1LJMP TT0ORG 0013HLJMP WB1; 调整时间、定时、INT1(SB0键);------主程序ORG 0030HMAIN: MOV YEAR,#02;初始化付值MOV MON,#05MOV DAY,#01MOV HOUR,#00MOV MIN,#00MOV SEC,#00CLR 40H ;定时单元1路清零CLR 41HCLR 42HCLR 43HCLR 44HCLR 45HCLR 46HCLR 47HCLR 48HCLR 49H;-------开中断MOV TMOD,#01H ;计数、模式1、T0MOV TL0,#0B0H ;100SM 计数定时MOV TH0,#3CH ;CLR P3.0MOV 20H,#0AH ;10次*100SMSETB PT0 ;T0为最高级SETB TR0 ;允许计数SETB ET0 ;允许T0中断SETB EX0 ;允许INT0中断SETB EX1 ;允许INT1中断SETB EA ;开总中断;------显示、定时器启动判断LOOP: MOV R1,#30H; 存储单元MOV R4,#01H; 位选通MOV R3,#03H; 三组显示NEXT: MOV A,@R1 ;MOV B,#10 ;将存储单元转换成两高低两组的BCD码DIV ABSWAP AORL A,BMOV P0,A;输出MOV P2,R4INC R1 ;下一单元MOV A,R4 ;RL A ;位移MOV R4,ALCALL DE5SM ;延时0.5SMDJNZ R3,NEXT ;全扫描显示一偏;------判断定时输出(只编写了一路)CJNE R7,#88H,LOOP ;是8则开,否则、定时已关、转;---------开MOV A,YEARCJNE A,YEAR_1,LOOP_1;年比较,不等转关MOV A,MONCJNE A,MON_1,LOOP_1MOV A,DAYCJNE A,DAY_1,LOOP_1MOV A,HOURCJNE A,HOUR_1,LOOP_1MOV A,MINCJNE A,MIN_1,LOOP_1CPL P3.0;---------关LOOP_1:MOV A,YEARCJNE A,YEAR_11, LOOP;年比较MOV A,MONCJNE A,MON_11,LOOPMOV A,DAYCJNE A,DAY_11,LOOPMOV A,HOURCJNE A,HOUR_11,LOOPMOV A,MINCJNE A,MIN_11,LOOPCPL P3.0LJMP LOOP;-----年月日显示中断子程序WB0: PUSH PSWPUSH ACCPUSH BPUSH 01HPUSH 02HPUSH 03HPUSH 04HMOV R2,#0FFH ;中断扫描次数TURN: MOV R1,#33HMOV R4,#01HMOV R3,#03HNEXT_1:MOV A,@R1MOV B,#10DIV ABSWAP AORL A,BMOV P0,AMOV P2,R4INC R1RL AMOV R4,ALCALL DE5SMDJNZ R3,NEXT_1DJNZ R2,TURN ;反复显示一定时间后返回POP 04HPOP 03HPOP 02HPOP 01HPOP BPOP ACCPOP PSWRETI;-----计数中断服务子程序TT0: PUSH PSWPUSH ACCPUSH BPUSH 06HMOV TH0,#3CH;重装计数MOV TL0,#0BH;DJNZ 20H,OUT ;转到中断跳出pop程序MOV 20H,#0AH ; 重装:100*10=1000;-----进位程序INC S ECMOV R6,SEC ;CJNE R6,#60,OUT;比较MOV SEC,#00 ;INC MINMOV R6,MINCJNE R6,#60,OUTMOV MIN,#00INC HOURMOV R6,HOURCJNE R6,#25,OUTMOV HOUR,#00INC DAYMOV R5,MONCJNE R5,#1,MON_22;是否1月、不是转2 月MOV R5,DAYCJNE R5,#32,OUT ; 本月是否益出INC MONMOV DAY,#1LJMP OUTOUT: P OP 06HPOP BPOP ACCPOP PSWRETIMON_22:MOV R5,MONCJNE R5,#2,MON_33;是否2月、不是转3月MOV A,YEAR ;判断是否瑞年MOV B,#4DIV ABMOV A,BJNZ OUT_1;不是则转(A不为零则转)MOV R5,DAYCJNE R5,#30,OUT;如是瑞年、判断是否到29天INC M ONMOV DAY,#1LJMP OUTOUT_1:MOV R5,DAYCJNE R5,#29,OUT ;平年二月判断INC MONMOV DAY,#1LJMP OUTMON_33:MOV R5,MONCJNE R5,#3,MON_44MOV R5,DAYCJNE R5,#32,OUTINC MONMOV DAY,#1LJMP OUTMON_44:MOV R5,MONCJNE R5,#4,MON_55MOV R5,DAYCJNE R5,#31,OUTINC M ONMOV DAY,#1LJMP OUTMON_55:MOV R5,MONCJNE R5,#5,MON_66MOV R5,DAYCJNE R5,#32,OUTINC M ONMOV DAY,#1LJMP OUTMON_66:MOV R5,MONCJNE R5,#6,MON_77MOV R5,DAYCJNE R5,#31,OUTINC M ONMOV DAY,#1LJMP OUTMON_77:CJNE R5,#7,MON_88MOV R5,DAYCJNE R5,#32,L1INC M ONMOV DAY,#1L1: LJMP OUTMON_88:MOV R5,MONCJNE R5,#8,MON_99MOV R5,DAYCJNE R5,#32,L2INC M ONMOV DAY,#1L2: LJMP OUTMON_99:MOV R5,MONCJNE R5,#9,MON_00MOV R5,DAYCJNE R5,#31,L3INC M ONMOV DAY,#1L3: LJMP OUTMON_00:MOV R5,MONCJNE R5,#10,MON_AAMOV R5,DAYCJNE R5,#32,L4INC M ONMOV DAY,#1L4: LJMP OUTMON_AA:MOV R5,MONCJNE R5,#11,MON_BBMOV R5,DAYCJNE R5,#31,L5INC M ONMOV DAY,#1L5: LJMP OUTMON_BB:MOV R5,DAYCJNE R5,#32,L6INC Y EARMOV MON,#1L6: LJMP OUT;-----校对时间、定时调整中断WB1 : PUSH PSWPUSH ACCPUSH BPUSH 00HMOV P2,#00HSHOW_1:MOV A,#01H;显示1MOV P0,AMOV P2,#0FFH;三组数码管都显示1路LCALL READ ;调用读p1口键程序CJNE A,01H,SHOW_1;去抖后比较LCALL DE250SM ; 延时250秒CJNE A,#0FBH,ttT1LJMP SB3_1ttT1: CJNE A,#0FEH,SHOW_1AJMP SHOW_2;-------二组显示SHOW_2:MOV A,#02H; 显示2MOV P0,AMOV P2,#0FFH;LCALL READCJNE A,01H,SHOW_2 ;去抖后比较LCALL DE250SM; 延时250秒CJNE A,#0FBH,T2;不等转去判断此时SB3按了没LJMP SB3_2T2: CJNE A,#0FEH,SHOW_2AJMP SHOW_3;_------三组显示SHOW_3:MOV A,#03H; 显示3MOV P0,AMOV P2,#0FFH;位码LCALL READCJNE A,01H,SHOW_3;去抖后比较LCALL DE250SM;延时250秒CJNE A,#0FBH,T3;不等转去判断此时SB3按了没LJMP SB3_3T3: CJNE A,#0FEH,SHOW_3AJMP SHOW_4;------即时年单元调时、显示SHOW_4:MOV A,YEAR ;调出年单元MOV B,#10 ;BCD转换DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#01H;LCALL READLCALL DE250SMCJNE A,01H,SHOW_4 ;去抖CJNE A,#0FEH,KEY2_1 ;按SB2 转年调整AJMP MON_CH ;按SB1往下调月单元KEY2_1:CJNE A,#0FDH,SHOW_4LCALL YEAR_AD ; 调用年调整AJMP SHOW_4 ;MON_CH:MOV A,MON ; 月单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#02H;LCALL READLCALL DE250SMCJNE A,01H,MON_CH ;去抖CJNE A,#0FEH,KEY2_2 ;按SB2 转月调整LJMP DAY_CH ;按SB1往下调日单元KEY2_2:CJNE A,#0FDH,MON_CHLCALL MON_AD ; 调用月调整LJMP MON_CH ;DAY_CH:MOV A,DAY ; 日单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#04H;LCALL READLCALL DE250SMCJNE A,01H,DAY_CH ;去抖CJNE A,#0FEH,KEY2_3 ;按SB2 转日调整LJMP HOUR_CH ;按SB1往下调时单元KEY2_3:CJNE A,#0FDH,DAY_CHLCALL DAY_AD ; 调用日调整LJMP DAY_CHHOUR_CH:MOV A,HOUR ; 时单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#01H;LCALL READLCALL DE250SMCJNE A,01H,HOUR_CH ;去抖CJNE A,#0FEH,KEY2_4 ;按SB2 转时调整AJMP MIN_CH ;按SB1往下调分单元KEY2_4:CJNE A,#0FDH,HOUR_CHLCALL HOUR_AD ; 调用时调整AJMP HOUR_CH ;MIN_CH:MOV A,MIN ; 分单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#02H;LCALL READLCALL DE250SMCJNE A,01H,MIN_CH ;去抖CJNE A,#0FEH,KEY2_5 ;按SB2 转分调整AJMP SEC_CH ;按SB1往下调秒单元KEY2_5:CJNE A,#0FDH,MIN_CHLCALL MIN_AD ; 调用分调整LJMP MIN_CH ;SEC_CH:MOV A,SEC ; 秒单元调整MOV B,#10DIV A BSWAP AORL A,BMOV P0,A ;MOV P2,#04H;LCALL READLCALL DE250SMCJNE A,01H,SEC_CH ;去抖CJNE A,#0FEH,KEY2_6 ;按SB2 秒调整LJMP OUT_A ;按SB1跳出KEY2_6:CJNE A,#0FDH,SEC_CHCLR SEC ; 归零LJMP SEC_CH ;;-------按SB2\定时器年单元加1子程序SB3_2:LJMP SHOW_2 ;二路没编返回SB3_3:LJMP SHOW_3 ;三路没编返回SB3_1:MOV A,YEAR_1 ; 调时年单元MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,SB3_1CJNE A,#0FBH,KEY2_7 ;按SB2 转年调整LJMP MON_111 ;按SB1往下调月单元KEY2_7:CJNE A,#0FDH, SB3_1INC Y EAR_1 ; 1路年单元加1MOV R5,YEAR_1CJNE R5,#09,SB3_1 ;益出MOV YEAR_1,#00HAJMP SB3_1 ;;-------月单元加1子程序MON_111:MOV A,MON_1 ; 调时月单元显示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MON_111CJNE A,#0FBH,KEY2_8 ;按SB2 转月调整LJMP DAY_111KEY2_8:CJNE A,#0FDH,MON_111INC M ON_1 ;1路月单元加1MOV R5,MON_1CJNE R5,#13,MON_111;益出MOV MON_1,#01HAJMP MON_111 ; 转到月显;_------日单元加1子程序DAY_111:MOV A,DAY_1 ; 调时日单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#04HLCALL READLCALL DE250SMCJNE A,01H,DAY_111CJNE A,#0FBH,KEY2_9 ;按SB2 转日调整LJMP HOUR_111KEY2_9:CJNE A,#0FDH,DAY_111INC D AY_1 ;1组日单元加1MOV R5,DAY_1CJNE R5,#32,DAY_111;益出MOV DAY_1,#01HAJMP DAY_111 ; 转到日显;-------按SB2时单元加1子程序HOUR_111:MOV A,HOUR_1 ; 调时时单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,HOUR_111CJNE A,#0FBH,KEY2_10 ; 按SB2 转时调整LJMP MIN_111KEY2_10:CJNE A,#0FDH,HOUR_111INC H OUR_1MOV R5,HOUR_1CJNE R5,#24,HOUR_111;益出MOV HOUR_1,#00HAJMP HOUR_111 ; 转到时显;-------分单元加1子程序MIN_111:MOV A,MIN_1 ; 调时分单元、并显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MIN_111CJNE A,#0FBH,KEY2_11 ;按SB2 转分调整AJMP OFF_CH ;按SB3往下调定时:关单元KEY2_11:CJNE A,#0FDH, MIN_111INC M IN_1 ;1路分单元加1MOV R5,MIN_1CJNE R5,#60,MIN_111;益处MOV MIN_1,#00HAJMP MIN_111 ; 转到分显;年单元调整OFF_CH:MOV A,YEAR_11 ; 调时年单元MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,OFF_CHCJNE A,#0FBH,KEY2_F7 ;按SB2 转年调整LJMP MON_OFF ;按SB1往下调月单元KEY2_F7:CJNE A,#0FDH,OFF_CHINC Y EAR_11 ; 1路年单元加1MOV R5,YEAR_11CJNE R5,#09,OFF_CH ;益出MOV YEAR_11,#00HAJMP OFF_CH ;;-------月单元加1子程序MON_OFF:MOV A,MON_11 ; 调时月单元显示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MON_OFFCJNE A,#0FBH,KEY2_F8 ;按SB2 转月调整LJMP DAY_OFFKEY2_F8:CJNE A,#0FDH,MON_OFFINC M ON_11 ;1路月单元加1MOV R5,MON_11CJNE R5,#13,MON_OFF;益出MOV MON_11, #01HAJMP MON_OFF ; 转到月显;_------日单元加1子程序DAY_OFF:MOV A,DAY_11 ; 调时日单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#04HLCALL READLCALL DE250SMCJNE A,01H,DAY_OFFCJNE A,#0FBH,KEY2_F9 ;按SB2 转日调整LJMP HOUR_OFFKEY2_F9:CJNE A,#0FDH,DAY_OFFINC D AY_11 ;1组日单元加1MOV R5,DAY_11CJNE R5,#32,DAY_OFF;益出MOV DAY_11,#01HAJMP DAY_OFF ; 转到日显;-------按SB2时单元加1子程序HOUR_OFF:MOV A,HOUR_11 ; 调时时单元显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#01HLCALL READLCALL DE250SMCJNE A,01H,HOUR_OFFCJNE A,#0FBH,KEY2_F10 ; 按SB2 转时调整LJMP MIN_OFFKEY2_F10:CJNE A,#0FDH,HOUR_OFFINC H OUR_11MOV R5,HOUR_11CJNE R5,#24,HOUR_OFF;益出MOV HOUR_11,#00HAJMP HOUR_OFF ; 转到时显;-------分单元加1子程序MIN_OFF:MOV A,MIN_11 ; 调时分单元、并显示提示MOV B,#10DIV A BSWAP AORL A,BMOV P0,AMOV P2,#02HLCALL READLCALL DE250SMCJNE A,01H,MIN_OFFCJNE A,#0FBH,KEY2_F11 ;按SB2 转分调整LJMP ON_1 ;按SB3往下调定时:开与关KEY2_F11:CJNE A,#0FDH, MIN_OFFINC M IN_11 ;1路分单元加1MOV R5,MIN_11CJNE R5,#60,MIN_OFF;益处MOV MIN_11,#00HLJMP MIN_OFF ; 转到分显;-------开、关定时ON_1: CJNE A,#0FBH,MIN_OFFK1: MOV A,#88HMOV R7,AMOV P0,AMOV P2,#0FFH;三组都显示开LCALL READLCALL DE250SMCJNE A,01H,ON_1;去抖后比较CJNE A,#0FBH,KEY2_12 ;按SB2 转关LJMP OUT_A ;按SB3调出、处于开状态KEY2_12:CJNE A,#0FDH, K1k2: MOV A,#00H; 显示0关MOV R7,AMOV P0,AMOV P2,#0FFH;LCALL READLCALL DE250SMCJNE A,01H,K2;去抖后比较CJNE A,#0FBH,KEY2_13 ;按SB2 转开LJMP OUT_A ;SB3调出、处关状态KEY2_13:CJNE A,#0FDH,K2 ; 比较按了没LJMP K1 ; 按了SB2、转开OUT_A:POP 00HPOP BPOP ACCPOP PSWRETI;_------读取按键程序READ: MOV A,P1;读取按键MOV R1,ALCALL DE10MSMOV A,P1RET;_----延时程序DE5SM:PUSH 01HMOV R1,#0FFHDJNZ R1,$POP 01HRETDE10MS:PUSH 04HPUSH 05HMOV R4,#0AHDl1: MOV R5,#0FFHDl2: DJNZ R5,$DJNZ R4,Dl1POP 05HPOP 04HRETDE250SM:PUSH 02HPUSH 00HMOV R0,#0FFH DEL: MOV R2,#0FFHDJNZ R2,$DJNZ R0,DELPOP 00HPOP 02HRET;_---调整时间进位程序MIN_AD:INC MINMOV R6,MINCJNE R6,#60,OU1MOV MIN,#00OU1: RETHOUR_AD:INC HOURMOV R6,HOURCJNE R6,#25,OU2MOV HOUR,#00OU2: RETDAY_AD:INC DAYMOV R6,DAYCJNE R6,#32,OU3 ; 是否益出MOV DAY,#01HOU3: RETMON_AD:INC MONMOV R6,MONCJNE R6,#13,OU4 ; 是否益出MOV MON,#01HOU4: RETYEAR_AD:INC YEARMOV R6,YEARCJNE R6,#09,OU5;是否益出MOV YEAR,#00HOU5: RETEND。
51秒表汇编语言
汇编语言是一种低级语言,用于编写计算机程序。
以下是一个简单的51秒表汇编语言程序示例:
```assembly
ORG 0x0000
LJMP MAIN
ORG 0x0005
RETI
MAIN: MOV TMOD, 0x01 ; 设置定时器模式
SETB TR0 ; 启动定时器
SETB ET0 ; 允许定时器中断
SETB EA ; 允许总中断
SETB TR0 ; 再次启动定时器
HERE: JNB TF0, HERE ; 等待定时器溢出
HERE: CLR TR0 ; 关闭定时器
HERE: RETI ; 返回主程序
```
该程序使用了8051微控制器的定时器/计数器0(Timer/Counter 0,简称T0)来计时。
程序首先将定时器模式设置为模式1(16位定时器/计数器),然后启动定时器,允许定时器中断和总中断,再次启动定时器,等待定时器溢出,关闭定时器,并返回主程序。
需要注意的是,汇编语言程序的编写依赖于具体的微控制器和编译器,因此该示例程序可能需要根据实际情况进行修改。
实验一99秒马表设计1.实验任务开始时,显示“00”,第1次按下按键后就开始计时。
第2次按键后,计时停止。
第3次按键后,计时归零。
2.实验要求用proteus软件画出电路图在keil软件中编写、调试程序要求秒表的误差每秒钟不高于0.01S撰写好实验报告,要求至少包含以下几项:实验目的实验任务与要求实验电路程序流程图实验程序电路仿真结果分析与误差分析实验总结#include"reg52.h"#define uchar unsigned char#define uint unsigned intsbit key=P3^2;uchar code table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uint num,num1;void delayms(uint n){uint i,j;for(i=n;i>0;i--)for(j=110;j>0;j--);}void display(uint num){uchar shi,ge;shi=num/10;ge=num%10;P2=0x00;P0=table[shi];delayms(5);P2=0x01;P0=table[ge];delayms(5);}void init(){TMOD=0x01;IE=0x83;TH0=(65536-45892)/256; TL0=(65536-45892)%256; IT0=0;}void main(){init();while(1){display(num);}}void I0_wai() interrupt 0 {uint num2;delayms(10);if(key==0){EX0=0;TR0=1;num2++;while(!key);}if(num2==1){TR0=1;}if(num2==2){TR0=0;}if(num2==3){TR0=1;num=0;num2=1;}EX0=1;}void T0_time() interrupt 1 {TH0=(65536-45892)/256; TL0=(65536-45892)%256; num1++;if(num1==20){num1=0;num++;if(num==100){num=0;}}}。
目录一,设计目标 (3)二,系统硬件设计 (4)三,系统软件设计 (7)四,系统调试与设计结果 (12)五,单片机实训小结 (13)设计目标近年来随着科学技术的发展,单片机的应用范围越来越广,也成为很多专业的必修课。
本文简单阐述了基于单片机的秒表设计。
本设计的主要特点是计时精度达到0.01秒,可以用来为各种体育竞赛计时等。
本设计的数字秒表采用AT89S52单片机为主要器件,利用其定时器的原理,结LED数码管以及外部中断电路来设计计时器。
将软硬件结合起来,使得系统能实现0~99.99秒的计时,计时精度位0.01秒。
当按下一个键1时,开始显示数字,即计时开始,再按下键2时,暂停计时并显示刚才的结果,这个时候如果再按键1,则继续计时,也就是显示的数字包括刚才的数据。
按下键3时,数据清零。
系统硬件设计1、1 总体方案的设计数字秒表具有显示直观、读取方便、精度高等优点,在计时中广泛应用。
本设计中用单片机和数码管组成数字秒,力求结构简单。
设计中包括硬件电路的设计和系统程序的设计。
硬件电路主要有主控制器、控制按钮与显示电路组成。
主控制器采用单片机AT89S52,显示电路采用四位共阴极数码管显示计时时间。
本设计利用AT89S52单片机的定时器,使其能精确计时。
利用键盘上的独立按键实现开始计时和暂停以及清零。
P0口输出段码数据,P2.0~P2.2连上译码器作为位选。
设计的基本要求是正确性。
计时器采用T0中断实现,定时溢出中断周期为1ms,当溢出中断后向CPU 发出溢出中断请求,每发出10次中断请求就对10ms位(即最后一位)加一,达到100次就对100ms位加一,以此类推,直到99.99s为止。
1.2 单片机的选择本设计在选取单片机时,充分借鉴了许多成型产品使用单片机的经验。
并根据自己的实际情况,选用了ATMEL公司的AT89S52。
ATMEL公司的89系列单片机以其卓越的性能、完善的兼容性、快捷便利的电擦写操作、低廉的价格完全替代了87C51/62和8751/52,低电压、低功耗,有DIP、PLCC、QFP封装,是目前性能最好、价格最低、最受欢迎的单片机之一。
主题:51单片机4位数码管秒表代码内容:1. 介绍51单片机51单片机是一种通用的单片机系列,广泛应用于各种电子设备中。
它具有稳定性好、成本低、易于编程等优点,因此备受电子爱好者和专业工程师的青睐。
2. 4位数码管秒表4位数码管秒表是一种常见的电子计时器,通过LED数码管显示出当前的时间,可以用于各种计时应用,比如比赛计时、实验计时等。
3. 代码编写以下是一段简单的51单片机4位数码管秒表代码:```c#include <reg52.h>#include <intrins.h>// 数码管位选端口sbit wei1 = P2^2;sbit wei2 = P2^3;sbit wei3 = P2^4;sbit wei4 = P2^5;// 数码管显示段选端口sbit se2 = P0^2;sbit se1 = P0^3;sbit se4 = P0^4;sbit se3 = P0^5;unsigned char code smgduan[17] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}; // 显示0~9,A,b,C,d,E,F,无的值void delay(unsigned int i) { // 延时while(i--);}void display(unsigned char *tab) { // 数码管显示 unsigned char i;for(i=0; i<7; i++) {P0=0; // 清除段选,以选中所显示的数码管 switch(i) { //确定位选case(0):wei1=0;wei2=wei3=wei4=1;break;case(1):wei2=0;wei1=wei3=wei4=1;break;case(2):wei3=0;wei1=wei2=wei4=1;break;case(3):wei4=0;wei1=wei2=wei3=1;break;default:break;}P0=tab[i]; //段码输出delay(5); // 数码管微秒级延迟}}void m本人n() {unsigned char a=0,b=0,c=0,d=0; //时钟的4位数据 unsigned int i=0;wei1=wei2=wei3=wei4=1; //段选、位选初始化while(1) {a++; // 微秒级的计数if(a==100) { //达到100a=0; b++; //b加1if(b==60) { //当b=60时b=0; c++; //c加1if(c==60) { //当c=60时c=0; d++; //d加1if(d==24) { //当d=24时d=0; //归零}}}}display(smgduan+d10); //显示个秒wei1=1;wei2=wei3=wei4=0; //位选delay(500); //延时display(smgduan+c/10+10); //显示十秒wei2=1;wei1=wei3=wei4=0; //位选delay(500); //延时display(smgduan+b10); //显示个分wei3=1;wei1=wei2=wei4=0; //位选delay(500); //延时display(smgduan+b/10+10); //显示十分wei4=1;wei1=wei2=wei3=0; //位选delay(500); //延时if(i++==200) { //当i=200时i=0;}}}```4. 代码分析该代码通过对51单片机的引脚进行控制,实现了4位数码管秒表的计时功能。
51单片机秒表程序设计1. 简介秒表是一种用于测量时间间隔的计时器,常见于体育比赛、实验室实验等场合。
本文将介绍如何使用51单片机设计一个简单的秒表程序。
2. 硬件准备•51单片机开发板•LCD液晶显示屏•按键开关•连接线3. 程序流程3.1 初始化设置1.设置LCD液晶显示屏为8位数据总线模式。
2.初始化LCD液晶显示屏。
3.设置按键开关为输入模式。
3.2 主程序循环1.显示初始界面,包括“00:00:00”表示计时器初始值。
2.等待用户按下开始/暂停按钮。
3.如果用户按下开始按钮,则开始计时,进入计时状态。
4.如果用户按下暂停按钮,则暂停计时,进入暂停状态。
5.在计时状态下,每隔1毫秒更新计时器的数值,并在LCD液晶显示屏上显示出来。
6.在暂停状态下,不更新计时器的数值,并保持显示当前数值。
3.3 计时器控制1.定义一个变量time用于存储当前的计时器数值,单位为毫秒。
2.定义一个变量running用于标记计时器的状态,0表示暂停,1表示运行。
3.定义一个变量start_time用于存储计时器开始的时间点。
4.定义一个变量pause_time用于存储计时器暂停的时间点。
5.在计时状态下,每隔1毫秒更新time的值为当前时间与start_time的差值,并将其转换为小时、分钟、秒的表示形式。
6.在暂停状态下,保持time的值不变。
3.4 按键检测1.检测按键开关是否被按下。
2.如果按键被按下,判断是开始/暂停按钮还是复位按钮。
3.如果是开始/暂停按钮,并且当前处于计时状态,则将计时状态设置为暂停状态,并记录暂停时间点为pause_time;如果当前处于暂停状态,则将计时状态设置为运行状态,并记录开始时间点为当前时间减去暂停时间的差值。
4.如果是复位按钮,则将计时器数值重置为0,并将计时状态设置为暂停。
4. 程序代码示例#include <reg51.h>// 定义LCD控制端口和数据端口sbit LCD_RS = P1^0;sbit LCD_RW = P1^1;sbit LCD_EN = P1^2;sbit LCD_D4 = P1^3;sbit LCD_D5 = P1^4;sbit LCD_D6 = P1^5;sbit LCD_D7 = P1^6;// 定义按键开关端口sbit START_PAUSE_BTN = P2^0;sbit RESET_BTN = P2^1;// 定义全局变量unsigned int time = 0; // 计时器数值,单位为毫秒bit running = 0; // 计时器状态,0表示暂停,1表示运行unsigned long start_time = 0; // 开始时间点unsigned long pause_time = 0; // 暂停时间点// 函数声明void delay(unsigned int ms);void lcd_init();void lcd_command(unsigned char cmd);void lcd_data(unsigned char dat);void lcd_string(unsigned char *str);void lcd_clear();void lcd_gotoxy(unsigned char x, unsigned char y);// 主函数void main() {// 初始化设置lcd_init();while (1) {// 显示初始界面lcd_clear();lcd_gotoxy(0, 0);lcd_string("00:00:00");// 等待用户按下开始/暂停按钮while (!START_PAUSE_BTN && !RESET_BTN);// 判断按钮类型并处理计时器状态if (START_PAUSE_BTN) {if (running) { // 当前处于计时状态,按下按钮将进入暂停状态 running = 0;pause_time = time;} else { // 当前处于暂停状态,按下按钮将进入计时状态running = 1;start_time = get_current_time() - pause_time;}} else if (RESET_BTN) { // 复位按钮按下,重置计时器time = 0;running = 0;}}}// 毫秒级延时函数void delay(unsigned int ms) {unsigned int i, j;for (i = ms; i > 0; i--) {for (j = 110; j > 0; j--);}}// LCD初始化函数void lcd_init() {lcd_command(0x38); // 设置8位数据总线模式lcd_command(0x0C); // 显示开,光标关闭lcd_command(0x06); // 光标右移,不移动显示器lcd_command(0x01); // 清屏}// 向LCD发送指令函数void lcd_command(unsigned char cmd) {LCD_RS = 0;LCD_RW = 0;LCD_EN = 1;LCD_D4 = cmd >> 4 & 1;LCD_D5 = cmd >> 5 & 1;LCD_D6 = cmd >> 6 & 1;LCD_D7 = cmd >> 7 & 1;delay(1);LCD_EN = 0;LCD_D4 = cmd >> 0 & 1;LCD_D5 = cmd >> 1 & 1;LCD_D6 = cmd >> 2 & 1;LCD_D7 = cmd >> 3 & 1;delay(1);LCD_EN = 0;}// 向LCD发送数据函数void lcd_data(unsigned char dat) { LCD_RS = 1;LCD_RW = 0;LCD_EN = 1;LCD_D4 = dat >> 4 & 1;LCD_D5 = dat >> 5 & 1;LCD_D6 = dat >> 6 & 1;LCD_D7 = dat >> 7 & 1;delay(1);LCD_EN = 0;LCD_D4 = dat >> 0 & 1;LCD_D5 = dat >> 1 & 1;LCD_D6 = dat >> 2 & 1;LCD_D7 = dat >> 3 & 1;delay(1);LCD_EN = 0;}// 向LCD发送字符串函数void lcd_string(unsigned char *str) {while (*str) {lcd_data(*str++);delay(5);}}// 清屏函数void lcd_clear() {lcd_command(0x01);}// 设置光标位置函数void lcd_gotoxy(unsigned char x, unsigned char y) {unsigned char addr;if (y == 0)addr = x | (0x80 + y);else if (y == 1)addr = x | (0xC0 + y);lcd_command(addr);}5. 总结本文介绍了使用51单片机设计一个简单的秒表程序。