⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clock.c

📁 单片机定时器
💻 C
字号:
/*
			单片机教学打铃控制器
	芯	  片:AT89S52
	晶	  振:频率12MHz
	按键说明:
			  Ring_Set   P1^0//时间设置
			  Time_Set   P1^1//闹铃设置
			  Left_Move  P1^2//向左移动
			  Add 	     P1^3//数据增加
			  Sub        P1^4//数据减小
			  Right_Move P1^5//向右移动
			  ESC        P1^6//取消
			  Enter      P1^7//确定

*/
#include "AT89X52.H"
#include "intrins.h"

#define uchar unsigned char
#define AddressWrite24C02 0xa0//24C02写地址
#define AddressRead24C02  0xa1//24C02读地址

uchar ClockData[]={0,0,12};//时钟数据
uchar RingDataH[40];//40个闹铃数据(时)
uchar RingDataL[40];//40个闹铃数据(分)
uchar RingCount=0;//闹铃总数
uchar counter=0;
uchar I2cStartByte=0xaa;//I2c开始标志字
uchar I2cEndByte=0x55;//I2c结束标志字
uchar S_Ray_Flag=0;//秒闪标志1
sbit S_Ray=P3^1;//秒闪
sbit s_ray=P3^0;//秒闪标志2
sbit Alarm=P3^4;//闹铃信号
sbit SDA=P3^2;//I2C BUS数据
sbit SCL=P3^3;//I2C BUS时钟

//---------------------T1中断,产生时钟-------------------------------
void Timer1(void)interrupt 3 using 1
{
	TH1=0x3c;
	TL1=0xb0;
	if(counter%10==0)
	{
		s_ray=~s_ray;
		if(S_Ray_Flag)S_Ray=0;
		else S_Ray=~S_Ray;
	}
	if(counter==20)
	{
		counter=1;
		if(ClockData[0]==59)
		{
			ClockData[0]=0;
			if(ClockData[1]==59)
			{
				ClockData[1]=0;
				if(ClockData[2]==23)
				{
					ClockData[2]=0;
				}
				else ClockData[2]++;//时
			}
			else ClockData[1]++;//分
		}
		else ClockData[0]++;//秒
	}
	else counter++;	
}
//------------------BCD码转换成字形码的程序-----------------------------
uchar BCD_to_Grapheme(uchar Data)
{
	switch(Data)
	{
		case 0:return 0x3f;
		case 1:return 0x06;
		case 2:return 0x5b;
		case 3:return 0x4f;
		case 4:return 0xe6;
		case 5:return 0xed;
		case 6:return 0xfd;
		case 7:return 0x07;
		case 8:return 0xff;
		case 9:return 0xef;
	}
}

//-----------------------------得到位地址的程序-------------------------
uchar GetClockBit(uchar ShowBit)
{
	switch(ShowBit)
	{
		case 0:return 0xdf;
		case 1:return 0xef;
		case 2:return 0xf7;
		case 3:return 0xfb;
		case 4:return 0xfd;
		case 5:return 0xfe;
	}
}
//---------------------延时count个ms的程序-------------------------
void Delay(uchar count)
{
	uchar i;
	while(count--)
	{
		for(i=0;i<123;i++)
		;
	}
}
//-----------------------动态扫描的程序-------------------------------
void Display(uchar *ShowAddress,uchar FlagBit)
{
	uchar ShowBit;
	uchar Show;
	for(ShowBit=0;ShowBit<6;ShowBit++)
	{
		if(FlagBit!=5)
		{
			switch(ShowBit)
			{
				case 0:Show=BCD_to_Grapheme((*ShowAddress)%10);break;
				case 1:Show=BCD_to_Grapheme((*ShowAddress)/10);break;
				case 2:Show=BCD_to_Grapheme((*(ShowAddress+1))%10);break;
				case 3:Show=BCD_to_Grapheme((*(ShowAddress+1))/10);break;
				case 4:Show=BCD_to_Grapheme((*(ShowAddress+2))%10);break;
				case 5:Show=BCD_to_Grapheme((*(ShowAddress+2))/10);break;
			}
		}
		P2=0xff;
		switch(FlagBit)
		{
			case 0:P0=Show;break;
			case 1://设秒闪动
					if(s_ray && (ShowBit==0||ShowBit==1))P0=0x40;
					else P0=Show;
					break;
			case 2://设分闪动
					if(s_ray && (ShowBit==2||ShowBit==3))P0=0x40;
					else P0=Show;
					break;
			case 3://设时闪动
					if(s_ray && (ShowBit==4||ShowBit==5))P0=0x40;
					else P0=Show;
					break;
			case 4://调闹铃时的闪动
					if(s_ray)P0=0x40;
					else P0=Show;
					break;
			case 5://调闹铃时的显示
					P0=*(ShowAddress+ShowBit);
					break;
		}	
		P2=GetClockBit(ShowBit);
		Delay(1);
	}
}

