时钟芯片RTC4543终于调试成功,分享给大家,希望有用到的人少走弯路吧
闲话不多说,先贴代码
common.h
#ifndef__COMMON_H__
#define __COMMON_H__
typedef unsigned char uint8;
typedef signed char int8;
typedef unsigned int uint16;
typedef signed int int16;
typedef unsigned long uint32;
typedef signed long int32;
typedef float fp32;
#endif
RTC4543.h
#ifndef _RTC4543DRIVER_H_
#define _RTC4543DRIVER_H_
#include "common.h"
/****************************************************************************
* 名 称:RTC_Delay
* 功 能:延时
* 入口参数:延时时间
* 出口参数:无
* 注 意:
****************************************************************************/
static void RTC_Delay(uint8 rtcdelaytime);
/****************************************************************************
* 名 称:RTC_Write
* 功 能:对RTC4543进行写入
* 入口参数:dat写入的数据,nbit写的位数,一般为8或4
* 出口参数:无
* 注 意:先写低位
****************************************************************************/
static void RTC_Write(uint8 dat,uint8 nbit);
/****************************************************************************
* 名 称:RTC_Read
* 功 能:对RTC4543进行读出
* 入口参数:nbit读的位数,一般为8或4
* 出口参数:无
* 注 意:先读低位
****************************************************************************/
static uint8 RTC_Read(uint8 nbit);
/****************************************************************************
* 名 称:Set_time()
* 功 能:RTC设置时间
* 入口参数:*P设置芯片 的时间
* 出口参数:无
* 注 意:设置的日期时间为曼彻斯特码,即BCD码,高4位代表10位,低4位代表个位
****************************************************************************/
void RTC_Settime(uint8 *p);
/****************************************************************************
* 名 称:Read_time()
* 功 能:RTC读取时间
* 入口参数:无
* 出口参数:*time
* 注 意:读取的日期时间为曼彻斯特码,即BCD码,高4位代表10位,低4位代表个位
****************************************************************************/
uint8* RTC_Readtime(void);
#endif
RTC4543.c
#include "RTC4543.h"
#include "STC12C5A60S2.h"
enum{
SETUP = 1,
CLR = 0,
};
sbit RTC_CE = P1^1;//RTC4543控制线
sbit RTC_CLK = P1^2;
sbit RTC_DATA= P1^3;
sbit RTC_WR = P1^4;
/****************************************************************************
* 名 称:RTC_Delay
* 功 能:延时
* 入口参数:延时时间
* 出口参数:无
* 注 意:
****************************************************************************/
static void RTC_Delay(uint8 rtcdelaytime)
{
uint8 i;
for(;rtcdelaytime > 0; rtcdelaytime--)
for(i = 10;i>0;i--);
}
/****************************************************************************
* 名 称:RTC_Write
* 功 能:对RTC4543进行写入
* 入口参数:dat写入的数据,nbit写的位数,一般为8或4
* 出口参数:无
* 注 意:先写低位
****************************************************************************/
static void RTC_Write(uint8 dat,uint8 nbit)
{
for(;nbit > 0; nbit--)
{
RTC_CLK = CLR;
if((dat&0x01) == 1)
{
RTC_DATA = 1;
}
else
{
RTC_DATA = 0;
}
RTC_Delay(1);
RTC_CLK = SETUP;
RTC_Delay(1);
dat >>= 1;
}
}
/****************************************************************************
* 名 称:RTC_Read
* 功 能:对RTC4543进行读出
* 入口参数:nbit读的位数,一般为8或4
* 出口参数:无
* 注 意:先读低位
****************************************************************************/
static uint8 RTC_Read(uint8 nbit)
{
uint8 dat =0;
for(;nbit > 0; nbit--)
{
RTC_CLK = CLR;
if(RTC_DATA == 1)
{
dat |= 0x80;
}
else
{
dat |= 0x00;
}
dat >>= 1;
RTC_CLK = SETUP;
RTC_Delay(1);
}
return dat;
}
/****************************************************************************
* 名 称:Set_time()
* 功 能:RTC设置时间
* 入口参数:*P设置芯片 的时间
* 出口参数:无
* 注 意:设置的日期时间为曼彻斯特码,即BCD码,高4位代表10位,低4位代表个位
****************************************************************************/
void RTC_Settime(uint8 *p)
{
RTC_WR = CLR;
RTC_CE = CLR;
RTC_CLK = CLR;
RTC_WR = SETUP;
RTC_Delay(1);
RTC_CE = SETUP;
RTC_Write(p[6],8);//设置秒钟
RTC_Write(p[5],8);//设置分钟
RTC_Write(p[4],8);//设置小时
RTC_Write(p[3],4);//设置星期
RTC_Write(p[2],8);//设置日期
RTC_Write(p[1],8);//设置月份
RTC_Write(p[0],8);//设置年份
RTC_CLK = CLR;
RTC_Delay(1);
RTC_CE = CLR;
RTC_Delay(1);
RTC_WR = CLR;
}
/****************************************************************************
* 名 称:Read_time()
* 功 能:RTC读取时间
* 入口参数:无
* 出口参数:*time
* 注 意:读取的日期时间为曼彻斯特码,即BCD码,高4位代表10位,低4位代表个位
****************************************************************************/
uint8* RTC_Readtime(void)
{
static uint8 time[7];
RTC_WR = SETUP;
RTC_DATA = SETUP;//必须
RTC_Delay(1);
RTC_CLK = CLR;
RTC_CE = CLR;
RTC_WR = CLR;
RTC_Delay(1);
RTC_CE = 1;
time[6] = RTC_Read(8)&0x7f;//读取秒钟
time[5] = RTC_Read(8)&0x7f;//读取分钟
time[4] = RTC_Read(8)&0x3f;//读取小时
time[3] =( RTC_Read(4)>>4)&0x07;//读取星期
time[2] = RTC_Read(8)&0x3f;//读取日期
time[1] = RTC_Read(8)&0x1f;//读取月份
time[0] = RTC_Read(8);//读取年份
RTC_CLK = CLR;
RTC_Delay(1);
RTC_CE = CLR;
RTC_Delay(1);
RTC_WR = SETUP;
return time;
}
刚开始画电路图的时候,是老师给的时钟电路,芯片也是他给的。他说他用RAM时用的这个芯片,想我也学学写芯片驱动。我就想老师都搞过这个东西应该不难吧,难也可以请教他嘛。于是我就用了。
写程序的时候,一看datasheet我傻眼了,好简单的数据手册,日本人做东西真不含糊啊,就两页,也没有应用手册,对于我一个新手怎么搞。
看啊看,理不出什么头绪,我就去找百度了,可是百度上的资料也少的可怜。最后,是在一个日本网站上才找到一个用AVR做控制芯片写的驱动。经过一番苦读那个代码,总算是把那些时序搞懂了。
这个芯片做的不够友好,没有寄存器读写的接口,每次读写都得要读写完整个寄存器表,即52位。。。
调试时,读出来的数据一直都是1,分析原因可能错误是:
1.时序还是没有弄对
2.芯片引脚被烧坏了
3.芯片封装做错了
于是根据以上分析去逐个排除
首先,先拿做的封装跟datasheet里面的对照,发现没有错误。
然后,对着datasheet,一步步检查时序,感觉也没有问题的。
最后,重新焊上一个芯片,调试助手发上来的数据依然为全1。
这时我快绝望的了。。。
我找来了我的老师(前面调试的时候,我也各种找他,他人很好,呵呵,不怕烦的),大神来的。。。因为他用过这个芯片,自然对它很熟悉,看了我代码也没有问题,其它也没有问题。他也表示不解。我说很怀疑这款芯片有问题。
他做各种测试,最后也不知道怎么,他想到把那两个下拉电阻拆掉,一上电竟然可以了。。。我擦。。。他给的电路在RAM可以用,在C51上有问题。。
经过一番的纠结,最后还是做出来了,不容易啊。不过写了这个驱动后,收获还是很大的。
总结几点吧:1.要敢于怀疑啊,前人的东西不一定都对的,我老师那个电路的RAM上可以用,在C51上就不行;2.坚持下去还是能解决的,给自己树立了信心。3.要善于分析问题。
希望对大家有用吧
[解决办法]
恭喜lz,其实经验这东西只能自己得益,没做过的只看看没什么印象的。
这就是嵌入式吧。
[解决办法]
感谢分享。
[解决办法]
恭喜,最好的学习进步的方式就是:发现问题->解决问题->总结经验
其实吧,学生有时太迷信老师了。我老婆就是大学教单片机的,根据我对她的了解,以及和她同事的接触,我基本可以说,大多数老师都是偏向于理论的,很多人说起来头头是道,实际代码都没怎么写过。
当然我不否认有实践能力很强的老师,只是学生不应太迷信老师,要敢于质疑。
在学校是这样,工作了以后也是一样