历史上的今天
返回首页

历史上的今天

今天是:2025年04月05日(星期六)

2020年04月05日 | stm8及DS1302的一些操作

2020-04-05 来源:eefocus

最近想看下DS1302内部RAM掉电后的状态,会是默认的全0x00么?


首先查阅网上的资料和芯片相关手册,并没有对它的介绍,DS1302是块很普通的时钟芯片,之前用别的单片机也操作过,但从来没有留意这点。决定操作下1302,看下RAM究竟是什么状态。


手头别的什么单片机都没有,就有块上次代理商留下的stm8L15X系列单片机demo板。那就用这块单片机试下吧。


首先配置系统时钟,在stm8的库文件(STM8S_StdPeriph_Lib_V2.1.0)里有相关的函数获取相关时钟状态,如下:


SysClkFreq =  CLK_GetClockFreq();

SysClkSource = CLK_GetSYSCLKSource();


从返回值可以看出,芯片默认时钟为内部HSI,2MHz。


重新设置成16M,内部时钟:


/*set system clock*/

CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSI);

CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);



之后是DS1302的相关函数,DS1302.h文件如下:


#ifndef DS1302_H

#define DS1302_H

 

//DS1302相关PIN

#define DS1302_PORT       GPIOC

#define DS1302_PORT_RST   GPIOE

 

#define DS1302_RST_PIN  GPIO_Pin_7

#define DS1302_IO_PIN   GPIO_Pin_0

#define DS1302_CLK_PIN  GPIO_Pin_7

 

#define DS1302_SEC_REG 0x80 

#define DS1302_MIN_REG 0x82 

#define DS1302_HR_REG 0x84 

#define DS1302_DATE_REG 0x86 

#define DS1302_MONTH_REG 0x88 

#define DS1302_DAY_REG 0x8a 

#define DS1302_YEAR_REG 0x8c 

#define DS1302_CONTROL_REG 0x8e 

#define DS1302_CHARGER_REG 0x90 

#define DS1302_CLKBURST_REG 0xbe 

 

#define DS1302_RAM_REG 0xc0 

 

typedef struct _DS1302_TIME

{

  unsigned char year;

  unsigned char month;

  unsigned char day;

  unsigned char week;

  unsigned char hour;

  unsigned char minute;

  unsigned char second;

  

}DS1302_TIME;

 

extern void ds1302_port_init(void);

extern unsigned char ds1302_check(void);

extern void ds1302_write_time(DS1302_TIME* time);

extern void ds1302_read_time(DS1302_TIME* time);

extern void ds1302_write_ram(unsigned char ram_num,unsigned char dat);

extern unsigned char  ds1302_read_ram(unsigned char ram_num); 

#endif


DS1302.c文件:

#include "stm8l15x.h"

#include "stm8l_discovery_lcd.h"

#include "discover_board.h"

#include "icc_measure.h"

#include "discover_functions.h"

#include "ds1302.h"

 

void delay()

{

    int i;

    for(i=0;i<10;i++)

       ;

}

 

void ds1302_port_init(void)

{

        GPIO_Init(DS1302_PORT,DS1302_CLK_PIN, GPIO_Mode_Out_PP_High_Fast);//RTC_CLK

        GPIO_Init(DS1302_PORT_RST,DS1302_RST_PIN, GPIO_Mode_Out_PP_High_Fast);//        

        GPIO_Init(DS1302_PORT,DS1302_IO_PIN, GPIO_Mode_In_FL_No_IT);      //RTC_DATA   

        

        GPIO_LOW(DS1302_PORT_RST,DS1302_RST_PIN); 

        GPIO_LOW(DS1302_PORT,DS1302_CLK_PIN); 

        

}

 

void read_IO(void){

        GPIO_Init(DS1302_PORT,DS1302_IO_PIN, GPIO_Mode_In_FL_No_IT);   //RTC_DATA        

}

  

void write_IO(void){ 

        GPIO_Init(DS1302_PORT,DS1302_IO_PIN, GPIO_Mode_Out_OD_HiZ_Fast);//RTC_DATA

}

 

 

void ds1302_write_byte(unsigned char temp) 

{

   unsigned char i;

   for (i=0;i<8;i++)     

   { 

       // delay_10us(5);

       GPIO_LOW(DS1302_PORT,DS1302_CLK_PIN);

        

       if(temp&0x01) {

           GPIO_HIGH(DS1302_PORT,DS1302_IO_PIN); 

       }else {

           GPIO_LOW(DS1302_PORT,DS1302_IO_PIN);

       }           

       temp>>=1; 

      //  delay_10us(10);

       GPIO_HIGH(DS1302_PORT,DS1302_CLK_PIN); 

             

    }

}  

unsigned char ds1302_read_byte(void) 

