【转】硬件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) mark 谢谢,不过附件无法下载,不知是否是改版的原因 下不了,我发贴,上传图片准是失败{:cry:} {:smile:}{:smile:} HAOTIE,DING
页:
[1]