单片机实验5-1
实验五万秒计时器的设计
班级物联0901 姓名李王张学号200908888888 指导老师袁文澹
一、实验目的
掌握数码管动态显示的基本方法;
掌握键盘按键控制的实现方法;
根据已知电路和设计要求在实验板上实现万秒计时器。
根据已知电路和设计要求在PROTEUS平台仿真实现控制系统。
二、实验内容
1、在STC89C52实验平台的4位数码管上实现动态显示0000→0001→0002→…→9998→9999→0000→0001→0002→…不断反复,每隔1s切换显示内容。
2、应用键盘控制时间的显示。键盘按键控制“停止计时”、“启动计时”、“加个位显示内容”、“加十位显示内容”、“加百位显示内容”、“加千位显示内容”。
3、思考:如何实现当4位数码管显示的内容为“9999”时,蜂鸣器蜂鸣。
三、实验原理
PS:电路原理图(可局部图)、实验实现控制的原理叙述。参照《单片机实验板电路原理图》
四、实验方法与步骤
设计思路和方法:
根据电路图,分析交通灯的设计思路
针对电路图及设计要求给出交通灯的程序框图。
设计步骤:
1、按照电路图上的MCU芯片与LED、7段数码管的连接方式,绘制交通灯控制系统电路图。
2、编写源代码。…
3、编译与调试。…
4、Proteus仿真运行及验证。…
五、实验结果与分析(实验程序设计必需先有程序框图,程序框图体现在实验报告中)
1、软件设计过程
a)源代码(汇编语言设计)
ORG 00H
…
END
b)编译、调试过程
c)编译结果分析
2、控制系统设计实现过程、结果及分析
a)控制系统电路图
b)实现过程
c)结果分析及结论
(…没有完成的过程或步骤请说明原因所在,实验结果偏差要分析原因,并给出可行的实验解决方案或建议,得出正确的结果)
六、实验结论(实验总结与实验心得)
…(给出实验的总结)
…(这是实验的心得)实验过程中经过对Wave6000仿真平台的操作,对软件仿真有了XXXX 的认识。其中,在进行编译时,刚开始没有成功,后来重新打开软件再进行修改、编译就此解决了问题。不过最后虽然输入了XXXX并进行了保存,但是不知道如何检测XXXX是否保存到XXXX 中。对于XXXX平台的设定,在这次实验中XXXX…。
注意:
1、此模板框架、字体大小不要修改,框架下的具体内容请按照各自试验自己认真完成。
2、试验电路图是《单片机实验电路板原理图》。
3、进实验室前请准备好程序流程框图和程序!
请重视实验!喜欢实验!
/***************************************************************************
标题:定时器中断-秒表-----汇编语言
效果:按1键启动或按2键停止数码管做精确的秒计数
说明:板使用12M晶振
******************************************************************************/ ;脚功能定义
SMG_q EQU P1.0 ;定义数码管阳级控制脚,千位
SMG_b EQU P1.1 ;定义数码管阳级控制脚,百位
SMG_s EQU P1.2 ;定义数码管阳级控制脚,十位
SMG_g EQU P1.3 ;定义数码管阳级控制脚,个位
KEY1 EQU P3.7 ;定义按键1
KEY2 EQU P3.6 ;定义按键2
;定义数据RAM空间
LMS EQU 37H ;定义一个变量存放计数值毫秒
LMIAO EQU 38H ;定义一个变量存放计数值秒
;数据存放
ORG 0100
TABLE: DB 0C0h,0F9H,0A4H,0b0H,99H,92H,82H,0F8H,80H,90H
;表:共阳数码管0-9
ORG 0000H
LJMP MAIN
ORG 000BH ;中断入口
LJMP TIMER
ORG 0200H
MAIN: MOV TMOD,#01H ;设置定时器1为1模式,即16位计算模式
MOV TH0,#0D8H ;给计数寄存器赋值,10毫秒时间
MOV TL0,#0F0H
MOV IE,#82H ;开总中断和T0中断
CLR TR0 ;
CLR A
MOV LMS,A ;计数缓冲清0
MOV LMIAO,A
M01: JB KEY1,M02 ;按下1键启动计数
CLR A
MOV LMS,A
MOV LMIAO,A ;
SETB TR0 ;
SJMP M1
M02: JB KEY2,M1 ;按下2键停止计数
CLR TR0 ;
M1: MOV A,LMS
CJNE A,#100,M2 ;以10毫秒计数,100次即为1秒
MOV LMS,#0
MOV A,LMIAO ;
INC A
MOV LMIAO,A ;
CJNE A,#100,M2 ;如果加到100秒,则清0
MOV LMIAO,#0
M2: LCALL DISPLAY ;显示
LJMP M01
TIMER: INC LMS ;定时中断产生,以10毫秒计数加1 MOV TH0,#0D8H ;重新装入定时器值10毫秒
MOV TL0,#0F0H
RETI
DISPLAY:MOV DPTR,#TABLE ;数码管显示子程序
MOV A,LMIAO ;
MOV B,#10
DIV AB
CLR SMG_q ;千位数码管
MOVC A,@A+DPTR ;
MOV P0,A
LCALL DELAY ;
MOV P0,#0FFH ;
SETB SMG_q ;
CLR SMG_b ;百位数码管
MOV A,B ;
MOVC A,@A+DPTR ;
ANL A,#0X7F ;加入小数点
MOV P0,A
LCALL DELAY ;
MOV P0,#0FFH ;
SETB SMG_b ;
MOV A,LMS ;
MOV B,#10
DIV AB
CLR SMG_s ;十位数码管
MOVC A,@A+DPTR ;
MOV P0,A
LCALL DELAY ;
MOV P0,#0FFH ;
SETB SMG_s ;
CLR SMG_g ;个位数码管
MOV A,B ;
MOVC A,@A+DPTR ;
MOV P0,A
LCALL DELAY ;
MOV P0,#0FFH ;
SETB SMG_g ;
RET
DELAY: MOV R7,#10 ;延时子程序
DJNZ R7,$
RET
END
/***************************************************************************
标题:定时器中断秒计数---C语言
效果:数码管做精确的秒计数00-99
说明:板使用12M晶振
******************************************************************************/ //头文件:
#include "reg51.h"
//变量定义:
code unsigned char table[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//表:共阳数码管0-9
unsigned char l_posit=0; //显示位置
unsigned char tt=0; //作为计数时间量
//引脚定义:
sbit SMG_q = P1^0; //定义数码管阳级控制脚(千位)
sbit SMG_b = P1^1; //定义数码管阳级控制脚(百位)
sbit SMG_s = P1^2; //定义数码管阳级控制脚(十位)
sbit SMG_g = P1^3; //定义数码管阳级控制脚(个位)
//函数声明:
void display(unsigned int da);//定义显示函数,参数为显示内容
void delay(unsigned int timer);
void init(); //初如化函数
//主函数,C语言的入口函数:
void main()
{
unsigned char bb=0; //作为显示变量
init(); //初始化中断控制寄存器
while(1){
if(tt==20){ //20*50MS定时时间为1秒
tt=0;
bb++; //计数变量加1
if(bb==100){ //99秒后清0
bb=0;
}
}
display(bb); //显示变量内容
delay(100);
}
}
//初始化函数
void init()
{
tt=0;
TMOD=0X01; //设置定时器1为模式一,即16位计算模式
TH0=(65536-50000)/256; //给计数寄存器赋值,50毫秒时间
TL0=(65536-50000)%256;
EA=1; //开启总中断
ET0=1; //开启定时器0中断
TR0=1; //启定定时器0
}
//中断函数,关键字"interrupt" ,这是C语言的中断函数表示法,1表时定地器0 void timer() interrupt 1
{
TH0=(65536-50000)/256; //重新赋值
TL0=(65536-50000)%256;
tt++; //50毫秒加1,加20次为一秒
}
//显示函数,参数为显示内容
void display(unsigned int da)
{
P0=0XFF; //
da=da%10000;
switch(l_posit){
case 0: //选择千位数码管,关闭其它位
SMG_q=0;
SMG_b=1;
SMG_s=1;
SMG_g=1;
P0=0xff;//table[da/1000]; //输出显示内容
break;
case 1: //选择百位数码管,关闭其它位
SMG_q=1;
SMG_b=0;
SMG_s=1;
SMG_g=1;
P0=0xff;//table[da%1000/100];
break;
case 2: //选择十位数码管,关闭其它位
SMG_q=1;
SMG_b=1;
SMG_s=0;
SMG_g=1;
P0=table[da%100/10];
break;
case 3: //选择个位数码管,关闭其它位
SMG_q=1;
SMG_b=1;
SMG_s=1;
SMG_g=0;
P0=table[da%10];
break;
}
l_posit++; //每调用一次将轮流显示一位if(l_posit>3)
l_posit=0;
}
//延时子函数,短暂延时
void delay(unsigned int timer){
while(timer--);
}