extern uint16_t year; //年
extern uint8_t mon,day,hour,minu,seco;//月日时分秒
void DS1302_Config(void) //引脚配置
{
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,GPIO_PIN_5);//CLK输出模式、弱上拉
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
gpio_bit_set(GPIOB, GPIO_PIN_5);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,GPIO_PIN_3);//RST输出模式、弱上拉
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_3);
gpio_bit_set(GPIOB, GPIO_PIN_3);
}
void DS1302_PortConfig(uint8_t dir)//DAT端口配置(根据需要配置成输出或输入模式)
{
// GPIO_InitTypeDef GPIO_InitStruct;
if(dir == IO_OUT)
{
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,GPIO_PIN_4);//输出模式、弱上拉
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
}
else
{
gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE,GPIO_PIN_4); //输入模式
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
}
gpio_bit_set(GPIOB, GPIO_PIN_4);
}
/*****************************************************
函数功能:向1302写一个字节数据
入口参数:x
***************************************************/
void Write1302(uint8_t dat)
{
uint8_t i;
DATA_OUT;
SCLK_0;
delay_us(3);
for(i=0;i<8;i++)
{
if(dat&0x01) DATA_1;
else DATA_0;
delay_us(4);
SCLK_1;
delay_us(4);
SCLK_0;
dat>>=1;
}
}
/*****************************************************
函数功能:根据命令字,向1302写一个字节数据
入口参数:Cmd,储存命令字;dat,储存待写的数据
***************************************************/
void WriteSet1302(uint8_t Cmd,uint8_t dat)
{
RST_0;
SCLK_0;
RST_1;
delay_us(4);
Write1302(Cmd);
Write1302(dat);
SCLK_1;
RST_0;
}
/*****************************************************
函数功能:从1302读一个字节数据
入口参数:x
***************************************************/
uint8_t Read1302(void)
{
uint8_t i,dat;
DATA_IN; //
DATA_0; //
delay_us(4);
for(i=0;i<8;i++)
{
dat>>=1;
if(gpio_input_bit_get(GPIOB,GPIO_PIN_3) == SET) //(DATA != 0)
dat|=0x80;
else
dat&=0x7f;
SCLK_1;
delay_us(4);
SCLK_0;
delay_us(4);
}
DATA_OUT; //
return dat;
}
/*****************************************************
函数功能:根据命令字,从1302读取一个字节数据
入口参数:Cmd
***************************************************/
uint8_t ReadSet1302(uint8_t Cmd)
{
uint8_t dat;
RST_0;
SCLK_0;
RST_1;
Write1302(Cmd);
dat=Read1302();
SCLK_1;
RST_0;
return dat;
}
/*****************************************************
函数功能: 1302进行初始化设置
***************************************************/
void DS1302_Init(void)
{
DATA_OUT;
/*--------------------这是每次都初始化的语句-----------------*/
/*
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x80,((55/10)<<4|(55%10))); //根据写秒寄存器命令字,写入秒的初始值
WriteSet1302(0x82,((11/10)<<4|(11%10))); //根据写分寄存器命令字,写入分的初始值
WriteSet1302(0x84,((9/10)<<4|(9%10))); //根据写小时寄存器命令字,写入小时的初始值
WriteSet1302(0x86,((6/10)<<4|(6%10))); //根据写日寄存器命令字,写入日的初始值
WriteSet1302(0x88,((2/10)<<4|(2%10))); //根据写月寄存器命令字,写入月的初始值
WriteSet1302(0x8c,((15/10)<<4|(15%10))); //根据写年寄存器命令字,写入年的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 选择2K电阻充电方式
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
*/
//如果不想每次都初始化时间,也就是掉电后还想让时钟继续走时的话 就用下面的语句 ,此时vcc1外接3v电池
uint8_t flag;
LCD_write_ASCII(0,4,"No");
flag= ReadSet1302(0x81);
if(flag&0x80) //判断时钟芯片是否关闭
{
WriteSet1302(0x8E,0x00); //关闭写保护
WriteSet1302(0x80,((45/10)<<4|(45%10))); //写入秒初始值
WriteSet1302(0x82,((15/10)<<4|(15%10))); //写入分的初始值
WriteSet1302(0x84,((9/10)<<4|(9%10))); //写入小时的初始值
WriteSet1302(0x86,((6/10)<<4|(6%10))); //写入日的初始值
WriteSet1302(0x88,((5/10)<<4|(5%10))); //写入月的初始值
WriteSet1302(0x8c,((19/10)<<4|(19%10))); //写入年的初始值
WriteSet1302(0x90,0xa5); //打开充电功能 5=一个二极管2K电阻,9=两个二极管2K电阻
// 6=一个二极管4K电阻,a=两个二极管4K电阻
// 7=一个二极管8K电阻,b=两个二极管8K电阻
WriteSet1302(0x8E,0x80); //打开写保护
LCD_write_ASCII(0,4,"OK");
}
}
//向DS302写入时钟数据
void DS1302_write_date(void)
{
uint8_t temp;
WriteSet1302(0x8E,0x00); //关闭写保护
WriteSet1302(0x80,0x80); //暂停时钟
WriteSet1302(0x90,0xa5); //涓流充电
temp = ((year%100)/10<<4|(year%10));
WriteSet1302(0x8C,temp); //年
temp = ((mon/10)<<4|(mon%10));
WriteSet1302(0x88,temp); //月
temp = ((day/10)<<4|(day%10));
WriteSet1302(0x86,temp); //日
temp = ((hour/10)<<4|(hour%10));
WriteSet1302(0x84,temp|0x80); //时(24小时制式)
temp = ((minu/10)<<4|(minu%10));
WriteSet1302(0x82,temp); //分
WriteSet1302(0x80,0x00); //秒
// WriteSet1302(0x8A,0x01); //周
WriteSet1302(0x8E,0x80); //打开写保护
}
//从DS302读出时钟数据
void DS1302_read_date(void)
{
uint8_t temp;
temp = ReadSet1302(0x8D); //年 0x8D
year = 2000 + ((temp&0x70)>>4)*10 + (temp&0x0F);
temp = ReadSet1302(0x89);; //月 0x89
mon = ((temp&0x70)>>4)*10 + (temp&0x0F);
temp = ReadSet1302(0x87); //日 0x87
day = ((temp&0x70)>>4)*10 + (temp&0x0F);
temp = ReadSet1302(0x85); //时 0x85
hour = ((temp&0x70)>>4)*10 + (temp&0x0F);
temp = ReadSet1302(0x83); //分 0x83
minu = ((temp&0x70)>>4)*10 + (temp&0x0F);
temp = ReadSet1302(0x81)&0x7f; //秒,屏蔽秒的第7位,避免超出59
seco = ((temp&0x70)>>4)*10 + (temp&0x0F);
}