PCF8563与AT89C51在5V下完全工作正常,同一块PCF8563与F149在3.7V下,却始终无法读写,PCF8563无应答信号,程序也几乎一样,延时也做了调整,如下:
/**————————————————————
I2C总线驱动程序(用两个普通IO模拟I2C总线)
包括100Khz(T=10us)的标准模式(慢速模式)选择,
和400Khz(T=2.5us)的快速模式选择,
默认11.0592Mhz的晶振。
----------------------------------*/
#include <absacc.h>
#include <reg51.h>
#include <intrins.h>
#include <msp43014x.h>
html特效代码天气时钟#define uchar unsigned char
#define uint unsigned int
#define Byte unsigned char
#define Word unsigned int
#define bool bit
#define true 1
#define false 0
sbit SDA=P0^0;
sbit SCL=P0^1;
uchar SystemError;
uchar bu[8];disp[13];
void delay(unsigned int n)
{
unsigned int i;
for (i=0; i<n; i++) {;}
}
/**--------------------------------------------------------------------------------
调用方式:void I2CStart(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
void I2CStart(void)
{
EA=0;
SDA=1;
SCL=1;
delay(5);//INI
SDA=0;
delay(5); //START
SCL=0;
}
/**--------------------------------------------------------------------------------
调用方式:void I2CStop(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用
-
--------------------------------------------------------------------------------*/
void I2CStop(void)
{
SCL=0;
SDA=0;
delay(5); //INI
SCL=1;
delay(5);
SDA=1; //STOP
EA=1;
}
/
**--------------------------------------------------------------------------------
调用方式:bit I2CAck(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用,等待从器件接收方的应答
---------------------------------------------------------------------------------*/
bool WaitAck(void)
{
uchar errtime=255;//因故障接收方无ACK,超时值为255。
SDA=1;
delay(5);
SCL=1;
delay(5);
while(SDA)//判断PINSDA是否为1
{
errtime--;
if(!errtime){
I2CStop();
SystemError=0x11;
return false;}
}
SCL=0;
return true;
}
/
**--------------------------------------------------------------------------------
调用方式:void SendAck(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,应答信号。
---------------------------------------------------------------------------------*/
void SendAck(void)
{
SDA=0;
delay(5);
SCL=1;
delay(5);
SCL=0;
}
/**--------------------------------------------------------------------------------
调用方式:void SendAck(void) ﹫2001/07/0 4
函数说明:私有函数,I2C专用,主器件为接收方,从器件为发送方时,非应答信号。
--------------------------------------------------------------------------------*/
void SendNotAck(void)
{
SDA=1;
delay(5);
SCL=1;
delay(5);
SCL=0;
}
/**--------------------------------------------------------------------------------
调用方式:void I2CSend(uchar ch) ﹫2001/07/0 5
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
void I2CSendByte(Byte ch)
{
uchar i=8;
while (i--)
{
SCL=0;
_nop_();
SDA=(bit)(ch&0x80);//送高位
ch<<=1;
delay(5);
SCL=1;
delay(5);
}
SCL=0;//发送完毕
}
/**--------------------------------------------------------------------------------
调用方式:uchar I2CReceive(void) ﹫2001/07/0 5
函数说明:私有函数,I2C专用
---------------------------------------------------------------------------------*/
Byte I2CReceiveByte(void)
{
unsigned char i=8;
unsigned char ddata=0;
SDA=1;
while (i--)
{
ddata<<=1;
SCL=0;
delay(5);//等待从器件送出数据
SCL=1;
delay(5);
ddata|=SDA;
}
SCL=0;//接收完毕
return ddata;
}
//---------------------------------------------------------------------------
//开始PCF8563T驱动程序
/
**--------------------------------------------------------------------------------
调用方式:void GetPCF8563(uchar firsttype,uchar count,uchar *buff) ﹫2001/08/0 7
函数说明:读取时钟芯片PCF8563的时间,设置要读的第一个时间类型firsttype,并设置读取
的字节数,则会一次把时间读取到buff中。顺序是:
0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
---------------------------------------------------------------------------------*/
void GetPCF8563(uchar firsttype,uchar count,uchar *buff)
{
uchar i;
I2CStart();
I2CSendByte(0xA2);
WaitAck();
I2CSendByte(firsttype);
WaitAck();
I2CStart();
I2CSendByte(0xA3);
WaitAck();
for (i=0;i<count;i++)
{
buff[i]=I2CReceiveByte();
if(i!=count-1) SendAck();//除最后一个字节外,其他都要从MASTER发应答。
}
SendNotAck();
I2CStop();
}
/**--------------------------------------------------------------------------------
调用方式:void SetPCF8563(uchar timetype,uchar value) ﹫2001/08/0 7
函数说明:调整时钟。timetype是要改的时间类型,value是新设置的时间值(BCD格式)。
0x02:秒/0x03:分/0x04:小时/0x05:日/0x06:星期/0x07:月(世纪)/0x08:年
---------------------------------------------------------------------------------*/
void SetPCF8563(uchar timetype,uchar value)
{
bit re;
I2CStart();
I2CSendByte(0xA2);
re=WaitAck();
I2CSendByte(timetype);
WaitAck();
I2CSendByte(value);
WaitAck();
I2CStop();
}
/**--------------------------------------------------------------------------------
调用方式:void SetAlarmHour(uchar count) ﹫2001/08/0 7
函数说明:设置报警闹钟在一天的第count点报警。例如:count=23,则在晚上11点报警。
---------------------------------------------------------------------------------*/
void SetAlarm(uchar alarmtype,uchar count)
{
SetPCF8563(0x01,0x02)
;
SetPCF8563(alarmtype,count);
}
/**--------------------------------------------------------------------------------
调用方式:void CleanAlarm(void) ﹫2001/08/0 7
函数说明:清除所有报警设置。
-
--------------------------------------------------------------------------------*/
void CleanAlarm(void)
{
SetPCF8563(0x01,0x00);
SetPCF8563(0x09,0x80);
SetPCF8563(0x0A,0x80);
SetPCF8563(0x0B,0x80);
SetPCF8563(0x0C,0x80);
// SetPCF8563(0x0D,0x00);
// SetPCF8563(0x0E,0x03);
}
void display(void){
disp[0]=(bu[0]&0x0f);
disp[1]=(bu[0]&0x70)>>4;//秒
disp[2]=(bu[1]&0x0f);
disp[3]=(bu[1]&0x70)>>4;//分
disp[4]=(bu[2]&0x0f);
disp[5]=(bu[2]&0x30)>>4;//时
disp[6]= (bu[3]&0x0f);
disp[7]= (bu[3]&0x30)>>4;//日
disp[8]= (bu[4]&0x07);//星期
disp[9]= (bu[5]&0x0f);
disp[10]=(bu[5]&0x10)>>4;//月
disp[11]=(bu[6]&0x0f);
disp[12]=(bu[6]&0xf0)>>4;//年
}
void main(void)
{
SetPCF8563(0x00,0x00);
SetPCF8563(0x01,0x00);
SetPCF8563(0x02,0x55);//设置秒
SetPCF8563(0x03,0x59);//设置分
SetPCF8563(0x04,0x23);//设置小时
SetPCF8563(0x05,0x28);//设置日
SetPCF8563(0x06,0x01);//设置星期
SetPCF8563(0x07,0x02);//设置月、世纪
SetPCF8563(0x08,0x93);//设置年
SetPCF8563(0x0A,0x80);
SetPCF8563(0x0B,0x80);
SetPCF8563(0x0C,0x80);
SetPCF8563(0x0D,0x0B);
GetPCF8563(0x03,0xc02,bu);
while(1){
GetPCF8563(0x02,0xc08,bu);
display();
}
}
本帖版权由 lmzhj 和 利尔达 共同拥有,未经许可不得转载。
lmzhj
查看公开信息
查lmzhj发表的更多帖子
添加 lmzhj 到好友列表
2003-07-27, 10:10 #2
lmzhj
初级会员
注册日期: Apr 2003
帖子: 14
精华: 0
现金: 20 元
资产: 20 元
声望: 10
续上
--------------------------------------------------------------------------------
续上
#include <msp430x14x.h>
#define uchar unsigned char
#define uint unsigned int
#define SDA BIT5 //SDA P2.5
#define SCL BIT4 //SCL P2.4
#define true 0x01
#define false 0x00
#define SDA_1 P2DIR&=~SDA //拉高 SDA = 1
#define SDA_0 P2DIR|= BIT5;P2OUT&=~SDA //SDA = 0
#define SCL_1 P2DIR&=~SCL //拉高 SCL = 1
#define SCL_0 P2DIR|= BIT4;P2OUT&=~SCL //SCL = 0
#define DIR_IN P2DIR&=~BIT5 //I/O(sda)口为输入
#define DIR_OUT P2DIR|= BIT5 //I/0(sda)口为输出
#define SDA_IN ((P2IN >> 5) & 0x01) //Read SDA.
unsigned char bu[8];
unsigned char SystemError;
void sysclk_set(void) //系统时钟设置
{
unsigned char i;
// BCSCTL1 &= ~(XT2OFF+XTS); // XT2开启,LFX1工作在低频
BCSCTL2 |= SELM1+SELS; // MCLK=SMCLK=XT2
do{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for(i=0xFF;i>0;i--); // Time for flag to set
}
while((IFG1 & OFIFG)!=0); // OSCFault flag still set?
BCSCTL2 |= SELM1+SELS; // MCLK=SMCLK=XT2
}
void ports_init(void) //端口初始化
{
P1DIR=0xFF; //P1为输出
P1OUT=0x00;
P2DIR=0xFF; //P1为输出
P2OUT=0x00;
P4DIR=0xFF; //P4为输出
P5DIR=0xFF; //P5为输出
P6SEL=0x7F; // 全部为外围
模块ADC功能
P6DIR=0x80;
}
/***********************************************
延时函数:void Delay(unsigned int n)
************************************************/
static void delay(unsigned int n)
{
unsigned int i;
for (i=0; i<n; i++) {;}
}
/***********************************************
调用方式:void I2Cstart(void)
************************************************/
void I2CStart(void)
{
//EA=0;//关所有中断
SDA_1;
SCL_1;
delay(5);
SDA_0;
delay(5);
SCL_0;
}
/***********************************************
停止:void I2CStop(void)
************************************************/
void I2CStop(void)
{
SCL_0;
SDA_0;
delay(5);
SCL_1;
delay(5);
SDA_1;//stop
//开中断EA=1;
}
/***********************************************
等待应答?unsigned char WaitAck(void)
等待从器件接收方的应答
************************************************/
unsigned char WaitAck(void)
{
uchar errtime=255;//因故障接收方无ACK,超时值为255
SDA_1;
delay(5);
SCL_1;
// P2DIR&=~SDA;//切换为输入
while((P2IN&BIT5)==BIT5)//判断PINSDA是否为1
{
errtime--;
if(!errtime)
{I2CStop();
SystemError=0x11;
return false;
}
}
SCL_0;
return true;
}
/***********************************************
应答:void SendAck(void)
主器件为接收方,从器件为发送方,应答信号
************************************************/
void SendAck(void)
{
SDA_0;
delay(5);
SCL_1;
delay(5);
SCL_0;
}
/***********************************************
非应答:void SendNotAck(void)
主器件为接收方,从器件为发送方
************************************************/
void SendNotAck(void)
{
SDA_1;
delay(5);
SCL_1;
delay(5);
SCL_0;
}
/***********************************************
发送字节:void I2CSendByte(unsigned char ch)
发送一个字节
************************************************/
void I2CSendByte(unsigned char ch)
{
uchar i=8;
while(i--)
{
SCL_0;
delay(5);
if(ch&0x80==0X80){SDA_1;}
else{SDA_0;}
ch<<=1;
delay(5);
SCL_1;
delay(5);
}
SCL_0;//发送完毕
}
/***********************************************
接收字节:Byte I2CReceieveByte(void)
接收一个字节
************************************************/
unsigned char I2CReceieveByte(void)
{
unsigned char i=8;
unsigned char ddata=0;
SDA_1;
while(i--)
{
ddata<<=1;
SCL_0;
delay(5);//等待从器件送出数据
SCL_1;
delay(5);
P2DIR&=~SDA;
if(P2IN&SDA)ddata++;//非0
delay(5);
}
SCL_0;//接收完毕
return ddata;
}
/***********************************************
PCF8563驱动
void GETPCF8563(uchar firsttype,uchar count,uchar *buFF)
功能:读取时钟芯片8563的时间,要设置要读的第一个时间类型
firsttype,并设置读取的字节数,则一次把时间读取到buFF中,
顺序是:0x02:秒,0x03:分,0x04:小时,0x05:日,0x06:星期,
0x07:月(世纪),0x08年:
**********************************************
**/
void GetPCF8563(unsigned char firsttype,unsigned char count,unsigned char *buff)
{
uchar i;
I2CStart();
I2CSendByte(0xA2);//
WaitAck();
I2CSendByte(firsttype);
WaitAck();
I2CStart();
I2CSendByte(0xA3);
WaitAck();
for(i=0;i<count;i++)
{
buff[i]=I2CReceieveByte();
if(i!=count-1)SendAck();//除非最后一个字节,其它都要从MASTER发应答
SendNotAck();
I2CStop();
}
}
/***********************************************
PCF8563驱动
void SetPCF8563(uchar timetype,uchar value)
功能:调整时钟芯片8563的时间,timetype要改的类型,value是新设置的
时间值(BCD格式),顺序是:
0x02:秒,0x03:分,0x04:小时,0x05:日,0x06:星期,
0x07:月(世纪),0x08年:
************************************************/
void SetPCF8563(unsigned char timetype,unsigned char value)
{
unsigned char te;
I2CStart();
I2CSendByte(timetype);
te=WaitAck();
I2CSendByte(value);
WaitAck();
I2CStop();
}
/***********************************************
PCF8563驱动
void SetAlarmHOUR(uchar count)
功能:设置报警闹钟在一天的第count点报警
************************************************/
void SetAlarmHOUR(unsigned char alarmtype,unsigned char count)
{
SetPCF8563(0x01,0x02);
SetPCF8563(alarmtype,count);
}
/***********************************************
PCF8563驱动
void CleanAlarm(void)
功能:清除所有报警
************************************************/
void CleanAlarm(void)
{
SetPCF8563(0x01,0x00);
SetPCF8563(0x09,0x80);
SetPCF8563(0x0A,0x80);
SetPCF8563(0x0B,0x80);
SetPCF8563(0x0C,0x80);
SetPCF8563(0x01,0x00);
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;// Stop watchdog timer
sysclk_set();
ports_init();
//关所有中断
SetPCF8563(0x00,0x00);
SetPCF8563(0x01,0x00);
SetPCF8563(0x02,0x55);//设置秒
SetPCF8563(0x03,0x59);//设置分
SetPCF8563(0x04,0x23);//设置小时
SetPCF8563(0x05,0x28);//设置日
SetPCF8563(0x06,0x01);//设置星期
SetPCF8563(0x07,0x02);//设置月、世纪
SetPCF8563(0x08,0x93);//设置年
SetPCF8563(0x0A,0x80);
SetPCF8563(0x0B,0x80);
SetPCF8563(0x0C,0x80);
SetPCF8563(0x0D,0x0B);
_NOP();
}
好多天也查不出是何原因。请版主和高手指点!谢谢!
本帖版权由 lmzhj 和 利尔达 共同拥有,未经许可不得转载。
lmzhj
查看公开信息
查lmzhj发表的更多帖子
添加 lmzhj 到好友列表
2003-08-04, 22:06 #3
htdlwzf
初级会员
注册日期: Jul 2003
帖子: 3
精华: 0
现金: 0 元
资产: 0 元
声望: 10
把c51的程序直接这样翻译我也做过,就是不成,因为51不像430要设置端口方向,你因该用逻辑分析仪或数字示波器分析波形是否符合iic总线要求,我调8563通过了。
本帖版权由 htdlwzf 和 利尔达 共同拥有,未经许可不得转载。
htdlwzf
查看公开信息
查htdlwzf发表的更多帖子
添加 htdlwzf 到好友列表
2003
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论