基于80C51的电子计时器的设计与实现Word文档下载推荐.docx
《基于80C51的电子计时器的设计与实现Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于80C51的电子计时器的设计与实现Word文档下载推荐.docx(18页珍藏版)》请在冰豆网上搜索。
开始"
"
暂停"
键,一个"
清零"
键。
这里采用顺序结构,通过对按键的扫描,判断要实现什么功能。
如下所示:
图3程序流程图
4.测试数据及设计结果
1、按下P1.0管脚的开关时,显示数据,如下图所示
图4.1系统运行图
2、按下P1.1S管脚的开关时,数据清零,如下图所示
参考文献
[1]刘国强,唐东红,李兴伟.基于AT89C51单片机的高精度测温系统的研制[J].仪器仪表学报.2005(S1)
[2]郑善锋,郑华杰,黄其智,尚志红.利用微机数据处理提高温度测量精度[J].电路与系统学报.2005(01)
[3]梁伟.一种精密的热电阻测温方法[J].电子产品世界.2003(15)
[4]李学礼,林海峰.基于Proteus软件的单片机实验室建设[J].单片机与嵌入式系统应用.2005(09)
附录
附录:
(程序)
;
定义计时单元地址
MINEQU31H;
存放分钟变量
SECEQU32H;
存放秒钟变量
DEDAEQU33H;
存放10ms计数值
按键端口状况值
K1_NEQU34H;
存放按键当前端口状况值
K1_PEQU35H;
存放按键上次端口状况值
K1_CEQU37H;
存放按键计数单元
XEQU36H;
LCD地址变量
按键引脚定义
K1EQUP3.3;
按键1引脚定义
K2EQUP3.4;
按键2引脚定义
LCD引脚定义
RSEQUP3.5;
LCDRS引脚定义
RWEQUP3.6;
LCDRW引脚定义
EEQUP3.7;
LCDRS引脚定义
ORG0000H;
程序由地址0开始执行
JMPMAIN
ORG0BH;
定时器0中断地址设置
JMPT0_INT
;
―――――――――――――主程序――――――――――――――
MAIN:
开始
MOVSP,#60H;
堆栈指针指向60H
CLRE;
E=0,禁止读/写LCD
ACALLSET_LCD;
调LCD控制子程序
ACALLINIT;
初始化变量
MOVK1_P,#01H;
按键上次端口设置1
ACALLINIT_TIMER;
调用初始化定时器
ACALLMEU;
调用工作菜单子程序
LOOP:
ACALLCONV;
时间计数处理
ACALLLOOP1;
调用清零键子程序
ACALLKEY;
判断是否有键按下
JZLOOP;
无键按下转LOOP
MOVK1_P,K1_N;
交换数据
ACALLKEY0;
调用按键功能子程序
JMPLOOP;
跳LOOP处循环
初始变量清零子程序
INIT:
初始变量清零
CLRA;
A清为零
MOVK1_C,A;
K1_C初始为0
MOVDEDA,A;
百分秒DEDA初始为0
MOVSEC,A;
秒SEC初始为0
MOVMIN,A;
分MIN初始为0
MOVK1_N,A;
K1_N初始为0
MOVK1_P,A;
K1_P初始为0
CLRTR0;
启动中断
RET
―――――――――――――――――――――
定时器初始化设置子程序
INIT_TIMER:
定时器初始化
MOVTMOD,#00000001B;
定时器0模式1
MOVIE,#10000010B;
开通中断
MOVTL0,#LOW(65536-10000);
定时初值装入低位
MOVTH0,#HIGH(65536-10000);
定时初值装入高位
中断服务程序
T0_INT:
定时器T0中断程序
PUSHACC;
入栈保护
MOVTL0,#LOW(65536-10000);
重加载
MOVTH0,#HIGH(65536-10000)
INCDEDA
MOVA,DEDA;
10ms计数值加1
CJNEA,#100,TT
MOVDEDA,#0
INCSEC;
秒加1
MOVA,SEC
CJNEA,#60,TT
INCMIN;
分加1
MOVSEC,#0
MOVA,MIN
CJNEA,#05,TT
MOVDEDA,#0;
百、分、秒单元清0
MOVSEC,#0
MOVMIN,#0
TT:
POPACC;
出栈
RETI;
中断程序返回
判断键是否按下子程序
LOOP1:
JBK2,LOOP2;
判清零键是否按下
JMPMAIN;
跳转主程序处
LOOP2:
判断K1键是否按下
KEY:
A清零
A值送入K1_N
MOVC,K1;
K1值送入C
RLCA;
同进位标志左移一位
ORLK1_N,A;
两个位作逻辑OR运算
MOVA,K1_N;
K1_N值送入A
XRLA,K1_P;
有键按下,A中内容不为零
功能键子程序
K1键第一次按功能子程序
KEY0:
MOVA,K1_P;
K1_P值送入A
JBACC.0,KEY3;
A的0位是1,转KEY3
INCK1_C;
K1_C加1
MOVA,K1_C;
K1_C值送入A
CJNEA,#01H,KEY1;
K1键是否第一次按?
MOVDPTR,#MENU1;
是,存入MENU1信息
MOVA,#1;
设置第一行显示
CALLLCD_PRINT;
调用显示字符子程序
SETBTR0;
K1键第二次按功能子程序
KEY1:
MOVA,K1_C;
CJNEA,#02H,KEY2;
K1键是否第二次按?
MOVDPTR,#MENU2;
是,存入MENU2信息
停止中断
RET;
K1键第三次按功能子程序
KEY2:
K1_C值送入A
CJNEA,#03H,KEY3;
K1键是否第三次按?
MOVDPTR,#MENU3;
是,存入MENU3信息
MOVA,#1;
K1键第四按功能子程序
KEY3:
CJNEA,#04H,KEY4;
K1键是否第四次按?
MOVDPTR,#MENU4;
是,存入MENU4信息
KEY4:
子程序返回
―――――――――――――LCD显示――――――――――――――
LCD控制子程序
SET_LCD:
;
CLRE
ACALLINIT_LCD;
初始化LCD
MOVR5,#10
ACALLDELAY
MOVDPTR,#LMESS1;
指针指到显示消息1
显示在第一行
ACALLLCD_PRINT;
MOVDPTR,#LMESS2;
指针指到显示消息2
MOVA,#2;
显示在第二行
LMESS1:
DB"
"
0;
LCD第一行显示消息
LMESS2:
TIME"
LCD第二行显示消息
LCD初始化子程序
INIT_LCD:
MOVA,#38H;
设置8位、2行、5x7点阵
ACALLWR_COMM;
调用写指令子程序
ACALLDELAY1;
调用延时子程序
MOVA,#0CH;
开显示,光标不闪烁
调用写指令子程序;
MOVA,#01H;
清除LCD显示屏
写指令子程序
WR_COMM:
MOVP1,A
CLRRS;
RS=0,选择指令寄存器
CLRRW;
RW=0,选择写模式
SETBE;
E=1,允许读/写LCM
调用延时子程序
E=0,禁止读/写LCM
写数据子程序
WR_DATA:
SETBRS;
RS=1,选择数据寄存器
E=1,允许读/写LCD
ACALLDE;
清除该行LCD的字符
CLR_LINE:
MOVR0,#24
CL1:
MOVA,#'
'
ACALLWR_DATA
DJNZR0,CL1
LCD存入工作菜单
MEU:
MOVDPTR,#MENU0;
存入工作菜单
第一行
CALLLCD_PRINT
RET
工作菜单
MENU0:
SECOND-CLOCK0"
0
MENU1:
BEGINCOUNT1"
MENU2:
PAUSTCOUNT2"
MENU3:
BEGINCOUNT3"
MENU4:
PAUSTCOUNT4"
0
菜单显示子程序
一行、二行显示字符
LCD_PRINT:
CJNEA,#1,LINE2;
判断是否为第一行
LINE1:
ACALLCLR_LINE;
清除该行字符数据
MOVA,#80H;
设置LCD的第一行地址
写入命令
JMPFILL
LINE2:
MOVA,#0C0H;
设置LCD的第二行地址
ACALLWR_COMM
FILL:
填入字符
MOVCA,@A+DPTR;
由消息区取出字符
CJNEA,#0,LC1;
判断是否为结束码
写入数据
LC1:
ACALLWR_DATA
INCDPTR;
指针加1
JMPFILL;
继续填入字符
转换数据子程
CONV:
转换为ASCII码并显示
MOVX,#5;
设置位置
ACALLSKOW_LINE2;
显示数据
INCX;
:
'
MOVB,X;
ACALLLCDP2;
MOVA,MIN;
加载分钟数据
MOVA,SEC;
加载秒数数据
CALLLCDP2;
在LCD的第二行显示数字
SKOW_LINE2:
MOVB,#10;
设置被除数
DIVAB;
结果A存商数,B存余数
ADDA,#30H;
A为十位数,转换为字符
PUSHB;
B放入堆栈暂存
设置LCD显示的位置
由LCD显示出来
POPB;
MOVA,B;
B为个位数
转换为字符
LCD显示位置加1
由LCD显示出来
在LCD的第二行显示字符
LCDP2:
设置显示地址
ADDA,#0C0H;
设置LCD的第二行地址
CALLWR_COMM;
由堆栈取出A
CALLWR_DATA;
写入数据
延时10MS
DELAY:
MOVR6,#50
D1:
MOVR7,#100
DJNZR7,$
DJNZR6,D1
DJNZR5,DELAY
延时5MS子程序
DELAY1:
MOVR6,#25
DEY:
MOVR7,#100
DJNZR6,DEY
延时500微秒
DE:
END;
程序结束
//C语言
#include"
reg51.h"
lcd1602.h"
sbitkey1=P1^0;
sbitkey2=P1^1;
unsignedcharcodedisp_data1[]={"
SECOND-CLOCK0"
};
unsignedcharcodedisp_dataq[]={"
unsignedcharcodedisp_dataw[]={"
unsignedcharcodedisp_datae[]={"
BEGINCOUNT3"
unsignedcharcodedisp_datar[]={"
PAUSTCOUNT4"
unsignedcharcodedisp_data2[]={"
TIME00:
00:
00"
};
unsignedcharcount=0;
unsignedcharmm=0;
unsignedcharm=0;
unsignedcharf=0;
voidconfig();
voidINIT_config();
voidTimeStop();
voidmain(){
config();
while
(1){
if(key2==0){
TimeStop();
config();
count=1;
mm=0;
m=0;
f=0;
}
if(key1==0){
if(count==1){
LCD_Print(0,1,disp_dataq);
INIT_config();
}
if(count==2)
{
TimeStop();
LCD_Print(0,1,disp_dataw);
if(count==3){
LCD_Print(0,1,disp_datae);
if(count==4)
LCD_Print(0,1,disp_datar);
count++;
DelayMs(50);
}
}
voidconfig(){
LCD_INIT();
DelayMs(5);
LCD_Print(0,0,disp_data1);
LCD_Print(1,0,disp_data2);
voidINIT_config(){
TMOD=0X01;
TH0=0xfc;
TL0=0x18;
ET0=1;
TR0=1;
EA=1;
voidTimeStop(){
EA=0;
TR0=0;
voidTimeRun()interrupt1{
staticunsignedchari=1;
if(i==10){
i=1;
mm++;
if(mm==100){
m++;
if(m==60){
f++;
}
if(f==60)
f=0;
}
LCD_Print_word(1,15,mm%10+48);
LCD_Print_word(1,14,mm/10+48);
LCD_Print_word(1,12,m%10+48);
LCD_Print_word(1,11,m/10+48);
LCD_Print_word(1,10,'
);
LCD_Print_word(1,9,f%10+48);
LCD_Print_word(1,8,f/10+48);
i++;