#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_data P0 //数据口 LCD_7-14
#define AM(X) X
#define PM(X) (X+12) // 转成24小时制
#define DS1302_SECOND 0x80 //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define WriteDeviceAddress 0xa0//24C02的从器件地址(写)
#define ReadDeviceAddress 0xa1//24C02的从器件地址(读)
sbit DS1302_CLK = P1^7; //实时时钟时钟线引脚
sbit DS1302_IO = P1^6; //实时时钟数据线引脚
sbit DS1302_RST = P1^5; //实时时钟复位线引脚
sbit key1=P3^5;
sbit key2=P3^6;
sbit key3=P3^7;
sbit key11=P3^5;
sbit key22=P3^6;
sbit key33=P3^7;
sbit keyshi=P3^5;
sbit keyfen=P3^6;
sbit IOCLK=P1^0;
sbit DATAOUT=P1^1;
sbit cs=P1^2;
sbit LCD_RS=P2^0; //寄存器选择输入 LCD_4
sbit LCD_RW=P2^1; //液晶读/写控制 LCD_5
sbit LCD_EN=P2^2; //液晶使能控制 LCD_6
sbit LCD_PSB=P2^3; //串/并方式控制 LCD_15
sbit LCD_RST=P2^5; //液晶复位端口 LCD_17
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
code uchar zk[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar shuzi[14];
sbit sda=P2^6;
sbit scl=P2^7;
bit write=0;
//volatile uchar key_value;
uchar num2;
uchar temp=0,temp1=0;
uint t,vot;
uchar a,tab24c02[10];
uchar shu[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2E,0x1a,0x3a};
uchar code table[]={0x82,0x92,0x8a,0x9a};
void delayms(uint zms)
{
uint i,j;
for(i=zms;i>0;i--)
for(j=110;j>0;j--);
}
void start( )
{
sda=1;
scl=1;
sda=0;
scl=0;
}
//停止信号函数
void stop( )
{
scl=0;
sda=0;
scl=1;
sda=1;
}
//24c02的应答信号函数
bit at24c02_ask( )
{
bit ErrorBit;
sda=1;
scl=1;
ErrorBit=sda;
scl=0;
return(ErrorBit);
}
//单片机写数据时的应答信号函数 ;注意:此函数在这个程序中没有用到。
void c51_ask( )
{
sda=0;
scl=1;
scl=0;
}
void c51_no_ask( )//单片机接收数据时的应答信号,一旦有该应答信号,则读操作结束
//也称作无应答信号函数
{
sda=1;
scl=1;
scl=0;
}
//写一个8位数到24C02函数
void write_8bit_24c02(uchar sentdata)
{
uchar k;
for(k=0;k<8;k++)
{
sda=(bit)(sentdata&0x80);
scl=1;
scl=0;
sentdata<<=1;
}
}
//写一个字节到24C02函数
void write_1byte_24c02(uchar ch,uchar address)
{
start( );//起始信号
write_8bit_24c02(WriteDeviceAddress);//向24C02写入“写操作命令”
at24c02_ask( );//24C02的应答
write_8bit_24c02(address);//向24C02写入地址,该地址用于存放待写入的数据
at24c02_ask( );//24C02的应答
write_8bit_24c02(ch);//向24C02写入数据,这个数据被保存在刚指定的地址中
at24c02_ask( );//24C02的应答
stop( );//停止信号
delayms(10);//此处必需要有延时,因为24C02在写数据时,需要5ms;否则24C02无法进行内部数据的擦写!
}
//从24C02中读出8位数
uchar read_8bit_24c02( )
{
uchar i;
uchar recdata=0;
for(i=0;i<8;i++)
{
scl=1;
recdata<<=1;
recdata|=((uchar) (sda));
scl=0;
}
return (recdata);
}
//从24C02中以选择读方式读出一个字节
uchar read_1byte_24c02(uchar address)
{
uchar ch;
start( );//起始信号
write_8bit_24c02(WriteDeviceAddress);//向24C02写入“写操作命令”
//注意:此处写在write_8bit_24c02函数中的地址是:WriteDeviceAddress,既0xa0
at24c02_ask( );//24C02的应答
write_8bit_24c02(address);//向24C02写入地址,该地址指向待调出的数据位置
at24c02_ask( );//24C02的应答
start( );//起始信号
write_8bit_24c02(ReadDeviceAddress);//向24C02写入“读操作命令”
//第2次写地址时,才写ReadDeviceAddress,既0xa1
at24c02_ask( );//24C02的应答
ch=read_8bit_24c02( );//从24C02的指定地址中读出数据,并将其保存在变量ch中
c51_no_ask( );//单片机无应答
stop( );//停止信号
return (ch);//读出字节,无需延时;
}
void DS1302InputByte(unsigned char d) //实时时钟写入一字节(内部函数),LSB
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0; //相当于汇编中的 RRC
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1;
}
}
unsigned char DS1302OutputByte(void) //实时时钟读取一字节(内部函数),LSB
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; //相当于汇编中的 RRC
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要写的数据
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令.注意:写字节命令中的地址的最低位为0(规定)
DS1302InputByte(ucDa); // 写1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //读取DS1302某地址的数据
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令.注意:读字节命令中的地址的最低位为1(规定)
ucData = DS1302OutputByte(); // 读1Byte数据
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_GetTime() //获取时钟芯片的时钟数据到自定义的结构型数组
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
shuzi[1] = (ReadValue&0x70)>>4 ;
shuzi[0]=(ReadValue&0x0F);//由于Read1302(DS1302_SECOND)得到的是BCD码,此举是将BCD码转换成十进制数.
ReadValue = Read1302(DS1302_MINUTE);
shuzi[3] = (ReadValue&0x70)>>4;
shuzi[2] =(ReadValue&0x0F);//BCD-十进制
ReadValue = Read1302(DS1302_HOUR);
shuzi[5] = (ReadValue&0x70)>>4;//若选择PM,则此处改为shuzi[5] = (ReadValue&0x10)>>4;
shuzi[4] =(ReadValue&0x0F);//BCD-十进制
ReadValue = Read1302(DS1302_DAY);
shuzi[7] = (ReadValue&0x70)>>4;
shuzi[6] =(ReadValue&0x0F);//BCD-十进制
ReadValue = Read1302(DS1302_WEEK);
shuzi[9] = (ReadValue&0x70)>>4 ;
shuzi[8] = (ReadValue&0x0F);//BCD-十进制
ReadValue = Read1302(DS1302_MONTH);
shuzi[11] = (ReadValue&0x70)>>4;
shuzi[10] = (ReadValue&0x0F);//BCD-十进制
ReadValue = Read1302(DS1302_YEAR);
shuzi[13] = (ReadValue&0x70)>>4;
shuzi[12] = (ReadValue&0x0F);//BCD-十进制
}
void lcd12864busy(void)
{
bit sign;
LCD_RS=0;
LCD_RW=1;
do{
LCD_data=0xff; //置数据传送端口为输入态
LCD_EN=1;
sign=(bit)(LCD_data>>7);//取得BF的值 ,BF的值为1时,表示处于忙碌状态
LCD_EN=0;
}while(sign);
}
void lcd12864write(uchar num,uchar v)
{
lcd12864busy();//忙判别
LCD_RS=v; //写指令时为0,写数时为1
LCD_RW=0;
LCD_EN=1;
LCD_data=num;
LCD_EN=0;
}
void WriteCharstringTo12864(uchar *string)
{
while(*string)
{
lcd12864write(*string++,1);
}
}
void WriteDataTo12864(uchar num)
{
lcd12864write(num,1);
}
void clrscr(void)
{
lcd12864write(0x34,0);
lcd12864write(0x30,0);
lcd12864write(0x01,0);}
uchar ad(void)
{
uchar j,temp1=00;
cs=1;
IOCLK=0;
cs=0;
_nop_();
for(j=0;j<8;j++)
{
temp1=temp1<<1;
IOCLK=1;
if(DATAOUT)
temp1++;
IOCLK=0;
}
IOCLK=0;
cs=1;
delayms(5);
return(temp1);
}
void yejingwendu()
{
uint tmp;
tmp=ad();
vot=tmp*(4740.0f/255);
t=(vot*1.0f)/10;
lcd12864write(0x82,0);
WriteCharstringTo12864("温度显示");
lcd12864write(0x92,0);
WriteDataTo12864(shu[t%1000/100]);
WriteDataTo12864(shu[t%100/10]);
WriteDataTo12864(shu[10]);
WriteDataTo12864(shu[t%10]);
lcd12864write(0x94,0);
WriteCharstringTo12864("℃");
write_1byte_24c02(t%1000/100,0x06);
write_1byte_24c02(t%100/10,0x07);
write_1byte_24c02(t%10,0x08);
}
void read()
{ for(a=0;a<6;a++)
{
tab24c02[a]=read_1byte_24c02(0x00+a);
lcd12864write(0x82,0);
WriteCharstringTo12864("时间保存");
lcd12864write(0x92,0);
WriteDataTo128