RTC_GM1302

        RTC_GM1302

 


 

 

 

复制代码
/* 
 * @Description : LVGL
 * @Author      : wangxy
 * @Date        : 2022-04-14
 * @LastEditTime: Today
 * @LastEditors : wangxy
 * @FilePath    : ESP32/rtc.c
 *
**/

#include "ESP32_Lvgl.h"

#define RTC_CLK  22    //39-GPIO22
#define RTC_SIO  21    //42-GPIO21
#define RTC_RST  25    //14-GPIO25

#define RTC_CLK_OUT    pinMode(RTC_CLK,OUTPUT);
#define RTC_CLK_SET    digitalWrite(RTC_CLK,1);
#define RTC_CLK_RESET  digitalWrite(RTC_CLK,0);

#define RTC_SIO_IN     pinMode(RTC_SIO, INPUT);
#define RTC_SIO_OUT    pinMode(RTC_SIO,OUTPUT);
#define RTC_SIO_SET    digitalWrite(RTC_SIO,1);
#define RTC_SIO_RESET  digitalWrite(RTC_SIO,0);
#define RTC_SIO_READ   digitalRead(RTC_SIO);

#define RTC_RST_OUT    pinMode(RTC_RST,OUTPUT);
#define RTC_RST_SET    digitalWrite(RTC_RST,1);
#define RTC_RST_RESET  digitalWrite(RTC_RST,0);

//unsigned char twdata[8]={0x58,0x59,0x23,0x31,0x12,0x06,0x04,0x80};/*定义初始化时钟数据数组,前7个为时钟数据,第8个为控制寄存器数据*/
unsigned char twdata[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80};
unsigned char trdata[7]; /*定义 1302 时钟数据数组,用来存放读出的时钟数据(BCD 码) */
unsigned char asc[14];   /*定义 ASC 码转换数组,用来存放时钟数据(BCD)转换过来的 ASC 码 */


void gm1302_rtc_init(void)
{
  RTC_CLK_OUT
  RTC_SIO_OUT
  RTC_RST_OUT
}




/********************************************************************
函 数 名:RTInputByte()
功 能:实时时钟写入一字节
说 明:往 GM1302 写入 1Byte 数据 (内部函数)
入口参数:d 写入的数据
返 回 值:无
***********************************************************************/
void RT_write_Byte(uchar ACC)   //低位先发
{
  RTC_SIO_OUT
  //Serial.printf("\nbegin_\n");
  for(uchar i=8; i>0; i--) {
    if(ACC&0x01){
      RTC_SIO_SET
      //Serial.printf("1 ");
    }else{
      RTC_SIO_RESET
      //Serial.printf("0 ");
    }
    RTC_CLK_SET
    RTC_CLK_RESET
    ACC = ACC >> 1; 
  }
  //Serial.printf("\nend_\n");
}

/********************************************************************
函 数 名:RTOutputByte()
功 能:实时时钟读取一字节
说 明:从 GM1302 读取 1Byte 数据 (内部函数)
入口参数:无
返 回 值:ACC
***********************************************************************/
uchar RT_read_Byte(void)   //低位先接收
{ 
  uchar ACC;
  RTC_SIO_IN
  for(uchar i=8; i>0; i--) {
    ACC = ACC >>1;
    int p =RTC_SIO_READ
    if(p){
      ACC =ACC|0x80;
    }else{
      //no
    }
    RTC_CLK_SET
    RTC_CLK_RESET
  }
  return(ACC);
}


/********************************************************************
函 数 名:W1302()
功 能:往 GM1302 写入数据
说 明:先写地址,后写命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: GM1302 地址, ucData: 要写的数据
返 回 值:无
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{ 
  RTC_RST_RESET
  RTC_CLK_RESET
  RTC_RST_SET
  RT_write_Byte(ucAddr); /* 地址,命令 */
  RT_write_Byte(ucDa); /* 写 1Byte 数据*/ 
  RTC_CLK_SET
  RTC_RST_RESET
}


/********************************************************************
函 数 名:R1302()
功 能:读取 GM1302 某地址的数据
说 明:先写地址,后读命令/数据 (内部函数)
调 用:RTInputByte() , RTOutputByte()
入口参数:ucAddr: GM1302 地址
返 回 值:ucData :读取的数据
***********************************************************************/
uchar R1302(uchar ucAddr)
{ 
  uchar ucData;
  RTC_RST_RESET
  RTC_CLK_RESET
  RTC_RST_SET
  RT_write_Byte(ucAddr); /* 地址,命令 */ 
  ucData = RT_read_Byte(); /* 读 1Byte 数据 */ 
  RTC_CLK_SET
  RTC_RST_RESET
  return(ucData); 
}

/********************************************************************
函 数 名:BurstW1302T()
功 能:往 GM1302 写入时钟数据(多字节方式)
说 明:先写地址,后写命令/数据
调 用:RTInputByte()
入口参数:pWClock: 时钟数据地址 格式为: 秒 分 时 日 月 星期 年 控制 8Byte (BCD 码)1B 1B 1B 1B 1B 1B 1B 1B
返 回 值:无
***********************************************************************/
void BurstW1302T(uchar *pWClock)
{ 
  W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/ 
  RTC_RST_RESET
  RTC_CLK_RESET
  RTC_RST_SET
  RT_write_Byte(0xbe); /* 0xbe:时钟多字节写命令 */ 
  for (uchar i = 8; i>0; i--){  /*8Byte = 7Byte 时钟数据 + 1Byte 控制*/ 
    RT_write_Byte(*pWClock); /* 写 1Byte 数据*/
    pWClock++; 
  }
  RTC_CLK_SET
  RTC_RST_RESET
}


