本文包含原理图、PCB、源代码、封装库、中英文PDF等资源
您需要 登录 才可以下载或查看,没有账号?注册会员
×
/********************************************************************************
* 描述: LCD1602显示实时时钟 *
* 显示方式: 设置三个按键,1号功能分别为选择时、分、秒,2号功能为每按一次数值加1,3号功能为
每按一次数值减1,每按一下,蜂鸣器都响一次,按键时钟有断电保护功能, *
* *
********************************************************************************/
#include <reg51.h>
#include <intrins.h>
#define AT24C02 0xa0
#define uchar unsigned char
#define uint unsigned int
sbit SCL=P2^0; //I2C 时钟
sbit SDA=P2^1; //I2C 数据
sbit rs=P2^6; //LCD命令/数据位
sbit rw=P2^5; //LCD读写数据位
sbit en=P2^7; //LCD使能位
sbit beep=P1^5; //按键蜂鸣声
sbit K1=P3^0; //选择位,选到相应的时、分、秒,则对应的地方闪烁
sbit K2=P3^1; //增加1
sbit K3=P3^2; //减少1
uchar shi,fen,miao;
uchar dot=':';
uchar keycase;
uchar num; //定时器溢出标志
void delays() //i2c延时函数
{
;;
}
void i2c_init() //i2c初始化
{
SDA=1;
delays();
SCL=1;
delays();
}
void i2c_respons() //i2c应答函数
{
uchar i;
SCL=1;
delays();
while((SDA==1)&&(i<250))
{
i++;
}
SCL=0;
delays();
}
void i2c_start() //i2c开始
{
SDA=1;
delays();
SCL=1;
delays();
SDA=0;
delays();
}
void i2c_stop() //i2c停止
{
SDA=0;
delays();
SCL=1;
delays();
SDA=1;
delays();
}
void i2c_write(unsigned char date) //i2c写入比特数据
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
SCL=0;
delays();
SDA=CY;
delays();
SCL=1;
delays();
}
SCL=0;
delays();
SDA=1;
delays();
}
unsigned char i2c_read() //i2c读取数据
{
uchar i,temp;
SCL=0;
delays();
SDA=1;
delays();
for(i=0;i<8;i++)
{
SCL=1;
delays();
temp=(temp<<1)|SDA;
delays();
SCL=0;
delays();
}
return temp;
}
void i2c_wadd(unsigned char address,unsigned char date) //i2c写入RAM地址
{
i2c_start();
i2c_write(0xa0);
i2c_respons();
i2c_write(address);
i2c_respons();
i2c_write(date);
i2c_stop();
}
unsigned char i2c_radd(unsigned char address) //i2c读取RAM存储数据
{
uchar date;
i2c_start();
i2c_write(0xa0);
i2c_respons();
i2c_write(address);
i2c_respons();
i2c_start();
i2c_write(0xa1);
i2c_respons();
date=i2c_read();
i2c_stop();
return date;
}
void delay(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void bp()
{
beep=~beep;
delay(300);
beep=~beep;
}
void write_com(uchar com) //写LCD命令
{
rs=0;
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write_data(uchar date) //写LCD显示数据
{
rs=1;
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void lcd_init() //LCD初始化
{
rs=0;
rw=0;
en=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
}
void T0_init() //定时器0中断设置初始化
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
}
void display(uchar addr,uint time) //显示函数
{
uchar s,g;
s=time/10;
g=time%10;
write_com(0x80+addr);
write_data(0x30+s);
write_data(0x30+g);
}
void keyscan() //检测KEY 是否被按下
{
if(0==K1)
{
delay(5);
if(0==K1) //确认K1被按下
{
bp();
keycase++; //功能键选择
while(!K1);
if(1==keycase) //选择到时
{
TR0=0; //关闭中断
write_com(0x80+0x02); //定位到 时位
write_com(0x0f); //光标闪烁开启
}
if(2==keycase) //选择到分
{
write_com(0x80+0x05);
}
if(3==keycase) //选择到秒
{
write_com(0x80+0x08);
}
if(4==keycase) //清除功能
{
TR0=1; //复位中断
keycase=0;
write_com(0x0c); //光标消失不闪烁
}
}
}
if(keycase!=0)
{
if(0==K2)
{
delay(5);
if(0==K2) //确认K2被按下
{
bp();
while(!K2);
if(1==keycase)
{
shi++;
if(shi>24)
{
shi=0;
}
display(2,shi);
write_com(0x80+0x02);
i2c_wadd(3,shi);
}
if(2==keycase)
{
fen++;
if(fen>59)
{
fen=0;
}
display(5,fen);
write_com(0x80+0x05);
i2c_wadd(2,fen);
}
if(3==keycase)
{
miao++;
if(miao>59)
{
miao=0;
}
display(8,miao);
write_com(0x80+0x08);
i2c_wadd(1,miao);
}
}
}
if(0==K3)
{
delay(5);
if(0==K3)
{
bp();
while(!K3);
if(1==keycase)
{
shi--;
if(shi<0)
{
shi=23;
}
display(2,shi);
write_com(0x80+0x02);
i2c_wadd(3,shi);
}
if(2==keycase)
{
fen--;
if(fen<0)
{
fen=59;
}
display(5,fen);
write_com(0x80+0x05);
i2c_wadd(2,fen);
}
if(3==keycase)
{
miao--;
if(miao<0)
{
miao=59;
}
display(8,miao);
write_com(0x80+0x08);
i2c_wadd(1,miao);
}
}
}
}
}
void main()
{
shi=0;
fen=0;
miao=0;
num=0;
i2c_init();
lcd_init();
T0_init();
write_com(0x80+0x04);
write_data(':');
delay(5);
write_com(0x80+0x07);
write_data(':');
delay(5);
miao=i2c_radd(1);
fen=i2c_radd(2);
shi=i2c_radd(3);
display(8,miao);
display(5,fen);
display(2,shi);
TR0=1;
while(1)
{
keyscan();
}
}
void TO_time() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
num++;
if(num==20)
{
num=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
display(2,shi);
i2c_wadd(3,shi);
}
display(5,fen);
i2c_wadd(2,fen);
}
display(8,miao);
i2c_wadd(1,miao);
}
}
问题描述:I2C不能保存数据啊 |
|