请问为什么我在IAR调试时钟芯片PCF8563在线编译时,它的秒跟分钟都是从0x7F开始,而不是从0开始,0x7F是在读的时候,让读出来的数与0x7F相"与"(下图所示),但是如果秒的初始值是0的话,与0x7F相'与'最后得到的秒应该也是0才对,但是编译时显示秒的值是0x7F,求会的朋友给下意见
程序如下:
#include "msp430.h"
#define PCF8563_RTC 0xA2 /* 定义器件地址 */
#define SDA_1 P3OUT |= BIT1 //SDA = 1
#define SDA_0 P3OUT &=~ BIT1 //SDA = 0
#define SCL_1 P3OUT |= BIT3 //SCL = 1
#define SCL_0 P3OUT &=~ BIT3 //SCL = 0
#define DIR_IN P3DIR &=~ BIT1 //I/O口为输入
#define DIR_OUT P3DIR |= BIT1 //I/0口为输出
#define SDA_IN ((P3IN >> 1) & 0x01) //Read SDA
#define over_time 255 /*应答超时门限*/
unsigned char Seconds;
unsigned char Minutes;
unsigned char hour;
unsigned char month;
unsigned char day;
unsigned char week;
unsigned char year;
unsigned char shiwei;
unsigned char Seconds1;
unsigned char Minutes1;
unsigned char hour1;
unsigned char month1;
unsigned char day1;
unsigned char week1;
unsigned char year1;
unsigned char shiwei1;
unsigned char temp1;
unsigned char temp2;
unsigned int tol;
unsigned char WriteByte(unsigned char dev_address,unsigned char sub_address, unsigned char sendData);
void pcf_init();
//----------------PCF8563初始化-----------------
void pcf_init()
{
WriteByte(PCF8563_RTC,0x00, 0x00); //启动时钟
}
/****************************************************************************
* 名称:Sys_Ini()
* 功能:系统初始化
* 入口参数:无
* 出口参数:无
****************************************************************************/
void Sys_Ini(void)
{
unsigned int i;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 &= ~XT2OFF; // XT2on
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG)); // OSCFault flag still set?
BCSCTL2 |= SELM_2 + SELS + DIVS_3;// MCLK/8 = SMCLK = XT2/8 (safe)
P3DIR |= 0xff; // P4 output
//P5DIR |= 0x0f;
}
/****************************************************************************
* 名称:Delay1us()
* 功能:us单位的延时函数
* 入口参数:us
* 出口参数:无
****************************************************************************/
void Delay1us(unsigned char us)
{
unsigned char i;
while (us)
{
for(i=0;i<20;i++)
;
--us;
}
}
/****************************************************************************
* 名称:DelayMS()
* 功能:ms级单位的延时函数
* 入口参数:dly
* 出口参数:无
****************************************************************************/
void DelayMS(unsigned int dly)//延时1ms
{ unsigned int i;
for(; dly>0; dly--)
for(i=0; i<1135; i++);
}
/*********************************************************************************
* 名称:Delay()
* 功能:短软件延时
* 入口参数:n 延时参数 : 1us
* 出口参数:无
**********************************************************************************/
void Delay(unsigned int n)
{
unsigned int i;
for (i=0; i<n;i++);
}
/**--------------------------------------------------------------------------------
调用方式:void Init(void) ﹫2002/01/2 40 4
函数说明:私有函数,I2C专用,I2C初始化函数
---------------------------------------------------------------------------------*/
void Init(void)
{
SDA_1; //拉高数据线
Delay(5);
SCL_1; //时钟保持高电平
Delay(5);
}
/**--------------------------------------------------------------------------------
调用方式:void Start(void) ﹫2002/01/2 40 4
函数说明:私有函数,I2C专用,起始条件函数
数据线下降沿而时钟线为高电平时为起始条件
---------------------------------------------------------------------------------*/
void Start(void)
{
DIR_OUT;
SDA_1;
SCL_1;
Delay(5); //INI
SDA_0;
Delay(5); //START
SCL_0;
}
/**------------------------------------------------------------------------------*/
/**--------------------------------------------------------------------------------
调用方式:void Stop(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用,结束条件函数
数据线上降沿而时钟线为高电平时为结束条件
---------------------------------------------------------------------------------*/
void Stop(void)
{
DIR_OUT;
SCL_0;
SDA_0;
Delay(5);
SCL_1;
Delay(5); //INI
SDA_1; //STOP
Delay(5);
}
/**--------------------------------------------------------------------------------
调用方式:SendByte(unsigned char WriteData) ﹫2001/07/0 5
函数说明:私有函数,I2C专用,发送一字节
---------------------------------------------------------------------------------*/
void SendByte(unsigned char WriteData)
{
unsigned char i;
for (i=0; i<8; i++)
{
DIR_OUT; //把P4.7设为输出
if (((WriteData >> 7) & 0x01) == 0x01) //输出8位到RTC
{
SDA_1;
}
else
{
SDA_0;
}
Delay(5);
SCL_1; //时钟高电平
WriteData = WriteData << 1; //待发数据左移一位
Delay(5); //保证时钟高电平周期大于4μs
SCL_0; //时钟置为低电平,发送一位
Delay(5);
}
DIR_IN; //把P4.7设为输入
Delay(5);
SCL_0; //置时钟为低电平
Delay(5);
}
/**--------------------------------------------------------------------------------
调用方式:unsigned char ReadByte(void) ﹫2001/07/0 5
函数说明:私有函数,I2C专用,接收一字节
---------------------------------------------------------------------------------*/
unsigned char ReceiveByte(void)
{
unsigned char i;
unsigned char TempBit = 0;
unsigned char TempData = 0;
SDA_1; //拉高数据线
Delay(5);
DIR_IN; //把P4.7设为输入
for (i=0; i<8; i++) //主机接收8位
{
SCL_1; //置时钟为高电平
Delay(5); //时钟低电平周期大于4.7μs
if (SDA_IN == 0x01 ) //判断输入最低位是否为1
{
TempBit = 1;
}
else
{
TempBit = 0;
}
TempData = (TempData << 1) | TempBit; //数据左移一位且接收1位数据
SCL_0; // 置时钟为低电平
Delay(5);
}
DIR_OUT; //把P4.7设为输出
return(TempData); //返回接收的数据
}
/**--------------------------------------------------------------------------------
调用方式:unsigned char ReceiveAck(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用,等待从器件接收方的应答
---------------------------------------------------------------------------------*/
unsigned char ReceiveAck(void)
{
//unsigned errtime=over_time; /*因故障接收方无ACK,超时值为255。*/
SDA_1; //置高数据线 准备接收应答位
Delay(5); //时钟低电平周期大于4μs
SCL_1;
Delay(5);
DIR_IN; //把P4.7设为输入
//while (SDA_IN == 0x01) /*此语句可有可无*/
//{
// errtime--;
//if (!errtime)
// {
// Stop();
// return 0x00;
// }
//}*/
SCL_0;
Delay(5);
return(0x01); //返回应答信号
}
/**--------------------------------------------------------------------------------
调用方式:void Acknowledge(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,应答信号。
--------------------------------------------------------------------------------*/
void Acknowledge(void)
{
DIR_OUT; //把P4.7设为输出
SDA_1;
SCL_0;
Delay(5);
SDA_0; //置SDA为高电平 发出应答信号
Delay(5); //时钟低电平周期大于4μs
SCL_1;
Delay(5);
SCL_0; //清时钟线,钳住I2C总线以便继续接收
Delay(5);
SDA_1;
}
/**--------------------------------------------------------------------------------
调用方式:void Acknowledge(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,非应答信号(拒绝应答)。
--------------------------------------------------------------------------------*/
void NAcknowledge(void)
{
DIR_OUT; //把P4.7设为输出
SDA_0;
SCL_0;
Delay(5);
SDA_1; //置SDA为高电平 发出应答信号
Delay(5);
SCL_1;
Delay(5); //时钟低电平周期大于4μs
SCL_0; //清时钟线,钳住I2C总线以便继续接收
Delay(5);
SDA_0;
}
/*******************************************************************
向有子地址器件发送1字节数据函数
函数原型: unsigned char ReadByte(unsigned char dev_address,unsigned char sub_address);
功能: 从启动总线到发送地址,子地址,结束总线的全过程,从器件
地址dev_address,子地址sub_address.
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
unsigned char ReadByte(unsigned char dev_address/*dev_address*/,unsigned char sub_address/*sub_address*/)
{
unsigned char RecData = 0;
Start(); //启动总线
SendByte(dev_address); //发送器件地址
ReceiveAck();
SendByte(sub_address); //发送器件子地址
ReceiveAck();
Delay(100);
Start(); //重新启动总线
SendByte(0xA3);
ReceiveAck();
RecData = ReceiveByte();
NAcknowledge();
Stop(); //结束总线
return(RecData);
}
/*******************************************************************
向有子地址器件读取1字节数据函数
函数原型: unsigned char WriteByte(unsigned char dev_address,unsigned char sub_address, unsigned char sendData);
功能: 从启动总线到发送地址,子地址,结束总线的全过程,从器件
地址sla,子地址suba.
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
unsigned char WriteByte(unsigned char dev_address,unsigned char sub_address, unsigned char sendData)
{
Start(); //启动总线
SendByte(dev_address); //发送器件地址
if(ReceiveAck()==0x01) //判断是否出错
{
SendByte(sub_address); //发送器件子地址
if(ReceiveAck()==0x01) //判断是否出错
{
SendByte(sendData); //发送数据
if(ReceiveAck()==0x01) //判断是否出错
{
Stop(); //结束总线
return(0x01);
}
else
{
Stop(); //结束总线
return(0x00);
}
}
else
{
Stop();
return(0x00);
}
}
else
{
Stop();
return(0x00);
}
}
/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时 调试时用
* 入口参数:dly 延时参数 : 1ms
* 出口参数:无
****************************************************************************/
void DelayNS(unsigned int dly)
{ unsigned int i,j;
for(j=0; j<=dly; j++)
{
for(i=0; i<1135; i++);
}
}
/********************************************************************************
*函数名: Rtc_ReadTime()
*参数: 无
*返回值: true(OK);false(ERROR)
*描述: 从Rtc读取时间
*编写: bobo.li
*版本信息:
********************************************************************************/
void Rtc_ReadTime(void)
{
Seconds = ReadByte(PCF8563_RTC,0x02)&0x7f; //读秒
Minutes = ReadByte(PCF8563_RTC,0x03)&0x7f; //读分
hour = ReadByte(PCF8563_RTC,0x04)&0x3f; //读时
day= ReadByte(PCF8563_RTC,0x05)&0x3f; //读天
week= ReadByte(PCF8563_RTC,0x06)&0x07; //读周
month = ReadByte(PCF8563_RTC,0x07)&0x1f; //读月
year = ReadByte(PCF8563_RTC,0x08); //读年
}
//----------------BCD转10进制-----------
unsigned char bcd_dec(unsigned char bat)
{
/*unsigned char temp1,temp2,tol;*/
temp1=bat&0x0f;
temp2=(bat&0xf0)>>4;
tol=temp2*10+temp1;
return tol;
}
void main (void)
{
shiwei=0x00;
Sys_Ini();
Init();
pcf_init();
WriteByte(PCF8563_RTC,0x02, 0x00); //秒的初始值
WriteByte(PCF8563_RTC,0x03, 0x00); //分的初始值
WriteByte(PCF8563_RTC,0x04, 0x00); //时的初始值
WriteByte(PCF8563_RTC,0x05, 0x00); //天的初始值
WriteByte(PCF8563_RTC,0x06, 0x00); //周的初始值
WriteByte(PCF8563_RTC,0x07, 0x00); //月的初始值
WriteByte(PCF8563_RTC,0x08, 0x00); //年的初始值
while(1)
{
Rtc_ReadTime();
Seconds1=bcd_dec(Seconds);
Minutes1=bcd_dec(Minutes);
hour1=bcd_dec(hour);
month1= bcd_dec(month);
day1=bcd_dec(day);
week1=bcd_dec(week);
year1=bcd_dec(year);
//shiwei1=bcd_dec(shiwei);
}
}