#include <xc.h>
#include "OLED.h"
//CONFIG1L芯片配置字
#pragma config RETEN = OFF //超低功耗稳压器禁止
#pragma config INTOSCSEL = HIGH //休眠期间 LF-INTOSC 于高功耗模式
#pragma config SOSCSEL = DIG //SOSC配置为( SCLKI)模式;使能 RC0 和 RC1 数字I/O
#pragma config XINST = OFF //扩展指令集使能位,禁止指令集扩展和变址寻址模式 (传统模式)
// CONFIG1H
#pragma config FOSC = HS1 //4 MHz - 16 MHz 外部晶振设置HS中等功耗振荡器,
#pragma config PLLCFG = ON //使能PLL x4功能,8M晶振经4倍频变为32MHz系统时钟
#pragma config FCMEN = OFF //禁止故障保护时钟监视器
#pragma config IESO = OFF //禁止双速启动
// CONFIG2L
#pragma config PWRTEN = OFF //禁止上电延时
#pragma config BOREN = SBORDIS //由硬件使能欠压复位
#pragma config BORV = 3 //设置电压为1.8v欠压复位
#pragma config BORPWR = ZPBORMV //选择ZPBORMV而不是BORMV
// CONFIG2H
#pragma config WDTEN = OFF //关看门狗
//#pragma config WDTEN = SWDTDIS //由硬件使能WDT,禁止SWDTEN位
#pragma config WDTPS = 256 //看门狗后分频1:256,溢出时间1.024s
// CONFIG3H
#pragma config CANMX = PORTB //CAN通信引脚设置到 RB2 和 RB3
#pragma config MSSPMSK = MSK7 //使能 7 位地址掩码模式
#pragma config MCLRE = ON //使能MCLR外部复位功能
// CONFIG4L
#pragma config STVREN = ON // 堆栈满/下溢复位
#pragma config BBSIZ = BB2K // 配置引导区大小为2K
// CONFIG5L
#pragma config CP0 = OFF //00800-01FFF代码不加密
#pragma config CP1 = OFF //02000-03FFF代码不加密
#pragma config CP2 = OFF //04000-05FFF代码不加密
#pragma config CP3 = OFF //06000-07FFF代码不加密
// CONFIG5H
#pragma config CPB = OFF //引导区代码不加密
#pragma config CPD = OFF //EEPROM数据不不加密
// CONFIG6L
#pragma config WRT0 = OFF // 00800-01FFF 写保护位不使能
#pragma config WRT1 = OFF // 02000-03FFF 写保护位不使能
#pragma config WRT2 = OFF // 04000-05FFF 写保护位不使能
#pragma config WRT3 = OFF // 06000-07FFF 写保护位不使能
// CONFIG6H
#pragma config WRTC = OFF //配置寄存器不受写保护
#pragma config WRTB = OFF //引导区不受写保护
#pragma config WRTD = OFF //EEPROM数据不受写保护
// CONFIG7L
#pragma config EBTR0 = OFF //00800-01FFF表读保护位不使能
#pragma config EBTR1 = OFF //02000-03FFF表读保护位不使能
#pragma config EBTR2 = OFF //04000-05FFF表读保护位不使能
#pragma config EBTR3 = OFF //06000-07FFF表读保护位不使能
// CONFIG7H
#pragma config EBTRB = OFF //引导区不受写保护
#define uint unsigned int
#define u8 unsigned char
#define LED1 LATDbits.LATD4 //定义LED1端口
#define LED2 LATEbits.LATE1 //定义LED2端口
#define uint unsigned int
#define uchar unsigned char
#define UINT8 unsigned char
#define HMS_FLAG 1
//--------与24C02相关的设置和子函数-------------
void delay()
{
uchar i;
for(i=0;i<10;i++);
} //简单短延时子函数
//sbit sda_24c02=P2^6; //定义24C02的数据线与单片机的连接
//sbit scl_24c02=P2^7;
#define sda_24c02 LATCbits.LATC4
#define scl_24c02 LATCbits.LATC5
void start_24c02(); //24C02开始信号
void stop_24c02(); //24C02停止
void respons_24c02(); //24C02应答
void init_24c02(); //24C02初始化
void write_byte_24c02(uchar date); //写一个byte到24C02
uchar read_byte_24c02(); //从24C02读一个byte
void write_add_24c02(uchar address,uchar date); //写一个字节到指定的24C02单元
uchar read_add_24c02(uchar address); //从24C02指定单元读一个字节数据
void write_add1_24c02(uchar address,uchar date); //写一个字节到指定的24C02单元
uchar read_add1_24c02(uchar address); //从24C02指定单元读一个字节数据
void XWrite_eeprom(UINT8 Address,UINT8 eeprom_Data);
UINT8 XRead_eeprom(UINT8 Address);
//sbit led=P1^0;
//unsigned char code table_num[]="0123456789"; //LCD显示的数字代码
void delay_ms(uint xms); //ms级延时子函数
unsigned char i; //
struct ccb
{
uchar second;
uchar minute;
uchar hour;
uchar day;
uchar month;
uchar year;
};
struct ccb CurrentTime;
UINT8 Change10ToBCD(UINT8 data1) //10->BCD数值转化
{
UINT8 high,low,result;
high=data1/10;
low=data1%10;
result=(high<<4)|low;
return result;
}
void init_ISL12026()
{
XWrite_eeprom(0x3F,0x02);
XWrite_eeprom(0x3F,0x06);
}
void ResetRtcTime()
{
init_ISL12026();
XWrite_eeprom(0x37,Change10ToBCD(20));//世纪
XWrite_eeprom(0x36,Change10ToBCD(0));//周
XWrite_eeprom(0x35,Change10ToBCD(10));//年
XWrite_eeprom(0x34,Change10ToBCD(1));//月
XWrite_eeprom(0x33,Change10ToBCD(1));//日
XWrite_eeprom(0x32,Change10ToBCD(12)|0x80);//时
XWrite_eeprom(0x31,Change10ToBCD(12));//分
XWrite_eeprom(0x30,Change10ToBCD(12));//秒
}
UINT8 ChangeBCDTo10(UINT8 data1) //BCD->10数值转化
{
UINT8 temp,result;
result=data1&0x0F;
temp=data1>>4;
result+=temp*10;
return result;
}
void readCurrentTime()
{
CurrentTime.year=ChangeBCDTo10(XRead_eeprom(0x35));
CurrentTime.month=ChangeBCDTo10(XRead_eeprom(0x34));
CurrentTime.day=ChangeBCDTo10(XRead_eeprom(0x33));
CurrentTime.hour=ChangeBCDTo10(XRead_eeprom(0x32)&0x7F);
CurrentTime.minute=ChangeBCDTo10(XRead_eeprom(0x31));
CurrentTime.second=ChangeBCDTo10(XRead_eeprom(0x30));
}
/**************************************************************************/
//按页写入。 pBuffer数组指针首地址,WriteAddr要写入页的首地址,NumByteToWrite写入字符个数
/*************************************************************************/
void ISL12026_PageWrite(UINT8* pBuffer, UINT8 WriteAddr, UINT8 NumByteToWrite)
{
init_ISL12026();
//XStart_iic();
start_24c02();
write_byte_24c02(0xde);
respons_24c02();
//XWriteByte(0);
//XReceiveAck();
write_byte_24c02(0);
respons_24c02();
//XWriteByte(WriteAddr);
//XReceiveAck();
write_byte_24c02(WriteAddr);
respons_24c02();
while(NumByteToWrite--)
{
//XWriteByte(*pBuffer);
//Point to the next byte to be written
write_byte_24c02(*pBuffer);
respons_24c02();
pBuffer++;
//XReceiveAck();
}
//XStop_iic();
stop_24c02();
for(i=0;i<40;i++)
delay();
}
/**************************************************************************/
//写入时间信息,按照秒,分,时,天,月,年的顺序写入
/*************************************************************************/
void ISL12026_TimeWrite(UINT8 second,UINT8 minute,UINT8 hour,UINT8 day,UINT8 month,UINT8 year)
{
UINT8 temp[8];
temp[0]=Change10ToBCD(second);
temp[1]=Change10ToBCD(minute);
temp[2]=Change10ToBCD(hour)|0x80;
temp[3]=Change10ToBCD(day);
temp[4]=Change10ToBCD(month);
temp[5]=Change10ToBCD(year);
temp[6]=Change10ToBCD(0); //周,不用则写0
temp[7]=Change10ToBCD(20);
ISL12026_PageWrite(temp,0x30,8);
}
/*
void saveX1226(UINT8 hour_year,UINT8 minute_month,UINT8 second_day,UINT8 index)
{
init_X1226();
if(index==HMS_FLAG)//写时分秒
{
XWrite_eeprom(0x30,Change10ToBCD(second_day));//秒
XWrite_eeprom(0x31,Change10ToBCD(minute_month));//分
XWrite_eeprom(0x32,Change10ToBCD(hour_year)|0x80);//时
}
else//写年月日星期
{
XWrite_eeprom(0x33,Change10ToBCD(second_day));//日
XWrite_eeprom(0x34,Change10ToBCD(minute_month));//月
XWrite_eeprom(0x35,Change10ToBCD(hour_year));//年
}
XWrite_eeprom(0x11,0x00);//按定时输出
//XWrite_eeprom(0x3F,0x00);
Delay(50);
}*/
/*void init_ISL12026_IQR()
{
//UINT8 mRtcStatus;
init_ISL12026();
//mRtcStatus=ChangeBCDTo10(XRead_eeprom(0x11));
//mRtcStatus=mRtcStatus;
XWrite_eeprom(0x11,0x00);//0x18, 1秒一个频冲
//Delay(100);
for(i=0;i<80;i++)
delay();
} */
void init_ISL12026_Alarm(UINT8 Hour_Week,UINT8 Minute_Month,UINT8 Second_Day,UINT8 index) // 设置报警时间
{
init_ISL12026();
if(index==HMS_FLAG)//写时分秒
{
XWrite_eeprom(0x00,Change10ToBCD(Second_Day));//秒
XWrite_eeprom(0x01,Change10ToBCD(Minute_Month));//分
XWrite_eeprom(0x02,Change10ToBCD(Hour_Week)|0x80);//时
}
else//写月日星期
{
XWrite_eeprom(0x03,Change10ToBCD(Second_Day));//日
XWrite_eeprom(0x04,Change10ToBCD(Minute_Month));//月
XWrite_eeprom(0x06,Change10ToBCD(Hour_Week));//年
}
XWrite_eeprom(0x11,0xA0);//按定时输出
//Delay(50);
for(i=0;i<40;i++)
delay();
}
void PowerInitTime(void)
{
struct ccb DownTime;
UINT8 mRtcStatus;
init_ISL12026();
//mRtcStatus=XRead_eeprom(0x14);
XWrite_eeprom(0x14,0x00);
mRtcStatus=XRead_eeprom(0x14);
mRtcStatus=ChangeBCDTo10(XRead_eeprom(0x3F));
if ( mRtcStatus & 0x01 ) //如果完全断电,设置为上次参数下载的时间
{
/*DownTime.year=ByteReadEeprom(DownLoadYearAddrOne);
DownTime.month=ByteReadEeprom(DownLoadMonthAddrOne);
DownTime.day=ByteReadEeprom(DownLoadDayAddrOne);
DownTime.hour=ByteReadEeprom(DownLoadHourAddrOne);
DownTime.minute=ByteReadEeprom(DownLoadMinuteAddrOne);
DownTime.second=ByteReadEeprom(DownLoadSecondAddrOne);
*/
ISL12026_TimeWrite(DownTime.second,DownTime.minute,DownTime.hour,DownTime.day,DownTime.month,DownTime.year);
}
}
void readSecond()
{
//CurrentTime.minute=ChangeBCDTo10(XRead_eeprom(0x31));
CurrentTime.second=ChangeBCDTo10(XRead_eeprom(0x30));
}
//MS延时函数
void MS_delay(uint MS)
{
uint x,y;
for(y=MS;y>0;y--)
{
for(x=796;x>0;x--);
}
}
void main(void)
{
unsigned int i;
unsigned char temp;
unsigned char second;
unsigned char bai,shi,ge;
unsigned char year,month,day,hour,minute;
ANCON0bits.ANSEL6=0; //RE1(AN6)配置为数字IO
ANCON1=0x00; //将部分带模拟输入功能的引脚设置为数字IO
//输出使用LAT寄存器,输入使用PORT寄存器
TRISDbits.TRISD4=0; //PORD4配置为输出
TRISEbits.TRISE1=0; //PORE1配置为输出
TRISC=0X00;
LCD_Init();
LCD_CLS();
init_ISL12026();
XWrite_eeprom(0x50,209);//
for(i=0;i<60000;i++);
XWrite_eeprom(0x52,126);//
for(i=0;i<60000;i++);
XWrite_eeprom(0x54,158);//
for(i=0;i<60000;i++);
temp=XRead_eeprom(0x52);
bai=temp/100+48;
shi=temp%100/10+48;
ge=temp%10+48;
LCD_P8x16Char(0,0,bai);
LCD_P8x16Char(8,0,shi);
LCD_P8x16Char(16,0,ge);
temp=XRead_eeprom(0x54);
bai=temp/100+48;
shi=temp%100/10+48;
ge=temp%10+48;
LCD_P8x16Char(32,0,bai);
LCD_P8x16Char(40,0,shi);
LCD_P8x16Char(48,0,ge);
temp=XRead_eeprom(0x50);
bai=temp/100+48;
shi=temp%100/10+48;
ge=temp%10+48;
LCD_P8x16Char(64,0,bai);
LCD_P8x16Char(72,0,shi);
LCD_P8x16Char(80,0,ge);
LCD_P8x16Str(0,2,(u8*)" : : ");
LCD_P8x16Str(0,4,(u8*)"20 - - ");
ISL12026_TimeWrite(50,59,23,31,12,23);
while(1)
{
readCurrentTime();
shi=(CurrentTime.second/10)+0x30;
ge=(CurrentTime.second%10)+0x30;
LCD_P8x16Char(48,2,shi);
LCD_P8x16Char(56,2,ge);
shi=(CurrentTime.minute/10)+0x30;
ge=(CurrentTime.minute%10)+0x30;
LCD_P8x16Char(24,2,shi);
LCD_P8x16Char(32,2,ge);
shi=(CurrentTime.hour/10)+0x30;
ge=(CurrentTime.hour%10)+0x30;
LCD_P8x16Char(0,2,shi);
LCD_P8x16Char(8,2,ge);
shi=(CurrentTime.day/10)+0x30;
ge=(CurrentTime.day%10)+0x30;
LCD_P8x16Char(64,4,shi);
LCD_P8x16Char(72,4,ge);
shi=(CurrentTime.month/10)+0x30;
ge=(CurrentTime.month%10)+0x30;
LCD_P8x16Char(40,4,shi);
LCD_P8x16Char(48,4,ge);
shi=(CurrentTime.year/10)+0x30;
ge=(CurrentTime.year%10)+0x30;
LCD_P8x16Char(16,4,shi);
LCD_P8x16Char(24,4,ge);
for(i=0;i<20000;i++);
}
}
void delay_ms(uint xms) //ms级延时子程序
{ unsigned int aa,bb;
for(aa=xms;aa>0;aa--)
for(bb=4000;bb>0;bb--); //调整数值以使本句运行时间为1ms
}
//--------与24C02相关的设置和子函数-------------
void start_24c02() //24c02开始信号
{ sda_24c02=1; delay();
scl_24c02=1; delay();
sda_24c02=0; delay(); }
void stop_24c02() //24c02停止
{ sda_24c02=0; delay();
scl_24c02=1; delay();
sda_24c02=1; delay(); }
void respons_24c02() //24c02应答
{ uchar i;
scl_24c02=1;
delay();
TRISCbits.TRISC4=1;
delay();
while((PORTCbits.RC4==1)&&(i<250))i++;
scl_24c02=0;
delay();
TRISCbits.TRISC4=0;
delay();
}
void init_24c02() //24c02初始化
{ sda_24c02=1; delay();
scl_24c02=1; delay(); }
void write_byte_24c02(uchar date) //写8个
{ uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
scl_24c02=0; delay();
if(temp&0x80)
{
sda_24c02=1; delay();
}
else
{
sda_24c02=0; delay();
}
scl_24c02=1; delay();
temp=temp<<1;
}
scl_24c02=0; delay();
sda_24c02=1; delay(); }
uchar read_byte_24c02()
{ uchar i,k;
scl_24c02=0; delay();
sda_24c02=1; delay();
TRISCbits.TRISC4=1;
delay();
for(i=0;i<8;i++)
{ scl_24c02=1; delay();
k=(k<<1)|PORTCbits.RC4;
scl_24c02=0; delay();
}
TRISCbits.TRISC4=0;
delay();
return k; }
void write_add_24c02(uchar address,uchar date)//将某数据写入24C02某个单元中
{ start_24c02();
write_byte_24c02(0xa0); //24c02的写地址(1010 0000)
respons_24c02();
write_byte_24c02(address);
respons_24c02();
write_byte_24c02(date);
respons_24c02();
stop_24c02(); }
uchar read_add_24c02(uchar address)//读出24c02某个单元数据到变量中
{ uchar date;
start_24c02();
write_byte_24c02(0xa0); //24c02的读地址(1010 0001)
respons_24c02();
write_byte_24c02(address);
respons_24c02();
start_24c02();
write_byte_24c02(0xa1);
respons_24c02();
date=read_byte_24c02();
stop_24c02();
return date; }
//--------与24C02相关的设置和子函数 结束-----------
void write_add1_24c02(uchar address,uchar date)//将某数据写入24C02某个单元中
{ start_24c02();
write_byte_24c02(address<<1);
respons_24c02();
write_byte_24c02(date);
respons_24c02();
stop_24c02(); }
uchar read_add1_24c02(uchar address)//读出24c02某个单元数据到变量中
{ uchar date;
start_24c02();
write_byte_24c02((address<<1)+1);
respons_24c02();
//start_24c02();
//write_byte_24c02(0xa1);
//respons_24c02();
date=read_byte_24c02();
stop_24c02();
return date; }
void XWrite_eeprom(UINT8 Address,UINT8 eeprom_Data)
{
//XStart_iic();
start_24c02();
//XWriteByte(0xDE);
write_byte_24c02(0xde);
//XReceiveAck();
respons_24c02();
/*XWriteByte(0);
XReceiveAck();
XWriteByte(Address);
XReceiveAck();
XWriteByte(eeprom_Data);
XReceiveAck();
XStop_iic();*/
write_byte_24c02(0);
//XReceiveAck();
respons_24c02();
write_byte_24c02(Address);
//XReceiveAck();
respons_24c02();
write_byte_24c02(eeprom_Data);
//XReceiveAck();
respons_24c02();
stop_24c02();
}
UINT8 XRead_eeprom(UINT8 Address)
{
UINT8 rdata;
//XStart_iic();
//XWriteByte(0xDE);
//XReceiveAck();
start_24c02();
write_byte_24c02(0xde);
respons_24c02();
//XWriteByte(0);
//XReceiveAck();
//XWriteByte(Address);
//XReceiveAck();
write_byte_24c02(0);
respons_24c02();
write_byte_24c02(Address);
respons_24c02();
/*XStart_iic();
XWriteByte(0xDF);
XReceiveAck();
rdata=XReadByte();
XNo_Acknowledge();
XStop_iic(); */
start_24c02();
write_byte_24c02(0xdf);
respons_24c02();
rdata=read_byte_24c02();
stop_24c02();
return(rdata);
}
效果图