PCF8583内部框图:
PCF8583写时序:
PCF8583读时序:
设备地址:
模块例程:
/******************************************************************************/
/**
/** 模 块 名: -------------------IIC.C--------------------------------------
/** -----------------PCF8583实时时钟模块-------------------------*/
/** 功能描述:
/**
/** 创 建 人: huangtiexiong 日期:2006-11-28 */
/** 修 改 人: 日期:2006-11-28 */
/** 其他说明:
/******************************************************************************/
#include "Includes.h" //文件包含
/*************************************************
模块级变量申明
*************************************************/
//…………模块级变量申明在这
static void IIC_Start(void);
static void IIC_Stop(void);
static void IIC_TxByte(int8u tx_byte);
static int8u IIC_RxByte(void);
static bool IIC_WaitAck(void);
static void IIC_SendAck(void);
static void IIC_SendNoAck(void);
/*************************************************
子函数定义
*************************************************/
/*******************************************************************************
*** 函 数 名: static void IIC_Start(void)
*** 功能描述:
*** 全局变量: NO !
*** 输 入: NO !
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: Start IIC.
/******************************************************************************/
static void IIC_Start(void)
{
EA = 0; //关中断;
SDA = 1; //初始化总线;
SCL = 1;
NOP();
SDA = 0; //启动总线;
NOP();
SCL = 0; //准备数据发送,启动IIC之后传输线全部置0;
}
/*******************************************************************************
*** 函 数 名: static void IIC_TxByte(int8u tx_byte)
*** 功能描述: 发送一个字节;
*** 全局变量: NO !
*** 输 入: tx_byte
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 操作完成后保证SCL为0;
/******************************************************************************/
static void IIC_TxByte(int8u tx_byte)
{//SDA:0; SCL:0.
int8u i;
for(i=0;i<8;i++)
{
if(tx_byte & 0x80)
SDA = 1; //因为Start函数中以把SCL拉低,数据直接发送;
else
SDA = 0;
tx_byte <<= 1; //因为发送顺序:由Msb——>Lsb;
SCL = 1;
NOP(); //延时;
SCL = 0;
}
}
/*******************************************************************************
*** 函 数 名: static bool IIC_WaitAck(void)
*** 功能描述: 发送一个字节;
*** 全局变量: NO !
*** 输 入: tx_byte
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 操作完成后保证SCL为0;
/******************************************************************************/
static bool IIC_WaitAck(void)
{//SDA:U; SCL:0.
int8u waitTime = 0xff; //设置Ack信号超时数;
SDA = 1; //将数据线拉高;
SCL = 1; //启动Ack脉冲;
NOP();
while(SDA)
{
waitTime--;
if(!waitTime)
{
SCL = 0; //SCL=0;
IIC_Stop();
return FALSE;
}
}
SCL = 0; //操作完成后确认SCL为0,此时SDA=0;
return TRUE;
}
/*******************************************************************************
*** 函 数 名: static int8u IIC_RxByte(void)
*** 功能描述: 接收一个字节;
*** 全局变量: NO !
*** 输 入: NO !
*** 输 出: 接收字节:tmp
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 操作完成后保证SCL为0;
/******************************************************************************/
static int8u IIC_RxByte(void)
{//SDA:0; SCL:0;
int8u tmp = 0;
int8u i;
for(i=0;i<8;i++)
{
SCL = 0;
SDA = 1; //向I/O口写1后准备读入;
NOP();
SCL = 1;
NOP();
tmp <<= 1;
if(SDA)
{
tmp |= 0x01;
}
}
SCL = 0; //SCL=0;
return tmp;
}
/*******************************************************************************
*** 函 数 名: static void IIC_SendAck(void)
*** 功能描述: 发送应答信号;
*** 全局变量: NO !
*** 输 入: NO !
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 操作完成后保证SCL为0;
/******************************************************************************/
static void IIC_SendAck(void)
{
SDA = 0;
NOP();
SCL = 1;
NOP();
SCL = 0;
}
/*******************************************************************************
*** 函 数 名: static void IIC_SendNoAck(void)
*** 功能描述: 发送非应答信号;
*** 全局变量: NO !
*** 输 入: NO !
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 操作完成后保证SCL为0;
/******************************************************************************/
static void IIC_SendNoAck(void)
{
SDA = 1;
NOP();
SCL = 1;
NOP();
SCL = 0;
}
/*******************************************************************************
*** 函 数 名: static void IIC_Stop(void)
*** 功能描述: 终止IIC传输;
*** 全局变量: NO !
*** 输 入: NO !
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 操作完成后保证SCL为1,同时打开中断;
/******************************************************************************/
static void IIC_Stop(void)
{
SDA = 0; //to stop IIC;
SCL = 0;
NOP();
SCL = 1;
NOP();
SDA = 1; //IIC Stoped !! 结束IIC之后传输线全部置1;
EA = 1; //Set EA.
}
/*******************************************************************************
*** 函 数 名: extern void PCF8583_ReadDat(int8u addrInter,int8u num,int8u *buff)
*** 功能描述: 对PCF8583读;
*** 全局变量: NO !
*** 输 入: addrInter:内部寻址;num:数据长度;buff:数据缓存;
*** 输 出: buff数据缓存;
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: IIC Start至Stop间传输的字节数不限;
PCF8583内部寄存器地址附自增功能;
/******************************************************************************/
extern void PCF8583_ReadDat(int8u addrInter,int8u num,int8u *buff)
{
int8u i;
IIC_Start(); //启动IIC Bus;
IIC_TxByte(0xa0); //PCF8583设备寻址;命令:写;
IIC_WaitAck(); //等待Ack信号;
IIC_TxByte(addrInter); //发送内部寄存器地址;
IIC_WaitAck(); //等待Ack信号;
IIC_Start(); //参考PCF读Read Mode时序;
IIC_TxByte(0xa1); //PCF8583设备寻址,命令:读;
IIC_WaitAck();
for(i=0;i {
buff = IIC_RxByte(); //读一个字节;
IIC_SendAck(); //发送应答信号;
}
buff[num-1] = IIC_RxByte();
IIC_SendNoAck(); //最后一个字节发送非应答信号;
IIC_Stop(); //终止本次传输,IIC Bus空闲;
}
/*******************************************************************************
*** 函 数 名: extern void PCF8583_WriteDat(int8u addrInter,int8u num,int8u *buff)
*** 功能描述: 对PCF8583写;
*** 全局变量: NO !
*** 输 入: addrInter:内部寻址;num:数据长度;buff:数据缓存;
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: IIC Start至Stop间传输的字节数不限;
PCF8583内部寄存器地址附自增功能;
/******************************************************************************/
extern void PCF8583_WriteDat(int8u addrInter,int8u num,int8u *buff)
{
int8u i;
IIC_Start();
IIC_TxByte(0xa0);
IIC_WaitAck();
IIC_TxByte(addrInter);
IIC_WaitAck();
for(i=0;i {
IIC_TxByte(buff);
IIC_WaitAck();
}
IIC_Stop();
}
/*******************************************************************************
*** 函 数 名: extern void PCF8583_WriteByte(int8u addrInter,int8u val)
*** 功能描述: 对PCF8583写一个字节;
*** 全局变量: NO !
*** 输 入: addrInter:内部寻址;val:待写字节数据;
*** 输 出: NO !
*** 创 建 人:huangtiexiong 日期:2006-11-28
*** 修 改 人: 日期:2006-11-28
*** 函数说明: 参照PCF8583读时序;
/******************************************************************************/
extern void PCF8583_WriteByte(int8u addrInter,int8u val)
{
IIC_Start();
IIC_TxByte(0xa0);
IIC_WaitAck();
IIC_TxByte(addrInter);
IIC_WaitAck();
IIC_TxByte(val);
IIC_WaitAck();
IIC_Stop();
}
extern void PCF8583_Init(void)
{
PCF8583_WriteByte(0x00,0x00); //Control reg. Alarm disabled。
}
/*******************************************************************************
**** End Of File
*******************************************************************************/
附Proteus仿真抓图:
终于又可以回窝睡觉了,俺自个儿一个赞—— !
用户1262146 2009-12-30 19:35
用户1262146 2009-12-30 19:34
用户144206 2008-5-11 19:58
用户107906 2007-6-10 22:12
谢谢楼上的大哥!
用户1491292 2007-6-8 17:38
用户107906 2007-6-4 02:54
谢谢。。。
我还有一个问题想请教:我的毕业设计也是用PCF8583来做时钟芯片,要求显示时间和日历。但是PCF8583的年数据只能0-3读取,也就是只能显示四年,如此往复。假如我想让实现正常的年份显示,该怎么对程序进行修改呢?
还望不吝赐教!
用户68356 2007-6-4 01:00
那得看你的鍵盤掃描及解碼程序怎么作咯,譬如是否鍵盤消抖,一次按鍵久按不放程序作何嚮應等,放在主循環中的話你首先得計算主循環走一遍的最大時間是多少,否則易導緻按鍵丟失;建議佔用一個定時器,將鍵盤掃描及解碼程序作為該定時器中斷服務例程,而且處理起來也比較靈活。
用户107906 2007-6-3 15:51
你好,如果要在你的电路基础上加上4个键盘调节时钟,应该怎么加呢?
是程序扫描还是用中断???
用户1171155 2007-5-13 21:47
给我一分八
我的邮箱:dingpinxing@163.com
用户68356 2007-3-26 23:49
我已将代码及仿真文件附日志后,有需要的自个下。