① 基于51单片机的电子秒表设计
这个是 数码管显示计数器程序。稍加更改 既满足要求
要精确定时,必须使用自装载方式。这里我们使用T2定时器,让它工作在16bit自动装载方式,这时,有另一个位置专门装着16位预装载值,T2溢出时,预装载值立即被置入。这就保证了精确定时。
但是,即使是16位定时器,最长的溢出时间也就几十毫秒,要定时一秒,就需要一个变量来保存溢出的次数,积累到了多少次之后,才执行一次操作。这样就可以累加到1秒或者更长的时间才做一次操作了。
T2定时器有个特殊的地方,它进入中断后,需要自己清除溢出标记,而51的其他定时器是自动清除的。请参考51单片机相关书籍。
如果使用T2定时器实现1秒精确定时
下面我们就来计算:
仿真器的晶振是22118400HZ,每秒钟可以执行1843200个机器周期。而T2每次溢出最多65536个机器周期。我们尽量应该让溢出中断的次数最少,这样对主程序的干扰也就最小。
选择每秒中断24次,每次溢出1843200/24=76800个机器周期,超出65536,无效。
选择每秒中断30次,每次溢出1843200/30=61440个机器周期
选择每秒中断32次,每次溢出1843200/32=57600个机器周期
选择每秒中断36次,每次溢出1843200/36=51200个机器周期
选择每秒中断40次,每次溢出1843200/40=46080个机器周期
从上面可以看到我们可以选择方式有很多,但是最佳的是每秒中断30次,每次溢出61440个机器周期。也就是赋定时器T2初值65536-61440=4096,换成十六进制就是0x1000。
从上面的计算也可以看出晶振2118400Hz的好处,它可以整除的倍数多,要准确定时非常方便。更常见的应用是在串口波特率上,使用22118400HZ可以输出最多准确的标准波特率。
如果是其他频率的晶振 按照上面的方法计算即可
******************************************************************/
#include <reg52.h> //包括一个52标准内核的头文件
#include<intrins.h>
/****************************声明函数*****************************/
void x8led(unsigned long ddd);
void delay882us(void);
/*****************************定义IO******************************/
sbit P20=P2^0;
sbit P21=P2^1;
sbit S16=P3^0;
sbit S15=P3^1;
sbit S14=P3^2;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
bit f=0;//位变量
/***************************定时器2中断**************************/
timer2() interrupt 5
{
static unsigned char t;
TF2=0;
t++;
if(t==30) //T2的预置值0x1000,溢出30次就是1秒钟,晶振22118400HZ 这里晶振频率不同则会有所不同
{
t=0;
f=1;//每次长时间的溢出,就置一个标记,以便主程序处理
}
}
/*****************************数码管扫描**************************/
void x8led(unsigned long ddd)
{
unsigned char q,r=0;
unsigned char l[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f};
//0-9的字段码
unsigned char xx[8]={0,0,0,0,0,0,0,0};
unsigned char y[8]={0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
xx[0]=ddd%10;
xx[2]=ddd/10%10;
xx[1]=ddd/100%10;
xx[3]=ddd/1000%10;
xx[4]=ddd/10000%10;
xx[6]=ddd/100000%10;
xx[5]=ddd/1000000%10;
xx[7]=ddd/10000000; //求出八位数,分别放在八个变量中
for(q=0;q<8;) //循环扫描
{
q++;
r++;
if(r==8)r=0;
P1=y[r];
P21=1;
delay882us();
P21=0;
P20=1;
P1=l[xx[r]];
delay882us();
P1=0xff;
P20=0;
}
}
/*******************************延时882us*************************/
void delay882us(void)
{
unsigned char i;
for(i=0;i<255;i++)
{
_nop_();
}
}
/*****************************主程序******************************/
void main(void)
{
unsigned long a=0;
RCAP2H =0x10; //赋T2的预置值0x1000,溢出30次就是1秒钟
RCAP2L =0x00;
TR2=1; //启动定时器
ET2=1; //打开定时器2中断
EA=1; //打开总中断
while(1)
{
if(f)//发现标记进入处理
{
f=0;//清除标记
a++;
if(a>99999999)a=0;
}
x8led(a);//将a的值送到数码管显示
}
}
/*****************************************************************/
② 自己做的基于单片机的秒表设计C语言程序但是第62行报错不知道怎么办,求大神帮忙
意思就是传进来参数fenshi、fenge,你在这个函数里却没有使用。
如果display使用不到这两个参数,就直接去掉就可以了。
这只是一个警告,没有什么影响。
或者这样修改一下:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit kaishi=P1^0;
sbit zanting=P1^1;
sbit dp=P0^0;
sbit w1=P2^6;
sbit w2=P2^7;
uchar temp1,temp2,temp3,aa,miaoshi,miaoge,fenshi,fenge,shishi,shige;
uchar code table[]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xfd};
void display(uchar fenshi,uchar fenge,uchar miaoshi,uchar miaoge);
void delay(uint z);
void init();
void main()
{
init();
while(1)
{
if(aa==16)
{
aa=0;
temp1++;
if(temp1==59)
{
temp1=0;
temp2++;
}
if(temp2==59)
{
temp2=0;
temp3++;
}
if(zanting==0)
{
while(zanting==0)
{
TR0=0;
display(fenshi,fenge,miaoshi,miaoge);
}
}
if(zanting!=0)
{
TR0=1;
}
miaoshi=temp1/10;
miaoge=temp1%10;
fenshi=temp2/10;
fenge=temp2%10;
}
display(fenshi,fenge,miaoshi,miaoge);
}
}
void delay(uint z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void display(uchar fenshi,uchar fenge,uchar miaoshi,uchar miaoge)
{
fenshi=fenshi;
fenge=fenge;
w1=0;
P0=table[miaoshi];
delay(2);
w1=1;
w2=0;
P0=table[miaoge];
delay(2);
w2=1;
}
void init()
{
temp1=00;
temp2=00;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void timer0()interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
aa++;
}
③ c语言设计51单片机设计简易秒表
1. 两位数码管,计时60秒可以么
2. 有空可以你帮写和仿真,但是不知道具体时间,用定时器,12M晶振,AT89单片机
④ 以下是基于单片机的电子秒表的C语言程序 球高手详细翻译 谢谢 越快越好 //
//12M晶振。4位共阴数码管,P0 段码,P2.1~P2.3 位控
//显示 00.00~99.99
//2011 07 07 E:\DPJ_C\00.00\00.00.c
//感觉你的程序不合适
#include <reg51.h>
#define uchar unsigned char
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
//sbit P23=P2^3;
sbit P07=P0^7;
sbit KS=P1^0; //开始
sbit KR=P1^1; //复位
uchar time,xs,ge,shi,,qian;
uchar code tab[ ]= {
0x3F,/*0*/
0x06,/*1*/
0x5B,/*2*/
0x4F,/*3*/
0x66,/*4*/
0x6D,/*5*/
0x7D,/*6*/
0x07,/*7*/
0x7F,/*8*/
0x6F,/*9*/
};
void delay_ms(unsigned int ms) //1ms延时
{
uchar a;
while(ms--)
for(a=123;a>0;a--);
}
void display(); //函数声明
void T0intinit( ) //定时器T0初始化
{
TMOD=0x01; //定时器0,设置定时器1采用16位定时方式
TH0=(65536-10000)/256; //10ms定时
TL0=(65536-10000)%256; //
EA=1; //打开总中断
ET0=1; //定时器0允许中断响应
}
void main()
{
T0intinit( );
while(1) //程序一直在while循环
{
display( ); //显示函数
while(!KS) //开始键按下
{
display( );//显示函数
if(KS) //
TR0=1;//定时器0启动
}
while(!KR) //清零键
{
display( );
if(KR)
TR0=0;//关定时器0
qian=0;//清零
=0;//清零
shi=0;//清零
ge=0;//清零
}
if(==10)//如果等于10
{
=0;//清零
qian++;//千位加加
}
if(qian==10)//如果qian等于10
{
qian=0;//清零
TR0=0;
}
}
}
void display( )//显示函数
{
//P23=0;
//P0=tab[ge];
//delay_ms(1);
//P23=1;
P22=0; //打开shi位选
P0=tab[shi];//将shi送入单片机
delay_ms(1);//延时
P22=1; //关闭位选
P21=0;打开位选
P0=tab[];将送入单片机
P07=1;//关闭位选
delay_ms(1);
P21=1;//关闭位选
P20=0;打开qian位选
P0=tab[qian];将qian送入单片机
delay_ms(1);
P20=1;//关闭位选
}
void T0int( ) interrupt 1 //定时器T0中断 方式1
{
TH0=(65536-10000)/256; //重装10ms定时常数
TL0=(65536-10000)%256;
ge++; //个位加加
if(ge==10) //如果ge等于10
{
ge=0;//清零
shi++;//十位加加
}
if(shi==10)//如果shi等于10
{
shi=0;//清零
++;//百位加加
}
}
⑤ 单片机课程设计电子秒表
<p>电路原理图已画好</p>
<p>实现你描述的全部功能</p>
<p>Keil
uVision3编译通过,C语言编写,有详细注释</p>
<p>实机调试通过</p>
<p>留个邮箱发给你...
</p>
<p>----------------------------</p>
<p>邮件已发......</p>
<p></p>
⑥ 求一个C语言设计的单片机程序,电子秒表,功能是LCD显示分 秒 毫秒,一个按键开始,另一个按键停止并清零
我有一个 自己写的 可以调时 暂停 并加AT24c02的 要吗?
⑦ 51单片机的秒表计时器设计,求大神帮忙设计电路图和C语言程序!!
这个程序可以实现秒的计时,按键控制开始、暂停、清零功能,更多功能自己在看清程序的基础上进行改进。
#include <reg51.H>
sbit P3_5 =P3^5;
unsigned char code dispcode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00};
unsigned char second;
unsigned char keycnt;
unsigned int tcnt;
void main(void)
{
unsigned char i,j;
TMOD=0x02;
ET0=1;
EA=1;
second=0;
P1=dispcode[second/10];
P2=dispcode[second%10];
while(1)
{
if(P3_5==0)
{
for(i=20;i>0;i--)
for(j=248;j>0;j--);
if(P3_5==0)
{
keycnt++;
switch(keycnt)
{
case 1:
TH0=0x06;
TL0=0x06;
TR0=1;
break;
case 2:
TR0=0;
break;
case 3:
keycnt=0;
second=0;
P1=dispcode[second/10];
P2=dispcode[second%10];
break;
}
while(P3_5==0);
}
}
}
}
void t0(void) interrupt 1 using 0
{
tcnt++;
if(tcnt==4000)
{
tcnt=0;
second++;
if(second==100)
{
second=0;
}
P1=dispcode[second/10];
P2=dispcode[second%10];
}
}