{

  unsigned char i,temp=0;

  for (i=0;i<8;i++)

  {

     GPIO_LOW(DS1302_PORT,DS1302_CLK_PIN);

     temp>>=1;

     if(GPIO_ReadInputDataBit(DS1302_PORT,DS1302_IO_PIN))

     {

          temp|=0x80;

     }

   // delay_10us(5);

     GPIO_HIGH(DS1302_PORT,DS1302_CLK_PIN); 

    

     

  } 

  return temp;

 

void ds1302_write( unsigned char address,unsigned char dat )     

{

  write_IO();

        GPIO_LOW(DS1302_PORT_RST,DS1302_RST_PIN);   //写地址,写数据 RST保持高电平

  GPIO_LOW(DS1302_PORT,DS1302_CLK_PIN);

  GPIO_HIGH(DS1302_PORT_RST,DS1302_RST_PIN);

        //delay_10us(1);

  ds1302_write_byte(address);

  ds1302_write_byte(dat);

        //delay_10us(1);

  GPIO_LOW(DS1302_PORT_RST,DS1302_RST_PIN);

  

}

/****************************************************************************/

unsigned char ds1302_read( unsigned char address )

{

  unsigned char ret;

        write_IO();

  GPIO_LOW(DS1302_PORT_RST,DS1302_RST_PIN);

  GPIO_LOW(DS1302_PORT,DS1302_CLK_PIN);

  GPIO_HIGH(DS1302_PORT_RST,DS1302_RST_PIN);

        // delay_10us(1);

  ds1302_write_byte(address|0x01);  //读标志:地址最后一位为1

        read_IO();

        ret = ds1302_read_byte();

         //delay_10us(1);

  GPIO_LOW(DS1302_PORT_RST,DS1302_RST_PIN);

return (ret);

}

 

unsigned char ds1302_check(void) 

    unsigned char ret;

    ds1302_write(DS1302_CONTROL_REG,0x80); 

    ret = ds1302_read(DS1302_CONTROL_REG);

    if(ret==0x80)

       return 1; 

    return 0; 

}

 

void ds1302_read_time(DS1302_TIME* time) 

   time->year=ds1302_read(DS1302_YEAR_REG); //年 

    time->month=ds1302_read(DS1302_MONTH_REG);//月 

   time->day=ds1302_read(DS1302_DATE_REG); //日 

    time->week=ds1302_read(DS1302_DAY_REG); //周 

    time->hour=ds1302_read(DS1302_HR_REG); //时 

    time->minute=ds1302_read(DS1302_MIN_REG); //分 

    time->second=ds1302_read(DS1302_SEC_REG); //秒 

void ds1302_write_time(DS1302_TIME* time) 

    ds1302_write(DS1302_CONTROL_REG,0x00); //关闭写保护 

    ds1302_write(DS1302_SEC_REG,0x80); //暂停 

    ds1302_write(DS1302_CHARGER_REG,0xa9); //涓流充电 

 

    //ds1302_write(DS1302_SECOND_ADDR, 0x00);           // 启动振荡器

   // ds1302_write(DS1302_YEAR_REG,time->year); //年 

   // ds1302_write(DS1302_MONTH_REG,time->month); //月 

   // ds1302_write(DS1302_DATE_REG,time->day); //日 

   // ds1302_write(DS1302_DAY_REG,time->week); //周 

    ds1302_write(DS1302_HR_REG,time->hour); //时 

    ds1302_write(DS1302_MIN_REG,time->minute); //分 

    ds1302_write(DS1302_SEC_REG,0x00); //秒 

    ds1302_write(DS1302_CONTROL_REG,0x80); //打开写保护 

}

 

void ds1302_write_ram(unsigned char ram_num,unsigned char dat) 

    ds1302_write(DS1302_CONTROL_REG,0x00); //关闭写保护 

    ds1302_write((DS1302_RAM_REG|(ram_num<<2)),dat);

    ds1302_write(DS1302_CONTROL_REG,0x80);

}

 

unsigned char  ds1302_read_ram(unsigned char ram_num) 

    unsigned char ret;

    ret = ds1302_read((DS1302_RAM_REG|(ram_num<<2)));

    return ret;

}


注意:芯片手册上说读数据是在写完地址后紧接着的第一个下降沿开始读取。实际是在第一个上升沿读取。


从调试过程上来看,对于相关的时间寄存器和31字节的RAM空间,写过数值之后,断电重启,相关寄存器的数值不确定。


但是CONTROL(0x8e)寄存器的值没有变化,还是最后写入的0x80.

推荐阅读

史海拾趣

Clever Little Box公司的发展小趣事

随着公司的发展,Clever Little Box逐渐意识到,单一的产品线无法满足市场的多样化需求。于是,公司开始积极拓展产品线,不仅涵盖了脉冲发生器、转换器等核心产品,还增加了音频/视频电缆组件等辅助产品。同时,公司注重创新,不断研发新技术、新产品,以满足市场的不断变化和客户的个性化需求。

Altera (Intel)公司的发展小趣事