/********************************************************************
函 数 名:BurstR1302T() 
功 能:读取 GM1302 时钟数据 
说 明:先写地址/命令,后读数据(时钟多字节方式) 
调 用:RTInputByte() , RTOutputByte() 
入口参数:pRClock: 读取时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD 码)1B 1B 1B 1B 1B 1B 1B 
返 回 值:无
***********************************************************************/
void BurstR1302T(uchar *pRClock)
{ 
  RTC_RST_RESET
  RTC_CLK_RESET
  RTC_RST_SET
  RT_write_Byte(0xbf); /* 0xbf:时钟多字节读命令 */ 
  for (uchar i=8; i>0; i--) { 
    *pRClock = RT_read_Byte(); /* 读 1Byte 数据 */ 
    pRClock++; 
  }
  RTC_CLK_SET
  RTC_RST_RESET
}


/********************************************************************
函 数 名:BurstW1302R()
功 能:往 GM1302 寄存器数写入数据(多字节方式)
说 明:先写地址,后写数据(寄存器多字节方式) 
调 用:RTInputByte() 
入口参数:pWReg: 寄存器数据地址 返 回 值:无
***********************************************************************/
void BurstW1302R(uchar *pWReg)
{
  W1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/ 
  RTC_RST_RESET
  RTC_CLK_RESET
  RTC_RST_SET
  RT_write_Byte(0xfe); /* 0xbe:时钟多字节写命令 */ 
  for (uchar i=31; i>0; i--){ /* 31Byte 寄存器数据 */  
    RT_write_Byte(*pWReg); /* 写 1Byte 数据*/ 
    pWReg++;
  }
  RTC_CLK_SET
  RTC_RST_RESET
}


/********************************************************************
函 数 名:BurstR1302R() 
功 能:读取 GM1302 寄存器数据 
说 明:先写地址,后读命令/数据(寄存器多字节方式) 
调 用:RTInputByte() , RTOutputByte() 
入口参数:pRReg: 寄存器数据地址 
返 回 值:无
***********************************************************************/
void BurstR1302R(uchar *pRReg) 
{ 
  RTC_RST_RESET
  RTC_CLK_RESET
  RTC_RST_SET
  RT_write_Byte(0xff); /* 0xff:时钟多字节读命令 */ 
  for (uchar i=31; i>0; i--){ /*31Byte 寄存器数据 */  
    *pRReg = RT_read_Byte(); /* 读 1Byte 数据 */ 
    pRReg++; 
  }
  RTC_CLK_SET
  RTC_RST_RESET
}


/********************************************************************
函 数 名:Set1302() 
功 能:设置初始时间,以单字节方式连续设置 GM1302 的 7 个时钟寄存器 
说 明:先写地址,后写数据(单字节方式) 
调 用:W1302() 
入口参数:pClock: 设置时钟数据地址 格式为: 秒 分 时 日 月 星期 年 7Byte (BCD 码)1B 1B 1B 1B 1B 1B 1B 
返 回 值:无
***********************************************************************/
void Set1302(uchar *pClock)
{
  uchar ucAddr = 0x80; //W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/ 
  for(uchar i =7; i>0; i--) {
    W1302(ucAddr,*pClock); /* 秒 分 时 日 月 星期 年 */ 
    pClock++; 
    ucAddr +=2;
  }
  W1302(0x8e,0x80); /* 控制命令,WP=1,写保护?*/ 
}


/********************************************************************
函 数 名:Get1302() 
功 能:单字节方式读取 GM1302 当前时间(7 个时钟数据) 
说 明: 
调 用:R1302() 
入口参数:ucCurtime: 保存当前时间地址。当前时间格式为: 秒 分 时 日 月 星期 年 
返 回 值:无
***********************************************************************/
void Get1302(uchar ucCurtime[]) 
{ 
  uchar ucAddr = 0x81; 
  for (uchar i=0; i<7; i++) { 
  ucCurtime[i] = R1302(ucAddr);/*格式为: 秒 分 时 日 月 星期 年 */ 
  ucAddr += 2; 
  } 
}

/********************************************************************
函 数 名:Bcd2asc( ) 
功 能:将读取的 GM1302 时钟数据(压缩型 bcd 码)转换成 asc 码存储在 asc 数组中 
说 明: 
调 用:
入口参数: 
返 回 值:无
***********************************************************************/
void Bcd2asc(void)
{
  uchar i,j;
  for (j=0,i=0; i<7; i++){
    asc[j++] =(trdata[i]&0xf0)>>4|0x30 ;/*格式为: 秒 分 时 日 月 星期 年 */ 
    asc[j++] =trdata[i]&0x0f|0x30;
  }
  Serial.printf("read time = %s\r\n",asc);
}


#if 0
/********************************************************************
函 数 名:main( ) 
功 能:先设置 GM1302 的时间,然后循环读取 GM1302 的时钟数据并保存, 将读取的时钟数据转换成 asc 码保存 
说 明:该主函数很简单,用户可以根据需要来选择多字节方式或者单字节方式 
调 用: 
入口参数: 
返 回 值:无
***********************************************************************/
void main(void)
{ 
  BurstW1302T(twdata); /* 多字节方式设置 GM1302 时间 */ 
  //Set1302(twdata); /* 单字节方式设置 GM1302 时间 */ 
  while(1) {
    BurstR1302T(trdata); /* 多字节方式读取 GM1302 时间*/ 
    //Get1302(trdata); /* 单字节方式读取 GM1302 时间*/ 
    Bcd2asc(); /* 时钟数据转换成 asc 码*/
  }
}

#endif






unsigned char hex_to_bcd(unsigned char hex)
{
    if (hex > 99)
        return 0;
    return ((hex / 10) << 4) +hex % 10;
}
复制代码

 

 

 


 

posted @   panda_w  阅读(211)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示