你好:
三个警告应该是void int_initial()与void timer0_initial()前边不用加void,然后就是Display()这个函数没有用。
其次我想说,TMOD=0x01就行了,因为程序里边只用到了定时器0,其他的状态不管,甚至可以说把其他定时器关掉。,也用不着TMOD&=0xfd。
然后中断函数要尽量精简、短小实干、不宜过长,因为中断本身就打扰了main函数的正常运行,而且中断内容太多反而容易在下次中断到来时还没处理完,就会栈溢出。养成好的习惯,中断就对最基本的时间计次就行,其余的都抛给main函数吧。
EA、ET0尽量就和定时器0一起初始化,你这习惯看着别扭。可读性略低。
中断里不要声明变量,你用个全局变量就OK。
希望我的回答能帮助到你。
2. 基于C51单片机的秒表设计。要求:1.用2位数码管显示秒数。 2. 有启动、停止、清零功能 。
选 。共阳数码管 16M晶振。
STRT EQU P2.5
STP EQU P2.6
CLRR EQU P2.7
ORG 00H
AJMP MAIN
ORG 0BH
AJMP T0INT
ORG 30H
MAIN: MOV R0,#20
MOV TMOD,#01H
MOV TH0,#3CH
MOV TL0,#0B0H
MOV DPTR,#TABLE
SETB EA
SETB ET0
k1: LCALL DISP
JB STRT,K2
LCALL DISP
JNB STRT,$-3
AJMP START
k2: JB STP,K3
LCALL DISP
JNB STP,STOP
K3: JB CLRR,K1
LCALL DISP
JNB CLRR,CLEAR
AJMP K3
START: SETB TR0
AJMP K1
STOP: CLR TR0
AJMP K2
CLEAR: CLR TR0
MOV 40H,#0
AJMP K1
T0INT: MOV TH0,#3CH
MOV TL0,#0B0H
DJNZ R0,RTI
MOV R0,#20
MOV A,40H
CJNE A,#99,ADD1
MOV 40H,#00H
CLR TR0
AJMP RTI
ADD1: ADD A,#01H
MOV 40H,A
RTI: RETI
DISP: MOV A,40H
MOV B,#10
DIV AB ;//当前值除以10
MOV 20H,A ;//得出的商送给十位
MOV 21H,B ;//得出的余数送给个位
CLR P2.0
SETB P2.1
MOV A,20H ;//十位显示
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
CLR P2.1
SETB P2.0
MOV A,21H ; //个位显示
MOVC A,@A+DPTR
MOV P0,A
RET
DELAY: ;误差 0us
MOV R6,#01H
DL0:
MOV R5,#61H
DJNZ R5,$
DJNZ R6,DL0
RET
TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H ;//共阳极0-9显示代码
DB 92H,82H,0F8H,80H,90H
END
3. 以单片机为核心,设计一个2位的LED数码显示作为“秒表”。 C语言程序+仿真,最好写明程序每一步的功能等
// 时钟秒表,仿真示例程序,可以参考一下。
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit qingling=P1^0; //清零
sbit tiaofen=P1^1; //调分
sbit tiaoshi=P1^2; //调时
sbit sounder=P1^7; //naozhong
uint a,b;
uchar hour,minu,sec, //时钟
hour0,minu0,sec0,//秒表
hour1,minu1,sec1;
h1,h2,m1,m2,s1,s2,//显示位
k,s;//状态转换标志
uchar code select[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uchar code table[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code tableh[]= {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
/*****************函数声明***********************/
void keyscan();
void init();
void delay(uchar z);
void display(uchar,uchar,uchar);
void sounde();
/*****************主函数*************************/
void main()
{
init();
while(1)
{
while(TR1)
{
keyscan(); //扫描函数
while(s==1) ///////////////s是状态标志,当s=0时,闹钟取消。s=1时,设定闹钟时间(也是通过调时,调分函数);
{ //s=2时,闹钟工作,时间与设定时刻一致时,闹钟响(一分钟后自动关闭,可手动关闭)。再次切换,s=0.
keyscan(); //s状态切换(0-》1-》2-》0)通过外部中断1实现。
display(hour1,minu1,sec1); //闹钟时刻显示
}
display(hour0,minu0,sec0);//时钟表显示
while(k) /*k是秒表状态(0-》1-》2-》0)通过外部中断0实现。0秒表关;1秒表从零计时;2秒表停,显示计时时间*/
{
display(hour,minu,sec); //秒表显示
}
}
}
}
/*****************初始化函数***********************/
void init()
{
a=0;
b=0;
k=0;
s=0;
hour0=0;
minu0=0;
sec0=0;
hour=0;
minu=0;
sec=0;
hour1=0;
minu1=0;
sec1=0;
TMOD=0x11; //定时器0,1工作于方式1;赋初值
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
EX0=1; //秒表中断
EX1=1; //闹钟设定中断
ET0=1;
ET1=1;
IT0=1; //边沿触发方式
IT1=1;
PX0=1;
PX1=1;
TR0=0; //初始,秒表不工作
TR1=1; //时钟一开始工作
}
/*****************定时器0中断*************/
void timer0_int() interrupt 1 //秒表
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
a++;
if(a==2)
{
a=0;
sec++;
if(sec==100)
{
sec=0; //毫秒级
minu++;
if(minu==60)
{
minu=0; //秒
hour++;
if(hour==60) //分
{
hour=0;
}
}
}
}
}
/*************外部中断0中断函数************/
void ex0_int() interrupt 0
{
k++;
if(k==3)
k=0;
if(k==1)
{
TR0=~TR0;
if(TR0==1)
{
hour=0;
minu=0;
sec=0;
}
}
if(k==2)
{
TR0=~TR0;
}
}
/*************外部中断1中断函数************/
void ex1_int() interrupt 2
{
s++;
if(s==3)
s=0;
}
/*************定时器1中断****************/
void timer1_int() interrupt 3 //控制时钟工作
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
if(s==2)
{
if(hour1==hour0 && minu0==minu1)
sounde();
}
b++;
if(b==20)
{
b=0;
sec0++;
if(sec0==60)
{
sec0=0;
minu0++;
if(minu0==60)
{
minu0=0;
hour0++;
if(hour0==24)
hour0=0;
}
}
}
}
/*************键盘扫描****************/
void keyscan()
{
if(s==1)
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec1=0;
minu1=0;
hour1=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu1++;
if(minu1==60)
{
minu1=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour1++;
if(hour1==24)
{
hour1=0;
}
while(!tiaoshi);
}
}
else //调整时钟时间
{
if(qingling==0)
{
delay(10);
if(qingling==0)
{
sec0=0;
minu0=0;
hour0=0;
}
}
if(tiaofen==0)
{
delay(10);
if(tiaofen==0)
{
minu0++;
if(minu0==60)
{
minu0=0;
}
while(!tiaofen);
}
}
if(tiaoshi==0)
{
hour0++;
if(hour0==24)
{
hour0=0;
}
while(!tiaoshi);
}
}
}
/*************显示函数****************/
void display(uchar hour,uchar minu,uchar sec)
{
h1=hour/10;
h2=hour%10;
m1=minu/10;
m2=minu%10;
s1=sec/10;
s2=sec%10;
P0=0xff;
P2=table[h1];
P0=select[7];
delay(5);
P0=0xff;
P2=tableh[h2];
P0=select[6];
delay(5);
P0=0xff;
P2=0x40;;
P0=select[5];
delay(5);
P0=0xff;
P2=table[m1];
P0=select[4];
delay(5);
P0=0xff;
P2=tableh[m2];
P0=select[3];
delay(5);
P0=0xff;
P2=0x40;
P0=select[2];
delay(5);
P0=0xff;
P2=table[s1];
P0=select[1];
delay(5);
P0=0xff;
P2=table[s2];
P0=select[0];
delay(5);
}
/*************闹钟函数****************/
void sounde()
{
sounder=~sounder;
}
/*************延时函数****************/
void delay(uchar z)
{
int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
4. 利用51单片机,通过两位数码管显示秒,按键实现计时和停止计时 具体内容内详
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR
ORG 0030H
MAIN:
MOV TMOD,#01H
MOV TH0,#HIGH(65536-10000)
MOV TL0,#LOW(65536-10000)
SETB ET0
SETB EA
MOV R0,#0
MOV R1,#0
MOV R2,#0
MOV R3,#9
CLR 00H
CLR 01H
LOOP:
JB P1.0,LP01
JNB P1.0,$
SETB TR0
CLR 01H
SJMP LOOP0
LP01:
JB P1.1,LP02
JNB P1.1,$
SETB 01H
SJMP LOOP0
LP02:
JB P1.2,LOOP0
JNB P1.1,$
CLR TR0
MOV P3,#0FDH
MOV P2,#0
MOV P3,#0FEH
MOV P2,#0
SJMP MAIN
LOOP0:
JB 00H,LOOP1
MOV A,R0
SJMP LOOP2
LOOP1:
MOV A,R1
LOOP2:
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV R3,A
SJMP LOOP
T0ISR:
CLR TR0
MOV TH0,#HIGH(65536-10000)
MOV TL0,#LOW(65536-10000)
SETB TR0
JB 01H,T0C
INC R2
T0C:
CPL 00H
MOV A,R3
JB 00H,T001
MOV P3,#0FDH
MOV P2,A
SJMP T002
T001:
MOV P3,#0FEH
MOV P2,A
T002:
MOV A,R2
CJNE A,#100,T0E
MOV R2,#0
INC R0
CJNE R0,#10,T0E
MOV R0,#0
INC R1
CJNE A,#10,T0E
MOV R1,#0
T0E:
RETI
T004:
CLR TR0
RETI
TABLE: ; 共阴极数码管显示代码表
DB 3FH,06H,5BH,4FH,66H ;01234
DB 6DH,7DH,07H,7FH,6FH ;56789
5. 51单片机 秒表设计
// 51单片机 秒表,显示时间为0000—9999秒,启动、停止,(停止后再次启动复位)
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar ,shi;
uint a1,a2;
sbit D1=P3^0;
sbit D2=P3^1;
sbit D3=P3^2;
sbit D4=P3^3;
sbit key=P3^5;
sbit key1=P3^7;
bit j ;
uint y ;
void main()
{
TMOD=0x01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
EA=1;
ET0=1;
TR0=1;
=0;
shi=0;
while(1)
{
if(key==0)
{
j=0;
}
if(key1==0)
{
j=1; a2=0;
}
}
}
void timer0()interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
a1++;
y++;
if(a1==100)
{
a1=0;
if(j==1) a2++;
if(a2>=10000) a2=0;
}
D1 = 1; D2 = 1; D3 = 1; D4 = 1;
if(y==1)
{
P1=table[a2%10000/1000];
D4=0;
}
if(y==2)
{
P1=table[a2%1000/100];
D3=0;
}
if(y==3)
{
P1=table[a2%100/10];
D2=0;
}
if(y==4)
{
P1=table[a2%10];
D1=0;
y=0;
}
}
6. 51单片机制作一个秒表
//功能:0~99秒的简易秒表设计,两个静态数码管,定时器采用中断方式
#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
uchar count=0;//对50ms定时时间进行计数
uchar miao=0; //秒计数器
//函数名:timer_1()
//函数功能:定时器T1的中断函数,T1在工作方式1下每50秒产生中断,执行该中断函数
//形式参数:无
//返回值:无
void timer_1() interrupt 3 //T1的中断类型号为3
{
TH1=(65536-50000)/256; //重新设置T1计数初值高8位
TL1=(65536-50000)%256; //重新设置T1计数初值低8位
count++; //50ms计数器加1
if(count==20) //1s时间到
{
count=0; //50ms计数器清0
miao++; //秒计数器加1
if(miao==100)miao=0; //miao计数到100,则从0开始计数
}
}
bit b=0;
void int_0() interrupt 0
{
if(b == 0){TR1 = 0;b = 1;}
else
{
b = 0;
TR1 = 1;
}
}
void int_1() interrupt 2
{
miao=0;
count = 0;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
TR1=1;
}
//函数名:disp
//函数功能:将i的值显示在两个静态连接的数码管上
//形式参数:i,取值范围0~99
//返回值:无
void disp(uchar i)
{
uchar led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//定义0~9显示码,共阳极数码管
P1=led[i/10]; //显示i高位
P2=led[i%10]; //显示i地位
}
void main()
{
TMOD=0x10;//设置T1在工作方式1
TH1=(65536-50000)/256;//设置T1计数初值高8位,定时时间50ms
TL1=(65536-50000)%256;//设置T1计数初值低8位
ET1=1;//开放T1中断允许
EX0 = 1;
IT0 = 1;
EX1 = 1;
IT1=1;
EA=1;//开放总中断允许
TR1=1;//启动T1开始计时
while(1)
{
disp(miao);//显示秒计数器值
}
}
7. 单片机秒表设计
用AT89C51设计一个2位的LED数码显示作为“秒表”,这应该是一个仿真题,可用两位一体的共阴数码管,用定时器T0定时,得到1秒计时。