专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

51单片机电子时钟C语言程序

作者:huqin   来源:本站原创   点击数:  更新时间:2014年04月05日   【字体:

51最基础简单易懂的单片机,差不多一个月的时间,断断续续地学习,终于算是学完了,下个目标是飞思卡尔s12x和k60 也就是ARM crotex-M4架构. 51最核心的部分,我觉得是中断的使用,一个项目离不开中断,还有就是串口的理解,还有就是IIC通信。
以 电子时钟 为结尾篇,附上代码。代码有些不怎么完美。但终究是差不多写出来了。结合了IIC通信,中断定时器的使用,键盘使用,还有液晶的显示。
 

#include <reg52.h>
 
sbit RS = P2^7;
sbit RW = P2^6;
sbit E = P2^5;
sbit Sda = P2^0;
sbit Scl = P2^1;
sbit keyleft = P1^0;
sbit keyup = P1^1;
sbit keydown = P1^2;
sbit keyright = P1^3;


unsigned char sec=0,min=0,hour=0;
unsigned char Year[20]="   2012.10.1   ";
unsigned char i;
unsigned int times = 0;
unsigned char countleft = 0,countright = 0;


unsigned char busycheck();


static void Start(void)
{
	Sda = 1;
	Scl = 1;
	Sda = 0;
}


static void Stop(void)
{
	Sda = 0;
	Scl = 1;
	Sda = 1;
}


static unsigned char Respons(void)
{
	unsigned char OverTime = 0;  //超时
	unsigned char TempFlag = 0;
	OverTime = 0;
    Sda = 1;     //释放数据线
    Scl = 1;
	while(1)
	{
		if(Sda)   //应答信号没来
		{
			if(OverTime++ > 200)
			{
			  TempFlag = 0;   //应答信号长时间没有来,认为无应答
			  break;
			}
		}
		else
		{
		   TempFlag = 1;    ///检测到应答信号
			break;
		}
	}
	Scl = 0;
	return TempFlag;
}


static void NoRespons(void)  //非应答
{
    Sda = 1;     //释放数据线
    Scl = 1;
	Scl = 0;
}


static void WriteByte(unsigned char temp)
{
	unsigned char i;
	Scl = 0;
	for(i = 0;i < 8;i++)
	{
		Sda = temp & 0x80;
		temp <<= 1;
		Scl = 1;    //scl拉高,准备写数据
		Scl = 0;   //scl拉低,写数据完成
	}
}


static unsigned char ReadByte(void)
{
	unsigned char i;
	unsigned char x = 0;
	for(i = 0;i < 8;i++)
	{
		Scl = 1;
		x <<= 1;
		x |= (unsigned char)Sda;
		Scl = 0;	
	}
	return x;
}


void WriteIIC(unsigned char device,unsigned char parameter,unsigned char temp)
{
	Start();
	WriteByte(device);
	if(Respons())
	{
		WriteByte(parameter);
		if(Respons())
		{
			WriteByte(temp);
			if(Respons())
			{
				Stop();
			}
			else
			{
				Stop();
			}
		}
		else
		{
			Stop();
		}
	}
	else
	{
		Stop();
	}
}
unsigned char ReadIIC(unsigned char device,unsigned char parameter)
{
	unsigned char x;
	Start();
	WriteByte(device);
	if(Respons())
	{
		WriteByte(parameter);
		if(Respons())
		{
			Start();
			WriteByte(device | 0x01);
			if(Respons())
			{
				x = ReadByte();
				NoRespons();
				Stop();
			}
			else
			{
				Stop();
			}
		}
		else
		{
			Stop();
		}
	}
	else
	{
		Stop();
	}
	return x;
}