//----------------得到键盘值的程序----------------------------------
uchar GetKey()
{
	switch(P1)
	{
		case 0xff:return 0;
		case 0xfe:return 1;
		case 0xfd:return 2;
		case 0xfb:return 3;
		case 0xf7:return 4;
		case 0xef:return 5;
		case 0xdf:return 6;
		case 0xbf:return 7;
		case 0x7f:return 8;
	}
}

//--------------------------定义I2C接口子程序-------------------------
/*
I2C特殊字节定义
*/
void I2cWait()//等待
{
	_nop_();
	_nop_();
}
	
void I2cStart()//开始
{	
	SDA=1;
	SCL=1;
	I2cWait();
	SDA=0;
	I2cWait();
	SCL=0;
}

void I2cStop()//停止
{
	SDA=0;
	I2cWait();
	SCL=1;
	I2cWait();
	SDA=1;
}
void I2cSendByte(uchar ByteData)//发送
{
	uchar i;
	for(i=0;i<8;i++)
	{
		if(ByteData&0x80)
			SDA=1;
		else
			SDA=0;
		ByteData<<=1;
		I2cWait();
		SCL=1;
		I2cWait();
		SCL=0;
		I2cWait();
	}
	SDA=1;
	I2cWait();
	SCL=1;
	I2cWait();
	SCL=0;
	I2cWait();
}

uchar I2cReceiveByte()//接收
{
	uchar i;
	uchar ByteData=0;
	for(i=0;i<8;i++)
	{
		SCL=1;
		I2cWait();
		ByteData<<=1;
		if(SDA)ByteData++;
		SCL=0;
		I2cWait();
	}
	SDA=1;
	I2cWait();
	SCL=1;
	I2cWait();
	SCL=0;
	I2cWait();
	return ByteData;
}
//--------------------------声明AT24C02的读写子程序-------------------
void I2cWrite24C02(uchar I2c24C02Addr,uchar I2c24C02Data)//写
{
	I2cStart();
	I2cSendByte(AddressWrite24C02);
	I2cSendByte(I2c24C02Addr);
	I2cSendByte(I2c24C02Data);
	I2cStop();
}

uchar I2cRead24C02(uchar I2c24C02Addr)//读
{
	uchar Data;
	I2cStart();
	I2cSendByte(AddressWrite24C02);
	I2cSendByte(I2c24C02Addr);
	I2cStart();
	I2cSendByte(AddressRead24C02);
	Data=I2cReceiveByte();
	I2cStop();
	return Data;
}
//-------------------------初始化24C02-----------------------------
void Initializtion(void)
{
	uchar i,j;
	uchar StartByte=I2cRead24C02(0);
	j=1;
	if(StartByte==I2cStartByte)
		for(i=0;i<40;i++)
		{
			if(I2cRead24C02(j)==I2cEndByte)break;
			RingDataH[i]=I2cRead24C02(j++);
			RingDataL[i]=I2cRead24C02(j++);
			RingCount++;
		}
	else
		{
			I2cWrite24C02(0,I2cStartByte);
			I2cWrite24C02(1,I2cEndByte);
		}
}

//-------------------排序的程序------------------------------------
void Taxis(void)
{
	uchar i,j,t;
	for(i=0;i<RingCount;i++)
		for(j=0;j<RingCount-i-1;j++)
			{
				if(RingDataH[j]>RingDataH[j+1])
					{
						t=RingDataH[j];
						RingDataH[j]=RingDataH[j+1];
						RingDataH[j+1]=t;
						t=RingDataL[j];
						RingDataL[j]=RingDataL[j+1];
						RingDataL[j+1]=t;
					}
				else if(RingDataH[j]==RingDataH[j+1])
						if(RingDataL[j]>RingDataL[j+1])
							{
								t=RingDataL[j];
								RingDataL[j]=RingDataL[j+1];
								RingDataL[j+1]=t;
							}
			}	
}

