基于proteus的时钟

原理图

在这里插入图片描述

代码程序

main.c

#include "common.h"

task_t data tasks[]={
	{display,1,0,TS_READY},
	{timecount,1000,0,TS_READY},
	{timeshow,50,0,TS_READY},
	{keyalone,8,0,TS_READY},
};
code u8 tasks_size=sizeof(tasks)/sizeof(task_t); // 当前系统中的任务数量
void init_task(){
	// 定义每个任务的句柄 handle 
	// 句柄的主要作是用来动态修改任务的属性。
	// 通过动态改变任务的属性,你可以实现延时、刷新速度调整、任务禁用启用等功能。
	display_h=tasks+0;
	timecount_h = tasks + 1;
	timeshow_h =tasks +2;
	keyalone_h =tasks +3;
	//将 timer2 设置为系统时钟。每毫秒加一
	//timer0 init
	TMOD=0X01;
	TL0 = 0x18;	//设置定时初值
	TH0 = 0xFC;
	TF0 = 0;	
	TR0 = 1;
	ET0=1;//打开定时器中断
	EA=1;//打开总中断
}
//tick用来记录当前的开机时间。单位ms。
u32 tick = 0;
void Time0() interrupt 1
{
	TL0 = 0x18;	//每次溢出之后要手动进行一次初始化。
	TH0 = 0xFC;
	++tick;//
}
task_t data * get_nearest_task(){
	u8 i;
	task_t data * data task;
	u32 timeout=u32_max;
	for(i=0;i<tasks_size;++i){
		if(tasks[i].t<timeout&&TS_READY==tasks[i].s){
			task=tasks+i;
			timeout=task->t;
		}
	}
	return task;
}
void main()
{
	init_task(); // 全局初始化。
	//       使用 data 关键字修饰的目的是将频繁使用的变量编译在 data 段,以优化程序运行性能。
	//       同理所有变量定义中的其它修饰关键字也可以去掉,比如 code data xdata 等。(但是程序性能会有部分影响,但是运行效果几乎没有区别)
	
	for(;;){
		static task_t data * data task;  // 由于编译中寄存器优化问题,必须将 task_t 变量定义为 static。
		task=get_nearest_task();         // 获取最近的就绪任务。
		if(task->t>tick)                 // 判断是否已经到达该任务的下一次执行时间。
			continue;                    // 如果没有没有到达,继续循环取出最近的任务判断。
		task->s=TS_RUNNING;              // 设置任务状态为运行中。(如果在程序中你不需要判断任务状态,就可以不用设置,省略掉)
		((fun_t)(task->f))();            // 将任务函数 f 取出,强制转换为函数类型((fun_t)(task->f)),然后调用()。
		task->s=TS_READY;                // 设置任务状态为就绪中。(同上,可以省略)
		task->t=tick+task->i;            // 更新任务的下一次调用时间 (t=tick+i)。(下一次调用时间更新为当前时间加上调用时间间隔)
	}
}

task.c

#include "common.h"

