历史上的今天
今天是: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.
史海拾趣
|
??问题1:音质与音效 一些玩家宣称通过调整天天好听等播放软件的EQ设置,可以有效改善小7的“音质”,亦云索爱手机的音质普遍强于诺基亚手机,原因在于索爱有独门武器——非同一般的EQ参数……这些说法都是错误的。 1、音质 ...… 查看全部问答> |
|
下面的代码调试时,会出现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 ...… 查看全部问答> |
|
前面gprs网络连接等都没问题,就是在at%ipsend发送数据,不能直接发送字符,好像要经过转换,这个方面我不太清楚,求高手解答。 at%ipsend=\"ffffffff\"是可以发送的,这是什么数据格式?有么有直接发送字符的方法?… 查看全部问答> |
|
我有一个cab格式的安装包,是一个无线网卡的驱动程序,怎么样让他在wince启动的时候能运行这个驱动程序?我只知道要改内核的注册表文件,但是具体怎么改不知道,谁能告诉我? 顺便问下,如果我吧内核烧到flash里面,然后在运行这个cab安装包,重启 ...… 查看全部问答> |
|
我在用AD12的时候寄存器设置如下: ADC12CTL0 = MSC+REFON+REF2_5V+SHT0_8+SHT1_8; ADC12CTL1 = (0<<12)+SHP+(3<<1); //转换首地址为0,序列通道多次转换 我这个程序的采样率是多少?我不会算,哪位高手教教我!! 十分感 ...… 查看全部问答> |




