- 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);
- }