//---------------------------闹铃设置--------------------------------
void Control_Ring_Set_Key(void)
{
	uchar Null[]={0x00,0x38,0x38,0x3e,0x37,0x00};//"Null"的字形码
	uchar ShowRing[3];
	uchar NowKey;
	uchar i,j=1;
	uchar BeforKey=0xff;
    uchar KeyCount=0;
	uchar FlagBit=3;
	uchar ShowRingCount=0;
	uchar count1=0x40;//无操作时的时间控制
	uchar count2=0xff;//无操作时的时间控制
	S_Ray_Flag=1;
	ShowRing[0]=RingDataL[ShowRingCount];
	ShowRing[1]=RingDataH[ShowRingCount];
	ShowRing[2]=ShowRingCount;
	while(1)
	{
		if(RingCount==0)
			Display(Null,5);
		else
			Display(ShowRing,FlagBit);
		if(KeyCount==2)
		{
			KeyCount=0;
			NowKey=GetKey();
			if(NowKey!=BeforKey)
			{
				count1=0x40;
				count2=0xff;
				switch(NowKey)
				{
					case 1://增加一个闹铃
							if(RingCount!=40 && FlagBit==4)
							{
								RingDataH[RingCount]=RingDataL[RingCount]=0;	
								ShowRingCount=RingCount++;
							}
							if(RingCount==0)
							{
								RingDataH[0]=RingDataL[0]=0;
								RingCount++;
							}
							ShowRing[0]=RingDataL[ShowRingCount];
							ShowRing[1]=RingDataH[ShowRingCount];
							ShowRing[2]=ShowRingCount;
							break;
					case 2://删除一个闹铃
							if(RingCount!=0 && FlagBit==4)
							{
								if(RingCount==1)
								{
									RingDataH[0]=RingDataL[0]=0;
								}
								else
									{
										for(i=ShowRingCount;i<RingCount;i++)
										{
											RingDataH[i]=RingDataH[i+1];
											RingDataL[i]=RingDataL[i+1];
										}
										RingDataH[i]=RingDataL[i]=0;
									}
								RingCount--;	
								if(RingCount==ShowRingCount)
									ShowRingCount--;
								ShowRing[0]=RingDataL[ShowRingCount];
								ShowRing[1]=RingDataH[ShowRingCount];
								ShowRing[2]=ShowRingCount;
							}
							break;

					case 3://左移
							if(RingCount!=0)
							{
								if(FlagBit==4)FlagBit=1;
								else FlagBit++;
							}
							break;
					case 4://闹铃时间增
							switch(FlagBit)
							{
								case 1:
										if(ShowRing[0]==59)
											ShowRing[0]=0;
										else
											ShowRing[0]++;
										RingDataL[ShowRingCount]=ShowRing[0];
										break;
								case 2:
										if(ShowRing[1]==23)
											ShowRing[1]=0;
										else
											ShowRing[1]++;
										RingDataH[ShowRingCount]=ShowRing[1];
										break;
								case 3:
										if(ShowRingCount==RingCount-1)
											ShowRingCount=0;
										else
											ShowRingCount++;
										ShowRing[0]=RingDataL[ShowRingCount];
										ShowRing[1]=RingDataH[ShowRingCount];
										ShowRing[2]=ShowRingCount;
										break;
							}
							break;
					case 5://闹铃时间减
							switch(FlagBit)
							{
								case 1:
										if(ShowRing[0]==0)
											ShowRing[0]=59;
										else
											ShowRing[0]--;
										break;
								case 2:
										if(ShowRing[1]==0)
											ShowRing[1]=23;
										else
											ShowRing[1]--;
										break;
								case 3:
										if(ShowRingCount==0)
											ShowRingCount=RingCount-1;
										else
											ShowRingCount--;
										ShowRing[0]=RingDataL[ShowRingCount];
										ShowRing[1]=RingDataH[ShowRingCount];
										ShowRing[2]=ShowRingCount;
										break;
							}
							break;
					case 6://右移
				    		if(RingCount!=0)
							{
								if(FlagBit==1)FlagBit=4;
								else FlagBit--;
							}
							break;
					case 7://取消
L3:							j=1;
							RingCount=0;
							EA=0;
							for(i=0;i<40;i++)
							{
								if(I2cRead24C02(j)==I2cEndByte)break;
								RingDataH[i]=I2cRead24C02(j++);
								RingDataL[i]=I2cRead24C02(j++);
								RingCount++;
							}
							EA=1;
							goto L2;
					case 8://确定
							j=1;
					    	RingDataL[ShowRingCount]=ShowRing[0];
							RingDataH[ShowRingCount]=ShowRing[1];
							Taxis();//排序
							for(i=0;i<RingCount;i++)
							{
								EA=0;
								I2cWrite24C02(j++,RingDataH[i]);
								EA=1;
								Display(ShowRing,FlagBit);
								EA=0;
								I2cWrite24C02(j++,RingDataL[i]);
								EA=1;
								Display(ShowRing,FlagBit);
							}
							EA=0;
							I2cWrite24C02(j,I2cEndByte);
							EA=1;
							if(RingCount==0)
								Display(Null,5);
							else
								Display(ShowRing,FlagBit);
							goto L2;
								
				}  
			}
			BeforKey=NowKey;
			count2--;
			if(count2==0)
			{
				count2=0x40;
				count1--;
				if(count1==0)
					goto L3;
			}
		}
		else KeyCount++;
	}
L2:S_Ray_Flag=0;
}

