#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 io LATCbits.LATC5 //数据输入输出线
#define ce LATCbits.LATC6 //复位信号线
#define sclk LATCbits.LATC4 //时钟信号线
u8 const write_addr[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //写的地址
u8 const read_addr[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //读的地址
u8 const read[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //读的地址
u8 const write[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};//秒分时日月周年,写的地址
u8 time[7]={0x40,0x59,0x23,0x31,0x12,0x07,0x23};//存读的数据
//MS延时函数
void MS_delay(uint MS)
{
uint x,y;
for(y=MS;y>0;y--)
{
for(x=796;x>0;x--);
}
}
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
//uchar time[7]={0,0,0x12,0x12,0x12,0x20,0x15}; //初始化的时间为2015年12月12日12:00
void Ds1302Write(u8 address,u8 date)
{
u8 n;
ce=0;
sclk=0;//
ce=1;
for (n=0;n<8;n++) //写地址
{
io=address & 0x01 ; //只保留1位
address>>=1; //右移一位
sclk=1; //写
sclk=0;
}
for (n=0; n<8; n++)//写数据
{
io=date & 0x01;
date>>=1;
sclk=1;
sclk=0;
}
ce=0;
}
u8 Ds1302Read(u8 address)
{
u8 n,date,date1;
ce=0;
sclk=0;
ce=1;
for(n=0;n<8;n++) //发地址
{
io=address & 0x01;
address>>= 1;
sclk= 1;
sclk= 0;
}
TRISCbits.TRISC5=1;
for(n=0;n<10;n++);
for(n=0;n<8;n++) //收数据
{
date1=PORTCbits.RC5;
date=(date>>1)|(date1<<7);//存入date中
sclk=1;
sclk=0;
}
ce=0;
sclk=1;//保证1302稳定,必须的
io=0;
io=1;
TRISCbits.TRISC5=0;
for(n=0;n<10;n++);
return date;
}
void Ds1302ReadTime()//读时间
{
u8 n;
for(n=0;n<7;n++)//读取7个字节的时钟信号:分秒时日月周年
{
time[n] =Ds1302Read(read[n]);
}
}
void Ds1302Init()
{
u8 n;
Ds1302Write(0x8E,0x00); //8E为写保护寄存器地址,00为不写保护
for(n=0;n<7;n++) //
{
Ds1302Write(write[n],time[n]); //地址加数据
}
Ds1302Write(0x8E,0x80); //开写保护
}
void main(void)
{
u8 i,j;
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();
LCD_P8x16Str(20,4,(u8*)"20 - - ");
LCD_P8x16Str(20,6,(u8*)" : : ");
//Draw_BMP(0,0,100,3,(u8*)Dot);
Ds1302Init();
while(1)
{
Ds1302ReadTime();
i=(time[0]>>4)+0x30;
j=(time[0]&0x0f)+0x30;
LCD_P8x16Char(68,6,i);
LCD_P8x16Char(76,6,j);
i=(time[1]>>4)+0x30;
j=(time[1]&0x0f)+0x30;
LCD_P8x16Char(44,6,i);
LCD_P8x16Char(52,6,j);
i=(time[2]>>4)+0x30;
j=(time[2]&0x0f)+0x30;
LCD_P8x16Char(20,6,i);
LCD_P8x16Char(28,6,j);
i=(time[3]>>4)+0x30;
j=(time[3]&0x0f)+0x30;
LCD_P8x16Char(84,4,i);
LCD_P8x16Char(92,4,j);
i=(time[4]>>4)+0x30;
j=(time[4]&0x0f)+0x30;
LCD_P8x16Char(60,4,i);
LCD_P8x16Char(68,4,j);
i=(time[6]>>4)+0x30;
j=(time[6]&0x0f)+0x30;
LCD_P8x16Char(36,4,i);
LCD_P8x16Char(44,4,j);
i=time[5]+0x30;
LCD_P8x16Char(36,2,i);
MS_delay(500);
}
}
效果图:
@比神乐 :不是的,也就是个维修电工习惯维修电子线路。
@王栋春 :你是搞硬件的吗
俺就纳闷了,为啥大家都是软件高手,可俺就是一窍不通!