sailorxing2 发表于 2011-7-30 00:35:49

【转】硬件TWI控制PCF8563的程序

几个月前,在古欣的指导下,我完成了这个程序。目前,这个程序是我在项目上用得很多的。现将有关硬件TWI控制PCF8563的部分贴出,供大家参考。其中时钟数组的定义请在主函数里完成。

/*******************************************
*   PCF8563的I2C(TWI)操作函数       *
* 文 件 名:TWI_8563.h               *
* 函数功能:利用CPU的硬件TWI接口操作   *
* 设   计:铜河                   *
* 修改日期:2007年04月09日             *
* 版   本:V1.0                   *
* 主控芯片:Mega16                   *
*******************************************/
#include <iom16v.h>
#include <macros.h>
//宏定义
//状态寄存器TWSR各种状态定义
//主模式启动状态
#define START         0x08   //启动总线
#define RESTART         0x10   //重新启动总线

//主发送模式各种状态
#define MT_SLA_ACK   0x18   //SLA_W写地址已发送,收到应答位
#define MT_SLA_NACK   0x20   //SLA_W写地址已发送,收到非应答位
#define MT_DATA_ACK   0x28   //写入数据已发送,收到应答位
#define MT_DATA_NACK   0x30   //写入数据已发送,收到应答位
#define MT_ARB_LOST   0x38   //SLA_W或数据仲裁失败

//主接收模式各种状态
#define MR_ARB_LOST   0x38   //
#define MR_SLA_ACK   0x40   //SLA_R已发送,收到应答位
#define MR_SLA_NACK   0x48   //SLA_R已发送,收到非应答位
#define MR_DATA_ACK   0x50   //接收到数据,应答位已返回
#define MR_DATA_NACK   0x58   //接收到数据,非应答位已返回

#define SLA_W         0xA2       //PCF8563写从地址
#define SLA_R         0xA3   //PCF8563读从地址

#define start()         (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define stop()         (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define waitack()   {while(!(TWCR&(1<<TWINT)));}
#define chkack()       (TWSR&0xf8)             //check ack
#define sendack()   (TWCR|=(1<<TWEA))
#define sendnack()   (TWCR&=~(1<<TWEA))
#define sendbyte(x)   {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
#define rcvnckbyte()   (TWCR=(1<<TWINT)|(1<<TWEN))
#define rcvackbyte()   (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA))

/* I2C Config */
#define I2C_ERR         0
#define I2C_CRR         1

//简化宏定义
#define uchar unsigned char
#define uint unsigned int


//TWI初始化
void Twi_Init(void)
{
TWBR=14;
TWSR=0;
}

//写入时间函数
uchar write_tim(uchar a)
{   
sendbyte(a);             //发送
waitack();               //等待写完成
if(chkack()!=MT_SLA_ACK)return I2C_ERR; //检查是否正确写入
else return I2C_CRR;
}
//读出时间函数
uchar read_tim(void)
{
rcvackbyte();               //接收一字节并返回应答
waitack();               //等待接收完成
if(chkack()!=MR_DATA_ACK)return I2C_ERR;       //检查是否接收成功
//   return I2C_ERR;
else
    return(TWDR);             //读出时钟数据
}

/**********************************
*       读出数据函数         *
**********************************/
uchar read_timer(void)
{
start();                   //启动总线
waitack();               //等待启动完成
if(chkack()!=START)return I2C_ERR;       //检查是否启动成功
write_tim(SLA_W);             //发送写地址
write_tim(0x02);             //写数据地址

start();
waitack();               //等待启动完成
if(chkack()!=RESTART)return I2C_ERR;   //检查是否启动成功
write_tim(SLA_R);             //发送读地址

timer=read_tim()&0x7F;       //读出秒数据
timer=read_tim()&0x7F;       //读出分数据
timer=read_tim()&0x3F;       //读出时数据
timer=read_tim()&0x3F;       //读出日数据
timer=read_tim()&0x07;       //读出周数据
    if(timer==0)timer=7;
timer=read_tim();         //读出月数据
    if((timer&0x80)==0)
      timer=0x20;         //世纪位为0,是21世纪
    else timer=0x19;         //世纪位不为0,是20世纪
timer=timer&0x1F;
timer=read_tim();         //读出年数据
stop();
return I2C_CRR;
}

/**********************************
*       写入时钟函数         *
**********************************/
uchar write_timer(void)
{
start();                   //启动总线
waitack();               //等待启动完成
if(chkack()!=START)return I2C_ERR;       //检查是否启动成功
write_tim(SLA_W);             //发送写地址
write_tim(0x00);             //写数据首地址
write_tim(0x20);             //写控制/状态寄存器1,暂停计时
write_tim(0x00);             //写控制/状态寄存器2
write_tim(0x00);             //写秒数据为0
write_tim(timer);         //写分数据
write_tim(timer);         //写时数据
write_tim(timer);         //写日数据
write_tim(timer);         //写周数据
write_tim(timer);         //写月数据
write_tim(timer);         //写年数据
stop();
return I2C_CRR;
}

/**********************************
*       启动时钟函数         *
**********************************/
uchar start_timer(void)
{
start();                   //启动总线
waitack();               //等待启动完成
if(chkack()!=START)return I2C_ERR;       //检查是否启动成功
write_tim(SLA_W);             //发送写地址
write_tim(0x00);             //写数据首地址
write_tim(0x00);             //写控制/状态寄存器1,暂停计时
stop();
return I2C_CRR;
}

完整的工作项目文件如下:
点击此处下载 ourdev_662050Z55IX3.rar(文件大小:71K) (原文件名:1602_time.rar)

zhaohui293 发表于 2011-8-19 08:12:51

mark

FLYMOUSE 发表于 2012-3-26 10:32:20

谢谢,不过附件无法下载,不知是否是改版的原因

sszzeettee 发表于 2012-3-26 10:37:31

下不了,我发贴,上传图片准是失败{:cry:}

dawenfly 发表于 2012-5-15 11:41:55

{:smile:}{:smile:}

fanice 发表于 2012-9-5 18:24:20

HAOTIE,DING
页: [1]
查看完整版本: 【转】硬件TWI控制PCF8563的程序