#include <msp430x54x.h>
#define SDA_1 P3OUT |= BIT7 //SDA = 1
#define SDA_0 P3OUT &=~ BIT7 //SDA = 0
#define SCL_1 P5OUT |= BIT4 //SCL = 1
#define SCL_0 P5OUT &=~ BIT4 //SCL = 0
#define DIR_IN P3DIR &=~ BIT7 //I/O口为输入
#define DIR_OUT P3DIR |= BIT7 //I/0口为输出
#define SDA_IN (P3IN & 0x80) //Read SDA
void Delay(void);
void start_I2C(void);
void stop_I2C(void);
void send_char(void);
int write_PCF8563();
unsigned char ctrl_Buf,ack, slave_addr, write_addr, writedata;
main()
{ WDTCTL = WDTPW+WDTHOLD; //关闭看门狗定时器
int Y;
P3DIR |= BIT7;
P5DIR |= BIT4;
slave_addr=0xA2;
write_addr=0x02;
writedata=59;
Y=write_PCF8563();
}
void Delay(void)
{_NOP();}
void start_I2C(void) //I2C的开始条件
{ SDA_1;
Delay();
SCL_1;
Delay();
SDA_0;
Delay();
SCL_0; // 钳住I2C总线,准备发送或接收数据
Delay();
}
void stop_I2C(void) //I2C的停止条件
{ SDA_0;
Delay();
SCL_1;
Delay();
SDA_1;
Delay();
}
void send_char(void) //发送一字节数据
{unsigned char cnt, tmp=0x80;
for(cnt=0;cnt<8;cnt++)
{if((ctrl_Buf&tmp)>0)
{SDA_1;}
else{SDA_0;}
tmp=tmp/2; //tmp右移一位
SCL_1; //置时钟线为高,通知从机开始接收数据位
Delay();
SCL_0;
}
Delay();
SDA_1; //8位发送完后释放数据线,准备接收应答位
Delay();
SCL_1;
DIR_IN;
if(SDA_IN ==1) //判断是否接收到应答信号
ack=0; //无应答
else ack=1; //应答
SCL_0;
Delay();
DIR_OUT;
}
int write_PCF8563()
{ start_I2C(); //启动总线
ctrl_Buf=slave_addr;
send_char(); //发送器件地址
if(ack==0)
return 0 ;
ctrl_Buf=write_addr;
send_char(); //发送器件子地址
if(ack==0)
return 0 ;
ctrl_Buf=writedata;
send_char(); //发送数据
if(ack==0)
return 0 ;
stop_I2C(); //结束总线
return 1;
}
这是用5438给PCF8563写数据的一个程序,用IAR编译后,查看Y的值(Y的作用是说明数据是否写入),显示ERROR.检查半天也不知道哪里出错,希望大家给看看
PS:MCLK=1.045MHZ
因为写数据过程中用不到ACK和NACK(即应答和不应答),所以没写。
因为PCF8563里数据存储为BCD码格式,会是这个原因吗?
[
本帖最后由 zzbaizhi 于 2012-2-17 16:53 编辑 ]
此帖出自
小平头技术问答
1 ack为应答标志位,无应答时ack=0,有应答时ack=1.如果从机无应答说明发送数据失败,write_PCF8563()返回0给Y, 主机发送 stop_I2C(); //结束总线 后说明发送数据成功,write_PCF8563()返回1给Y。所以通过判断Y的值,来判断写数据是否成功。
2 在写数据过程中,主机发送一个字节后便检测应答以确认从机是否收到,所以主机只需要检测,而从机应答(ACK).我觉得主机不需要应答,所以就把ACK去掉了。如果需要加上ACK这个子函数的话,是为了给从机用吗?
3 使用PCF8563时,一定要使用它的驱动程序吗?
[ 本帖最后由 zzbaizhi 于 2012-2-19 09:45 编辑 ]一周热门 更多>