课程设计——分组秒表C程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/***************************************************************************** * 标题: 试验数码管调试秒表(译码器位选共阴极)
*
*
* 说明:本计时器可一次性记录3个人的时间
*
* 使用S1,S2,S3按键
* (1)S1为功能按键,按4次有效:
* 第1次:开始计时
* 第2次:记录第一个人的时间
* 第3次:记录第二个人的时间
* 第4次:记录第三个人的时间,显示停止,且不再计时
* (2)S2为读取按键,按3次有效
* 第1次:读取第一个人的时间
* 第2次:读取第二个人的时间
* 第3次:读取第三个人的时间
* 当按下第4次时,又读取第一个人的时间
* (3)S3为复位按键
******************************************************************************/
#include<reg52.h>
#include<stdio.h>
#include<string.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit A_138 = P1^7;
sbit B_138 = P1^6;
sbit C_138 = P1^5;
sbit BEEP = P3^7;
sbit S1 = P1^4;
sbit S2 = P1^3;
sbit S3 = P1^2;
sbit CP = P3^4;
sbit AB = P1^1;
sbit DS = P3^2;
uint count;//定义变量count临时储存定时器的时间
uint time;//时间,以0.01秒为一个单位
uint n;
uint t2,t1,ge,shi,bai,qian; //0.01秒,0.1秒,秒, 十秒,百秒,千秒
uint S1num,S2num,S3num; //分别表示功能键按下的次数,读取键按下的次数,复位键uchar table[]={ 0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x80, // . 10
};
uchar fbai[3],fshi[3],fge[3],ft1[3],ft2[3]; //定义5个数组来存放个人时间
void init();
void delay(uint z);
void duanxuan(uint value);
void weixuan(uint value);
void disp(uint wei,uint duan);
void calculate(uint value);
void disp_time();
void disp_time1(uint i);
void keyscan();
void reset();
uchar readkey();
void main()
{
init(); //初始化
while(1)
{
calculate(time); //计算时间
disp_time(); //显示时间
keyscan(); //按键判断
reset(); //复位判断
}
}
/********************* 初始化化***********************/
void init()
{
BEEP = 0; //蜂鸣器关
TMOD=0x01; //定时器T0,工作方式1; 12mhz晶振
// TH0=0xec;
// TL0=0x78; //T0定时5ms
TH0=0xf7;
TL0=0x04; //定时2.3ms
EA=1; //CPU总中断允许位
ET0=1; //定时/计数器中断允许位
TR0=0; //启动定时器0
}
/*********************** 延时函数(约10ms)***********************/ void delay(uint z)
{
uint x,y;
for(x=80;x>0;x--)
for(y=z;y>0;y--);
}
/******************************************************************* 功能说明:数码管段选,当temp右移8位时,把temp的值全赋给74LS164 参数说明:value为数码管显示的数值
*******************************************************************/
void duanxuan(uint value)
{
uint temp,i;
temp=table[value];
for(i=0;i<8;i++)
{
CP=0; //CP给低电平
AB=temp&0x01; //保留最低位发送,即低位在前
CP=1; //CP给高电平,产生一个上升沿,74ls164工作
temp>>=1; //temp右移
}
}
/*******************************************************************
功能说明:数码管位选
参数说明:value为第i个数码管,从高位向低位依次递增(百位——数码管1,十位——数码管2,以此类推)
*******************************************************************/
void weixuan(uint value)
{
switch(value)
{
case 1:{A_138 = 0; B_138 = 0; C_138 =0;}break; //选中第1个数码管
case 2:{A_138 = 1; B_138 = 0; C_138 =0;}break; //选中第2个数码管
case 3:{A_138 = 0; B_138 = 1; C_138 =0;}break; // .
case 4:{A_138 = 1; B_138 = 1; C_138 =0;}break; // .
case 5:{A_138 = 0; B_138 = 0; C_138 =1;}break; // .
case 6:{A_138 = 1; B_138 = 0; C_138 =1;}break; //选中第6个数码管
default:{A_138 = 1; B_138 = 1; C_138 =1;}break; //不选中数码管,即关掉位选}
}
/******************************************************************* 功能说明:数码管显示,调用weixuan(uint value),duanxuan(uint value)函数参数说明:wei为位选,duan为段选
*******************************************************************/ void disp(uint wei,uint duan)
{
weixuan(7); //关掉位选,避免闪烁
duanxuan(duan);//数码管段选
weixuan(wei); //数码管位选
delay(10);
}
/******************************************************************* 功能说明:给定一个算法,把一个数分解到个位,十位,百位
参数说明:value为要进行分解的数
*******************************************************************/ void calculate(uint value)
{
bai = value/10000%10; //百位数值
shi = value/1000%10; //十位数值
ge = value%1000/100; //个位数值
t1 =value%100/10; //0.1秒
t2 = value%10; //0.01秒
}
/*********************** 显示时间***********************/
void disp_time()
{
disp(1,bai); //第1个数码管显示百位的数值
disp(2,shi); //第2个数码管显示十位的数值
disp(3,ge); //第3个数码管显示个位的数值
disp(3,10); //加小数点
disp(4,t1); //第4个数码管显示-1位的数值
disp(5,t2); //第5个数码管显示-2位的数值
}
/******************************************************************* 功能说明:记录个人时间
参数说明:i代表第i个人
*******************************************************************/ void disp_time1(uint i)
{
disp(1,fbai[i]); //显示第i个人的百位
disp(2,fshi[i]); // .
disp(3,fge[i]); // .
disp(3,10); //加小数点
disp(4,ft1[i]); // .
disp(5,ft2[i]); // .
}
/******************************************************************* 功能说明:按键功能
参数说明:
*******************************************************************/ void keyscan()
{
if(S1==0) //判断S1键是否按下
{
delay(5); //延时消抖
if(S1==0)
{
S1num++;
while(!S1); //判断是否松手
BEEP=1;
delay(20);
BEEP=0;
switch(S1num)
{
case 1: {TR0=1;disp_time();}break; //按下1次打开定时器0,开始计时
case 2: {fbai[1]=bai;fshi[1]=shi;fge[1]=ge;ft1[1]=t1;ft2[1]=t2;}break;//按下2次,存储第一个人时间,但是还在计时
case 3: {fbai[2]=bai;fshi[2]=shi;fge[2]=ge;ft1[2]=t1;ft2[2]=t2;}break;//按下3次,存储第二个人时间,但是还在计时
default: {TR0=0;}break; //按下4次的时候,存储第三个人时间,定时器停止工作,数码管显示清零
}
}
}
/********************************************************************/
n=readkey(); //用n来代替S2num,表示S2按下的次数
switch(n)
{
case 1:{
do
{
readkey(); //判断S2键是否被按下
disp_time1(1); //显示第一组时间
reset(); //判断是否复位
}while(S2num==1); //当S2按键只被按下1次的时候一直做此循环}break;
case 2:{
do
{
readkey();
disp_time1(2);
reset();
}while(S2num==2);
}break;
default: S2num=0;break;
}
}
/******************************************************************* 功能说明:记录S2键按下次数
参数说明:
*******************************************************************/ uchar readkey()
{
if(S2==0) //判断S2键是否按下
{
delay(5); //延时消抖
if(S2==0)
{
S2num++;
while(!S2); //判断是否松手
BEEP=1;
delay(20);
BEEP=0;
}
}
return S2num;
}
/*********************** 复位函数***********************/
void reset()
{
if(S3==0) //判断复位键是否按下
{
delay(5); //延时消抖
if(S3==0)
{
while(!S3); //判断是否松手
S1num=0; //S1复位
S2num=0; //S2复位
S3num=1; //复位键判断标准
TR0=0; //关闭定时器0
time=0; //计数清零
memset(fbai,0,sizeof(fbai)); //将fbai[]这个数组清零
memset(fshi,0,sizeof(fshi));
memset(fge,0,sizeof(fge));
memset(ft1,0,sizeof(ft1));
memset(ft2,0,sizeof(ft2));
BEEP=1;
delay(20);
BEEP=0;
}
}
}
/*********************** 定时/计数器0 ***********************/ void timer0() interrupt 1
{
TH0=0xf7;
TL0=0x04;
count++;
if(count==2)
{
count=0;
time++;
}
}。

相关文档
最新文档