u8 code dsp_code[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//共阳段码表
u8 dsp_buff[]={0,0,0,0,0,0};
sbit k1= P2^6;
sbit k2=P2^7;
sbit k3=P3^0;
sbit k4=P3^1;
u8 show_stat=0;
u8 time_sec=54;
u8 time_min=59;
u8 time_hou=16;
u8 sec_flag=0;
u8 min_flag=0;
u8 ch_start=0;
u8 run_flag=1;
u8 temp=0;
/************************显示函数*********************/
task_t* display_h;

void display(){

	static u8 dsp_com=0;
	SEG_LE=1;
	P0=0xff;
	P0=dsp_code[dsp_buff[dsp_com]];
	P2=(1<<dsp_com)|0xc0;
	SEG_LE=0;
	if(++dsp_com==6) dsp_com=0;
}

/***********************时钟计数********************/
task_t* timecount_h;

void timecount(){
		if(run_flag==1){
			if(++time_sec==60){
				time_sec=0;
				sec_flag=1;
			}
			if(sec_flag==1){
				if(++time_min==60){
					time_min=0;
					min_flag=1;
				}
				sec_flag=0;
			}
			if(min_flag==1){
				if(++time_hou==24){
					time_hou=0;
					
				}
				min_flag=0;
			}
			
		}
}
/************************显示刷新*****************/
task_t* timeshow_h;
void timeshow(){
	static u16 count=0;
	static u8 blink=0;
	if(show_stat==0){
		dsp_buff[0]=time_hou/10;
		dsp_buff[1]=time_hou%10;
		dsp_buff[2]=time_min/10;
		dsp_buff[3]=time_min%10;
		dsp_buff[4]=time_sec/10;
		dsp_buff[5]=time_sec%10;
	}
	else if(show_stat==1){
			if(blink){
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
			else{
					dsp_buff[0]=10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
	
	}
	else if(show_stat==2){
			if(blink){
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
			else{
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
	
	}
	else if(show_stat==3){
			if(blink){
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
			else{
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
	
	}
	else if(show_stat==4){
			if(blink){
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
			else{
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
	
	}
	else if(show_stat==5){
			if(blink){
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
			else{
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=10;
					dsp_buff[5]=time_sec%10;
			}
	
	}
	else if(show_stat==6){
			if(blink){
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=time_sec%10;
			}
			else{
					dsp_buff[0]=time_hou/10;
					dsp_buff[1]=time_hou%10;
					dsp_buff[2]=time_min/10;
					dsp_buff[3]=time_min%10;
					dsp_buff[4]=time_sec/10;
					dsp_buff[5]=10;
			}
	
	}
	count+=50;
	if(count>600){
		blink=1;		
	}
	else
		blink=0;
	if(count>1200)
			count=0;
}
/****************************独立按键*************************/
task_t* keyalone_h;
void keyalone(){
		static u8 key_stat=0;
		u8 key_val=0;
		if(k3==0)
			key_val = 3;
		else if(k1==0)
			key_val = 1;
		else if(k2==0)
			key_val =2;
		else if(k4==0)
			key_val=4;
		else 
			key_val=0;
		switch(key_stat){
			case 0:
				if(key_val!=0)
					key_stat=1;
				break;
			case 1:
				if(key_val==0)
						key_stat=0;
				else{
					key_stat=2;
					if(key_val==1){
						if(show_stat==1){
							if(time_hou/10<2){
							temp = (time_hou/10)+1;
							time_hou=temp*10+time_hou%10;
							}
						}
						else if(show_stat==2){
							if(time_hou%10<9){
								time_hou=time_hou + 1;
							}
						}
						else if(show_stat==3){
							if(time_min/10<5){
							temp = (time_min/10)+1;
							time_min=temp*10+time_min%10;
							}
						}
						else if(show_stat==4){
							if(time_min%10<9){
								time_min=time_min + 1;
							}
						}
						else if(show_stat==5){
							if(time_sec/10<5){
							temp = (time_sec/10)+1;
							time_sec=temp*10+time_sec%10;
							}
						}
						else if(show_stat==6){
							if(time_sec%10<9){
								time_sec=time_sec + 1;
							}
						}
					}
					else if(key_val==2){
						if(show_stat==1){
							if(time_hou/10>0){
								temp = (time_hou/10)-1;
								time_hou=temp*10+time_hou%10;
							}
						}
						else if(show_stat==2){
								if(time_hou%10>0){
									time_hou=time_hou - 1;
							}
						}
						
						else if(show_stat==3){
							if(time_min/10>0){
								temp = (time_min/10)-1;
								time_min=temp*10+time_min%10;
							}
						}
						else if(show_stat==4){
								if(time_min%10>0){
									time_min=time_min - 1;
							}
						}
						else if(show_stat==5){
							if(time_sec/10>0){
								temp = (time_sec/10)-1;
								time_sec=temp*10+time_sec%10;
							}
						}
						else if(show_stat==6){
								if(time_sec%10>0){
									time_sec=time_sec - 1;
							}
						}
					}
					else if(key_val==3){//当k3被按下
							switch(show_stat){
								case 0:
									show_stat=1;
									run_flag=0;
								break;
								case 1:
									show_stat=2;
									run_flag=0;
								break;
								case 2:
									show_stat=3;
									run_flag=0;
								break;
								case 3:
									show_stat=4;
									run_flag=0;
								break;
								case 4:
									show_stat=5;
									run_flag=0;
								break;
								case 5:
									show_stat=6;
									run_flag=0;
								break;
								case 6:
									show_stat=0;
									run_flag=1;
								break;
									
							}
					
					}
					else if(key_val==4){//当k4被按下的时候
							show_stat=0;
							run_flag=1;
					
					}
					
				}
				break;
			case 2:
				if(key_val==0)
					key_stat=0;
				break;
				
		
		}

}
#ifndef __COMMON_H_
#define __COMMON_H_

#include<reg52.h>
#include "intrins.h"
sbit SEG_LE = P1^0;
sbit led2 = P1^1;
typedef unsigned char u8;  // 定义u8类型,简写,加快开发速度。
typedef unsigned int u16;
typedef unsigned long u32;

#define u8_max ((u8)-1)    // u8 最大值
#define u16_max ((u16)-1)
#define u32_max ((u32)-1)

#define true 1              // 同上
#define false 0

// 定义函数类型 相当于定义一个参数为空,返回值为空的函数类型。2byte
typedef void fun_t(void);
// 定义任务结构体
typedef struct{
	u16 f;   //function // 任务对应的函数,调用的时候需要将其强制转换为 fun_t 函数类型来调用。
	u16 i;   //interval // f 函数每隔多少毫秒调用一次。
	u32 t;   //timeout  // f 函数下一次调用的时间。如果 (t<=tick) f 函数就会被调用,调用完成过后就会更新 (t=tick+i) (下一次调用时间更新为当前时间加上调用时间间隔)
	u8 s;    //state    // 当前任务的状态 TS_DISABLE(禁用),TS_READY(就绪),TS_RUNNING(运行)
}task_t;
enum TS_STATE{TS_DISABLE,TS_READY,TS_RUNNING};  // TASK STATE 当前任务状态的枚举。
extern u32 tick;

/******************************全局变量区*******************************/

/******************************任务函数区********************************/

void display();//数码管显示
void timecount();//计数模块
void timeshow();
void keyalone();
/******************************任务控制块********************************/
extern task_t* display_h;//数码管显示
extern task_t* timecount_h;//计数模块
extern task_t* timeshow_h;
extern task_t* keyalone_h;
#endif
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值