//-------------时间设置的程序--------------------------------------------
void Control_Time_Set_Key()
{
	uchar S_Flag=1;
	uchar M_Flag=1;
	uchar H_Flag=1;
	uchar count1=0x40;//无操作时的时间控制
	uchar count2=0xff;//无操作时的时间控制
	uchar NowKey=0xff;
	uchar BeforKey=0xff;
    uchar KeyCount=0;
	uchar FlagBit=1;
	uchar LS_ClockData[3];
	LS_ClockData[2]=ClockData[2];
	LS_ClockData[1]=ClockData[1];
	LS_ClockData[0]=ClockData[0];
	while(1)
	{
		if(S_Flag)LS_ClockData[0]=ClockData[0];
		if(M_Flag)LS_ClockData[1]=ClockData[1];
		if(H_Flag)LS_ClockData[2]=ClockData[2];
		Display(LS_ClockData,FlagBit);//动态扫描显示
		if(KeyCount==2)
		{
		
			KeyCount=0;
			NowKey=GetKey();
			if(NowKey!=BeforKey)
			{
				count1=0x40;
				count2=0xff;
				switch(GetKey())
				{
					case 3://向左移动
							if(FlagBit==3)FlagBit=1;
							else FlagBit++;
							break;
					case 4://增加
							switch(FlagBit)
							{
								case 1://秒增加
										if(LS_ClockData[0]==59)
											LS_ClockData[0]=0;
										else LS_ClockData[0]++;	
										S_Flag=0;
										break;
								case 2://分增加
										if(LS_ClockData[1]==59)
											LS_ClockData[1]=0;
										else LS_ClockData[1]++;
										M_Flag=0;
										break;
								case 3://时增加
										if(LS_ClockData[2]==23)
											LS_ClockData[2]=0;
										else LS_ClockData[2]++;
										H_Flag=0;
										break;
							}
							break;
					case 5://减小
							switch(FlagBit)
							{
								case 1://秒减小
										if(LS_ClockData[0]==0)
											LS_ClockData[0]=59;
										else LS_ClockData[0]--;
										S_Flag=0;
										break;
								case 2://分减小
										if(LS_ClockData[1]==0)
											LS_ClockData[1]=59;
										else LS_ClockData[1]--;
										M_Flag=0;
										break;
								case 3://时减小
										if(LS_ClockData[2]==0)
											LS_ClockData[2]=23;
										else LS_ClockData[2]--;
										H_Flag=0;
										break;
							}
							break;
					case 6://向右移动
							if(FlagBit==1)FlagBit=3;
							else FlagBit--;
							break;
					case 7://取消
							goto L1;
					case 8://确定
							ClockData[2]=LS_ClockData[2];
							ClockData[1]=LS_ClockData[1];
							ClockData[0]=LS_ClockData[0];
							goto L1;
				}
			}
			BeforKey=NowKey; 
			count2--;
			if(count2==0)
			{
				count2=0x40;
				count1--;
				if(count1==0)
					goto L1;
			}
		}
		else KeyCount++;
	}
L1:;
}

//----------------------主程序-----------------------------------------------
void main()
{
	uchar NowKey;
	uchar BeforKey=0xff;
    uchar KeyCount=0;
	uchar i=1;
	Alarm=0;
	S_Ray=1;
	s_ray=1;
	Initializtion();//读24C02
	TMOD=0x10;//设置T1
	EA=1;
	ET1=1;
	PT1=1;
	TH1=0x3c;
	TL1=0xb0;
	TR1=1;
	while(1)
	{	
		Display(ClockData,0);//动态扫描
		//闹铃监视
		for(i=0;i<RingCount;i++)
		{
			if((RingDataH[i]==ClockData[2]) && (RingDataL[i]==ClockData[1]))
			{
				Alarm=1;
				break;
			}
			else Alarm=0;
		}
		//按键控制
		if(KeyCount==2)
		{
		
			KeyCount=0;
			NowKey=GetKey();
			if(NowKey!=BeforKey)
			{
				switch (NowKey)
				{
					case 1:
							Control_Time_Set_Key();
							break;
					case 2:
							Alarm=0;
							Control_Ring_Set_Key();	
							break;
					default:
							break;
				}
			}
			BeforKey=NowKey;
		}
		else KeyCount++;
	}
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -