采用51单片机设计一个计时器前期准备
一、所执行的功能
1、可以计时;
2、可以存储时间;
3、可以查看存储的时间;
二、器材
1、51单片机(STC89C52RC)及单片机最小系统;
2、7段数码管及74HC573锁存器2个;
3、按键;
4、电源;
三、硬件电路的设计
1、51单片机最小系统:电源、复位电路、晶振电路、下载电路、51单片机
2、显示电路
3、按键电路
四、分析单片机编程的内部资源
1、I/O口的使用;
2、定时/计数器的使用;
五、软件编写流程的设计
1、定义端口(数码管显示端口,定义按键输入的端口,每个端口分配不同的名字)
2、硬件资源的初始化(初始化定时计数器,初始化LED数码管、初始化按键)
3、定时计数器:用于精确计时的产生;
4、I/O口:LED数码管显示;按键检测;
5、功能的初始化(工作状态初始化、显示器初始化);
6、工作状态:a、等待状态;b、计数状态;c、存储状态;
六、程序代码
#include<reg52.h>
/*****************端口定义****************/
typedef unsignedint UINT16;
typedef unsignedchar UINT8;
#define DATA P0
sbitseg_sel=P2^0; //段选
sbitbit_sel=P2^1; //位选
sbitstart=P2^2; //开始
sbitstore=P2^3; //存储
sbitdiskey=P2^4; //回显
sbitreset=P2^5; //复位
UINT8 codeseg_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
UINT8 codebit_table[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
UINT8n_ten_ms,n_second,n_minute;
UINT8 run_flag;
UINT8temp_buf[5][3];
UINT8 arry_point;
/************延时函数*************/
void delayms(UINT8ms)
{
UINT8 x,y;
for (x=ms;x>0;x--)
for(y=112;y>0;y--);
}
/********定时器初始化**********/
voidInitTimer0(void)
{
TMOD = 0x01; //定时器模式寄存器设置
TH0 = 0x0DC; //定时器赋初值时间50微秒
TL0 = 0x000;
EA = 1; //打开总开关
ET0 = 1; //打开中断
//TR0 = 1; //打开定时器
}
/**********数码管的初始化********/
voiddisplay_led(UINT8 which_bit,UINT8 which_number)
{
bit_sel=1;
DATA=bit_table[which_bit];
bit_sel=0;
seg_sel=1;
DATA=0x00;
seg_sel=0;
seg_sel=1;
DATA=seg_table[which_number];
seg_sel=0;
}
/**************数码管显示***********/
void display(UINT8which_bit,UINT8 which_number)
{
UINT8 ge,ten;
ten=which_number/10;
ge=which_number%10;
display_led(5,16);
delayms(5);
display_led(2,16);
delayms(5);
if(which_bit==1)
{
display_led(6,ten);
delayms(5);
display_led(7,ge);
delayms(5);
}
if(which_bit==2)
{
display_led(3,ten);
delayms(5);
display_led(4,ge);
delayms(5);
}
if(which_bit==3)
{
display_led(0,ten);
delayms(5);
display_led(1,ge);
delayms(5);
}
}
/*************回显按键函数***************/
voiddiskey_keyscan()
{
if(diskey==0)
{
delayms(5);
if(diskey==0)
{
arry_point--;
n_ten_ms=temp_buf[arry_point][0];
n_second=temp_buf[arry_point][1];
n_minute=temp_buf[arry_point][2];
}
while(!diskey);
}
}
/*************开始键函数*************/
voidstart_keyscan()
{
if(start==0)
{
delayms(5);
if(start==0)
{
run_flag=~run_flag;
}
while(!start);
}
if(run_flag)
{
TR0=1;
}
else if(!run_flag)
{
TR0=0;
diskey_keyscan();
}
}
/*************复位按键函数***********/
void reset_keyscan()
{
if(reset==0)
{
delayms(5);
if(reset==0)
{
n_ten_ms=0;
n_second=0;
n_minute=0;
run_flag=0;
}
while(!reset);
}
}
/************存储按键函数************/
voidstore_keyscan()
{
if(store==0)
{
delayms(5);
if(store==0)
{
if((arry_point>=0)&&(arry_point<5))
{
temp_buf[arry_point][0]=n_ten_ms;
temp_buf[arry_point][1]=n_second;
temp_buf[arry_point][2]=n_minute;
arry_point++;
}
}
while(!store);
}
}
/*************按键扫描函数***********/
void keyscan()
{
start_keyscan();
delayms(5);
reset_keyscan();
delayms(5);
store_keyscan();
delayms(5);
}
/**********扫描函数************/
void reflash()
{
display(1,n_ten_ms);
display(2,n_second);
display(3,n_minute);
}
/**********主函数**************/
int main(void)
{
InitTimer0();
while(1)
{
keyscan();
reflash();
}
}
/**********中断***************/
voidTimer0Interrupt(void) interrupt 1
{
TH0 = 0x0DC;
TL0 = 0x000;
n_ten_ms++;
if(n_ten_ms>=100)
{
n_ten_ms=0;
n_second++;
if(n_second>=60)
{
n_second=0;
n_minute++;
if(n_minute>=60)
{
n_minute=0;
}
}
}
}