void writecmd(unsigned char cmd)
{
	while(busycheck());
	RS = 0;
	RW = 0;
	E = 1;
	P0 = cmd;
	E = 0;
}
void writedata(unsigned char dat)
{
	while(busycheck());
	RS = 1;
	RW = 0;
	E = 1;
	P0 = dat;
	E = 0;
}
unsigned char busycheck()
{
	P0 = 0xff;
	RS = 0;
	RW = 1;
	E = 0;
	E = 1;
	return(P0 & 0x80);
}
void writedate(unsigned char add,unsigned char date)
{
	unsigned char shi,ge;
	shi = date/10;
	ge = date%10;
	writecmd(0x80+0x40+add);
	writedata(0x30+shi);
	writedata(0x30+ge);
}
void Init()
{	
	writecmd(0x38);//显示模式
        writecmd(0x08);//关屏
        writecmd(0x01);//清屏
        writecmd(0x06);//设置光标右移
	writecmd(0x0c);//显示,无标 闪烁
	writecmd(0x80);
	for(i = 0;i < 20;i++)
		writedata(Year[i]);
	writecmd(0x80+0x40+6);
	writedata(':');
	writecmd(0x80+0x40+9);
	writedata(':');
	sec = ReadIIC(0xa0,0);
	min = ReadIIC(0xa0,2);
	hour = ReadIIC(0xa0,4);
	writedate(10,sec);
	writedate(7,min);
	writedate(4,hour);
	TMOD = 0x02;
	TH0 = 6;
	TL0 = 6;
	EA = 1;
	ET0 = 1;
	TR0 = 1;
}
void delay()
{
	unsigned char x = 2000;
	while(x--);
}
void keyscan()
{
	if(!keyleft)
	{
		delay();
		if(!keyleft)
		{
			TR0 = 0;
			if(countleft == 0)
			{
				countleft++;
				writecmd(0x80+0x40+10);
				writecmd(0x0f);
			}
			else
				if(countleft == 1)
				{
					countleft++;
					writecmd(0x80+0x40+7);
				}
				else
					if(countleft == 2)
					{
					countleft++;
					writecmd(0x80+0x40+4);
					}
					else
						if(countleft == 3)
						{
							TR0 = 1;
							writecmd(0x0c);
							countleft = 0;
						}
						else
						{
						}		 	
		}
		else
		{
		}
	}
	else
	{
	}
	if(!keydown)
	{
		delay();
		if(!keydown)
		{
			if(countleft == 1)
			{
				sec--;
				if(sec == 60)
					sec = 0;
				writedate(10,sec);
				WriteIIC(0xa0,1,sec);
				writecmd(0x80+0x40+10);
			}
			else
				if(countleft == 2)
				{
					min--;
					if(min == 60)
						min = 0;
					writedate(7,min);
					WriteIIC(0xa0,2,min);
					writecmd(0x80+0x40+7);
				}
				else
					if(countleft == 2)
					{
						hour--;
						if(hour == 24)
							hour = 0;
						writedate(4,hour);
						WriteIIC(0xa0,3,hour);
						writecmd(0x80+0x40+4);
					}
					else
					{
					}		 	
		}
		else
		{
		}
	}
	else
	{
	}
	if(!keyright)
	{
		delay();
		if(!keyright)
		{
			if(countleft == 1)
			{
				sec++;
				if(sec == 60)
					sec = 0;
				writedate(10,sec);
				writecmd(0x80+0x40+10);
			}
			else
				if(countleft == 2)
				{
					min++;
					if(min == 60)
						min = 0;
					writedate(7,min);
					writecmd(0x80+0x40+7);
				}
				else
					if(countleft == 2)
					{
						hour++;
						if(hour == 24)
							hour = 0;
						writedate(4,hour);
						writecmd(0x80+0x40+4);
					}
					else
					{
					}		 	
		}
		else
		{
		}
	}
	else
	{
	}
}
void main()
{
	Init();
	while(1)
	{
		keyscan();
	}
}


void Time0(void) interrupt 1
{
	times++;
	if(times == 3686)
		{
			times = 0;
			sec++;
			if(sec == 60)
			{
				sec = 0;
				min++;
				if(min == 60)
				{
					min = 0;
					hour++;
					if(hour == 24)
					{
						hour = 0;
					}
					writedate(4,hour);
					WriteIIC(0xa0,3,hour);
				}
				writedate(7,min);
				WriteIIC(0xa0,2,min);
			}
			writedate(10,sec);
			WriteIIC(0xa0,1,sec);
		}
} 
关闭窗口

相关文章