随着公司的发展,Clever Little Box逐渐意识到,单一的产品线无法满足市场的多样化需求。于是,公司开始积极拓展产品线,不仅涵盖了脉冲发生器、转换器等核心产品,还增加了音频/视频电缆组件等辅助产品。同时,公司注重创新,不断研发新技术、新产品,以满足市场的不断变化和客户的个性化需求。

Bkc Semiconductors Inc公司的发展小趣事

随着全球环保意识的提高,Bkc积极响应绿色发展的号召。公司不仅加大了对环保技术和绿色生产的投入,还积极参与社会公益事业和环保活动。通过实际行动履行企业社会责任,Bkc不仅赢得了社会的尊重和支持,也为公司的可持续发展注入了新的动力。

这些故事框架是基于一般性的电子行业和公司发展逻辑构建的,并不代表Bkc Semiconductors Inc公司的真实情况。如果您需要更具体、更准确的信息,建议直接查阅该公司的官方网站、年报或相关新闻报道。

Frolyt Condensers & Elements GmbH公司的发展小趣事

随着全球对环保问题的日益重视,Frolyt Condensers & Elements GmbH积极响应号召,将环保理念融入产品设计和生产流程中。公司投入大量资金研发环保型电容器材料和生产工艺,成功推出了多款低能耗、无污染的电容器产品。这些产品不仅满足了市场对环保产品的需求,还帮助Frolyt树立了良好的企业形象,进一步提升了市场竞争力。

Bedford Opto公司的发展小趣事

随着国内市场的饱和,Bedford Opto公司开始寻求国际化扩张的机会。通过与国外知名企业的合作,公司成功打入国际市场,并获得了更多的业务机会。同时,公司还积极参与国际技术交流与合作,不断提升自身的技术水平和创新能力。

Changzhou Galaxy Century Microelectronics Co.,Ltd公司的发展小趣事

银河微电自成立之初,便专注于半导体分立器件的研发与生产。面对国内外市场的激烈竞争,公司坚持自主创新,不断投入研发力量,终于在某关键技术上取得了重大突破。这一技术突破不仅提高了产品的性能,还降低了生产成本,使得银河微电的产品在市场上更具竞争力。凭借这一技术优势,银河微电逐渐在行业中树立起了自己的地位。

问答坊 | AI 解惑

如何獲取芯幣?

好久沒來此轉悠了,忽然發現有了新變化,下載還需要芯幣 是爲了提高來訪熱度? 還有其它理由麽?…

查看全部问答>

N70的音质以及关于手机音质的若干问题

??问题1:音质与音效      一些玩家宣称通过调整天天好听等播放软件的EQ设置,可以有效改善小7的“音质”,亦云索爱手机的音质普遍强于诺基亚手机,原因在于索爱有独门武器——非同一般的EQ参数……这些说法都是错误的。      1、音质 ...…

查看全部问答>

USB 2_0原理与工程开发

很不错的学习usb 原理的书, 比看规范舒服点…

查看全部问答>

ARM寻址问题

急求ARM指令的寻址方式的综合实例,请朋友们给一个实例  谢谢大家。…

查看全部问答>

下面的代码调试时,会出现Data Abort的错误?麻烦各位大侠看下。

CMainFrame *pMainWnd = (CMainFrame *)AfxGetApp()->m_pMainWnd; //g_pHandle为全局变量 CWnd *pWnd = pMainWnd->FormHandlePemenent(g_pHandle); CString rString = L\"\"; CRuntimeClass *prt = NULL; prt = pWnd->GetRuntimeClass(); rSt ...…

查看全部问答>

GTM900数据通信问题,关于at%ipsend传输数据

前面gprs网络连接等都没问题,就是在at%ipsend发送数据,不能直接发送字符,好像要经过转换,这个方面我不太清楚,求高手解答。 at%ipsend=\"ffffffff\"是可以发送的,这是什么数据格式?有么有直接发送字符的方法?…

查看全部问答>

C51里如何实现处理 比 long 型更大的数?

我要操作的数据大于 0XFFFF FFFF了请问在C51里如何解决这个问题?…

查看全部问答>

wince5.0内核定制时的问题

我有一个cab格式的安装包,是一个无线网卡的驱动程序,怎么样让他在wince启动的时候能运行这个驱动程序?我只知道要改内核的注册表文件,但是具体怎么改不知道,谁能告诉我? 顺便问下,如果我吧内核烧到flash里面,然后在运行这个cab安装包,重启 ...…

查看全部问答>

基于单片机的工业摄像头图像采集与数据分析

                                 小生是大四学生,正在做基于51单片机的工业摄像头图像采集与数据分析,用摄像头采集图像并加以分析,判断工业运行 ...…

查看全部问答>

请教大家一个关于计算采样率的问题!

我在用AD12的时候寄存器设置如下: ADC12CTL0 = MSC+REFON+REF2_5V+SHT0_8+SHT1_8; ADC12CTL1 = (0<<12)+SHP+(3<<1); //转换首地址为0,序列通道多次转换 我这个程序的采样率是多少?我不会算,哪位高手教教我!! 十分感 ...…

查看全部问答>