以 电子时钟 为结尾篇,附上代码。代码有些不怎么完美。但终究是差不多写出来了。结合了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);
}
}